guppyalgos.testing

Helpers for inspecting Guppy programs with a statevector simulator.

Functions

align_phase(vec[, threshold])

Align the global phase of a vector so that the first large element is real.

assert_allclose_ignorephase(a, b[, threshold])

Stopgap measure until simulations respect global phase.

assert_cntrl_unitary(circ, ...[, ...])

Check the coherent blocks of a controlled unitary.

chebyshev_power_matrix(mat, power)

Return the Chebyshev polynomial of a Hermitian matrix.

extract_state_branches_in_superposition(...)

Project a superposition state onto every requested branch of a single register.

get_statevector(main, n_qubits, *[, ...])

Get the state vector for guppy main program.

get_statevector_projected(main, n_qubits, ...)

Return a statevector after sequential register post-selection.

get_total_state_on_only_specified_registers(...)

Extract the total state over all registers specified by result_tags.

get_unitary(circ, n_qubits[, endianness, ...])

Compute the unitary by iterating shots in a loop.

get_unitary_assumed_phase(circ, n_qubits[, ...])

Compute the unitary by iterating shots in a loop.

get_unitary_projected(circ, n_state_qubits, ...)

Project into one or more non-state registers of a guppy circuit.

hamming_weight(i, n)

Compute the hamming weight of i as an n bit binary string.

project_state_onto_bitstring(state, bitstring)

Projects a state onto the desired bitstring on the specified qubits.

statevector_projected_selene(main, n_qubits, ...)

Project named state_result registers in sequence.

switch_endianness(vec)

Switch the endianness of a vector.

switch_matrix_endianness(mat)

Switch the endianness of a matrix.

Classes

Endianness(*values)

Endianness of statevector / unitary output in test helpers.

SubQuestState(state, total_qubits, ...)

Wrapper for SeleneQuestState that represents a pure substate of a system.

class guppyalgos.testing.Endianness(*values)

Endianness of statevector / unitary output in test helpers.

BIG = 0
LITTLE = 1
class guppyalgos.testing.SubQuestState(state, total_qubits, specified_qubits, projected_out_qubits)

Wrapper for SeleneQuestState that represents a pure substate of a system.

Has the same public interface as SeleneQuestState. Pure substates appear when doing projections or discarding unentangled qubits, but doing sequences of these operations requires carefully keeping track of qubit indices within the sim on a global and local level. This wrapper handles the reindexing by silently keeping track of qubits that have already been “projected out”.

get_density_matrix(zero_threshold=1e-12)

Get the density matrix of the subsystem given by the specified qubits.

Return type:

ndarray

get_dirac_notation(zero_threshold=1e-12)

Get dirac notation for the state of the subsystem.

Return type:

list[TracedState]

get_single_dirac_notation(zero_threshold=1e-12)

Get dirac notation of the pure subsystem if possible.

Return type:

TracedState

get_single_state(zero_threshold=1e-12)

Get the pure state of the subsystem if possible.

Return type:

ndarray

get_state_vector_distribution(zero_threshold=1e-12)

Get the statevector distribution of the subsystem.

Return type:

list[TracedState[ndarray]]

property specified_qubits: list[int]

Gets specified qubits in global frame.

property state: ndarray

Gets full statevector.

total_qubits: int
guppyalgos.testing.align_phase(vec, threshold=1e-08)

Align the global phase of a vector so that the first large element is real.

Return type:

GenericAlias[complex128]

guppyalgos.testing.assert_allclose_ignorephase(a, b, threshold=1e-08)

Stopgap measure until simulations respect global phase.

Return type:

None

guppyalgos.testing.assert_cntrl_unitary(circ, expected_active_unitary, n_state_qubits, post_select_dict, *, control_name='control', endianness=Endianness.BIG, n_extra_qubits=0, threshold=1e-08)

Check the coherent blocks of a controlled unitary.

The circuit must conjugate its control with Hadamard gates and accept that one-qubit control register before any registers in post_select_dict. If its active operation is \(A\), projecting the control onto zero and one must respectively produce \((I + A) / 2\) and \((I - A) / 2\).

Return type:

None

guppyalgos.testing.chebyshev_power_matrix(mat, power)

Return the Chebyshev polynomial of a Hermitian matrix.

Return type:

GenericAlias[complex128]

guppyalgos.testing.extract_state_branches_in_superposition(states, branch_tag, result_tags, branch_bitstrings)

Project a superposition state onto every requested branch of a single register.

Parameters:
  • states (dict[str, SeleneQuestState]) – State dictionary as returned by Quest.extract_states_dict.

  • branch_tag (str) – State-result tag of the register used to select branches.

  • result_tags (list[str]) – State-result tags to keep after each branch projection.

  • branch_bitstrings (list[list[bool]]) – Bitstrings to project onto for the branch register.

Return type:

dict[tuple[bool, ...], TracedState[SeleneQuestState]]

Returns:

A dictionary mapping each branch bitstring to its projected state. Each projected state lives on the remaining result_tags registers only, with the remaining registers encoded directly in projected_state.state.state.

guppyalgos.testing.get_statevector(main, n_qubits, *, main_args_dict=None)

Get the state vector for guppy main program.

The main program must name the state result as “result_state”.

Parameters:
  • main (TypeAliasType) – The guppy main function to execute

  • n_qubits (int) – The number of qubits in the circuit.

  • main_args_dict (dict[str, Any] | None) – arguments to pass to guppy main function.

Returns:

The state vector representing the circuit.

Return type:

NDArray[np.complex128]

guppyalgos.testing.get_statevector_projected(main, n_qubits, post_select_dict, renormalize=True, *, main_args_dict=None)

Return a statevector after sequential register post-selection.

This is a user friendly convenience wrapper around statevector_projected_selene that exposes only the final NumPy statevector instead of the full SeleneQuestState container. It executes the same sequence of projections on the named registers and returns the final projected statevector. Unlike statevector_projected_selene, this wrapper does not expose the option to return final specified qubits, so the result is always the statevector over the remaining unprojected qubits. Use statevector_projected_selene directly when you need that extra control.

Parameters:
  • main (TypeAliasType) – The guppy main function to execute.

  • n_qubits (int) – The total number of qubits in the compiled program.

  • post_select_dict (dict[str, list[bool]]) – Mapping from state_output tag to the boolean bitstring to project that register onto, applied in insertion order.

  • renormalize (bool) – Whether to renormalize the state after each projection step.

  • main_args_dict (dict[str, Any] | None) – arguments to pass to guppy main function.

Returns:

The projected statevector.

Return type:

NDArray[np.complex128]

guppyalgos.testing.get_total_state_on_only_specified_registers(states, result_tags)

Extract the total state over all registers specified by result_tags.

This function makes several assumptions, firstly the state_results in your guppy are located in the same place, and have tags matching result_tags and additionally that the total state of these registers is pure (unentangled with any other qubits).

Parameters:
  • states (dict[str, SeleneQuestState]) – state dictionary, as returned

  • Quest.extract_states_dict. (by)

  • result_tags (list[str]) – List of state_result tags corresponding to the desired

  • registers.

Return type:

tuple[SubQuestState, dict[str, list[int]]]

Returns:

A SubQuestState for the pure state over all specified registers, with specified_qubits equal to all those qubits. A dictionary mapping result tags to specified_qubit lists.

guppyalgos.testing.get_unitary(circ, n_qubits, endianness=Endianness.BIG, n_extra_qubits=0)

Compute the unitary by iterating shots in a loop.

This function is a wrapper around the get_statevector function, which computes the statevector for each basis state. The resulting statevectors are then combined to form the unitary matrix.

Parameters:
  • circ (GuppyFunctionDefinition[(array[qubit, TypeVar(n_state, bound= nat)], ), None]) – The circuit function to be executed.

  • n_qubits (int) – The number of qubits in the circuit.

  • endianness (Endianness) – Convert to big endian (default)

  • n_extra_qubits (int) – Extra qubits to add to the emulator pool for internal ancilla. These ancilla must be returned to zero.

Returns:

The unitary matrix representing the circuit.

Return type:

NDArray[np.complex128]

guppyalgos.testing.get_unitary_assumed_phase(circ, n_qubits, endianness=Endianness.BIG, n_extra_qubits=0)

Compute the unitary by iterating shots in a loop.

Similar to get_unitary, but uses _compute_sv_bits_phaseless which directly accesses the Quest result with .get_single_state instead of get_statevector. This is needed to apply mem_swaps, but loses phase information.

Parameters:
  • circ (GuppyFunctionDefinition[(array[qubit, TypeVar(n_state, bound= nat)], ), None]) – The circuit function to be executed.

  • n_qubits (int) – The number of qubits in the circuit.

  • endianness (Endianness) – Convert to big endian (default)

  • n_extra_qubits (int) – Extra qubits to add to the simulator pool for internal ancilla. These ancilla must be returned to zero.

Returns:

The unitary matrix representing the circuit.

Return type:

NDArray[np.complex128]

guppyalgos.testing.get_unitary_projected(circ, n_state_qubits, post_select_dict, pre_select_dict=None, endianness=Endianness.BIG, n_extra_qubits=0)

Project into one or more non-state registers of a guppy circuit.

This function will project into a sub-block of a unitary matrix defined by the matrix element mapping the pre-selected input to the post-selected output. Each projected register starts in the zero state when no pre_select_dict is provided.

The circuit must take one, two, or three projected registers followed by the state register. The user-supplied circuit is responsible for applying any state_result tags to those projected registers and discarding the allocated registers after calling circ.

Parameters:
  • circ (GuppyFunctionDefinition) – The circuit function to be executed. It must accept the projected registers and a state register, and it must emit the state_result tags referenced by post_select_dict.

  • n_state_qubits (int) – The number of qubits in the state block.

  • post_select_dict (dict[str, list[bool]]) – Mapping from projected register name to the bitstring to project onto. The insertion order determines projected register order when calling circ.

  • pre_select_dict (dict[str, list[bool]] | None) – Optional mapping from projected register name to the bitstring used to prepare each projected register before applying circ. If None, all projected registers are initialized to zero.

  • endianness (Endianness) – Convert to big endian (default)

  • n_extra_qubits (int) – Extra qubits to add to the emulator pool beyond the explicitly named registers. Use this when the circuit internally allocates ancilla qubits via qubit().

Returns:

The projected matrix.

Return type:

NDArray[np.complex128]

guppyalgos.testing.hamming_weight(i, n)

Compute the hamming weight of i as an n bit binary string.

Return type:

int

guppyalgos.testing.project_state_onto_bitstring(state, bitstring, zero_threshold=1e-12, new_specified_qubits=None, renormalize=True)

Projects a state onto the desired bitstring on the specified qubits.

Parameters:
  • state (SeleneQuestState | SubQuestState) – Output quest state

  • bitstring (list[bool]) – Desired bitstring on state.specified_qubits with bitstring[0] the MSB

  • zero_threshold (float) – point below which the output state counts as having 0 amplitude

  • new_specified_qubits (list[int] | None) – List of indices of qubits you are interested in after the projection, these must be disjoint with the qubits projected on

  • renormalize (bool) – Whether to renormalize the projected state

Return type:

TracedState[SubQuestState]

Returns:

TracedState, which contains a SubQuestState, a statevector over the qubits which have not been projected on, along with the probability of the postselection succeeding. The output SubQuestState has specified qubits determined by new_specified_qubits, with specified_qubits=[] if new_specified_qubits=None, and keeps track of which qubits have been projected out so far.

guppyalgos.testing.statevector_projected_selene(main, n_qubits, post_select_dict, returned_specified_qubits=None, renormalize=True, *, returned_state_tag=None, main_args_dict=None)

Project named state_result registers in sequence.

This executes main, extracts the named state_result entries, and then applies project_state_onto_bitstring repeatedly in the order the register names appear in post_select_dict. Each projection can pass the remaining specified qubits from the next register so that later projections operate on the expected subspace.

All state results should be disjoint in their specified qubits. In practice, it is safest to use them at the same point in the program over all qubits, to avoid accidentally overlapping qubits.

Parameters:
  • main (TypeAliasType) – The guppy main function to execute.

  • n_qubits (int) – The total number of qubits in the compiled program.

  • post_select_dict (dict[str, list[bool]]) – Mapping from state_result tag to the boolean bitstring to project that register onto. The insertion order of this dictionary determines the projection order.

  • returned_specified_qubits (list[int] | None) – Optional specified-qubit list to assign to the final returned state after all projections have been applied.

  • returned_state_tag (str | None) – Optional state-result tag whose qubits should be marked as the specified qubits in the returned state.

  • renormalize (bool) – Whether to renormalize the state after each projection step.

  • main_args_dict (dict[str, Any] | None) – arguments to pass to guppy main function.

Returns:

The final state after all requested register projections have been applied.

Return type:

SeleneQuestState

guppyalgos.testing.switch_endianness(vec)

Switch the endianness of a vector.

Parameters:

vec (GenericAlias[complex128]) – The input 2^n vec.

Returns:

The vec with reversed bit order.

Return type:

NDArray[np.complex128]

guppyalgos.testing.switch_matrix_endianness(mat)

Switch the endianness of a matrix.

Parameters:

mat (GenericAlias[complex128]) – The input 2^n x 2^n matrix.

Returns:

The mat with reversed bit order in both dimensions.

Return type:

NDArray[np.complex128]