<jupyter_start><jupyter_text>Before you begin, execute this cell to import numpy and packages from the D-Wave Ocean suite, and all necessary functions for the gate-model framework you are going to use, whether that is the Forest SDK or Qiskit. In the case of Forest SDK, it also starts the qvm and quilc servers.<jupyter_code>%run -i "assignment_helper.py"
%matplotlib inline<jupyter_output><empty_output><jupyter_text>State preparationAs explained in <NAME>'s guest lecture, to prepare a state in a particular encoding is done by rotating vectors, in other words to map vectors into others, which is the basic idea of kernel learning. This procedure gives rise to interesting kernels, without the need of specifying the mapping function.Let us work with an easy training data set of two vectors, $S = \{(\begin{bmatrix}0 \\ 1\end{bmatrix}, 0), (\begin{bmatrix}\frac{1}{2}\sqrt{2} \\ \frac{1}{2}\sqrt{2}\end{bmatrix}, 1)\}$. Let's have a test instance $\begin{bmatrix}1 \\ 0\end{bmatrix}$. We will build the interference circuit for this.**Exercise 1** (1 point).Create a circuit in your preferred framework that works on four qubits: ancilla, index, data, and class. Put the ancilla and index qubits into a uniform superposition. Verify for yourself that this also encodes the test data in the coefficients of the $|0000\rangle$, $|0100\rangle$ states as well as in the $|0010\rangle$, $| 0110\rangle$ states.Place your solution in an object called `circuit`.<jupyter_code>###
### YOUR CODE HERE

ancilla_qubit = 0
index_qubit = 1
data_qubit = 2
class_qubit = 3

# Verify for yourself that this preparation is also sufficient to represent the test vector

###
amplitudes = get_amplitudes(circuit)
assert np.allclose(amplitudes, np.array([0.5 +0.j, 0.5+0.j, 0.5 +0.j, 0.5+0.j, 0.+0.j, 0. +0.j, 0.+0.j,
       0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j]))<jupyter_output><empty_output><jupyter_text>**Exercise 2** (1 point).Extend the circuit to prepare the first training instance, by pushing the feature values into the coefficients of the $|0001\rangle$ and $|0101\rangle$, without affecting any of the other coefficients.<jupyter_code>###
### YOUR CODE HERE


###
amplitudes = get_amplitudes(circuit)
assert np.allclose(amplitudes, np.array([0.5 +0.j, 0. +0.j, 0.5 +0.j, 0.5+0.j, 0.+0.j, 0.5+0.j, 0.+0.j,
       0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j]))<jupyter_output><empty_output><jupyter_text>**Exercise 3** (2 points).As a final step in the preparation, extend the circuit to push the feature values of the second training instance into the coefficients of the $|0011\rangle$ and $|0111\rangle$ states.Remember that, as explained in the lecture notebook, loading vectors with amplitude encoding requires to apply a double controlled rotation by an angle determined by the coordinates of the vector.<jupyter_code>###
### YOUR CODE HERE


###
amplitudes = get_amplitudes(circuit)
assert np.allclose(amplitudes, np.array([0.5 +0.j,  0. +0.j,  0.5 +0.j,  np.sqrt(2)/4 + 0.j,  0.+0.j,  0.5+0.j,
       0.+0.j,  np.sqrt(2)/4 +0.j,  0. +0.j,  0. +0.j,  0. +0.j,  0. +0.j, 0. +0.j,  0. +0.j,  0. +0.j,  0. +0.j]))<jupyter_output><empty_output><jupyter_text>**Exercise 4** (1 point). Finish the state preparation circuit by a conditional flip of the class qubit, such that the coefficients of the second training vector and those of the copy of the test vector have the class bit equal to 1, without affecting any of the other coefficients.It is very useful at this point, for testing purposes, to add code which shows the state vectors, as done in the lecture notebook<jupyter_code>###
### YOUR CODE HERE

###

amplitudes = get_amplitudes(circuit)
assert np.allclose(amplitudes, np.array([ 0.5 +0.j,  0.  +0.j,  0. +0.j,  0.+0.j, 0.  +0.j,  0.5 +0.j,  0. +0.j,  0.+0., 0.  +0.j,  0.  +0.j,  0.5+0.j,  np.sqrt(2)/4 +0j, 0.  +0.j,  0.  +0.j,  0. +0.j,  np.sqrt(2)/4 +0.j]))<jupyter_output><empty_output><jupyter_text>Interference as a kernel**Exercise 5** (1 point). At this point, our state is:$|\psi\rangle = \frac{1}{\sqrt{2}}\sum_{m=0}^{1}|y_m\rangle|m\rangle|\psi_{x^m}\rangle|0\rangle + |y_m\rangle|m\rangle|\psi_{\tilde{x}}\rangle|1\rangle$Apply the Hadamard gate on the ancilla to produce the interference and create: $ |\psi\rangle = \frac{1}{2\sqrt{2}}\sum_{m=0}^{1}|y_m\rangle|m\rangle(|\psi_{x^m}\rangle+|\psi_{\tilde{x}}\rangle)|0\rangle+|y_m\rangle|m\rangle(|\psi_{x^m}\rangle-|\psi_{\tilde{x}}\rangle)|1\rangle$<jupyter_code>###
### YOUR CODE HERE

###
amplitudes = get_amplitudes(circuit)
assert np.allclose(amplitudes, np.array([  np.sqrt(2)/4+0.j , np.sqrt(2)/4+0.j , 0.        +0.j , 0.        +0.j,
  np.sqrt(2)/4+0.j ,-np.sqrt(2)/4+0.j , 0.        +0.j , 0.        +0.j,
  0.        +0.j,  0.        +0.j , (np.sqrt(2)+1)/4+0.j , (np.sqrt(2)-1)/4+0.j,
  0.        +0.j , 0.        +0.j , 0.25      +0.j ,-0.25      +0.j]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16326530612244897, 'fraction_numerical': 0.052939987876338655, 'mean_word_length': 3.7872340425531914, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '73016', 'license': 'MIT', 'n_tokens_mistral': 1953, 'n_tokens_neox': 1812, 'n_words': 589, 'path': 'coding_assignments/11_Kernel_Methods.ipynb', 'repo_name': 'MochizukiShinichi/Quantum_Machine_Learning_Solution', 'size': '4955'}