pytket.utils

Utility functions for performing high-level procedures in pytket

pytket.utils.append_pauli_measurement(pauli_string, circ)[source]

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.

Return type:

None

pytket.utils.compare_statevectors(first, second)[source]

Check approximate equality up to global phase for statevectors.

Parameters:
  • first (ndarray) – First statevector.

  • second (ndarray) – Second statevector.

Return type:

bool

Returns:

Approximate equality.

pytket.utils.compare_unitaries(first, second)[source]

Check approximate equality up to global phase for unitaries.

Parameters:
  • first (ndarray) – First unitary.

  • second (ndarray) – Second unitary.

Return type:

bool

Returns:

Approximate equality.

pytket.utils.counts_from_shot_table(shot_table)[source]

Summarises a shot table into a dictionary of counts for each observed outcome.

Parameters:

shot_table (ndarray) – Table of shots from a pytket backend.

Return type:

dict[tuple[int, ...], int]

Returns:

Dictionary mapping observed readouts to the number of times observed.

pytket.utils.expectation_from_counts(counts)[source]

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.

Parameters:

counts (dict[tuple[int, ...], int]) – Counts of each measurement outcome observed.

Return type:

float

Returns:

The expectation value in the range [-1, 1].

pytket.utils.expectation_from_shots(shot_table)[source]

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 (ndarray) – The table of shots to interpret.

Return type:

float

Returns:

The expectation value in the range [-1, 1].

pytket.utils.gen_term_sequence_circuit(operator, reference_state, partition_strat=PauliPartitionStrat.CommutingSets, colour_method=GraphColourMethod.Lazy)[source]

Sequences the terms of a QubitPauliOperator \(P\) to generate a circuit approximating \(e^{-i \frac{\pi}{2} P}\). This method performs Trotterisation on \(P\) with a single Trotter step.

This method uses a given partitioning strategy and a graph colouring

method for term sequencing.

The resulting Circuit will contain a sequence of CircBoxes. Each CircBox corresponds to a set of Pauli strings. Each exponentiated Pauli string in the set is realised as a PauliExpBox.

The ordering of terms prioritises reducing the two qubit gate count of the circuit when the PauliSimp or GuidedPauliSimp passes are applied rather than minimising the trotter error.

Parameters:
Return type:

Circuit

pytket.utils.get_operator_expectation_value(state_circuit, operator, backend, n_shots=None, partition_strat=None, colour_method=GraphColourMethod.LargestFirst, **kwargs)[source]

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 (int | None) – 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 (PauliPartitionStrat | None) – If retrieving shots, can perform measurement reduction using a chosen strategy

Return type:

complex

Returns:

\(\left<\psi | H | \psi \right>\)

pytket.utils.get_pauli_expectation_value(state_circuit, pauli, backend, n_shots=None)[source]

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 (int | None) – 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

Return type:

complex

Returns:

\(\left<\psi | P | \psi \right>\)

pytket.utils.permute_basis_indexing(matrix, permutation)[source]
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 (ndarray) – Original unitary matrix

  • permutation (tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list

Return type:

ndarray

Returns:

Updated unitary matrix

pytket.utils.permute_qubits_in_statevector(state, permutation)[source]

Rearranges a statevector according to a permutation of the qubit indices.

>>> # A 3-qubit state:
>>> state = np.array([0.0, 0.0625, 0.1875, 0.25, 0.375, 0.4375, 0.5, 0.5625])
>>> permutation = [1, 0, 2] # swap qubits 0 and 1
>>> # Apply the permutation that swaps indices 2 (="010") and 4 (="100"), and swaps
>>> # indices 3 (="011") and 5 (="101"):
>>> permute_qubits_in_statevector(state, permutation)
array([0.    , 0.0625, 0.375 , 0.4375, 0.1875, 0.25  , 0.5   , 0.5625])
Parameters:
  • state (ndarray) – Original statevector.

  • permutation (tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list.

Return type:

ndarray

Returns:

Updated statevector.

pytket.utils.permute_rows_cols_in_unitary(matrix, permutation)[source]

Rearranges the rows of a unitary matrix according to a permutation of the qubit indices.

Parameters:
  • matrix (ndarray) – Original unitary matrix

  • permutation (tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list

Return type:

ndarray

Returns:

Updated unitary matrix

pytket.utils.prepare_circuit(circ, allow_classical=True, xcirc=None)[source]

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 (Circuit) – input circuit

  • allow_classical (bool) – allow insertion of mid-circuit classical operations?

  • xcirc (Circuit | None) – 1-qubit circuit implementing an X gate in the transformed circuit (if omitted, an X gate is used)

Return type:

tuple[Circuit, Circuit]

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)[source]

Converts raw counts of observed outcomes into the observed probability distribution.

Parameters:

counts (dict[tuple[int, ...], int]) – Dictionary mapping observed readouts to the number of times observed.

Return type:

dict[tuple[int, ...], float]

Returns:

Probability distribution over observed readouts.

pytket.utils.probs_from_state(state, min_p=1e-10)[source]

Converts statevector to the probability distribution over readouts in the computational basis. Ignores probabilities lower than min_p.

Parameters:
  • state (ndarray) – Full statevector with big-endian encoding.

  • min_p (float) – Minimum probability to include in result

Return type:

dict[tuple[int, ...], float]

Returns:

Probability distribution over readouts.

pytket.utils.readout_counts(ctr)[source]

Convert counts from OutcomeArray types to tuples of ints.

Return type:

Counter[tuple[int, ...]]

OutcomeArray class and associated methods.

class pytket.utils.outcomearray.OutcomeArray(input_array: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], width: int)[source]

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:
  • width – Number of bit entries stored, less than or equal to the bit capacity of the array.

  • n_outcomes – Number of outcomes stored.

choose_indices(indices)[source]

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.

Return type:

OutcomeArray

Returns:

New array corresponding to given permutation.

counts()[source]

Calculate counts of outcomes in OutcomeArray

Return type:

Counter[OutcomeArray]

Returns:

Counter of outcome, number of instances

classmethod from_dict(ar_dict)[source]

Create an OutcomeArray from JSON serializable dictionary (as created by to_dict).

Parameters:

dict – Dictionary representation of OutcomeArray.

Return type:

OutcomeArray

Returns:

Instance of OutcomeArray

classmethod from_ints(ints, width, big_endian=True)[source]
Create OutcomeArray from iterator of integers corresponding to outcomes

where the bitwise representation of the integer corresponds to the readouts.

Parameters:
  • ints (Sequence[int]) – Iterable of outcome integers

  • width (int) – Number of qubit measurements

  • big_endian (bool) – whether to use big endian encoding (or little endian if False), defaults to True

Return type:

OutcomeArray

Returns:

OutcomeArray instance

classmethod from_readouts(readouts)[source]

Create OutcomeArray from a 2D array like object of read-out integers, e.g. [[1, 1, 0], [0, 1, 1]]

Return type:

OutcomeArray

to_dict()[source]

Return a JSON serializable dictionary representation of the OutcomeArray.

Return type:

dict[str, Any]

Returns:

JSON serializable dictionary

to_intlist(big_endian=True)[source]

Express each outcome as an integer corresponding to the bit values.

Parameters:

big_endian (bool) – whether to use big endian encoding (or little endian if False), defaults to True

Return type:

list[int]

Returns:

List of integers, each corresponding to an outcome.

to_readout()[source]

Convert a singleton to a single readout (1D array)

Return type:

ndarray

to_readouts()[source]

Convert OutcomeArray to a 2D array of readouts, each row a separate outcome and each column a bit value.

Return type:

ndarray

property n_outcomes: Any

Number of outcomes stored.

property width: int

Number of bit entries stored, less than or equal to the bit capacity of the array.

pytket.utils.outcomearray.readout_counts(ctr)[source]

Convert counts from OutcomeArray types to tuples of ints.

Return type:

Counter[tuple[int, ...]]

class pytket.utils.operators.QubitPauliOperator(dictionary=None)[source]

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=None)[source]
compress(abs_tol=1e-10)[source]

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.

Return type:

None

dot_state(state, qubits=None)[source]

Applies the operator to the given state, mapping qubits to indexes according to qubits.

  • When qubits is an explicit list, the qubits are ordered with qubits[0] as the most significant qubit for indexing into state.

  • If None, qubits sequentially indexed from 0 in the default register and ordered by ILO-BE so Qubit(0) is the most significant.

Parameters:
  • state (ndarray) – The initial statevector

  • qubits (list[Qubit] | None) – Sequencing of qubits in state, if not mapped to the default register. Defaults to None

Return type:

ndarray

Returns:

The dot product of the operator with the statevector

classmethod from_list(pauli_list)[source]

Construct a QubitPauliOperator from a serializable JSON list format, as returned by QubitPauliOperator.to_list()

Return type:

QubitPauliOperator

Returns:

New QubitPauliOperator instance.

get(key, default)[source]

Get the coefficient of a particular string present in the operator.

Return type:

Expr

get_dict()[source]

Generate a dict representation of QubitPauliOperator, mapping each QubitPauliString in the support to its corresponding value.

Return type:

dict[QubitPauliString, Expr]

Returns:

A dict of Pauli strings and their coefficients as key-value pairs

state_expectation(state, qubits=None)[source]

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 with qubits[0] as the most significant qubit for indexing into state.

  • If None, qubits sequentially indexed from 0 in the default register and ordered by ILO-BE so Qubit(0) is the most significant.

Parameters:
  • state (ndarray) – The initial statevector

  • qubits (list[Qubit] | None) – Sequencing of qubits in state, if not mapped to the default register. Defaults to None

Return type:

complex

Returns:

The expectation value of the statevector and operator

subs(symbol_dict)[source]

Substitutes any matching symbols in the QubitPauliOperator.

Parameters:

symbol_dict (dict[Symbol, complex]) – A dictionary of symbols to fixed values.

Return type:

None

to_list()[source]
Generate a list serialized representation of QubitPauliOperator,

suitable for writing to JSON.

Return type:

list[dict[str, Any]]

Returns:

JSON serializable list of dictionaries.

to_sparse_matrix(qubits=None)[source]

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 with qubits[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 than Qubit("a", 1) or Qubit("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.

Parameters:

qubits (list[Qubit] | int | None) – Sequencing of qubits in the matrix, either as an explicit list, number of qubits to pad to, or infer from the operator. Defaults to None

Return type:

csc_matrix

Returns:

A sparse matrix representation of the operator.

property all_qubits: set[Qubit]

The set of all qubits the operator ranges over (including qubits that were provided explicitly as identities)

class pytket.utils.graph.Graph(c)[source]

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.

__init__(c)[source]
as_nx()[source]

Return a logical representation of the circuit as a DAG.

Return type:

MultiDiGraph

Returns:

Representation of the DAG

get_DAG()[source]

Return a visual representation of the DAG as a graphviz object.

Return type:

Digraph

Returns:

Representation of the DAG

get_qubit_graph()[source]

Return a visual representation of the qubit connectivity graph as a graphviz object.

Return type:

Graph

Returns:

Representation of the qubit connectivity graph of the circuit

save_DAG(name, fmt='pdf')[source]

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.

Parameters:
  • name (str) – Prefix of file name

  • fmt (str) – File format, e.g. “pdf”, “png”, …

Return type:

None

save_qubit_graph(name, fmt='pdf')[source]

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.

Parameters:
  • name (str) – Prefix of file name

  • fmt (str) – File format, e.g. “pdf”, “png”, …

Return type:

None

view_DAG()[source]

View the DAG.

This method creates a temporary file, and returns its filename so that the caller may delete it afterwards.

Return type:

str

Returns:

filename of temporary created file

view_qubit_graph()[source]

View the qubit connectivity graph.

This method creates a temporary file, and returns its filename so that the caller may delete it afterwards.

Return type:

str

Returns:

filename of temporary created file

pytket.utils.distribution

class pytket.utils.distribution.EmpiricalDistribution(C)[source]

Represents an empirical distribution of values.

Supports methods for combination, marginalization, expectation value, etc.

>>> dist1 = EmpiricalDistribution(Counter({(0, 0): 3, (0, 1): 2, (1, 0): 4, (1, 1):
... 0}))
>>> dist2 = EmpiricalDistribution(Counter({(0, 0): 1, (0, 1): 0, (1, 0): 2, (1, 1):
... 1}))
>>> dist1.sample_mean(lambda x : x[0] + 2*x[1])
0.8888888888888888
>>> dist3 = dist2.condition(lambda x: x[0] == 1)
>>> dist3
EmpiricalDistribution(Counter({(1, 0): 2, (1, 1): 1}))
>>> dist4 = dist1 + dist3
>>> dist4
EmpiricalDistribution(Counter({(1, 0): 6, (0, 0): 3, (0, 1): 2, (1, 1): 1}))
__add__(other)[source]

Combine two distributions.

Return type:

EmpiricalDistribution[TypeVar(T0)]

__eq__(other)[source]

Compare distributions for equality.

Return type:

bool

__getitem__(x)[source]

Get the count associated with an observation.

Return type:

int

as_counter()[source]

Return the distribution as a collections.Counter object.

Return type:

Counter[TypeVar(T0)]

condition(criterion)[source]

Return a new distribution conditioned on the given criterion.

Parameters:

criterion (Callable[[TypeVar(T0)], bool]) – A boolean function defined on all possible observations.

Return type:

EmpiricalDistribution[TypeVar(T0)]

map(mapping)[source]

Return a distribution over a transformed domain.

The provided function maps elements in the original domain to new elements. If it is not injective, counts are combined.

Parameters:

mapping (Callable[[TypeVar(T0)], TypeVar(T1)]) – A function defined on all possible observations, mapping them to another domain.

Return type:

EmpiricalDistribution[TypeVar(T1)]

sample_mean(f)[source]

Compute the sample mean of a functional.

The provided function maps observations to numerical values.

Return type:

Union[float, complex]

Returns:

Estimate of the mean of the functional based on the observations.

sample_variance(f)[source]

Compute the sample variance of a functional.

The provided function maps observations to numerical values.

The sample variance is an unbiased estimate of the variance of the underlying distribution.

Return type:

Union[float, complex]

Returns:

Estimate of the variance of the functional based on the observations.

property support: set[T0]

Return the support of the distribution (set of all observations).

property total: int

Return the total number of observations.

class pytket.utils.distribution.ProbabilityDistribution(P, min_p=0.0)[source]

Represents an exact probability distribution.

Supports methods for combination, marginalization, expectation value, etc. May be derived from an EmpiricalDistribution.

__getitem__(x)[source]

Get the probability associated with a possible outcome.

Return type:

float

as_dict()[source]

Return the distribution as a dict object.

Return type:

dict[TypeVar(T0), float]

as_rv_discrete()[source]

Return the distribution as a scipy.stats.rv_discrete object.

This method returns an RV over integers {0, 1, …, k-1} where k is the size of the support, and a list whose i’th member is the item corresponding to the value i of the RV.

Return type:

tuple[rv_discrete, list[TypeVar(T0)]]

condition(criterion)[source]

Return a new distribution conditioned on the given criterion.

Parameters:

criterion (Callable[[TypeVar(T0)], bool]) – A boolean function defined on all possible outcomes.

Return type:

ProbabilityDistribution[TypeVar(T0)]

expectation(f)[source]

Compute the expectation value of a functional.

The provided function maps possible outcomes to numerical values.

Return type:

Union[float, complex]

Returns:

Expectation of the functional.

classmethod from_empirical_distribution(ed)[source]

Estimate a probability distribution from an empirical distribution.

Return type:

ProbabilityDistribution[TypeVar(T0)]

map(mapping)[source]

Return a distribution over a transformed domain.

The provided function maps elements in the original domain to new elements. If it is not injective, probabilities are combined.

Parameters:

mapping (Callable[[TypeVar(T0)], TypeVar(T1)]) – A function defined on all possible outcomes, mapping them to another domain.

Return type:

ProbabilityDistribution[TypeVar(T1)]

variance(f)[source]

Compute the variance of a functional.

The provided function maps possible outcomes to numerical values.

Return type:

Union[float, complex]

Returns:

Variance of the functional.

property support: set[T0]

Return the support of the distribution (set of all possible outcomes).

pytket.utils.distribution.convex_combination(dists)[source]

Return a convex combination of probability distributions.

Each pair in the list comprises a distribution and a weight. The weights must be non-negative and sum to 1.

>>> dist1 = ProbabilityDistribution({0: 0.25, 1: 0.5, 2: 0.25})
>>> dist2 = ProbabilityDistribution({0: 0.5, 1: 0.5})
>>> dist3 = convex_combination([(dist1, 0.25), (dist2, 0.75)])
>>> dist3
ProbabilityDistribution({0: 0.4375, 1: 0.5, 2: 0.0625})
:rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~pytket.utils.distribution.ProbabilityDistribution\`\\ \\\[\:py\:class\:\`\~typing.TypeVar\`\\ \\\(\`\`T0\`\`\)\]`
>>> dist3.expectation(lambda x : x**2)
0.75

pytket.utils.expectations

pytket.utils.expectations.expectation_from_counts(counts)[source]

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.

Parameters:

counts (dict[tuple[int, ...], int]) – Counts of each measurement outcome observed.

Return type:

float

Returns:

The expectation value in the range [-1, 1].

pytket.utils.expectations.expectation_from_shots(shot_table)[source]

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 (ndarray) – The table of shots to interpret.

Return type:

float

Returns:

The expectation value in the range [-1, 1].

pytket.utils.expectations.get_operator_expectation_value(state_circuit, operator, backend, n_shots=None, partition_strat=None, colour_method=GraphColourMethod.LargestFirst, **kwargs)[source]

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 (int | None) – 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 (PauliPartitionStrat | None) – If retrieving shots, can perform measurement reduction using a chosen strategy

Return type:

complex

Returns:

\(\left<\psi | H | \psi \right>\)

pytket.utils.expectations.get_pauli_expectation_value(state_circuit, pauli, backend, n_shots=None)[source]

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 (int | None) – 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

Return type:

complex

Returns:

\(\left<\psi | P | \psi \right>\)

pytket.utils.measurements

pytket.utils.measurements.append_pauli_measurement(pauli_string, circ)[source]

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.

Return type:

None

pytket.utils.prepare

pytket.utils.prepare.prepare_circuit(circ, allow_classical=True, xcirc=None)[source]

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 (Circuit) – input circuit

  • allow_classical (bool) – allow insertion of mid-circuit classical operations?

  • xcirc (Circuit | None) – 1-qubit circuit implementing an X gate in the transformed circuit (if omitted, an X gate is used)

Return type:

tuple[Circuit, Circuit]

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.results

class pytket.utils.results.BitPermuter(permutation)[source]

Class for permuting the bits in an integer

Enables inverse permuation and uses caching to speed up common uses.

permute(val, inverse=False)[source]

Return input with bit values permuted.

Parameters:
  • val (int) – input integer

  • inverse (bool) – whether to use the inverse permutation, defaults to False

Return type:

int

Returns:

permuted integer

permute_all()[source]

Permute all integers within bit-width specified by permutation.

Return type:

list[int]

Returns:

List of permuted outputs.

pytket.utils.results.compare_statevectors(first, second)[source]

Check approximate equality up to global phase for statevectors.

Parameters:
  • first (ndarray) – First statevector.

  • second (ndarray) – Second statevector.

Return type:

bool

Returns:

Approximate equality.

pytket.utils.results.compare_unitaries(first, second)[source]

Check approximate equality up to global phase for unitaries.

Parameters:
  • first (ndarray) – First unitary.

  • second (ndarray) – Second unitary.

Return type:

bool

Returns:

Approximate equality.

pytket.utils.results.counts_from_shot_table(shot_table)[source]

Summarises a shot table into a dictionary of counts for each observed outcome.

Parameters:

shot_table (ndarray) – Table of shots from a pytket backend.

Return type:

dict[tuple[int, ...], int]

Returns:

Dictionary mapping observed readouts to the number of times observed.

pytket.utils.results.get_n_qb_from_statevector(state)[source]

Given a statevector, returns the number of qubits described

Parameters:

state (ndarray) – Statevector to inspect

Raises:

ValueError – If the dimension of the statevector is not a power of 2

Return type:

int

Returns:

n such that len(state) == 2 ** n

pytket.utils.results.int_dist_from_state(state, min_p=1e-10)[source]

Converts statevector to the probability distribution over its indices. Ignores probabilities lower than min_p.

Parameters:
  • state (ndarray) – A statevector.

  • min_p (float) – Minimum probability to include in result

Return type:

dict[int, float]

Returns:

Probability distribution over the vector’s indices.

pytket.utils.results.permute_basis_indexing(matrix, permutation)[source]
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 (ndarray) – Original unitary matrix

  • permutation (tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list

Return type:

ndarray

Returns:

Updated unitary matrix

pytket.utils.results.permute_qubits_in_statevector(state, permutation)[source]

Rearranges a statevector according to a permutation of the qubit indices.

>>> # A 3-qubit state:
>>> state = np.array([0.0, 0.0625, 0.1875, 0.25, 0.375, 0.4375, 0.5, 0.5625])
>>> permutation = [1, 0, 2] # swap qubits 0 and 1
>>> # Apply the permutation that swaps indices 2 (="010") and 4 (="100"), and swaps
>>> # indices 3 (="011") and 5 (="101"):
>>> permute_qubits_in_statevector(state, permutation)
array([0.    , 0.0625, 0.375 , 0.4375, 0.1875, 0.25  , 0.5   , 0.5625])
Parameters:
  • state (ndarray) – Original statevector.

  • permutation (tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list.

Return type:

ndarray

Returns:

Updated statevector.

pytket.utils.results.permute_rows_cols_in_unitary(matrix, permutation)[source]

Rearranges the rows of a unitary matrix according to a permutation of the qubit indices.

Parameters:
  • matrix (ndarray) – Original unitary matrix

  • permutation (tuple[int, ...]) – Map from current qubit index (big-endian) to its new position, encoded as a list

Return type:

ndarray

Returns:

Updated unitary matrix

pytket.utils.results.probs_from_counts(counts)[source]

Converts raw counts of observed outcomes into the observed probability distribution.

Parameters:

counts (dict[tuple[int, ...], int]) – Dictionary mapping observed readouts to the number of times observed.

Return type:

dict[tuple[int, ...], float]

Returns:

Probability distribution over observed readouts.

pytket.utils.results.probs_from_state(state, min_p=1e-10)[source]

Converts statevector to the probability distribution over readouts in the computational basis. Ignores probabilities lower than min_p.

Parameters:
  • state (ndarray) – Full statevector with big-endian encoding.

  • min_p (float) – Minimum probability to include in result

Return type:

dict[tuple[int, ...], float]

Returns:

Probability distribution over readouts.

pytket.utils.serialization.migration

pytket.utils.serialization.migration.circuit_dict_from_pytket1_dict(circuit_data)[source]

Update the serialization of a pytket 1 circuit to an equivalent pytket circuit. (This converts ClassicalExpBox to ClExprOp operations.)

Parameters:

circuit_data (dict[str, Any]) – serialization of pytket 1 circuit

Return type:

dict[str, Any]

Returns:

serialization of equivalent pytket circuit

pytket.utils.spam

pytket.utils.spam.compress_counts(counts, tol=1e-06, round_to_int=False)[source]

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.

Parameters:
  • counts (dict[tuple[int, ...], float]) – Input counts

  • tol (float) – Value below which counts are pruned. Defaults to 1e-6.

  • round_to_int (bool) – Whether to round each count to an integer. Defaults to False.

Return type:

dict[tuple[int, ...], int | float]

Returns:

Filtered counts

class pytket.utils.spam.SpamCorrecter(qubit_subsets, backend=None)[source]

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, backend=None)[source]

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 | None) – 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)[source]

Calculate the calibration matrices from the results of running calibration circuits.

Parameters:

results_list (list[BackendResult]) – 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.

Return type:

None

calibration_circuits()[source]

Generate calibration circuits according to the specified correlations.

Return type:

list[Circuit]

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.

correct_counts(result, parallel_measures, method='bayesian', options=None)[source]

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 (list[dict[Qubit, Bit]]) – 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.

Return type:

BackendResult

Returns:

A new result object with counts modified to reflect SPAM correction.

classmethod from_dict(d)[source]

Build a SpamCorrecter instance from a dictionary in the format returned by to_dict.

Return type:

SpamCorrecter

Returns:

Dictionary of calibration information.

get_parallel_measure(circuit)[source]
For a given circuit, produces and returns a list[dict[Qubit, Bit]] object required

for correcting counts results.

Parameters:

circuit (Circuit) – Circuit with some Measure operations.

Return type:

list[dict[Qubit, Bit]]

Returns:

A list of dictionaries mapping Qubit to Bit where each separate dictionary details some set of Measurement operations run in parallel.

to_dict()[source]

Get calibration information as a dictionary.

Return type:

dict

Returns:

Dictionary output

pytket.utils.stats

pytket.utils.stats.gate_counts(circ)[source]

Count the number of gates of each type in a circuit.

Parameters:

circ (Circuit) – circuit

Return type:

Counter[OpType]

Returns:

count of gates of each type

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[source]

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)[source]

Get registered callable.

Return type:

Callable[[list[Expr | float]], ImmutableDenseMatrix]

classmethod is_registered(typ)[source]

Check if type has a callable registered.

Return type:

bool

classmethod register_func(typ, f, replace=False)[source]

Register a callable for an optype.

Parameters:
Return type:

None

pytket.utils.symbolic.circuit_apply_symbolic_qubit(circ, input_qb)[source]

Apply circuit to an input state to calculate output symbolic state.

Parameters:
  • circ (Circuit) – Input Circuit.

  • input_qb (Expr) – Sympy Qubit expression corresponding to a state.

Return type:

Qubit

Returns:

Output state after circuit acts on input_qb.

pytket.utils.symbolic.circuit_apply_symbolic_statevector(circ, input_state=None)[source]

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:
Return type:

ImmutableDenseMatrix

Returns:

Symbolic state after circ acts on input_state.

pytket.utils.symbolic.circuit_to_symbolic_gates(circ)[source]

Generate a multiplication expression of sympy gates from Circuit

Parameters:

circ (Circuit) – Input circuit

Raises:

ValueError – If circ does not match a unitary operation.

Return type:

Mul

Returns:

Symbolic gate multiplication expression.

pytket.utils.symbolic.circuit_to_symbolic_unitary(circ)[source]

Generate a symbolic unitary from Circuit.

Unitary matches pytket default ILO BasisOrder.

Parameters:

circ (Circuit) – Input circuit

Return type:

ImmutableDenseMatrix

Returns:

Symbolic unitary.

pytket.utils.term_sequence

pytket.utils.term_sequence.gen_term_sequence_circuit(operator, reference_state, partition_strat=PauliPartitionStrat.CommutingSets, colour_method=GraphColourMethod.Lazy)[source]

Sequences the terms of a QubitPauliOperator \(P\) to generate a circuit approximating \(e^{-i \frac{\pi}{2} P}\). This method performs Trotterisation on \(P\) with a single Trotter step.

This method uses a given partitioning strategy and a graph colouring

method for term sequencing.

The resulting Circuit will contain a sequence of CircBoxes. Each CircBox corresponds to a set of Pauli strings. Each exponentiated Pauli string in the set is realised as a PauliExpBox.

The ordering of terms prioritises reducing the two qubit gate count of the circuit when the PauliSimp or GuidedPauliSimp passes are applied rather than minimising the trotter error.

Parameters:
Return type:

Circuit