1qubit state preparation
By: Yuichiro Minato
Tags: Quantum Computing

If you want any quantum state on quantum computing circuit, you can use the technique called state preparation.

Basic 1qubit of state preparation will be done on the bloch sphere. We just need 2 angles to create any quantum state on bloch sphere.

Blueqat

This time we try use blueqat to check the process. The installation will be done with a simple package installation.

pip3 install blueqat

Blueqat is a quantum computing SDK widely used over the world.

State preparation

Basically the value of qubit starts from |0> state. If you want any quantum state, this can be done by applying two angles to the initial qubit value.

The quantum state of 1qubit is written in the superposition of 0 and 1 state. The coefficients have these rules.

And with two angles we have,

Unitary matrix

These operation on angles are done with Quantum gate or Unitary matrix. The basic unitary matrix to realize this operation would be,

Starting from state |0> we can apply this Unitary matrix to the initial state vector [1,0] and we actually get the desired vector of quantum state.

Rz gate

To get this Unitary operation we can use this rule to apply Rz and Ry.

Rz gate is a simple rotation around the Z-axis.

Checking the outline

To check if we can have any quantum state with gate operation, we can have small trial.

import numpy as np

import matplotlib.pyplot as plt

from blueqat import Circuit

import math



x = []

y = []

z = []



#try 100times

for _ in range(100):

beta = math.pi* 2 * np.random.rand()

theta = math.pi * 2 * np.random.rand()



a = Circuit(1).ry(theta)[0].rz(beta)[0].run()



x.append(a[0].real * np.sign(a[1].imag))

z.append(a[1].real)

y.append(a[0].imag)



#aspect ratio of the figure

g = plt.subplot()

g.set_aspect('equal')



#draw

plt.scatter(x, z)

Now we have,

With 1000times we have,

We have roughly good result on 2D plot.

Optimizing angle with target

Now we can have a small trial on optimizing angle of quantum state.

When you want to create a 1qubit quantum state, you will think about angle on bloch sphere to get any quantum state.

But it is difficult for people to understand the basic idea of quantum state as polar coordinates. And now we try to make a quantum state just from optimization.

This time we use Bayesian Optimization as a blackbox optimization of 2angles.

And instead of using Ry and Rz, this time we will use u3 gate which has 3angles to optimize but we just fix the last angle as 0 value. We only have the former 2angles of u3 gate to get quantum state.

angle1 = math.pi * 2 * np.random.rand()

angle2 = math.pi * 2 * np.random.rand()



Circuit(1).u3(angle1, angle2, 0)[0].run()

Bayesian Optimization

Bayesian optimization is an optimization algorithm to optimize function looking at a priority of data from gaussian process. Now we use a package on python.

pip install bayesian-optimization

And start using it, first defining the function. This calculate the difference between the real part of quantum state vector and the target value we want.

from bayes_opt import BayesianOptimization



def f(angle1, angle2, target):

a = Circuit(1).u3(angle1, angle2, 0)[0].run()

return (a[0].real-target[0])**2 + (a[1].real - target[1])**2

By applying this we can optimize two angles in the quantum circuit.

from blueqat import Circuit

import math

import numpy as np

from bayes_opt import BayesianOptimization



#circuit

def f(angle1, angle2, target = np.array([np.sqrt(0.5),np.sqrt(0.5)])):

a = Circuit(1).u3(angle1, angle2, 0)[0].run()

return -(a[0].real - target[0])**2 - (a[1].real - target[1])**2



#optimize it

pbounds = {'angle1': (0, math.pi*2), 'angle2': (0, math.pi*2)}

optimizer = BayesianOptimization(f=f, pbounds=pbounds)

optimizer.maximize(init_points=10, n_iter=50)



print(optimizer.max)

we get,

| iter | target | angle1 | angle2 |

-------------------------------------------------

| 1 | -0.7327 | 0.2003 | 3.282 |

| 2 | -0.9524 | 0.4899 | 2.856 |

| 3 | -0.4593 | 2.354 | 1.45 |

| 4 | -0.5662 | 3.169 | 3.179 |

| 5 | -0.4942 | 0.5972 | 4.882 |

| 6 | -0.3781 | 0.5393 | 5.303 |

| 7 | -1.273 | 5.008 | 5.489 |

| 8 | -3.165 | 3.09 | 3.499 |

| 9 | -1.669 | 2.443 | 4.11 |

| 10 | -0.69 | 6.1 | 5.614 |

| 11 | -0.1078 | 3.919 | 3.862 |

| 12 | -1.37 | 2.787 | 1.919 |

| 13 | -0.3761 | 4.152 | 1.727 |

| 14 | -1.168 | 4.23 | 5.143 |

| 15 | -0.6822 | 3.408 | 1.685 |

| 16 | -1.311 | 4.819 | 0.8573 |

| 17 | -1.665 | 3.75 | 5.286 |

| 18 | -2.66 | 3.833 | 0.3566 |

| 19 | -2.613 | 2.793 | 2.552 |

| 20 | -0.4097 | 0.6042 | 1.167 |

| 21 | -0.1723 | 3.821 | 2.797 |

| 22 | -1.184 | 1.389 | 4.078 |

| 23 | -1.087 | 4.535 | 5.162 |

| 24 | -0.9746 | 0.5102 | 2.902 |

| 25 | -0.34 | 3.513 | 2.958 |

| 26 | -0.1602 | 3.904 | 3.218 |

| 27 | -0.04193 | 4.224 | 3.574 |

| 28 | -0.03123 | 4.35 | 3.017 |

| 29 | -0.03125 | 4.29 | 2.439 |

| 30 | -0.01726 | 4.823 | 2.63 |

| 31 | -0.1488 | 4.778 | 2.061 |

| 32 | -0.01487 | 4.943 | 3.309 |

| 33 | -0.05823 | 4.696 | 4.0 |

| 34 | -0.1753 | 5.381 | 3.834 |

| 35 | -0.1758 | 5.548 | 2.965 |

| 36 | -0.2838 | 5.525 | 2.217 |

| 37 | -0.5071 | 6.16 | 3.524 |

| 38 | -0.1158 | 1.539 | 1.015 |

| 39 | -0.06165 | 1.132 | 0.3688 |

| 40 | -0.01805 | 1.89 | 0.3364 |

| 41 | -0.3807 | 0.3208 | 0.173 |

| 42 | -0.5858 | 6.283 | 2.51 |

| 43 | -0.5858 | 0.0 | 6.198 |

| 44 | -0.02791 | 1.262 | 6.046 |

| 45 | -0.04453 | 1.994 | 6.283 |

| 46 | -0.02551 | 1.805 | 5.532 |

| 47 | -0.1834 | 2.531 | 5.792 |

| 48 | -0.5858 | 6.283 | 1.251 |

| 49 | -0.5858 | 6.283 | 0.0 |

| 50 | -0.5858 | 6.283 | 4.521 |

| 51 | -0.7615 | 1.283 | 1.842 |

| 52 | -0.149 | 2.484 | 0.6693 |

| 53 | -0.5858 | 0.0 | 1.808 |

| 54 | -0.2028 | 2.479 | 0.0 |

| 55 | -0.5478 | 3.087 | 6.283 |

| 56 | -0.5858 | 0.0 | 4.252 |

| 57 | -0.1683 | 1.242 | 5.276 |

| 58 | -0.5858 | 0.0 | 0.833 |

| 59 | -0.5858 | 6.283 | 6.283 |

| 60 | -0.2502 | 2.301 | 5.054 |

=================================================

{'target': -0.014865460893328637, 'params': {'angle1': 4.943094687657537, 'angle2': 3.3091935692009673}}

Now we can check,

angle1 = 4.943094687657537

angle2 = 3.3091935692009673

Circuit(1).u3(angle1, angle2, 0)[0].run() #=>array([0.78379353+0.j , 0.61231963+0.10359717j])

We could get near value as the basic superposition of 0 and 1 just from optimization process start from the random number.

Another one

Now we try another target |1>. The target state vector is [0, 1].

#Quantum circuit

def f(angle1, angle2, target = np.array([0,1])):

a = Circuit(1).u3(angle1, angle2, 0)[0].run()

return -(a[0].real - target[0])**2 - (a[1].real - target[1])**2



#optimize it

pbounds = {'angle1': (0, math.pi*2), 'angle2': (0, math.pi*2)}

optimizer = BayesianOptimization(f=f, pbounds=pbounds)

optimizer.maximize(init_points=10, n_iter=50)



print(optimizer.max)

We have,

| iter | target | angle1 | angle2 |

-------------------------------------------------

| 1 | -1.983 | 0.02621 | 0.8867 |

| 2 | -2.618 | 0.8599 | 3.764 |

| 3 | -2.872 | 5.281 | 5.926 |

| 4 | -1.663 | 1.182 | 1.547 |

| 5 | -0.6877 | 4.656 | 2.399 |

| 6 | -2.81 | 5.276 | 5.809 |

| 7 | -1.871 | 0.5834 | 4.793 |

| 8 | -1.385 | 3.267 | 4.889 |

| 9 | -2.193 | 0.5157 | 2.069 |

| 10 | -2.865 | 0.9174 | 3.321 |

| 11 | -3.589 | 4.202 | 0.2936 |

| 12 | -0.2109 | 4.053 | 3.398 |

| 13 | -1.123 | 5.36 | 3.382 |

| 14 | -0.01512 | 3.324 | 2.742 |

| 15 | -3.815 | 3.102 | 3.448 |

| 16 | -0.07718 | 3.671 | 2.793 |

| 17 | -0.121 | 3.488 | 2.358 |

| 18 | -0.3797 | 4.39 | 3.016 |

| 19 | -0.5351 | 4.53 | 3.716 |

| 20 | -2.71 | 2.882 | 2.274 |

| 21 | -0.2961 | 4.013 | 2.381 |

| 22 | -0.7492 | 3.961 | 1.826 |

| 23 | -0.5563 | 4.144 | 4.201 |

| 24 | -1.184 | 4.79 | 4.418 |

| 25 | -1.387 | 5.51 | 2.379 |

| 26 | -1.394 | 4.785 | 1.679 |

| 27 | -2.0 | 6.283 | 3.967 |

| 28 | -1.705 | 4.119 | 4.963 |

| 29 | -0.1041 | 2.511 | 5.992 |

| 30 | -0.3113 | 2.011 | 6.283 |

| 31 | -0.3833 | 2.048 | 5.603 |

| 32 | -0.00014 | 3.118 | 6.283 |

| 33 | -0.01949 | 3.109 | 5.75 |

| 34 | -3.899 | 3.712 | 6.179 |

| 35 | -0.0343 | 2.771 | 6.283 |

| 36 | -0.1527 | 2.687 | 5.486 |

| 37 | -0.7088 | 1.428 | 6.003 |

| 38 | -0.01922 | 2.89 | 5.959 |

| 39 | -0.8806 | 2.183 | 4.92 |

| 40 | -1.522 | 0.4832 | 6.283 |

| 41 | -2.0 | 6.283 | 0.0 |

| 42 | -0.3857 | 1.879 | 0.0 |

| 43 | -0.8582 | 1.215 | 0.0 |

| 44 | -0.3269 | 2.113 | 0.6199 |

| 45 | -0.08525 | 2.557 | 0.1076 |

| 46 | -0.08887 | 2.768 | 0.6752 |

| 47 | -0.00194 | 3.059 | 0.1708 |

| 48 | -2.0 | 6.283 | 1.488 |

| 49 | -2.351 | 3.25 | 1.009 |

| 50 | -0.7587 | 1.475 | 0.6372 |

| 51 | -0.6132 | 2.233 | 1.169 |

| 52 | -0.9948 | 1.459 | 5.243 |

| 53 | -1.727 | 0.274 | 0.0 |

| 54 | -2.0 | 6.283 | 5.196 |

| 55 | -2.0 | 6.283 | 2.839 |

| 56 | -0.04419 | 2.753 | 0.3642 |

| 57 | -2.0 | 0.0 | 5.534 |

| 58 | -0.01754 | 2.877 | 0.0 |

| 59 | -2.0 | 6.283 | 6.283 |

| 60 | -0.7593 | 4.933 | 2.945 |

=================================================

{'target': -0.00013995588043141157, 'params': {'angle1': 3.1179319255565385, 'angle2': 6.283185307179586}}

And check,

angle1 = 3.1179319255565385

angle2 = 6.283185307179586

Circuit(1).u3(angle1, angle2, 0)[0].run()



#=>array([0.01183009+0.0000000e+00j, 0.99993002-2.4491222e-16j])

Now we have very similar vector as the |1> state. We cloud optimize it.

Conclusion

We could get target state vector without understanding the basic idea of bloch sphere just optimizing 2angles as a value. It would be useful for quantum machine learning.