Propagation (pauli_prop.propagation)¶
Functions for performing Pauli propagation.
- class RotationGates(gates, qargs, thetas)[source]¶
Bases:
NamedTupleAn intermediate minimal representation of a
QuantumCircuit.During
propagate_through_circuit()theQuantumCircuitgets converted into a sequence of rotation gates, extracting the parameters and acted-upon qubit indices. These data structures can be passed to the Rust-accelerated internal function in a straight forward manner.Create new instance of RotationGates(gates, qargs, thetas)
- Parameters:
- append_circuit_instruction(inst, qargs, num_qubits, *, clifford=None)[source]¶
Parses a circuit instruction and appends its data to the internal lists.
- Parameters:
inst (CircuitInstruction) – The circuit instruction to parse and append
qargs (list[int]) – The list of qubit indices of the instruction in the context of its circuit
num_qubits (int) – The number of qubits of the circuit containing this instruction
clifford (Clifford | None) – An optional Clifford through which the provided instruction should be moved. The Clifford must act on all qubits in the circuit.
- Raises:
ValueError – Unsupported gate encountered in circuit
ValueError – If given,
cliffordmust act on all qubits in circuit
- Return type:
None
- count(value, /)¶
Return number of occurrences of value.
- index(value, start=0, stop=9223372036854775807, /)¶
Return first index of value.
Raises ValueError if the value is not present.
- circuit_to_rotation_gates(circuit)[source]¶
Converts the provided circuit to an intermediate representation.
- Parameters:
circuit (QuantumCircuit) – The circuit to convert. It may contain gates that are Pauli rotations or PauliLindbladError instances.
- Returns:
The extracted rotation gate data.
- Raises:
ValueError – when an unsupported gate is encountered in
circuit.- Return type:
- propagate_through_rotation_gates(operator, rot_gates, max_terms, atol, frame)[source]¶
Propagate a sparse Pauli operator, \(O\), through a circuit (represented in
rot_gates), \(U\).For Schrödinger propagation: \(U O U†\).
For Heisenberg propagation: \(U† O U\).
In general, the memory and time required for propagating through a circuit grows exponentially with the number of operations in the circuit due to the exponential growth in the number of terms of the operator in the Pauli basis. To regulate this exponential difficulty, one may truncate small Pauli terms (i.e. set them to zero), resulting in a bias proportional to the magnitudes of the truncated terms. After propagating through each operation in the circuit, terms are truncated with respect to two parameters:
Only the
max_termslargest Pauli components are kept; any smaller terms will be truncated. This option makes it possible to estimate in advance how much time and memory will suffice for the computation.Terms with magnitudes less than
atolare truncated (set to zero).
Note
This function pre-allocates space in memory for the full-sized operator and operator buffer. It is the caller’s responsibility to ensure they have enough memory to hold operators containing
max_termsterms. Whenmax_termsisNone, the memory and time requirements typically grow exponentially with the number of operations in the circuit.- Parameters:
operator (SparsePauliOp) – The operator to propagate
rot_gates (RotationGates) – The circuit represented in the form of
RotationGates(see alsocircuit_to_rotation_gates()).max_terms (int) – The maximum number of terms the operator may contain as it is propagated
atol (float) – Terms with coeff magnitudes less than this will not be added to the operator as it is propagated. This parameter is not a guarantee on the accuracy of the returned operator.
frame (str) –
sfor Schrödinger evolutionhfor Heisenberg evolution
- Returns:
The evolved operator
- Raises:
ValueError –
frameis neitherhnors.ValueError –
atolis negative.ValueError –
max_termsis not positive.
- Return type:
- propagate_through_circuit(operator, circuit, max_terms, atol, frame)[source]¶
Propagate a sparse Pauli operator, \(O\), through a circuit, \(U\).
For Schrödinger propagation: \(U O U†\).
For Heisenberg propagation: \(U† O U\).
In general, the memory and time required for propagating through a circuit grows exponentially with the number of operations in the circuit due to the exponential growth in the number of terms of the operator in the Pauli basis. To regulate this exponential difficulty, one may truncate small Pauli terms (i.e. set them to zero), resulting in a bias proportional to the magnitudes of the truncated terms. After propagating through each operation in the circuit, terms are truncated with respect to two parameters:
Only the
max_termslargest Pauli components are kept; any smaller terms will be truncated. This option makes it possible to estimate in advance how much time and memory will suffice for the computation.Terms with magnitudes less than
atolare truncated (set to zero).
Note
This function pre-allocates space in memory for the full-sized operator and operator buffer. It is the caller’s responsibility to ensure they have enough memory to hold operators containing
max_termsterms. Whenmax_termsisNone, the memory and time requirements typically grow exponentially with the number of operations in the circuit.- Parameters:
operator (SparsePauliOp) – The operator to propagate
circuit (QuantumCircuit) – The circuit through which the operator will be propagated
max_terms (int) – The maximum number of terms the operator may contain as it is propagated
atol (float) – Terms with coeff magnitudes less than this will not be added to the operator as it is propagated. This parameter is not a guarantee on the accuracy of the returned operator.
frame (str) –
sfor Schrödinger evolutionhfor Heisenberg evolution
- Returns:
The evolved operator
- Raises:
ValueError –
frameis neitherhnors.ValueError –
atolis negative.ValueError –
max_termsis not positive.
- Return type:
- propagate_through_operator(op1, op2, max_terms=None, coerce_op1_traceless=False, num_leading_terms=0, frame='s', atol=0.0, search_step=4)[source]¶
Propagate an operator, op1 or \(O\), through another operator, op2 or \(U\).
For Schrödinger evolution: \(U O U†\).
For Heisenberg evolution: \(U† O U\).
Evolution is performed in the Pauli basis by summing terms of the form \(U_i O_j U_k\) (neglecting the dagger, see note below). The number of such terms is cubic in operator size (len(op1) * len(op2)**2) and will generally include many duplicate Paulis.
Setting max_terms produces an approximate result, where only the max_terms largest terms (in coefficient magnitude) are computed. This can be much faster but results in some error due to truncation of smaller terms.
The approximate computation involves two parts: searching for the terms to keep, then computing those terms. Increasing
search_stepgreatly (cubically) speeds up the search, at an accuracy cost that is often small.It is possible that some Paulis present in the kept terms would have also appeared in the truncated terms. Because such truncated terms are never computed, they cannot possibly be merged into the kept terms sharing the same Pauli. Thus, the
n``th-largest term in the approximate result is not guaranteed to equal the nth-largest term in the exact result. Likewise, convergence to the exact result with increasing ``max_termscan be non-monotonic.Note
\(O\) is assumed to be Hermitian (\(O_j' = :math:`O_j†\))
- Parameters:
op1 (SparsePauliOp) – The operator to propagate
op2 (SparsePauliOp) – The operator through which to propagate
max_terms (int | None) –
When not
None, produces an approximate result including only themax_termslargest terms in the direct product of the three operators in Pauli space.When
max_termsisNoneand the number of qubits is < 12, the propagation will be performed in the computational basis using matrix multiplication. For systems > 12 qubits, all Pauli terms are computed and summed; however, this is usually not a good way to compute exact evolution due to the many duplicate terms present.coerce_op1_traceless (bool) – A flag denoting whether to remove identity terms from the output operator.
num_leading_terms (int) – The number of terms in
op1to conjugate by every term inop2. The set of included terms is expanded to include its union with the set of terms \(U_i O_j U_i†\), for \(j < num_leading_terms\). This can improve accuracy for the leading components of O in the output, at some computational runtime cost.frame (str) – s for Schrödinger evolution h for Heisenberg evolution
atol (float) – Terms in the evolved operator with magnitudes below
atolwill be truncatedsearch_step (int) – A parameter that can speed up the search of the very large 3D space to identify the
max_termslargest terms in the product. Setting this step size >1 accelerates that search by a factor ofsearch_step**3, at a potential cost in accuracy. This inaccuracy is expected to be small forsearch_step**3 << max_terms.
- Returns:
The transformed operator
- Raises:
ValueError –
frameis neithersnorh.ValueError –
search_stepis not positive.ValueError –
max_termscontains an invalid value.
- Return type:
- evolve_through_cliffords(circuit)[source]¶
Evolve (Schrödinger frame) all non-Clifford instructions through all Clifford gates in the circuit.
This shifts all recognized Clifford gates to the beginning of the circuit and updates the bases of Pauli-rotation gates (e.g.
RxGate,RzzGate,PauliEvolutionGate) and PauliLindbladError channels. Other operations are not supported. See Pauli.evolve docs for more info about evolution of Paulis by Cliffords.The effect is similar to going to the Clifford interaction picture in arXiv:2306.04797 but without mapping all rotation angle magnitudes to be \(\leq \pi/4\).
The function returns two objects representing the Clifford and non-Clifford parts of the circuit.
- Parameters:
circuit (QuantumCircuit) – The
QuantumCircuitto transform. Can contain only Pauli-rotation gates,PauliLindbladError(appended to the circuit as quantum channels), and recognized Clifford gates.- Returns:
Clifford - A single all-qubit Clifford representing the first part of the circuit
QuantumCircuit - A circuit containing the remaining, transformed part of the circuit
- Raises:
ValueError – Input circuit contains unsupported gate
- Return type: