pytket.utils
Utility functions for performing high-level procedures in pytket
- pytket.utils.append_pauli_measurement(pauli_string: QubitPauliString, circ: Circuit) None
Appends measurement instructions to a given circuit, measuring each qubit in a given basis.
- Parameters
pauli_string (QubitPauliString) – The pauli string to measure
circ (Circuit) – Circuit to add measurement to.
- pytket.utils.compare_statevectors(first: ndarray, second: ndarray) bool
Check approximate equality up to global phase for statevectors.
- Parameters
first (np.ndarray) – First statevector.
second (np.ndarray) – Second statevector.
- Returns
Approximate equality.
- Return type
- pytket.utils.compare_unitaries(first: ndarray, second: ndarray) bool
Check approximate equality up to global phase for unitaries.
- Parameters
first (np.ndarray) – First unitary.
second (np.ndarray) – Second unitary.
- Returns
Approximate equality.
- Return type
- pytket.utils.counts_from_shot_table(shot_table: ndarray) Dict[Tuple[int, ...], int]
Summarises a shot table into a dictionary of counts for each observed outcome.
- pytket.utils.expectation_from_counts(counts: Dict[Tuple[int, ...], int]) float
Estimates the expectation value of a circuit from shot counts. Computes the parity of ‘1’s across all bits to determine a +1 or -1 contribution from each readout, and returns the weighted average.
- pytket.utils.expectation_from_shots(shot_table: ndarray) float
Estimates the expectation value of a circuit from its shots. Computes the parity of ‘1’s across all bits to determine a +1 or -1 contribution from each row, and returns the average.
- Parameters
shot_table (np.ndarray) – The table of shots to interpret.
- Returns
The expectation value in the range [-1, 1].
- Return type
- pytket.utils.gen_term_sequence_circuit(operator: QubitPauliOperator, reference_state: Circuit, partition_strat: PauliPartitionStrat = PauliPartitionStrat.CommutingSets, colour_method: GraphColourMethod = GraphColourMethod.Lazy) Circuit
Sequences QubitPauliOperator terms to generate a circuit made of CircBoxes. Each CircBox contains a sequence of PauliExpBox objects.
- Parameters
operator (QubitPauliOperator) – The operator terms to sequence
reference_state (Circuit) – reference state to add sequenced terms to.
partition_strat (PauliPartitionStrat, optional) – a Partition strategy
- pytket.utils.get_operator_expectation_value(state_circuit: Circuit, operator: QubitPauliOperator, backend: Backend, n_shots: Optional[int] = None, partition_strat: Optional[PauliPartitionStrat] = None, colour_method: GraphColourMethod = GraphColourMethod.LargestFirst, **kwargs: Optional[Union[int, float, str]]) complex
Estimates the expectation value of the given circuit with respect to the operator based on its individual Pauli terms. If the QubitPauliOperator has symbolic values the expectation value will also be symbolic. The input circuit must belong to the default qubit register and have contiguous qubit ordering.
- Parameters
state_circuit (Circuit) – Circuit that generates the desired state \(\left|\psi\right>\)
operator (QubitPauliOperator) – Operator \(H\). Currently does not support free symbols for the purpose of obtaining expectation values.
backend (Backend) – pytket backend to run circuit on.
n_shots (Optional[int], optional) – Number of shots to run if backend supports shots/counts. None will force the backend to give the full state if available. Defaults to None
partition_strat (Optional[PauliPartitionStrat], optional) – If retrieving shots, can perform measurement reduction using a chosen strategy
- Returns
\(\left<\psi | H | \psi \right>\)
- Return type
- pytket.utils.get_pauli_expectation_value(state_circuit: Circuit, pauli: QubitPauliString, backend: Backend, n_shots: Optional[int] = None) complex
Estimates the expectation value of the given circuit with respect to the Pauli term by preparing measurements in the appropriate basis, running on the backend and interpreting the counts/statevector
- Parameters
state_circuit (Circuit) – Circuit that generates the desired state \(\left|\psi\right>\).
pauli (QubitPauliString) – Pauli operator
backend (Backend) – pytket backend to run circuit on.
n_shots (Optional[int], optional) – Number of shots to run if backend supports shots/counts. Set to None to calculate using statevector if supported by the backend. Defaults to None
- Returns
\(\left<\psi | P | \psi \right>\)
- Return type
- pytket.utils.permute_basis_indexing(matrix: ndarray, permutation: Tuple[int, ...]) ndarray
- Rearranges the first dimensions of an array (statevector or unitary)
according to a permutation of the bit indices in the binary representation of row indices.
- Parameters
matrix (np.ndarray) – Original unitary matrix
permutation (Tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list
- Returns
Updated unitary matrix
- Return type
np.ndarray
- pytket.utils.permute_qubits_in_statevector(state: ndarray, permutation: Tuple[int, ...]) ndarray
Rearranges a statevector according to a permutation of the qubit indices.
- Parameters
state (np.ndarray) – Original statevector.
permutation (Tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list.
- Returns
Updated statevector.
- Return type
np.ndarray
- pytket.utils.permute_rows_cols_in_unitary(matrix: ndarray, permutation: Tuple[int, ...]) ndarray
Rearranges the rows of a unitary matrix according to a permutation of the qubit indices.
- Parameters
matrix (np.ndarray) – Original unitary matrix
permutation (Tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list
- Returns
Updated unitary matrix
- Return type
np.ndarray
- pytket.utils.prepare_circuit(circ: Circuit, allow_classical: bool = True, xcirc: Optional[Circuit] = None) Tuple[Circuit, Circuit]
Prepare a circuit for processing by a backend device.
This method first makes all inputs into Create operations (assuming an initial all- zero state) and all outputs into Discard operations (so that the circuit can no longer be usefully extended or appended to another circuit). It then attempts to apply various simplifications that take advantage of the known initial state and the fact that any unmeasured state is discarded. Finally, it separates the circuit into two circuits, the first of which is to be run on the backend (after any further compilation has been applied), and the second of which is a pure-classical circuit (on the same bits) which encodes classical post-processing of the measurement results. This post-processing is applied automatically when you pass the classical circuit as the ppcirc argument to BackendResult.get_counts() or BackendResult.get_shots().
The original circuit is not modified by this method.
- Parameters
circ – input circuit
allow_classical – allow insertion of mid-circuit classical operations?
xcirc – 1-qubit circuit implementing an X gate in the transformed circuit (if omitted, an X gate is used)
- Returns
(c0, ppcirc) where c0 is the simplified circuit and ppcirc should be passed to BackendResult.get_counts() or BackendResult.get_shots() when retrieving the final results.
- pytket.utils.probs_from_counts(counts: Dict[Tuple[int, ...], int]) Dict[Tuple[int, ...], float]
Converts raw counts of observed outcomes into the observed probability distribution.
- pytket.utils.probs_from_state(state: ndarray, min_p: float = 1e-10) Dict[Tuple[int, ...], float]
Converts statevector to the probability distribution over readouts in the computational basis. Ignores probabilities lower than min_p.
- pytket.utils.readout_counts(ctr: Counter[OutcomeArray]) Counter[Tuple[int, ...]]
Convert counts from
OutcomeArray
types to tuples of ints.
- class pytket.utils.OutcomeArray(input_array: ndarray, width: int)
Array of measured outcomes from qubits. Derived class of numpy.ndarray.
Bitwise outcomes are compressed into unsigned 8-bit integers, each representing up to 8 qubit measurements. Each row is a repeat measurement.
- Parameters
- choose_indices(indices: List[int]) OutcomeArray
Permute ordering of bits in outcomes or choose subset of bits. e.g. [1, 0, 2] acting on a bitstring of length 4 swaps bit locations 0 & 1, leaves 2 in the same place and deletes location 3.
- Parameters
indices (List[int]) – New locations for readout bits.
- Returns
New array corresponding to given permutation.
- Return type
- counts() Counter[OutcomeArray]
Calculate counts of outcomes in OutcomeArray
- Returns
Counter of outcome, number of instances
- Return type
Counter[OutcomeArray]
- classmethod from_dict(ar_dict: Dict[str, Any]) OutcomeArray
Create an OutcomeArray from JSON serializable dictionary (as created by to_dict).
- Parameters
dict – Dictionary representation of OutcomeArray.
- Returns
Instance of OutcomeArray
- Return type
- classmethod from_ints(ints: Sequence[int], width: int, big_endian: bool = True) OutcomeArray
- Create OutcomeArray from iterator of integers corresponding to outcomes
where the bitwise representation of the integer corresponds to the readouts.
- Parameters
- Returns
OutcomeArray instance
- Return type
- classmethod from_readouts(readouts: Union[_SupportsArray[dtype], _NestedSequence[_SupportsArray[dtype]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) OutcomeArray
Create OutcomeArray from a 2D array like object of read-out integers, e.g. [[1, 1, 0], [0, 1, 1]]
- to_dict() Dict[str, Any]
Return a JSON serializable dictionary representation of the OutcomeArray.
- Returns
JSON serializable dictionary
- Return type
Dict[str, Any]
- to_intlist(big_endian: bool = True) List[int]
Express each outcome as an integer corresponding to the bit values.
- to_readout() ndarray
Convert a singleton to a single readout (1D array)
- to_readouts() ndarray
Convert OutcomeArray to a 2D array of readouts, each row a separate outcome and each column a bit value.
- class pytket.utils.QubitPauliOperator(dictionary: Optional[Dict[QubitPauliString, Union[int, float, complex, Expr]]] = None)
Generic data structure for generation of circuits and expectation value calculation. Contains a dictionary from QubitPauliString to sympy Expr. Capacity for symbolic expressions allows the operator to be used to generate ansätze for variational algorithms.
Represents a mathematical object \(\sum_j \alpha_j P_j\), where each \(\alpha_j\) is a complex symbolic expression and \(P_j\) is a Pauli string, i.e. \(P_j \in \{ I, X, Y, Z\}^{\otimes n}\).
A prototypical example is a molecular Hamiltonian, for which one may wish to calculate the expectation value \(\langle \Psi | H | \Psi \rangle\) by decomposing \(H\) into individual Pauli measurements. Alternatively, one may wish to evolve a state by the operator \(e^{-iHt}\) for digital quantum simulation. In this case, the whole operator must be decomposed into native operations.
In both cases, \(H\) may be represented by a QubitPauliOperator.
- __init__(dictionary: Optional[Dict[QubitPauliString, Union[int, float, complex, Expr]]] = None) None
- compress(abs_tol: float = 1e-10) None
Substitutes all free symbols in the QubitPauliOperator with 1, and then removes imaginary and real components which have magnitudes below the tolerance. If the resulting expression is 0, the term is removed entirely.
Warning: This methods assumes significant expression structure is known a priori, and is best suited to operators which have simple product expressions, such as excitation operators for VQE ansätze and digital quantum simulation. Otherwise, it may remove terms relevant to computation. Each expression is of the form \(f(a_1,a_2,\ldots,a_n)\) for some symbols \(a_i\). \(|f(a_1,a_2,\ldots,a_n)|\) is assumed to monotonically increase in both real and imaginary components for all \(a_i \in [0, 1]\).
- Parameters
abs_tol (float) – The threshold below which to remove values.
- dot_state(state: ndarray, qubits: Optional[List[Qubit]] = None) ndarray
Applies the operator to the given state, mapping qubits to indexes according to
qubits
.When
qubits
is an explicit list, the qubits are ordered withqubits[0]
as the most significant qubit for indexing intostate
.If
None
, qubits sequentially indexed from 0 in the default register and ordered by ILO-BE soQubit(0)
is the most significant.
- Parameters
state (numpy.ndarray) – The initial statevector
qubits (Union[List[Qubit], None], optional) – Sequencing of qubits in
state
, if not mapped to the default register. Defaults to None
- Returns
The dot product of the operator with the statevector
- Return type
numpy.ndarray
- classmethod from_list(pauli_list: List[Dict[str, Any]]) QubitPauliOperator
Construct a QubitPauliOperator from a serializable JSON list format, as returned by QubitPauliOperator.to_list()
- Returns
New QubitPauliOperator instance.
- Return type
- state_expectation(state: ndarray, qubits: Optional[List[Qubit]] = None) complex
Calculates the expectation value of the given statevector with respect to the operator, mapping qubits to indexes according to
qubits
.When
qubits
is an explicit list, the qubits are ordered withqubits[0]
as the most significant qubit for indexing intostate
.If
None
, qubits sequentially indexed from 0 in the default register and ordered by ILO-BE soQubit(0)
is the most significant.
- subs(symbol_dict: Dict[Symbol, complex]) None
Substitutes any matching symbols in the QubitPauliOperator.
- Parameters
symbol_dict (Dict[Symbol, complex]) – A dictionary of symbols to fixed values.
- to_list() List[Dict[str, Any]]
- Generate a list serialized representation of QubitPauliOperator,
suitable for writing to JSON.
- Returns
JSON serializable list of dictionaries.
- Return type
List[Dict[str, Any]]
- to_sparse_matrix(qubits: Optional[Union[List[Qubit], int]] = None) csc_matrix
Represents the sparse operator as a dense operator under the ordering scheme specified by
qubits
, and generates the corresponding matrix.When
qubits
is an explicit list, the qubits are ordered withqubits[0]
as the most significant qubit for indexing into the matrix.If
None
, then no padding qubits are introduced and we use the ILO-BE convention, e.g.Qubit("a", 0)
is more significant thanQubit("a", 1)
orQubit("b")
.Giving a number specifies the number of qubits to use in the final operator, treated as sequentially indexed from 0 in the default register (padding with identities as necessary) and ordered by ILO-BE so
Qubit(0)
is the most significant.
- class pytket.utils.Graph(c: Circuit)
- __init__(c: Circuit)
A class for visualising a circuit as a directed acyclic graph (DAG).
Note: in order to use graph-rendering methods, such as
Graph.save_DAG()
, it is necessary to have the Graphviz tools installed and on your path. See the Graphviz website for instructions on how to install them.- Parameters
c (pytket.Circuit) – Circuit
- as_nx() MultiDiGraph
Return a logical representation of the circuit as a DAG.
- Returns
Representation of the DAG
- Return type
networkx.MultiDiGraph
- get_DAG() Digraph
Return a visual representation of the DAG as a graphviz object.
- Returns
Representation of the DAG
- Return type
graphviz.DiGraph
- get_qubit_graph() Graph
Return a visual representation of the qubit connectivity graph as a graphviz object.
- Returns
Representation of the qubit connectivity graph of the circuit
- Return type
graphviz.Graph
- save_DAG(name: str, fmt: str = 'pdf') None
Save an image of the DAG to a file.
The actual filename will be “<name>.<fmt>”. A wide range of formats is supported. See https://graphviz.org/doc/info/output.html.
- save_qubit_graph(name: str, fmt: str = 'pdf') None
Save an image of the qubit connectivity graph to a file.
The actual filename will be “<name>.<fmt>”. A wide range of formats is supported. See https://graphviz.org/doc/info/output.html.
pytket.utils.spam
- pytket.utils.spam.compress_counts(counts: Dict[Tuple[int, ...], float], tol: float = 1e-06, round_to_int: bool = False) Dict[Tuple[int, ...], int]
Filter counts to remove states that have a count value (which can be a floating-point number) below a tolerance, and optionally round to an integer.
- class pytket.utils.spam.SpamCorrecter(qubit_subsets: List[List[Node]], backend: Optional[Backend] = None)
A class for generating “state preparation and measurement” (SPAM) calibration experiments for
pytket
backends, and correcting counts generated from them.Supports saving calibrated state to a dictionary format, and restoring from the dictionary.
- __init__(qubit_subsets: List[List[Node]], backend: Optional[Backend] = None)
Construct a new SpamCorrecter.
- Parameters
qubit_subsets (List[List[Node]]) – A list of lists of correlated Nodes of an Architecture. Qubits within the same list are assumed to only have SPAM errors correlated with each other. Thus to allow SPAM errors between all qubits you should provide a single list.
backend – Backend on which the experiments are intended to be run (optional). If provided, the qubits in qubit_subsets must be nodes in the backend’s associated Architecture. If not provided, it is assumed that the experiment will be run on an Architecture`with the nodes in `qubit_subsets, and furthermore that the intended architecture natively supports X gates.
- Raises
ValueError – There are repeats in the qubit_subsets specification.
- calculate_matrices(results_list: List[BackendResult]) None
Calculate the calibration matrices from the results of running calibration circuits.
- Parameters
results_list – List of results from Backend. Must be in the same order as the corresponding circuits generated by calibration_circuits.
- Raises
RuntimeError – Calibration circuits have not been generated yet.
- calibration_circuits() List[Circuit]
Generate calibration circuits according to the specified correlations.
- Returns
A list of calibration circuits to be run on the machine. The circuits should be processed without compilation. Results from these circuits must be given back to this class (via the calculate_matrices method) in the same order.
- Return type
List[Circuit]
- correct_counts(result: BackendResult, parallel_measures: List[Dict[Qubit, Bit]], method: str = 'bayesian', options: Optional[Dict] = None) BackendResult
Modifies count distribution for result, such that the inversion of the pure noise map represented by characterisation matrices is applied to it.
- Parameters
result (BackendResult) – BackendResult object to be negated by pure noise object.
parallel_measures (ParallelMeasures) – Used to permute corresponding BackendResult object so counts order matches noise characterisation and to amend characterisation matrices to correct the right bits. SpamCorrecter.get_parallel_measure returns the required object for a given circuit.
- Raises
ValueError – Measured qubit in result not characterised.
- Returns
A new result object with counts modified to reflect SPAM correction.
- Return type
- classmethod from_dict(d: Dict) SpamCorrecter
Build a SpamCorrecter instance from a dictionary in the format returned by to_dict.
- Returns
Dictionary of calibration information.
- Return type
- get_parallel_measure(circuit: Circuit) List[Dict[Qubit, Bit]]
- For a given circuit, produces and returns a ParallelMeasures object required
for correcting counts results.
- Parameters
circuit (Circuit) – Circuit with some Measure operations.
- Returns
A list of dictionaries mapping Qubit to Bit where each separate dictionary details some set of Measurement operations run in parallel.
- Return type
ParallelMeasures
pytket.utils.symbolic
Collection of methods to calculate symbolic statevectors and unitaries, for symbolic circuits. This uses the sympy.physics.quantum module and produces sympy objects. The implementations are slow and scale poorly, so this is only suitable for very small (up to 5 qubit) circuits.
- class pytket.utils.symbolic.SymGateRegister
Static class holding mapping from OpType to callable generating symbolic matrix. Allows users to add their own definitions, or override existing definitions.
- classmethod get_func(typ: OpType) Callable[[List[Union[Expr, float]]], ImmutableDenseMatrix]
Get registered callable.
- pytket.utils.symbolic.circuit_apply_symbolic_qubit(circ: Circuit, input_qb: Expr) Qubit
Apply circuit to an input state to calculate output symbolic state.
- pytket.utils.symbolic.circuit_apply_symbolic_statevector(circ: Circuit, input_state: Optional[Union[ndarray, ImmutableDenseMatrix]] = None) ImmutableDenseMatrix
Apply circuit to an optional input statevector to calculate output symbolic statevector. If no input statevector given, the all zero state is assumed. Statevector follows pytket default ILO BasisOrder.
- Parameters
circ (Circuit) – Input Circuit.
input_state (Optional[Union[np.ndarray, ImmutableMatrix]], optional) – Input statevector as a column vector, defaults to None.
- Returns
Symbolic state after circ acts on input_state.
- Return type
ImmutableMatrix
- pytket.utils.symbolic.circuit_to_symbolic_gates(circ: Circuit) Mul
Generate a multiplication expression of sympy gates from Circuit
- Parameters
circ (Circuit) – Input circuit
- Raises
ValueError – If circ does not match a unitary operation.
- Returns
Symbolic gate multiplication expression.
- Return type
Mul