pauli_rotations#

Functionality#

Herein, we collect a family of programs that implement Pauli rotations on the target qubit, via one of \(R_X\), \(R_Y\), or \(R_Z\) gates, controlled by the state of multiple qubits.

polynomial_pauli_rotations.py#

Callee: PolynomialPauliRotations

A circuit implementing polynomial Pauli rotations.

For a polynomial \(p(x)\), an \(n\)-qubit computational basis state \(\ket{x}_n\) and a target qubit \(\ket{0}\), this operator acts as:

\[ \ket{0}_1\ket{x}_n \mapsto \cos\left(\frac{p(x)}{2}\right)\ket{0}_1\ket{x}_n + \sin\left(\frac{p(x)}{2}\right)\ket{1}_1\ket{x}_n. \]

Let \(d\) be the degree of \(p(x)\) and \(q_j \in \{0,1\}\) be the value of the \(j\)-th qubit, where \(q_0\) is the least significant qubit involved in the state \(\ket{x}_n\). Then for

\[ x=\sum_{j=0}^{n-1} 2^j q_j, \]

​ For example, if \(n=3\), the bit pattern is \((q_2q_1q_0)=101\) and \(x=1\cdot2^2+0\cdot2^1+1\cdot2^0=5\). Then we can write

\[ p(x) = \sum_{j=0}^{d} c_j x^j \]

where \(c\) are the input coefficients, coeffs, which has a length of \(d\). For example, given coeffs=[c_0, c_1, c_2], \(p(x)\) becomes \(c_0+c_1x+c_2x^2\).

Note that as we can see in Qiskit’s documentation [25] [26], the above formula-based program specification can only denotes the case basis="Y". For other bases, the rotation is applied around the corresponding Pauli axis. Here, we generalize the formula to other bases as follows:

\[\begin{split} \ket{0}_1\ket{x}_n \mapsto \begin{cases} \cos\left(\frac{p(x)}{2}\right)\ket{0}_1\ket{x}_n - i\sin\left(\frac{p(x)}{2}\right)\ket{1}_1\ket{x}_n, & \text{basis = ``X''} \\ \cos\left(\frac{p(x)}{2}\right)\ket{0}_1\ket{x}_n + \sin\left(\frac{p(x)}{2}\right)\ket{1}_1\ket{x}_n, & \text{basis = ``Y''} \\ e^{-i\frac{p(x)}{2}} \ket{0}_1\ket{x}_n, & \text{basis = ``Z''} \end{cases} \end{split}\]

Test expectations:

If the basis is X or Y, since \(\ket{x}\) is initialized as a pure state, the results of \(p(x)\) are reflected in amplitudes of two basis states whose target qubit is in state 0 and 1 respectively. Probabilities of these two states obtained by measurement can verify the correctness of the implementation. Without losing the phase information for basis X and Z, results are obtained by state-vector backend in our tests.

Doc reference: [25] [26]


linear_pauli_rotations.py#

Callee: LinearPauliRotations

Linearly-controlled X, Y or Z rotation.

For an \(n\)-qubit register of state qubits \(\ket{x}_n\), a target qubit \(\ket{0}_1\) and the basis ‘Y’ this circuit acts as:

    q_0: ─────────────────────────■───────── ... ──────────────────────
                                  │
                                  .
                                  │
q_(n-1): ─────────────────────────┼───────── ... ───────────■──────────
          ┌────────────┐  ┌───────┴───────┐       ┌─────────┴─────────┐
    q_n: ─┤ RY(offset) ├──┤ RY(2^0 slope) ├  ...  ┤ RY(2^(n-1) slope) ├
          └────────────┘  └───────────────┘       └───────────────────┘

This can for example be used to approximate linear functions, with \(a = \texttt{slope} / 2\) and \(b = \texttt{offset} / 2\) and the basis 'Y':

\[ \ket{0}_1\ket{x}_n \mapsto \cos(ax + b)\ket{0}_1\ket{x}_n + \sin(ax + b)\ket{1}_1\ket{x}_n \]

Since for small arguments \(\sin(x) \approx x\) this operator can be used to approximate linear functions.

Similar to PolynomialPauliRotations, we generalize the formula to other bases as follows:

\[\begin{split} \ket{0}_1\ket{x}_n \mapsto \begin{cases} \cos(ax + b)\ket{0}_1\ket{x}_n - i\sin(ax + b)\ket{1}_1\ket{x}_n, & \text{basis = ``X''} \\ \cos(ax + b)\ket{0}_1\ket{x}_n + \sin(ax + b)\ket{1}_1\ket{x}_n, & \text{basis = ``Y''} \\ e^{-i(ax + b)} \ket{0}_1\ket{x}_n, & \text{basis = ``Z''} \end{cases}. \end{split}\]

Test expectations:

Similar to PolynomialPauliRotations.

Doc reference: [27] [28]


uniform_controlled_rotations.py#

Callee: UniformlyControlledRotations

A circuit implementing uniformly controlled rotations [29].

Assume an initial state of \(n\) control qubits and one target qubit, \(\ket{0}_1\ket{\psi}_n\), where we can rewrite \(\ket{\psi}_n\) in the computational basis \(\{\ket{x}_n\}_{x=0}^{2^n-1}\) as:

\[ \ket{\psi}_n = \sum_{x=0}^{2^n-1} \alpha_x \ket{x}_n. \]

Given a list of angles \([\theta_0, \theta_1, \ldots, \theta_{2^n-1}]\), the operator of this program acts as:

\[ \ket{0}_1\ket{\psi}_n \mapsto \sum_{x=0}^{2^n-1} \alpha_x \left( \cos\left(\frac{\theta_x}{2}\right)\ket{0}_1 + \sin\left(\frac{\theta_x}{2}\right)\ket{1}_1 \right) \ket{x}_n. \]

API#

qolumbina.programs.pauli_rotations.linear_pauli_rotations#

Linearly-controlled X, Y or Z rotation.

class LinearPauliRotations(num_state_qubits, slope=1, offset=0, basis='Y', label=None)[source]#

Bases: QuantumCircuit

Linearly-controlled X, Y or Z rotation.

Parameters:
  • num_state_qubits (int) – The number of qubits representing the state, i.e., \(n\).

  • slope (float) – The slope of the linear function, i.e., \(2a\). The default is 1.0.

  • offset (float) – The offset of the linear function, i.e., \(2b\). The default is 0.0.

  • basis (str) – The type of Pauli rotation ("X", "Y", "Z"). The default is "Y".

  • label (str | None)

qolumbina.programs.pauli_rotations.polynomial_pauli_rotations#

Polynomially controlled Pauli-rotations.

class PolynomialPauliRotations(num_state_qubits, coeffs=None, basis='Y', label=None)[source]#

Bases: QuantumCircuit

A circuit implementing polynomial Pauli rotations.

Parameters:
  • num_state_qubits (int) – The number of qubits representing the state, i.e., \(n\).

  • coeffs (list[float] | None) – The coefficients of the polynomial. coeffs[i] is the coefficient of the i-th power of x. Defaults to linear: [0, 1].

  • basis (str) – The type of Pauli rotation ('X', 'Y', 'Z'). The default is 'Y'.

  • label (str | None) – Optional label for the circuit.

binomial_coefficients(n)[source]#

Return a dictionary of binomial coefficients

Based-on/forked from sympy’s binomial_coefficients() function [1].

Parameters:

n (int)

Return type:

dict[tuple[int, int], int]

get_rotation_coefficients()[source]#

Compute the coefficient of each monomial.

Returns:

A dictionary with pairs {control_state: rotation angle} where control_state is a tuple of 0 or 1 bits.

Return type:

dict[tuple[int, …], float]

large_coefficients_iter(m, n)[source]#

Return an iterator of multinomial coefficients

Based-on/forked from sympy’s multinomial_coefficients_iterator() function [2].

Parameters:
  • m (int)

  • n (int)

multinomial_coefficients(m, n)[source]#

Return an iterator of multinomial coefficients

Based-on/forked from sympy’s multinomial_coefficients() function [3].

Parameters:
  • m (int)

  • n (int)

qolumbina.programs.pauli_rotations.uniform_controlled_rotations#

Uniformly controlled rotation from arXiv:0407010

class UniformlyControlledRotations(theta_list, if_barrier=False, name=None)[source]#

Bases: QuantumCircuit

Uniformly controlled rotation circuit.

Applies a rotation on the ancilla qubit controlled by the state of n qubits.

Parameters:
  • theta_list (list[float]) – List of rotation angles for each control state, i.e., \([\theta_0, \theta_1, \ldots, \theta_{2^n-1}]\). The length of the list must be the power of two, i.e., \(2^n\) for \(n\) control qubits.

  • if_barrier (bool) – Whether to add barriers. Default is False.

  • name (str | None) – Optional name of the circuit.

Raises:

ValueError – If the length of theta_list is not a power of two.

Note

The circuit applies RY rotations on the ancilla qubit.

alpha2theta(alpha)[source]#
Parameters:
  • alpha (list[float]) – list of angles that get applied controlled on \(0,\cdots,2^n-1\)

  • theta – list of angles occuring in circuit construction

Return type:

ndarray

conversion_matrix(N)[source]#

conversion matrix from alpha to theta

Parameters:

N (int)

Return type:

ndarray

uni_con_rot_recursive_step(qc, qubits, anc, theta)[source]#
Parameters:
  • qc (QuantumCircuit) – qiskit QuantumCircuit object

  • qubits (QuantumRegister) – qiskit QuantumRegister object

  • anc (QuantumRegister) – ancilla qubit register on which rotation acts

  • theta (list[float]) – list of angles specifying rotations for \(0,\cdots,2^{n-1}\)

Return type:

QuantumCircuit

uniformly_controlled_rot(n, theta)[source]#
Parameters:
  • n (int)

  • theta (list[float])

Return type:

QuantumCircuit

create_uniformly_controlled_rotations(thetas, if_barrier=False)[source]#
Parameters:
  • thetas (list[float])

  • if_barrier (bool)