quimb.tensor.circuit.core

Representation-agnostic quantum circuit interface (CircuitBase).

Classes

CircuitBase

Representation-agnostic interface shared by every circuit simulator.

Module Contents

class quimb.tensor.circuit.core.CircuitBase(N=None, psi0=None, gate_opts=None, gate_contract='auto-split-gate', gate_propagate_tags='register', tags=None, psi0_dtype='complex128', psi0_tag='PSI0', tag_gate_numbers=True, gate_tag_id='GATE_{}', tag_gate_rounds=True, round_tag_id='ROUND_{}', tag_gate_labels=True, bra_site_ind_id='b{}', dtype=None, to_backend=None, convert_eager=False)[source]

Representation-agnostic interface shared by every circuit simulator.

Holds the circuit description (the list of Gate objects, gate application front-end and convenience methods, named-parameter management, backend/dtype conversion, the from_* constructors, drawing) plus the generic _apply_gate dispatch. It carries no exact-contraction machinery, so representation-specific simulators can compose this interface without inheriting the exact Circuit.

Subclasses must implement the _init_state and psi hooks and may override calc_qubit_ordering (the default is a trivial sorted order).

Notes

The named-parameter methods (register_named_params/get_params/ set_params/update_params_from) index gate tensors by tag, so they are only functional when tag_gate_numbers=True (the exact Circuit default). Representations that disable gate-number tagging (MPS/PEPS/PEPO) inherit them but they are non-functional there.

tag_gate_numbers = True
tag_gate_rounds = True
tag_gate_labels = True
dtype = None
to_backend = None
convert_eager = False
_backend_gate_cache
gate_opts
_gates = []
_ket_site_ind_id
_bra_site_ind_id = 'b{}'
_gate_tag_id = 'GATE_{}'
_round_tag_id = 'ROUND_{}'
_sample_n_gates = -1
_storage
_sampled_conditionals
_named_params
_named_param_exprs
copy()[source]

Copy the circuit and its state.

_maybe_convert(obj, dtype=None)[source]
apply_to_arrays(fn)[source]

Apply a function to all the arrays in the circuit.

static _normalize_named_param_value(value)[source]
property named_params

Named circuit parameters and their current values.

property named_param_names

Names of registered circuit parameters.

property param_expressions

Gate parameter expressions keyed by gate index.

register_named_params(named_params, gate_expressions=None)[source]

Register named circuit parameters and gate dependencies.

Parameters:
  • named_params (sequence[str] or mapping[str, scalar]) – Either names to register, which default to nan until bound, or a mapping supplying initial values.

  • gate_expressions (mapping[int, tuple], optional) – Mapping from gate index to the expressions used to generate that gate’s parameters. Each expression can be a constant, a string expression referencing the named parameters, or a callable taking the current named parameter mapping.

_set_gate_params(i, params)[source]
_apply_named_param_updates()[source]
get_params()[source]

Get a pytree - in this case a dict - of all the parameters in the circuit.

Returns:

Dictionary containing any named parameters plus any directly parametrized gates not driven by named parameter expressions.

Return type:

dict

set_params(params)[source]

Set the parameters of the circuit.

Parameters:

params (dict) – Dictionary mapping gate numbers and/or registered named parameter names to new values.

classmethod from_qsim_str(contents, progbar=False, **circuit_opts)[source]

Generate a Circuit instance from a ‘qsim’ string.

classmethod from_qsim_file(fname, progbar=False, **circuit_opts)[source]

Generate a Circuit instance from a ‘qsim’ file.

The qsim file format is described here: https://quantumai.google/qsim/input_format.

classmethod from_qsim_url(url, progbar=False, **circuit_opts)[source]

Generate a Circuit instance from a ‘qsim’ url.

from_qasm[source]
from_qasm_file[source]
from_qasm_url[source]
classmethod from_openqasm2_str(contents, progbar=False, **circuit_opts)[source]

Generate a Circuit instance from an OpenQASM 2.0 string.

classmethod from_openqasm2_file(fname, progbar=False, **circuit_opts)[source]

Generate a Circuit instance from an OpenQASM 2.0 file.

classmethod from_openqasm2_url(url, progbar=False, **circuit_opts)[source]

Generate a Circuit instance from an OpenQASM 2.0 url.

classmethod from_openqasm3_str(contents, progbar=False, **circuit_opts)[source]

Construct a circuit from an OpenQASM 3.0 string.

Parameters:
  • contents (str) – The OpenQASM 3 source code to parse.

  • progbar (bool, optional) – Whether to show a progress bar while applying the parsed gates.

  • **circuit_opts – Options forwarded to the Circuit constructor.

Returns:

A circuit populated with the parsed gates. If symbolic input declarations are present, they are registered as generic named circuit parameters so that set_params() can bind them later.

Return type:

Circuit

classmethod from_openqasm3_file(fname, progbar=False, **circuit_opts)[source]

Construct a circuit from an OpenQASM 3.0 file.

Parameters:
  • fname (str or path-like) – Path to the OpenQASM 3 file.

  • progbar (bool, optional) – Whether to show a progress bar while applying the parsed gates.

  • **circuit_opts – Options forwarded to the Circuit constructor.

Returns:

The parsed circuit instance.

Return type:

Circuit

classmethod from_openqasm3_url(url, progbar=False, **circuit_opts)[source]

Construct a circuit from an OpenQASM 3.0 URL.

Parameters:
  • url (str) – URL pointing to an OpenQASM 3 source file.

  • progbar (bool, optional) – Whether to show a progress bar while applying the parsed gates.

  • **circuit_opts – Options forwarded to the Circuit constructor.

Returns:

The parsed circuit instance.

Return type:

Circuit

classmethod from_gates(gates, N=None, progbar=False, **kwargs)[source]

Generate a Circuit instance from a sequence of gates.

Parameters:
  • gates (sequence[Gate] or sequence[tuple]) – The sequence of gates to apply.

  • N (int, optional) – The number of qubits. If not given, will be inferred from the gates.

  • progbar (bool, optional) – Whether to show a progress bar.

  • kwargs – Supplied to the Circuit constructor.

property gates
property num_gates
ket_site_ind(i)[source]

Get the site index for the given qubit.

bra_site_ind(i)[source]

Get the ‘bra’ site index for the given qubit, if forming an operator.

gate_tag(g)[source]

Get the tag for the given gate, indexed linearly.

round_tag(r)[source]

Get the tag for the given round (/layer).

_apply_gate(gate, tags=None, **gate_opts)[source]

Apply a Gate to this Circuit. This is the main method that all calls to apply a gate should go through.

Parameters:
  • gate (Gate) – The gate to apply.

  • tags (str or sequence of str, optional) – Tags to add to the gate tensor(s).

apply_gate(gate_id, *gate_args, params=None, qubits=None, controls=None, gate_round=None, parametrize=None, **gate_opts)[source]

Apply a single gate to this tensor network quantum circuit. If gate_round is supplied the tensor(s) added will be tagged with 'ROUND_{gate_round}'. Alternatively, putting an integer first like so:

circuit.apply_gate(10, 'H', 7)

Is automatically translated to:

circuit.apply_gate('H', 7, gate_round=10)
Parameters:
  • gate_id (Gate, str, or array_like) –

    Which gate to apply. This can be:

    • A Gate instance, i.e. with parameters and qubits already specified.

    • A string, e.g. 'H', 'U3', etc. in which case gate_args should be supplied with (*params, *qubits).

    • A raw array, in which case gate_args should be supplied with (*qubits,).

  • gate_args (list[str]) – The arguments to supply to it.

  • gate_round (int, optional) – The gate round. If gate_id is integer-like, will also be taken from here, with then gate_id, gate_args = gate_args[0], gate_args[1:].

  • gate_opts – Supplied to the gate function, options here will override the default gate_opts.

apply_gate_raw(U, where, controls=None, gate_round=None, **gate_opts)[source]

Apply the raw array U as a gate on qubits in where. It will be assumed to be unitary for the sake of computing reverse lightcones.

apply_gates(gates, progbar=False, **gate_opts)[source]

Apply a sequence of gates to this tensor network quantum circuit.

Parameters:
  • gates (Sequence[Gate] or Sequence[Tuple]) – The sequence of gates to apply.

  • gate_opts – Supplied to apply_gate().

h(i, gate_round=None, **kwargs)[source]
x(i, gate_round=None, **kwargs)[source]
y(i, gate_round=None, **kwargs)[source]
z(i, gate_round=None, **kwargs)[source]
s(i, gate_round=None, **kwargs)[source]
sdg(i, gate_round=None, **kwargs)[source]
t(i, gate_round=None, **kwargs)[source]
tdg(i, gate_round=None, **kwargs)[source]
sx(i, gate_round=None, **kwargs)[source]
sxdg(i, gate_round=None, **kwargs)[source]
x_1_2(i, gate_round=None, **kwargs)[source]
y_1_2(i, gate_round=None, **kwargs)[source]
z_1_2(i, gate_round=None, **kwargs)[source]
w_1_2(i, gate_round=None, **kwargs)[source]
hz_1_2(i, gate_round=None, **kwargs)[source]
cnot(i, j, gate_round=None, **kwargs)[source]
cx(i, j, gate_round=None, **kwargs)[source]
cy(i, j, gate_round=None, **kwargs)[source]
cz(i, j, gate_round=None, **kwargs)[source]
iswap(i, j, gate_round=None, **kwargs)[source]
iden(i, gate_round=None)[source]
swap(i, j, gate_round=None, **kwargs)[source]
rx(theta, i, gate_round=None, parametrize=False, **kwargs)[source]
ry(theta, i, gate_round=None, parametrize=False, **kwargs)[source]
rz(theta, i, gate_round=None, parametrize=False, **kwargs)[source]
u3(theta, phi, lamda, i, gate_round=None, parametrize=False, **kwargs)[source]
u2(phi, lamda, i, gate_round=None, parametrize=False, **kwargs)[source]
u1(lamda, i, gate_round=None, parametrize=False, **kwargs)[source]
phase(lamda, i, gate_round=None, parametrize=False, **kwargs)[source]
cu3(theta, phi, lamda, i, j, gate_round=None, parametrize=False, **kwargs)[source]
cu2(phi, lamda, i, j, gate_round=None, parametrize=False, **kwargs)[source]
cu1(lamda, i, j, gate_round=None, parametrize=False, **kwargs)[source]
cphase(lamda, i, j, gate_round=None, parametrize=False, **kwargs)[source]
fsim(theta, phi, i, j, gate_round=None, parametrize=False, **kwargs)[source]
fsimg(theta, zeta, chi, gamma, phi, i, j, gate_round=None, parametrize=False, **kwargs)[source]
givens(theta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
givens2(theta, phi, i, j, gate_round=None, parametrize=False, **kwargs)[source]
xx_plus_yy(theta, beta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
xx_minus_yy(theta, beta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
rxx(theta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
ryy(theta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
rzz(theta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
crx(theta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
cry(theta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
crz(theta, i, j, gate_round=None, parametrize=False, **kwargs)[source]
su4(theta1, phi1, lamda1, theta2, phi2, lamda2, theta3, phi3, lamda3, theta4, phi4, lamda4, t1, t2, t3, i, j, gate_round=None, parametrize=False, **kwargs)[source]
ccx(i, j, k, gate_round=None, **kwargs)[source]
ccnot(i, j, k, gate_round=None, **kwargs)[source]
toffoli(i, j, k, gate_round=None, **kwargs)[source]
ccy(i, j, k, gate_round=None, **kwargs)[source]
ccz(i, j, k, gate_round=None, **kwargs)[source]
cswap(i, j, k, gate_round=None, **kwargs)[source]
fredkin(i, j, k, gate_round=None, **kwargs)[source]
clear_storage()[source]

Clear all cached data.

_maybe_init_storage()[source]
simulate_counts(C, seed=None, reverse=False, **to_dense_opts)[source]

Simulate measuring all qubits in the computational basis many times. Unlike sample(), this generates all the samples simultaneously using the full wavefunction constructed from to_dense(), then calling simulate_counts().

Warning

Because this constructs the full wavefunction it always requires exponential memory in the number of qubits, regardless of circuit depth and structure.

Parameters:
  • C (int) – The number of ‘experimental runs’, i.e. total counts.

  • seed (int, optional) – A seed for reproducibility.

  • reverse (bool, optional) – Whether to reverse the order of the subsystems, to match the convention of qiskit for example.

  • to_dense_opts – Suppled to to_dense().

Returns:

results – The number of recorded counts for each

Return type:

dict[str, int]

xeb(samples_or_counts, cache=None, cache_maxsize=2**20, progbar=False, **amplitude_opts)[source]

Compute the linear cross entropy benchmark (XEB) for samples or counts, amplitude per amplitude.

Parameters:
  • samples_or_counts (Iterable[str] or Dict[str, int]) – Either the raw bitstring samples or a dict mapping bitstrings to the number of counts observed.

  • cache (dict, optional) – A dictionary to store the probabilities in, if not supplied quimb.utils.LRU(cache_maxsize) will be used.

  • cache_maxsize – The maximum size of the cache to be used.

  • optional – The maximum size of the cache to be used.

  • progbar – Whether to show progress as the bitstrings are iterated over.

  • optional – Whether to show progress as the bitstrings are iterated over.

  • amplitude_opts – Supplied to amplitude().

update_params_from(tn)[source]

Assuming tn is a tensor network with tensors tagged GATE_{i} corresponding to this circuit (e.g. from circ.psi or circ.uni) but with updated parameters, update the current circuit parameters and tensors with those values.

This is an inplace modification of the Circuit.

Parameters:

tn (TensorNetwork) – The tensor network to find the updated parameters from.

draw(figsize=None, radius=1 / 3, drawcolor=(0.5, 0.5, 0.5), linewidth=1)[source]

Draw a simple linear schematic of the circuit.

Parameters:
  • figsize (tuple, optional) – The size of the figure, if not given will be set based on the number of gates and qubits.

  • radius (float, optional) – The radius of the gates.

  • drawcolor (tuple, optional) – The color of the wires.

  • linewidth (float, optional) – The linewidth of the wires.

Returns:

  • fig (matplotlib.Figure) – The figure object.

  • ax (matplotlib.Axes) – The axis object.

__repr__()[source]
abstractmethod _init_state(N, dtype='complex128')[source]
abstractmethod get_psi()[source]

Get a copy of the current state tensor network. This is the single method each representation must implement to expose its state, and is what the psi property calls.

property psi

Tensor network representation of the current state, a copy, see get_psi().

calc_qubit_ordering(qubits=None)[source]

Default trivial qubit ordering; the exact Circuit overrides this with a lightcone-aware ordering used for sampling.