Skip to content

workbench_algorithms.experimental.utils.arbitrary_state_prep_utils

Utilities for arbitrary state prep.

SupportedOps

Bases: Enum

Specifies which rotation ops the multiplexed rotations support.

StatePrepData dataclass

StatePrepData(
    coefficients: Iterable[float | complex], epsilon: float
)

Data for specifying an arbitrary state to prepare.

ArbitraryStatePrepData dataclass

ArbitraryStatePrepData(
    coefficients: Iterable[float | complex],
    bits_of_precision: int,
)

Data for specifying an arbitrary state to prepare via LKS state prep.

epsilon property

epsilon: float

Accuracy of the state prep protocol, determined using Eq. 49 from arxiv:1812.00954.

compute_ry_angle_array

compute_ry_angle_array(
    coeffs: Iterable[float],
) -> list[list[float]]

Calculate rotation angles needed to prepare an arbitrary pure state.

In particular, for a state \(\frac{e^{i \theta}}{\|a\|_2}\sum_i a_i \ket{i}\), with complex coefflitudes \(a_i\), where \(e^{i \theta}\) is the global phase and \(\|a\|_2\) is the two-norm, this function finds angles for rotations which prepare the magnitude component of each coefflitude in the state vector.

We follow equation 8 in arXiv:0407010.

Note

The output rotations are in degrees to coincide with the convention used elsewhere in Workbench.

Returns:

Type Description
list[list[float]]

Nested list of \(Y\) rotation angles that prepare the magnitudes per term in the input target coefficients.

Notes
  • The reference above actually presents the calculation of these angles with the inverse goal of state preparation; assume you start in an arbitrary state, and now must apply specific-angle + axis rotations to return to the all-zero state.
  • This function corresponds to equations in the text for determining angles meant to zero out the magnitudes of an input arbitrary superposition state.
  • We simply return the reverse-order list of the angles we calculate.

compute_rz_angle_array

compute_rz_angle_array(
    coeffs: Iterable[float],
) -> list[list[float]]

Calculate rotation angles needed to prepare an arbitrary pure state.

In particular, for a state \(\frac{e^{i \theta}}{\|a\|_2}\sum_i a_i \ket{i}\), with complex coefflitudes \(a_i\), where \(e^{i \theta}\) is the global phase and \(\|a\|_2\) is the two-norm, this function finds angles for rotations which prepare the phase component of each coefflitude in the state vector.

We follow equation 5 in arXiv:0407010.

Note: rotations default to degrees, as it is now used in all the implementations here

Returns:

Type Description
tuple[list[list[float]], float]

We return a tuple with two different items: - A nested list of \(Z\) rotation angles that prepare the correct phases for each coefficient in target_state_coeffs. - A float between 0 and 1 that corresponds to the angle \(\theta\) in the global phase \(e^{i \theta}\).

Notes
  • The reference above actually presents the calculation of these angles with the inverse goal of state preparation; assume you start in an arbitrary state, and now must apply specific-angle + axis rotations to return to the all-zero state.
  • This function corresponds to equations in the text for determining angles meant to equalize the phases in an input arbitrary superposition state.
  • We simply return the reverse-order list of the angles we calculate.

pauli_rotation_helper

pauli_rotation_helper(
    angle: float,
    opcode: SupportedOps,
    target_reg: Qubits,
    ctrl: Qubits | int = 0,
)

Parses the specification of an op given by opcode to a QPU rotation op which is applied on target_reg.

ppr_to_rz_compute

ppr_to_rz_compute(
    qc: QPU,
    x_qbits: Qubits | int,
    z_qbits: Qubits | int,
    ctrl: Qubits | int = 0,
)

PPR as standard gates.

Parameters:

Name Type Description Default
qc QPU

QPU instance.

required
x_qbits Qubits | int

Qubit register where Pauli Xs act (or zero if none).

required
z_qbits Qubits | int

Qubit register where Pauli Zs act (or zero if none).

required
ctrl Qubits | int

Qubits register to control the ppr on.

0

get_amp_array_from_angle_array

get_amp_array_from_angle_array(
    angles_2d_list: list[list[float]],
) -> list[float]

Takes a list of angles used in Grover-Rudolph state prep and converts them to a list of resulting amplitudes.

Compute amplitude array from a 2D list of angles qubit by qubit, in a tree-like structure. For each qubit layer, we grab the previous layer amps and calculate the cos and sin values parameterized by the current qubit layer angles, and put the two values for each of the angles in the current qubit layer's amp_list.

Parameters:

Name Type Description Default
angles_2d_list list[list[float]]

Each sublist represents angles for a qubit layer.

required

Returns:

Type Description
list[float]

The last computed amplitude list.

get_approximated_weight_using_angle_truncation_function

get_approximated_weight_using_angle_truncation_function(
    weights: Iterable[float], b: int
) -> np.ndarray

Computes the approximated weight using angle truncation.

Parameters:

Name Type Description Default
weights Iterable[float]

Input weight values (real or complex).

required
b int

Truncation precision for the rotation angle.

required

Returns:

Type Description
ndarray

Approximated weight after angle truncation.

LKS_get_b_from_epsilon

LKS_get_b_from_epsilon(
    inputs: Iterable[float],
    epsilon: float,
    b_upper_bound: int = 1000,
    return_theory_bound_and_actual_diff: bool = False,
) -> int | tuple[int, float, float]

Get a numerically-optimized number of bits of precision for LKS state prep.

Finds the minimum bit precision such that the L2-norm difference between the normalized input and its discretized version is below a given epsilon threshold.

Parameters:

Name Type Description Default
epsilon float

Acceptable L2-norm threshold.

required
inputs Iterable[float]

Real or complex input values.

required
b_upper_bound int

Max bit precision to check.

1000
return_theory_bound_and_actual_diff bool

Whether to return (bit_precision, theory_eps, actual_eps)

False

Returns:

Type Description
int | tuple[int, float, float]

Best bit precision, or (bit_precision, expected_eps, norm_diff)

Raises:

Type Description
ValueError

If no suitable bit precision is found.