# Find a unitary to prepare state $|0\rangle$ to a specific vector

I am working with Variational Quantum Linear Solver (VQLS) algorithm, where it needs to prepare a control_b circuit. Assume b is 1d with $$2^n$$ elements in it.

$${\bf Ax = b} \tag{1}$$ I need to find a unitary U which can prepare state $$\vert0\rangle$$ to $${\bf b}$$, i.e., $$U\vert0\rangle = {\bf b} \tag{2}$$

Any proper method or Qiskit implementation would be helpful.

• – glS
Oct 4 '21 at 8:12

Note: this is not a qiskit answer. I have no idea if qiskit provides specific methods.

Firstly, you can only do this if $$|b\rangle$$ has length 1. If not, you need to rescale it. Let me assume that the vector has $$2^n$$ elements (if it's not a power of 2, you can pad it with extra 0s). For simplicity, I'm going to assume that $$|b\rangle$$ is real.

Then, what I'd do is prepare a binary tree of depth $$n$$. The root just has the value 1. At any layer $$k$$, you have $$2^k$$ nodes, and node $$i$$ is labelled with the total weight of the $$i^{th}$$ set of $$2^{n-k}$$ elements. So, at the first layer, the first node has the total weight of the first half of the elements (by weight, I mean "sum of the mod-square"), while the second node contains the weight of the second half. At the second layer, there are four nodes which have the weight of the list when it's split into quarters.

The idea of this is that all the terms in the output with labels $$0x$$ have total weight equal to the first label on the first layer. That can then be used to split up into the 0 and 1 terms on the second qubit at the second layer, and so on....

How this translates into a quantum circuit...

1. Start with all $$n$$ qubits in the $$|0\rangle$$ state.
2. Apply a $$Y$$ rotation on the first qubit such that the mod-square of the two amplitudes coincide with the weights of the two labels at the first level of your tree.
3. Apply a controlled-Y rotation, controlled off the first qubit and targetting the second, by an amount such that the mod-square of the 10 and 11 terms match the labels of the third and fourth nodes of the second level of the tree.
4. Apply a controlled-Y rotation, controlled off the first qubit being 0 and targetting the second, by an amount such that the mod-square of the 00 and 01 terms match the labels of the first and second nodes of the second level of the tree.
5. Apply a controlled-controlled-Y rotation controlled off the first two qubits and targetting the third qubit such that the mod-square of the 110 and 111 terms match the labels of the seventh and eight nodes of the third level of the tree.
6. Hopefully you get the pattern by now...

There are definitely simplifications you can make to this procedure, but hopefully this gets you started.

• Thanks for the approach, got to know the basics! Oct 4 '21 at 5:37

Check Qiskit documentation Summary of Quantum Operations under Arbitrary initialization. The function initialize does what you need (function documentation here).

Example:

from qiskit import QuantumCircuit
import math

desired_vector = [1/math.sqrt(2),-1/math.sqrt(2)]

qc = QuantumCircuit(1) #circuit with 1 qubit

qc.initialize(desired_vector, [0]) #0 in the index of the qubit


will initialize the qubit to the state

[1/math.sqrt(2),-1/math.sqrt(2)]


you can check by doing

from qiskit import execute, Aer

simulator=Aer.get_backend('statevector_simulator')
job = execute(qc, simulator)
qc_state = job.result().get_statevector(qc)
print(qc_state)


If you want the unitary matrix, you can use the unitary_simulator, in the following way

usimulator=Aer.get_backend('unitary_simulator')

job = execute(qc, usimulator)
umatrix = job.result().get_unitary(qc,decimals=3) #decimals is not necessary
print(umatrix)


which provides

[[ 0.707+0.j -0.707+0.j]
[-0.707-0.j -0.707-0.j]]


## Alternative solution

As any state $$|b\rangle$$ is written as $$|b\rangle=\cos(\theta/2)|0\rangle + e^{i\varphi}\sin(\theta/2)|1\rangle$$ (global phase does not matter), if you know $$\theta$$ and $$\varphi$$, you can easily construct this state by applying $$P(\varphi)R_y(\theta)|0\rangle$$, where $$P(\varphi)$$ is a phase gate and $$R_y$$ is a rotation gate in the $$y$$-axis.

In Qiskit, this can be done as follows

from qiskit import QuantumCircuit
import math

theta=math.pi/2
phi=0

qc = QuantumCircuit(1) #circuit with 1 qubit

qc.ry(theta,0)
qc.p(phi,0)


The unitary of such operation is straightforward: $$\begin{bmatrix}\cos(\theta/2) & -\sin(\theta/2) \\ \sin(\theta/2)e^{i\varphi} & \cos(\theta/2)e^{i\varphi} \end{bmatrix}.$$

Such a gate can also be implemented directly with Qiskit native gate U3 (with $$\lambda=0$$).

• This won't provide the unitary. I understand what you have performed, but it only provides the statevector as b which I do not want. Oct 2 '21 at 3:10
• Once the circuit is created you can easily get the unitary by using Qiskit's Operator class which accepts a QuantumCircuit as a parameter to its constructor. However, since your goal is to implement VQLS, I think you need to use the preparation circuit as a part of a bigger circuit. One way to do this in Qiskit is to convert it into a gate by using to_gate method. Oct 2 '21 at 7:16
• @Sajal I updated the post with the instructions to calculate the unitary matrix and added an alternative method. Oct 3 '21 at 17:55
• @Egretta.Thula I had actually tried that, but it was not working saying error due to initialization, but it was working for this bell state circuit. I don't know, what's the problem here, as the thing is same, only the number of qubits are changing Oct 4 '21 at 5:33
• @Mauricio Thanks for the update. I was able to find out the problem when I tried with this unitary_simulator. It worked when I tried it with execute, but when I was running it through the simulator's run method, it was creating an error. Anyways, thanks for updating, it might help later. Oct 4 '21 at 5:36