# Arbitrary State Generation¶

## Overview¶

This module is concerned with making a program that can generate an arbitrary state. In particular, if one is given a nonzero complex vector $$\mathbf{a}\in\mathbb{C}^N$$ with components $$a_i$$, the goal is to produce a program that takes in the state $$\vert 0\rangle$$ and outputs the state

$$\vert \Psi \rangle = \sum_{i=0}^{N-1}\frac{a_i}{\vert \mathbf{a}\vert} \vert i\rangle$$

where $$\vert i\rangle$$ is interpreted by taking $$i$$ in its binary representation.

This problem is approached in two different ways in this module, and will be described in the sections to follow. The first is to directly construct a circuit using a sequence of CNOT, rotation, Hadamard, and phase gates, that produces the desired state. The second is to construct a unitary matrix that could be decomposed into different circuits depending on which gates one would see fit.

More details on the first approach can be found in references [1] and [2].

## Arbitrary State Generation via Specific Circuit¶

The method in this approach follows the algorithm described in [1]. The idea is to imagine beginning with the desired state $$\vert \Psi \rangle$$. First, controlled RZ gates are used to unify the phases of the coefficients of consecutive pairs of basis states. Next, controlled RY gates are used to unify the magnitudes (or probabilities) of those pairs of basis states, and hence unify the coefficients altogether. Next, a swap is performed so that in subsequent steps, multiple pairs of consecutive states will have the same pair of coefficients. This process can be repeated, with each successive step of rotations requiring fewer controls due to the interspersed swaps. Finally, with all states having the same coefficient, the Hadamard gate can be applied to all the qubits to select out the $$\vert 0 \rangle$$ state. Lastly, a combination of a PHASE gate and RZ gate can be applied to remove the global phase. The reverse of this program, which can be found by applying all gates in reverse and all rotations with negated angles, this provides the desired program for arbitrary state generation.

One key part of this algorithm is that each rotation step is uniformly controlled. This has a relatively efficient decomposition into CNOTs and uncontrolled rotations, and is the subject of reference [2].

## Arbitrary State Generation via Unitary Matrix¶

The method in this approach is to create a unitary operator mapping the ground state of a set of qubits to the desired outcome state. This requires constructing a unitary matrix whose leftmost column is $$\vert \Psi \rangle$$. By replacing the left column of the identity matrix with $$\vert \Psi \rangle$$ and then QR factorizing it, one can construct such a matrix.

## Source Code Docs¶

Here you can find documentation for the different submodules in arbitrary_state.

### grove.arbitrary_state.arbitrary_state¶

Class for generating a program that can generate an arbitrary quantum state. References are available at:

Note that the algorithm used creates a circuit that begins with a target state and brings it to the all zero state. Thus, many of this module’s functions involve finding gates to be applied in the reversed circuit.

grove.alpha.arbitrary_state.arbitrary_state.create_arbitrary_state(vector, qubits=None)

This function makes a program that can generate an arbitrary state.

Applies the methods described in references above.

Given a complex vector $$\mathbf{a}$$ with components $$a_i$$ ($$i$$ ranging from $$0$$ to $$N-1$$), produce a program that takes in the state $$\vert 0 \rangle$$ and outputs the state

$\sum_{i=0}^{N-1}\frac{a_i}{\vert \mathbf{a}\vert} \vert i\rangle$

where $$i$$ is given in its binary expansion.

Parameters: vector (1darray) – the vector to put into qubit form. qubits (list(int)) – Which qubits to encode the vector into. Must contain at least the minimum number of qubits $$n$$ needed for all elements of vector to be present as a coefficient in the final state. If more than $$n$$ are provided, only the first $$n$$ will be used. If no list is provided, the default will be qubits $$0, 1, \ldots, n-1$$. a program that takes in $$\vert 0\rangle^{\otimes n}$$ and produces a state that represents this vector, as described above. Program
grove.alpha.arbitrary_state.arbitrary_state.get_cnot_control_positions(k)

Returns a list of positions for the controls of the CNOTs used when decomposing uniformly controlled rotations, as outlined in arXiv:quant-ph/0407010.

Referencing Fig. 2 in the aforementioned paper, this method uses the convention that, going up from the target qubit, the control qubits are labelled $$1, 2, \ldots, k$$, where $$k$$ is the number of control qubits. The returned list provides the qubit that controls each successive CNOT, in order from left to right.

Parameters: k (int) – the number of control qubits the list of positions of the controls list
grove.alpha.arbitrary_state.arbitrary_state.get_reversed_unification_program(angles, control_indices, target, controls, mode)

Gets the Program representing the reversed circuit for the decomposition of the uniformly controlled rotations in a unification step.

If $$n$$ is the number of controls, the indices within control indices must range from 1 to $$n$$, inclusive. The length of control_indices and the length of angles must both be $$2^n$$.

Parameters: angles (list) – The angles of rotation in the the decomposition, in order from left to right control_indices (list) – a list of positions for the controls of the CNOTs used when decomposing uniformly controlled rotations; see get_cnot_control_positions for labelling conventions. target (int) – Index of the target of all rotations controls (list) – Index of the controls, in order from bottom to top. mode (str) – The unification mode. Is either ‘phase’, corresponding to controlled RZ rotations, or ‘magnitude’, corresponding to controlled RY rotations. The reversed circuit of this unification step. Program
grove.alpha.arbitrary_state.arbitrary_state.get_rotation_parameters(phases, magnitudes)

Simulates one step of rotations.

Given lists of phases and magnitudes of the same length $$N$$, such that $$N=2^n$$ for some positive integer $$n$$, finds the rotation angles required for one step of phase and magnitude unification.

Parameters: phases (list) – real valued phases from $$-\pi$$ to $$\pi$$. magnitudes (list) – positive, real value magnitudes such that the sum of the square of each magnitude is $$2^{-m}$$ for some nonnegative integer $$m$$. A tuple t of four lists such that t[0] are the z-rotations needed to unify adjacent pairs of phases t[1] are the y-rotations needed to unify adjacent pairs of magnitudes t[2] are the updated phases after these rotations are applied t[3] are the updated magnitudes after these rotations are applied tuple
grove.alpha.arbitrary_state.arbitrary_state.get_uniformly_controlled_rotation_matrix(k)

Returns the matrix represented by $$M_{ij}$$ in arXiv:quant-ph/0407010.

This matrix converts the angles of $$k$$-fold uniformly controlled rotations to the angles of the efficient gate decomposition.

Parameters: k (int) – number of control qubits the matrix $$M_{ij}$$ 2darray

### grove.arbitrary_state.unitary_operator¶

Module for creating a unitary operator for encoding any complex vector into the wavefunction of a quantum state. For example, the input vector $$[a, b, c, d]$$ would result in the state

$a\vert 00\rangle + b\vert01\rangle + c\vert10\rangle + d\vert11\rangle$
grove.alpha.arbitrary_state.unitary_operator.fix_norm_and_length(vector)

Create a normalized and zero padded version of vector.

Parameters: vector (1darray) – a vector with at least one nonzero component. a vector that is the normalized version of vector, padded at the end with the smallest number of 0s necessary to make the length of the vector $$2^m$$ for some positive integer $$m$$. 1darray
grove.alpha.arbitrary_state.unitary_operator.get_bits_needed(n)

Calculates the smallest positive integer $$m$$ for which $$2^m\geq n$$.

Parameters: n (int) – A positive integer The positive integer $$m$$, as specified above int
grove.alpha.arbitrary_state.unitary_operator.unitary_operator(state_vector)

Uses QR factorization to create a unitary operator that can encode an arbitrary normalized vector into the wavefunction of a quantum state.

Assumes that the state of the input qubits is to be expressed as

$(1, 0, \ldots, 0)^T$
Parameters: array state_vector (1d) – Normalized vector whose length is at least two and a power of two. Unitary operator that encodes state_vector 2d array

References