quimb.tensor.circuit

Tools for quantum circuit simulation using tensor networks.

TODO: - [ ] gate-by-gate sampling - [ ] sub-MPO apply for MPS simulation - [ ] multi qubit gates via MPO for MPS simulation

Attributes

Classes

LRU

Least recently used dict, which evicts old items. Taken from python

Dense1D

Mimics other 1D tensor network structures, but really just keeps the

MatrixProductOperator

Initialise a matrix product operator, with auto labelling and tagging.

TensorNetworkGenVector

A tensor network which notionally has a single tensor and outer index

TensorNetworkGenOperator

A tensor network which notionally has a single tensor and two outer

PTensor

A tensor whose data array is lazily generated from a set of parameters

Tensor

A labelled, tagged n-dimensional array. The index labels are used

Gate

A simple class for storing the details of a quantum circuit gate.

Circuit

Class for simulating quantum circuits using tensor networks. The class

CircuitMPS

Quantum circuit simulation keeping the state always in a MPS form. If

CircuitPermMPS

Quantum circuit simulation keeping the state always in an MPS form, but

CircuitDense

Quantum circuit simulation keeping the state in full dense form.

Functions

deprecated(fn, old_name, new_name)

Mark a function as deprecated, and indicate the new name.

ensure_dict(x)

Make sure x is a dict, creating an empty one if x is None.

tree_map(f, tree[, is_leaf])

Map f over all leaves in tree, returning a new pytree.

HTN_CP_operator_from_products(array_seqs, upper_inds, ...)

Construct a CP form hyper tensor network of the sum of matrix strings:

MPO_identity_like(mpo, **mpo_opts)

Return an identity matrix operator with the same physical index and

MPS_computational_state(binary[, dtype, cyclic])

A computational basis state in Matrix Product State form.

TN_from_sites_computational_state(site_map[, ...])

A computational basis state in general tensor network form.

get_tags(ts)

Return all the tags in found in ts.

oset_union(xs)

Non-variadic ordered set union taking any sequence of iterables.

rand_uuid([base])

Return a guaranteed unique, shortish identifier, optional appended

tags_to_oset(tags)

Parse a tags argument into an ordered set.

tensor_contract(*tensors[, output_inds, optimize, ...])

Contract a collection of tensors into a scalar or tensor, automatically

recursive_stack(x)

_convert_ints_and_floats(x)

_put_registers_last(x)

parse_qsim_str(contents)

Parse a 'qsim' input format string into circuit information.

parse_qsim_file(fname, **kwargs)

Parse a qsim file.

parse_qsim_url(url, **kwargs)

Parse a qsim url.

to_clean_list(s, delimiter)

Split, strip and filter a string by a given character into a list.

multi_replace(s, replacements)

Replace multiple substrings in a string.

get_openqasm2_regexes()

parse_openqasm2_str(contents)

Parse the string contents of an OpenQASM 2.0 file. This parser does not

parse_openqasm2_file(fname, **kwargs)

Parse an OpenQASM 2.0 file.

parse_openqasm2_url(url, **kwargs)

Parse an OpenQASM 2.0 url.

register_constant_gate(name, G, num_qubits[, tag])

register_param_gate(name, param_fn, num_qubits[, tag])

register_special_gate(name, fn, num_qubits[, tag, array])

rx_gate_param_gen(params)

ry_gate_param_gen(params)

rz_gate_param_gen(params)

u3_gate_param_gen(params)

u2_gate_param_gen(params)

u1_gate_param_gen(params)

cu3_param_gen(params)

cu2_param_gen(params)

cu1_param_gen(params)

crx_param_gen(params)

Parametrized controlled X-rotation.

cry_param_gen(params)

Parametrized controlled Y-rotation.

crz_param_gen(params)

Parametrized controlled Z-rotation.

fsim_param_gen(params)

fsimg_param_gen(params)

givens_param_gen(params)

rxx_param_gen(params)

Parametrized two qubit XX-rotation.

ryy_param_gen(params)

Parametrized two qubit YY-rotation.

rzz_param_gen(params)

Parametrized two qubit ZZ-rotation.

su4_gate_param_gen(params)

See https://arxiv.org/abs/quant-ph/0308006 - Fig. 7.

apply_swap(psi, i, j, **gate_opts)

build_controlled_gate_htn(ncontrol, gate, upper_inds, ...)

Build a low rank hyper tensor network (CP-decomp like) representation of

_apply_controlled_gate_mps(psi, gate[, tags])

Apply a multi-controlled gate to a state represented as an MPS.

_apply_controlled_gate_htn(psi, gate[, tags, ...])

apply_controlled_gate(psi, gate[, tags, contract, ...])

_cached_param_gate_build(fn, params)

sample_bitstring_from_prob_ndarray(p)

Sample a bitstring from n-dimensional tensor p of probabilities.

rehearsal_dict(tn, tree)

parse_to_gate(gate_id, *gate_args[, params, qubits, ...])

Map all types of gate specification into a Gate object.

Module Contents

class quimb.tensor.circuit.LRU(maxsize, *args, **kwds)[source]

Bases: collections.OrderedDict

Least recently used dict, which evicts old items. Taken from python collections OrderedDict docs.

__getitem__(key)[source]

x.__getitem__(y) <==> x[y]

__setitem__(key, value)[source]

Set self[key] to value.

quimb.tensor.circuit.deprecated(fn, old_name, new_name)[source]

Mark a function as deprecated, and indicate the new name.

quimb.tensor.circuit.ensure_dict(x)[source]

Make sure x is a dict, creating an empty one if x is None.

quimb.tensor.circuit.tree_map(f, tree, is_leaf=is_not_container)[source]

Map f over all leaves in tree, returning a new pytree.

Parameters:
  • f (callable) – A function to apply to all leaves in tree.

  • tree (pytree) – A nested sequence of tuples, lists, dicts and other objects.

  • is_leaf (callable) – A function to determine if an object is a leaf, f is only applied to objects for which is_leaf(x) returns True.

Return type:

pytree

class quimb.tensor.circuit.Dense1D(array, phys_dim=2, tags=None, site_ind_id='k{}', site_tag_id='I{}', **tn_opts)[source]

Bases: TensorNetwork1DVector

Mimics other 1D tensor network structures, but really just keeps the full state in a single tensor. This allows e.g. applying gates in the same way for quantum circuit simulation as lazily represented hilbert spaces.

Parameters:
  • array (array_like) – The full hilbert space vector - assumed to be made of equal hilbert spaces each of size phys_dim and will be reshaped as such.

  • phys_dim (int, optional) – The hilbert space size of each site, default: 2.

  • tags (sequence of str, optional) – Extra tags to add to the tensor network.

  • site_ind_id (str, optional) – String formatter describing how to label the site indices.

  • site_tag_id (str, optional) – String formatter describing how to label the site tags.

  • tn_opts – Supplied to TensorNetwork.

_EXTRA_PROPS = ('_site_ind_id', '_site_tag_id', '_L')
classmethod rand(n, phys_dim=2, dtype=float, **dense1d_opts)[source]

Create a random dense vector ‘tensor network’.

class quimb.tensor.circuit.MatrixProductOperator(arrays, *, sites=None, L=None, shape='lrud', tags=None, upper_ind_id='k{}', lower_ind_id='b{}', site_tag_id='I{}', **tn_opts)[source]

Bases: TensorNetwork1DOperator, TensorNetwork1DFlat

Initialise a matrix product operator, with auto labelling and tagging.

Parameters:
  • arrays (sequence of arrays) – The tensor arrays to form into a MPO.

  • sites (sequence of int, optional) – Construct the MPO on these sites only. If not given, enumerate from zero. Should be monotonically increasing and match arrays.

  • L (int, optional) – The number of sites the MPO should be defined on. If not given, this is taken as the max sites value plus one (i.e.g the number of arrays if sites is not given).

  • shape (str, optional) – String specifying layout of the tensors. E.g. ‘lrud’ (the default) indicates the shape corresponds left-bond, right-bond, ‘up’ physical index, ‘down’ physical index. End tensors have either ‘l’ or ‘r’ dropped from the string.

  • tags (str or sequence of str, optional) – Global tags to attach to all tensors.

  • upper_ind_id (str) – A string specifiying how to label the upper physical site indices. Should contain a '{}' placeholder. It is used to generate the actual indices like: map(upper_ind_id.format, range(len(arrays))).

  • lower_ind_id (str) – A string specifiying how to label the lower physical site indices. Should contain a '{}' placeholder. It is used to generate the actual indices like: map(lower_ind_id.format, range(len(arrays))).

  • site_tag_id (str) – A string specifiying how to tag the tensors at each site. Should contain a '{}' placeholder. It is used to generate the actual tags like: map(site_tag_id.format, range(len(arrays))).

_EXTRA_PROPS = ('_site_tag_id', '_upper_ind_id', '_lower_ind_id', 'cyclic', '_L')
classmethod from_fill_fn(fill_fn, L, bond_dim, phys_dim=2, sites=None, cyclic=False, shape='lrud', tags=None, upper_ind_id='k{}', lower_ind_id='b{}', site_tag_id='I{}')[source]

Create an MPO by supplying a ‘filling’ function to generate the data for each site.

Parameters:
  • fill_fn (callable) – A function with signature fill_fn(shape : tuple[int]) -> array_like.

  • L (int) – The number of sites.

  • bond_dim (int) – The bond dimension.

  • phys_dim (int or Sequence[int], optional) – The physical dimension(s) of each site, if a sequence it will be cycled over.

  • sites (None or sequence of int, optional) – Construct the MPO on these sites only. If not given, enumerate from zero.

  • cyclic (bool, optional) – Whether the MPO should be cyclic (periodic).

  • shape (str, optional) – String specifying layout of the tensors. E.g. ‘lrud’ (the default) indicates the shape corresponds left-bond, right-bond, ‘up’ physical index, ‘down’ physical index. End tensors have either ‘l’ or ‘r’ dropped from the string.

  • tags (str or sequence of str, optional) – Global tags to attach to all tensors.

  • upper_ind_id (str) – A string specifiying how to label the upper physical site indices. Should contain a '{}' placeholder.

  • lower_ind_id (str) – A string specifiying how to label the lower physical site indices. Should contain a '{}' placeholder.

  • site_tag_id (str, optional) – How to tag the physical sites. Should contain a '{}' placeholder.

Return type:

MatrixProductState

classmethod from_dense(A, dims=2, sites=None, L=None, tags=None, site_tag_id='I{}', upper_ind_id='k{}', lower_ind_id='b{}', **split_opts)[source]

Build an MPO from a raw dense matrix.

Parameters:
  • A (array) – The dense operator, it should be reshapeable to (*dims, *dims).

  • dims (int, sequence of int, optional) – The physical subdimensions of the operator. If any integer, assume all sites have the same dimension. If a sequence, the dimension of each site. Default is 2.

  • sites (sequence of int, optional) – The sites to place the operator on. If None, will place it on first len(dims) sites.

  • L (int, optional) – The total number of sites in the MPO, if the operator represents only a subset.

  • tags (str or sequence of str, optional) – Global tags to attach to all tensors.

  • site_tag_id (str, optional) – The string to use to label the site tags.

  • upper_ind_id (str, optional) – The string to use to label the upper physical indices.

  • lower_ind_id (str, optional) – The string to use to label the lower physical indices.

  • split_opts – Supplied to tensor_split().

Return type:

MatrixProductOperator

fill_empty_sites(mode='full', phys_dim=None, fill_array=None, inplace=False)[source]

Fill any empty sites of this MPO with identity tensors, adding size 1 bonds or draping existing bonds where necessary such that the resulting tensor has nearest neighbor bonds only.

Parameters:
  • mode ({'full', 'minimal'}, optional) – Whether to fill in all sites, including at either end, or simply the minimal range covering the min to max current sites present.

  • phys_dim (int, optional) – The physical dimension of the identity tensors to add. If not specified, will use the upper physical dimension of the first present site.

  • fill_array (array, optional) – The array to use for the identity tensors. If not specified, will use the identity array of the same dtype as the first present site.

  • inplace (bool, optional) – Whether to perform the operation inplace.

Returns:

The modified MPO.

Return type:

MatrixProductOperator

fill_empty_sites_[source]
add_MPO(other, inplace=False, **kwargs)[source]
add_MPO_[source]
_apply_mps(other, compress=False, contract=True, **compress_opts)[source]
_apply_mpo(other, compress=False, contract=True, **compress_opts)[source]
apply(other, compress=False, **compress_opts)[source]

Act with this MPO on another MPO or MPS, such that the resulting object has the same tensor network structure/indices as other.

For an MPS:

       | | | | | | | | | | | | | | | | | |
 self: A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A
       | | | | | | | | | | | | | | | | | |
other: x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x

                       -->

       | | | | | | | | | | | | | | | | | |   <- other.site_ind_id
  out: y=y=y=y=y=y=y=y=y=y=y=y=y=y=y=y=y=y

For an MPO:

       | | | | | | | | | | | | | | | | | |
 self: A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A
       | | | | | | | | | | | | | | | | | |
other: B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B
       | | | | | | | | | | | | | | | | | |

                       -->

       | | | | | | | | | | | | | | | | | |   <- other.upper_ind_id
  out: C=C=C=C=C=C=C=C=C=C=C=C=C=C=C=C=C=C
       | | | | | | | | | | | | | | | | | |   <- other.lower_ind_id

The resulting TN will have the same structure/indices as other, but probably with larger bonds (depending on compression).

Parameters:
Return type:

MatrixProductOperator or MatrixProductState

dot[source]
permute_arrays(shape='lrud')[source]

Permute the indices of each tensor in this MPO to match shape. This doesn’t change how the overall object interacts with other tensor networks but may be useful for extracting the underlying arrays consistently. This is an inplace operation.

Parameters:

shape (str, optional) – A permutation of 'lrud' specifying the desired order of the left, right, upper and lower (down) indices respectively.

trace(left_inds=None, right_inds=None)[source]

Take the trace of this MPO.

partial_transpose(sysa, inplace=False)[source]

Perform the partial transpose on this MPO by swapping the bra and ket indices on sites in sysa.

Parameters:
  • sysa (sequence of int or int) – The sites to transpose indices on.

  • inplace (bool, optional) – Whether to perform the partial transposition inplace.

Return type:

MatrixProductOperator

rand_state(bond_dim, **mps_opts)[source]

Get a random vector matching this MPO.

identity(**mpo_opts)[source]

Get a identity matching this MPO.

show(max_width=None)[source]
class quimb.tensor.circuit.TensorNetworkGenVector(ts=(), *, virtual=False, check_collisions=True)[source]

Bases: TensorNetworkGen

A tensor network which notionally has a single tensor and outer index per ‘site’, though these could be labelled arbitrarily and could also be linked in an arbitrary geometry by bonds.

_EXTRA_PROPS = ('_sites', '_site_tag_id', '_site_ind_id')
property site_ind_id
The string specifier for the physical indices.
site_ind(site)[source]
property site_inds
Return a tuple of all site indices.
property site_inds_present
All of the site inds still present in this tensor network.
reset_cached_properties()[source]

Reset any cached properties, one should call this when changing the actual geometry of a TN inplace, for example.

reindex_sites(new_id, where=None, inplace=False)[source]

Modify the site indices for all or some tensors in this vector tensor network (without changing the site_ind_id).

Parameters:
  • new_id (str) – A string with a format placeholder to accept a site, e.g. “ket{}”.

  • where (None or sequence) – Which sites to update the index labels on. If None (default) all sites.

  • inplace (bool) – Whether to reindex in place.

reindex_sites_[source]
reindex_all(new_id, inplace=False)[source]

Reindex all physical sites and change the site_ind_id.

reindex_all_[source]
gen_inds_from_coos(coos)[source]

Generate the site inds corresponding to the given coordinates.

phys_dim(site=None)[source]

Get the physical dimension of site, defaulting to the first site if not specified.

to_dense(*inds_seq, to_qarray=False, to_ket=None, **contract_opts)[source]

Contract this tensor network ‘vector’ into a dense array. By default, turn into a ‘ket’ qarray, i.e. column vector of shape (d, 1).

Parameters:
  • inds_seq (sequence of sequences of str) – How to group the site indices into the dense array. By default, use a single group ordered like sites, but only containing those sites which are still present.

  • to_qarray (bool) – Whether to turn the dense array into a qarray, if the backend would otherwise be 'numpy'.

  • to_ket (None or str) – Whether to reshape the dense array into a ket (shape (d, 1) array). If None (default), do this only if the inds_seq is not supplied.

  • contract_opts – Options to pass to contract().

Return type:

array

to_qarray[source]
gate_with_op_lazy(A, transpose=False, inplace=False, **kwargs)[source]

Act lazily with the operator tensor network A, which should have matching structure, on this vector/state tensor network, like A @ x. The returned tensor network will have the same structure as this one, but with the operator gated in lazily, i.e. uncontracted.

\[| x \rangle \rightarrow A | x \rangle\]

or (if transpose=True):

\[| x \rangle \rightarrow A^T | x \rangle\]
Parameters:
  • A (TensorNetworkGenOperator) – The operator tensor network to gate with, or apply to this tensor network.

  • transpose (bool, optional) – Whether to contract the lower or upper indices of A with the site indices of x. If False (the default), the lower indices of A will be contracted with the site indices of x, if True the upper indices of A will be contracted with the site indices of x, which is like applying A.T @ x.

  • inplace (bool, optional) – Whether to perform the gate operation inplace on this tensor network.

Return type:

TensorNetworkGenVector

gate_with_op_lazy_[source]
gate(G, where, contract=False, tags=None, propagate_tags=False, info=None, inplace=False, **compress_opts)[source]

Apply a gate to this vector tensor network at sites where. This is essentially a wrapper around gate_inds() apart from where can be specified as a list of sites, and tags can be optionally, intelligently propagated to the new gate tensor.

\[| \psi \rangle \rightarrow G_\mathrm{where} | \psi \rangle\]
Parameters:
  • G (array_ike) – The gate array to apply, should match or be factorable into the shape (*phys_dims, *phys_dims).

  • where (node or sequence[node]) – The sites to apply the gate to.

  • contract ({False, True, 'split', 'reduce-split', 'split-gate',) – ‘swap-split-gate’, ‘auto-split-gate’}, optional How to apply the gate, see gate_inds().

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

  • propagate_tags ({False, True, 'register', 'sites'}, optional) –

    Whether to propagate tags to the new gate tensor:

    - False: no tags are propagated
    - True: all tags are propagated
    - 'register': only site tags corresponding to ``where`` are
      added.
    - 'sites': all site tags on the current sites are propgated,
      resulting in a lightcone like tagging.
    

  • info (None or dict, optional) – Used to store extra optional information such as the singular values if not absorbed.

  • inplace (bool, optional) – Whether to perform the gate operation inplace on the tensor network or not.

  • compress_opts – Supplied to tensor_split() for any contract methods that involve splitting. Ignored otherwise.

Return type:

TensorNetworkGenVector

See also

TensorNetwork.gate_inds

gate_[source]
gate_simple_(G, where, gauges, renorm=True, **gate_opts)[source]

Apply a gate to this vector tensor network at sites where, using simple update style gauging of the tensors first, as supplied in gauges. The new singular values for the bond are reinserted into gauges.

Parameters:
  • G (array_like) – The gate to be applied.

  • where (node or sequence[node]) – The sites to apply the gate to.

  • gauges (dict[str, array_like]) – The store of gauge bonds, the keys being indices and the values being the vectors. Only bonds present in this dictionary will be used.

  • renorm (bool, optional) – Whether to renormalise the singular after the gate is applied, before reinserting them into gauges.

gate_fit_local_(G, where, max_distance=0, fillin=0, gauges=None, **fit_opts)[source]
local_expectation_cluster(G, where, normalized=True, max_distance=0, fillin=False, gauges=None, optimize='auto', max_bond=None, rehearse=False, **contract_opts)[source]

Approximately compute a single local expectation value of the gate G at sites where, either treating the environment beyond max_distance as the identity, or using simple update style bond gauges as supplied in gauges.

This selects a local neighbourhood of tensors up to distance max_distance away from where, then traces over dangling bonds after potentially inserting the bond gauges, to form an approximate version of the reduced density matrix.

\[\langle \psi | G | \psi \rangle \approx \frac{ \mathrm{Tr} [ G \tilde{\rho}_\mathrm{where} ] }{ \mathrm{Tr} [ \tilde{\rho}_\mathrm{where} ] }\]

assuming normalized==True.

Parameters:
  • G (array_like) – The gate to compute the expecation of.

  • where (node or sequence[node]) – The sites to compute the expectation at.

  • normalized (bool, optional) – Whether to locally normalize the result, i.e. divide by the expectation value of the identity.

  • max_distance (int, optional) – The maximum graph distance to include tensors neighboring where when computing the expectation. The default 0 means only the tensors at sites where are used.

  • fillin (bool or int, optional) – When selecting the local tensors, whether and how many times to ‘fill-in’ corner tensors attached multiple times to the local region. On a lattice this fills in the corners. See select_local().

  • gauges (dict[str, array_like], optional) – The store of gauge bonds, the keys being indices and the values being the vectors. Only bonds present in this dictionary will be used.

  • optimize (str or PathOptimizer, optional) – The contraction path optimizer to use, when exactly contracting the local tensors.

  • max_bond (None or int, optional) – If specified, use compressed contraction.

  • rehearse ({False, 'tn', 'tree', True}, optional) –

    Whether to perform the computations or not:

    - False: perform the computation.
    - 'tn': return the tensor networks of each local expectation,
      without running the path optimizer.
    - 'tree': run the path optimizer and return the
      ``cotengra.ContractonTree`` for each local expectation.
    - True: run the path optimizer and return the ``PathInfo`` for
      each local expectation.
    

Returns:

expectation

Return type:

float

local_expectation_simple[source]
compute_local_expectation_cluster(terms, *, max_distance=0, fillin=False, normalized=True, gauges=None, optimize='auto', max_bond=None, return_all=False, rehearse=False, executor=None, progbar=False, **contract_opts)[source]

Compute all local expectations of the given terms, either treating the environment beyond max_distance as the identity, or using simple update style bond gauges as supplied in gauges.

This selects a local neighbourhood of tensors up to distance max_distance away from each term’s sites, then traces over dangling bonds after potentially inserting the bond gauges, to form an approximate version of the reduced density matrix.

\[\sum_\mathrm{i} \langle \psi | G_\mathrm{i} | \psi \rangle \approx \sum_\mathrm{i} \frac{ \mathrm{Tr} [ G_\mathrm{i} \tilde{\rho}_\mathrm{i} ] }{ \mathrm{Tr} [ \tilde{\rho}_\mathrm{i} ] }\]

assuming normalized==True.

Parameters:
  • terms (dict[node or (node, node), array_like]) – The terms to compute the expectation of, with keys being the sites and values being the local operators.

  • max_distance (int, optional) – The maximum graph distance to include tensors neighboring each term’s sites when computing the expectation. The default 0 means only the tensors at sites of each term are used.

  • fillin (bool or int, optional) – When selecting the local tensors, whether and how many times to ‘fill-in’ corner tensors attached multiple times to the local region. On a lattice this fills in the corners. See select_local().

  • normalized (bool, optional) – Whether to locally normalize the result, i.e. divide by the expectation value of the identity. This implies that a different normalization factor is used for each term.

  • gauges (dict[str, array_like], optional) – The store of gauge bonds, the keys being indices and the values being the vectors. Only bonds present in this dictionary will be used.

  • optimize (str or PathOptimizer, optional) – The contraction path optimizer to use, when exactly contracting the local tensors.

  • max_bond (None or int, optional) – If specified, use compressed contraction.

  • return_all (bool, optional) – Whether to return all results, or just the summed expectation.

  • rehearse ({False, 'tn', 'tree', True}, optional) –

    Whether to perform the computations or not:

    - False: perform the computation.
    - 'tn': return the tensor networks of each local expectation,
      without running the path optimizer.
    - 'tree': run the path optimizer and return the
      ``cotengra.ContractonTree`` for each local expectation.
    - True: run the path optimizer and return the ``PathInfo`` for
      each local expectation.
    

  • executor (Executor, optional) – If supplied compute the terms in parallel using this executor.

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

  • contract_opts – Supplied to contract().

Returns:

expecs – If return_all==False, return the summed expectation value of the given terms. Otherwise, return a dictionary mapping each term’s location to the expectation value.

Return type:

float or dict[node or (node, node), float]

compute_local_expectation_simple[source]
local_expectation_exact(G, where, optimize='auto-hq', normalized=True, rehearse=False, **contract_opts)[source]

Compute the local expectation of operator G at site(s) where by exactly contracting the full overlap tensor network.

compute_local_expectation_exact(terms, optimize='auto-hq', *, normalized=True, return_all=False, rehearse=False, executor=None, progbar=False, **contract_opts)[source]

Compute the local expectations of many operators, by exactly contracting the full overlap tensor network.

Parameters:
  • terms (dict[node or (node, node), array_like]) – The terms to compute the expectation of, with keys being the sites and values being the local operators.

  • optimize (str or PathOptimizer, optional) – The contraction path optimizer to use, when exactly contracting the full tensor network.

  • normalized (bool, optional) – Whether to normalize the result.

  • return_all (bool, optional) – Whether to return all results, or just the summed expectation.

  • rehearse ({False, 'tn', 'tree', True}, optional) –

    Whether to perform the computations or not:

    - False: perform the computation.
    - 'tn': return the tensor networks of each local expectation,
      without running the path optimizer.
    - 'tree': run the path optimizer and return the
      ``cotengra.ContractonTree`` for each local expectation.
    - True: run the path optimizer and return the ``PathInfo`` for
      each local expectation.
    

  • executor (Executor, optional) – If supplied compute the terms in parallel using this executor.

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

  • contract_opts – Supplied to contract().

Returns:

expecs – If return_all==False, return the summed expectation value of the given terms. Otherwise, return a dictionary mapping each term’s location to the expectation value.

Return type:

float or dict[node or (node, node), float]

partial_trace(keep, max_bond, optimize, flatten=True, reduce=False, normalized=True, symmetrized='auto', rehearse=False, method='contract_compressed', **contract_compressed_opts)[source]

Partially trace this tensor network state, keeping only the sites in keep, using compressed contraction.

Parameters:
  • keep (iterable of hashable) – The sites to keep.

  • max_bond (int) – The maximum bond dimensions to use while compressed contracting.

  • optimize (str or PathOptimizer, optional) – The contraction path optimizer to use, should specifically generate contractions paths designed for compressed contraction.

  • flatten ({False, True, 'all'}, optional) – Whether to force ‘flattening’ (contracting all physical indices) of the tensor network before contraction, whilst this makes the TN generally more complex to contract, the accuracy is usually improved. If 'all' also flatten the tensors in keep.

  • reduce (bool, optional) – Whether to first ‘pull’ the physical indices off their respective tensors using QR reduction. Experimental.

  • normalized (bool, optional) – Whether to normalize the reduced density matrix at the end.

  • symmetrized ({'auto', True, False}, optional) – Whether to symmetrize the reduced density matrix at the end. This should be unecessary if flatten is set to True.

  • rehearse ({False, 'tn', 'tree', True}, optional) –

    Whether to perform the computation or not:

    - False: perform the computation.
    - 'tn': return the tensor network without running the path
      optimizer.
    - 'tree': run the path optimizer and return the
      ``cotengra.ContractonTree``..
    - True: run the path optimizer and return the ``PathInfo``.
    

  • contract_compressed_opts (dict, optional) – Additional keyword arguments to pass to contract_compressed().

Returns:

rho – The reduce density matrix of sites in keep.

Return type:

array_like

local_expectation(G, where, max_bond, optimize, flatten=True, normalized=True, symmetrized='auto', reduce=False, rehearse=False, **contract_compressed_opts)[source]

Compute the local expectation of operator G at site(s) where by approximately contracting the full overlap tensor network.

Parameters:
  • G (array_like) – The local operator to compute the expectation of.

  • where (node or sequence of nodes) – The sites to compute the expectation for.

  • max_bond (int) – The maximum bond dimensions to use while compressed contracting.

  • optimize (str or PathOptimizer, optional) – The contraction path optimizer to use, should specifically generate contractions paths designed for compressed contraction.

  • method ({'rho', 'rho-reduced'}, optional) – The method to use to compute the expectation value.

  • flatten (bool, optional) – Whether to force ‘flattening’ (contracting all physical indices) of the tensor network before contraction, whilst this makes the TN generally more complex to contract, the accuracy is usually much improved.

  • normalized (bool, optional) – If computing via partial_trace, whether to normalize the reduced density matrix at the end.

  • symmetrized ({'auto', True, False}, optional) – If computing via partial_trace, whether to symmetrize the reduced density matrix at the end. This should be unecessary if flatten is set to True.

  • rehearse ({False, 'tn', 'tree', True}, optional) –

    Whether to perform the computation or not:

    - False: perform the computation.
    - 'tn': return the tensor network without running the path
      optimizer.
    - 'tree': run the path optimizer and return the
      ``cotengra.ContractonTree``..
    - True: run the path optimizer and return the ``PathInfo``.
    

  • contract_compressed_opts (dict, optional) – Additional keyword arguments to pass to contract_compressed().

Returns:

expec

Return type:

float

compute_local_expectation(terms, max_bond, optimize, *, flatten=True, normalized=True, symmetrized='auto', reduce=False, return_all=False, rehearse=False, executor=None, progbar=False, **contract_compressed_opts)[source]

Compute the local expectations of many local operators, by approximately contracting the full overlap tensor network.

Parameters:
  • terms (dict[node or (node, node), array_like]) – The terms to compute the expectation of, with keys being the sites and values being the local operators.

  • max_bond (int) – The maximum bond dimension to use during contraction.

  • optimize (str or PathOptimizer) – The compressed contraction path optimizer to use.

  • method ({'rho', 'rho-reduced'}, optional) –

    The method to use to compute the expectation value.

    • ’rho’: compute the expectation value via the reduced density matrix.

    • ’rho-reduced’: compute the expectation value via the reduced density matrix, having reduced the physical indices onto the bonds first.

  • flatten (bool, optional) – Whether to force ‘flattening’ (contracting all physical indices) of the tensor network before contraction, whilst this makes the TN generally more complex to contract, the accuracy can often be much improved.

  • normalized (bool, optional) – Whether to locally normalize the result.

  • symmetrized ({'auto', True, False}, optional) – Whether to symmetrize the reduced density matrix at the end. This should be unecessary if flatten is set to True.

  • return_all (bool, optional) – Whether to return all results, or just the summed expectation. If rehease is not False, this is ignored and a dict is always returned.

  • rehearse ({False, 'tn', 'tree', True}, optional) –

    Whether to perform the computations or not:

    - False: perform the computation.
    - 'tn': return the tensor networks of each local expectation,
      without running the path optimizer.
    - 'tree': run the path optimizer and return the
      ``cotengra.ContractonTree`` for each local expectation.
    - True: run the path optimizer and return the ``PathInfo`` for
      each local expectation.
    

  • executor (Executor, optional) – If supplied compute the terms in parallel using this executor.

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

  • contract_compressed_opts – Supplied to contract_compressed().

Returns:

expecs – If return_all==False, return the summed expectation value of the given terms. Otherwise, return a dictionary mapping each term’s location to the expectation value.

Return type:

float or dict[node or (node, node), float]

compute_local_expectation_rehearse[source]
compute_local_expectation_tn[source]
class quimb.tensor.circuit.TensorNetworkGenOperator(ts=(), *, virtual=False, check_collisions=True)[source]

Bases: TensorNetworkGen

A tensor network which notionally has a single tensor and two outer indices per ‘site’, though these could be labelled arbitrarily and could also be linked in an arbitrary geometry by bonds. By convention, if converted to a dense matrix, the ‘upper’ indices would be on the left and the ‘lower’ indices on the right.

_EXTRA_PROPS = ('_sites', '_site_tag_id', '_upper_ind_id', '_lower_ind_id')
property upper_ind_id
The string specifier for the upper phyiscal indices.
upper_ind(site)[source]

Get the upper physical index name of site.

reindex_upper_sites(new_id, where=None, inplace=False)[source]

Modify the upper site indices for all or some tensors in this operator tensor network (without changing the upper_ind_id).

Parameters:
  • new_id (str) – A string with a format placeholder to accept a site, e.g. “up{}”.

  • where (None or sequence) – Which sites to update the index labels on. If None (default) all sites.

  • inplace (bool) – Whether to reindex in place.

reindex_upper_sites_[source]
property upper_inds
Return a tuple of all upper indices.
property upper_inds_present
Return a tuple of all upper indices still present in the tensor
network.
property lower_ind_id
The string specifier for the lower phyiscal indices.
lower_ind(site)[source]

Get the lower physical index name of site.

reindex_lower_sites(new_id, where=None, inplace=False)[source]

Modify the lower site indices for all or some tensors in this operator tensor network (without changing the lower_ind_id).

Parameters:
  • new_id (str) – A string with a format placeholder to accept a site, e.g. “up{}”.

  • where (None or sequence) – Which sites to update the index labels on. If None (default) all sites.

  • inplace (bool) – Whether to reindex in place.

reindex_lower_sites_[source]
property lower_inds
Return a tuple of all lower indices.
property lower_inds_present
Return a tuple of all lower indices still present in the tensor
network.
to_dense(*inds_seq, to_qarray=False, **contract_opts)[source]

Contract this tensor network ‘operator’ into a dense array.

Parameters:
  • inds_seq (sequence of sequences of str) – How to group the site indices into the dense array. By default, use a single group ordered like sites, but only containing those sites which are still present.

  • to_qarray (bool) – Whether to turn the dense array into a qarray, if the backend would otherwise be 'numpy'.

  • contract_opts – Options to pass to contract().

Return type:

array

to_qarray[source]
phys_dim(site=None, which='upper')[source]

Get the physical dimension of site.

gate_upper_with_op_lazy(A, transpose=False, inplace=False)[source]

Act lazily with the operator tensor network A, which should have matching structure, on this operator tensor network (B), like A @ B. The returned tensor network will have the same structure as this one, but with the operator gated in lazily, i.e. uncontracted.

\[B \rightarrow A B\]

or (if transpose=True):

\[B \rightarrow A^T B\]
Parameters:
  • A (TensorNetworkGenOperator) – The operator tensor network to gate with, or apply to this tensor network.

  • transpose (bool, optional) – Whether to contract the lower or upper indices of A with the upper indices of B. If False (the default), the lower indices of A will be contracted with the upper indices of B, if True the upper indices of A will be contracted with the upper indices of B, which is like applying the transpose first.

  • inplace (bool, optional) – Whether to perform the gate operation inplace on this tensor network.

Return type:

TensorNetworkGenOperator

gate_upper_with_op_lazy_[source]
gate_lower_with_op_lazy(A, transpose=False, inplace=False)[source]

Act lazily ‘from the right’ with the operator tensor network A, which should have matching structure, on this operator tensor network (B), like B @ A. The returned tensor network will have the same structure as this one, but with the operator gated in lazily, i.e. uncontracted.

\[B \rightarrow B A\]

or (if transpose=True):

\[B \rightarrow B A^T\]
Parameters:
  • A (TensorNetworkGenOperator) – The operator tensor network to gate with, or apply to this tensor network.

  • transpose (bool, optional) – Whether to contract the upper or lower indices of A with the lower indices of this TN. If False (the default), the upper indices of A will be contracted with the lower indices of B, if True the lower indices of A will be contracted with the lower indices of this TN, which is like applying the transpose first.

  • inplace (bool, optional) – Whether to perform the gate operation inplace on this tensor network.

Return type:

TensorNetworkGenOperator

gate_lower_with_op_lazy_[source]
gate_sandwich_with_op_lazy(A, inplace=False)[source]

Act lazily with the operator tensor network A, which should have matching structure, on this operator tensor network (B), like \(B \rightarrow A B A^\dagger\). The returned tensor network will have the same structure as this one, but with the operator gated in lazily, i.e. uncontracted.

Parameters:
  • A (TensorNetworkGenOperator) – The operator tensor network to gate with, or apply to this tensor network.

  • inplace (bool, optional) – Whether to perform the gate operation inplace on this tensor

Return type:

TensorNetworkGenOperator

gate_sandwich_with_op_lazy_[source]
quimb.tensor.circuit.HTN_CP_operator_from_products(array_seqs, upper_inds, lower_inds, tags_each=None, tags_all=None, bond_ind=None)[source]

Construct a CP form hyper tensor network of the sum of matrix strings:

\[\sum_i A_i B_i C_i \ldots\]

using a single hyper index to enumerate each sequence of operators.

Parameters:
  • array_seqs (sequence[arrays_like]) – The arrays to use in each product, each of which should be 2D.

  • upper_inds (sequence[sequence[str]]) – The upper indices to use for each array in each product.

  • lower_inds (sequence[sequence[str]]) – The lower indices to use for each array in each product.

  • tags_each (sequence[sequence[str]], optional) – The tags to use for each array in each product.

  • tags_all (sequence[str], optional) – The tags to use for the whole hyper tensor network.

  • bond_ind (str, optional) – The name of the hyper index to use, by default randomly generated.

Returns:

htn

Return type:

TensorNetwork

quimb.tensor.circuit.MPO_identity_like(mpo, **mpo_opts)[source]

Return an identity matrix operator with the same physical index and inds/tags as mpo.

quimb.tensor.circuit.MPS_computational_state(binary, dtype='float64', cyclic=False, **mps_opts)[source]

A computational basis state in Matrix Product State form.

Parameters:
  • binary (str or sequence of int) – String specifying the state, e.g. '00101010111' or [0, 0, 1].

  • dtype ({'float64', 'complex128', 'float32', 'complex64'}, optional) – The data type to use for the array representation.

  • cyclic (bool, optional) – Generate a MPS with periodic boundary conditions or not, default open boundary conditions.

  • mps_opts – Supplied to MatrixProductState constructor.

quimb.tensor.circuit.TN_from_sites_computational_state(site_map, site_tag_id='I{}', site_ind_id='k{}', dtype='float64')[source]

A computational basis state in general tensor network form.

Parameters:
  • site_map (dict[hashable, str]) – Mapping of site to computational state, which should be one of ('0', '1', '+', '-').

  • site_tag_id (str, optional) – Format string for site tag labels.

  • site_ind_id (str, optional) – Format string for site index labels.

  • dtype ({'float64', 'complex128', 'float32', 'complex64'}, optional) – The data type to use for the array representation.

Return type:

TensorNetworkGenVector

class quimb.tensor.circuit.PTensor(fn, params, inds=(), tags=None, left_inds=None)[source]

Bases: Tensor

A tensor whose data array is lazily generated from a set of parameters and a function.

Parameters:
  • fn (callable) – The function that generates the tensor data from params.

  • params (sequence of numbers) – The initial parameters supplied to the generating function like fn(params).

  • inds (optional) – Should match the shape of fn(params), see Tensor.

  • tags (optional) – See Tensor.

  • left_inds (optional) – See Tensor.

See also

PTensor

__slots__ = ('_data', '_inds', '_tags', '_left_inds', '_owners')
classmethod from_parray(parray, inds=(), tags=None, left_inds=None)[source]
copy()[source]

Copy this parametrized tensor.

_set_data(x)[source]
property data
property fn
get_params()[source]

Get the parameters of this PTensor.

set_params(params)[source]

Set the parameters of this PTensor.

property params
property shape
The size of each dimension.
property backend
The backend inferred from the data.
_apply_function(fn)[source]

Apply fn to the data array of this PTensor (lazily), by composing it with the current parametrized array function.

conj(inplace=False)[source]

Conjugate this parametrized tensor - done lazily whenever the .data attribute is accessed.

conj_[source]
unparametrize()[source]

Turn this PTensor into a normal Tensor.

__getstate__()[source]

Helper for pickle.

__setstate__(state)[source]
class quimb.tensor.circuit.Tensor(data=1.0, inds=(), tags=None, left_inds=None)[source]

A labelled, tagged n-dimensional array. The index labels are used instead of axis numbers to identify dimensions, and are preserved through operations. The tags are used to identify the tensor within networks, and are combined when tensors are contracted together.

Parameters:
  • data (numpy.ndarray) – The n-dimensional data.

  • inds (sequence of str) – The index labels for each dimension. Must match the number of dimensions of data.

  • tags (sequence of str, optional) – Tags with which to identify and group this tensor. These will be converted into a oset.

  • left_inds (sequence of str, optional) – Which, if any, indices to group as ‘left’ indices of an effective matrix. This can be useful, for example, when automatically applying unitary constraints to impose a certain flow on a tensor network but at the atomistic (Tensor) level.

Examples

Basic construction:

>>> from quimb import randn
>>> from quimb.tensor import Tensor
>>> X = Tensor(randn((2, 3, 4)), inds=['a', 'b', 'c'], tags={'X'})
>>> Y = Tensor(randn((3, 4, 5)), inds=['b', 'c', 'd'], tags={'Y'})

Indices are automatically aligned, and tags combined, when contracting:

>>> X @ Y
Tensor(shape=(2, 5), inds=('a', 'd'), tags={'Y', 'X'})
__slots__ = ('_data', '_inds', '_tags', '_left_inds', '_owners')
_set_data(data)[source]
_set_inds(inds)[source]
_set_tags(tags)[source]
_set_left_inds(left_inds)[source]
get_params()[source]

A simple function that returns the ‘parameters’ of the underlying data array. This is mainly for providing an interface for ‘structured’ arrays e.g. with block sparsity to interact with optimization.

set_params(params)[source]

A simple function that sets the ‘parameters’ of the underlying data array. This is mainly for providing an interface for ‘structured’ arrays e.g. with block sparsity to interact with optimization.

copy(deep=False, virtual=False)[source]

Copy this tensor.

Note

By default (deep=False), the underlying array will not be copied.

Parameters:
  • deep (bool, optional) – Whether to copy the underlying data as well.

  • virtual (bool, optional) – To conveniently mimic the behaviour of taking a virtual copy of tensor network, this simply returns self.

__copy__[source]
property data
property inds
property tags
property left_inds
check()[source]

Do some basic diagnostics on this tensor, raising errors if something is wrong.

property owners
add_owner(tn, tid)[source]

Add tn as owner of this Tensor - it’s tag and ind maps will be updated whenever this tensor is retagged or reindexed.

remove_owner(tn)[source]

Remove TensorNetwork tn as an owner of this Tensor.

check_owners()[source]

Check if this tensor is ‘owned’ by any alive TensorNetworks. Also trim any weakrefs to dead TensorNetworks.

_apply_function(fn)[source]
modify(**kwargs)[source]

Overwrite the data of this tensor in place.

Parameters:
  • data (array, optional) – New data.

  • apply (callable, optional) – A function to apply to the current data. If data is also given this is applied subsequently.

  • inds (sequence of str, optional) – New tuple of indices.

  • tags (sequence of str, optional) – New tags.

  • left_inds (sequence of str, optional) – New grouping of indices to be ‘on the left’.

apply_to_arrays(fn)[source]

Apply the function fn to the underlying data array(s). This is meant for changing how the raw arrays are backed (e.g. converting between dtypes or libraries) but not their ‘numerical meaning’.

isel(selectors, inplace=False)[source]

Select specific values for some dimensions/indices of this tensor, thereby removing them. Analogous to X[:, :, 3, :, :] with arrays. The indices to select from can be specified either by integer, in which case the correspoding index is removed, or by a slice.

Parameters:
  • selectors (dict[str, int], dict[str, slice]) – Mapping of index(es) to which value to take.

  • inplace (bool, optional) – Whether to select inplace or not.

Return type:

Tensor

Examples

>>> T = rand_tensor((2, 3, 4), inds=('a', 'b', 'c'))
>>> T.isel({'b': -1})
Tensor(shape=(2, 4), inds=('a', 'c'), tags=())

See also

TensorNetwork.isel

isel_[source]
add_tag(tag)[source]

Add a tag or multiple tags to this tensor. Unlike self.tags.add this also updates any TensorNetwork objects viewing this Tensor.

expand_ind(ind, size, mode=None, rand_strength=None, rand_dist='normal')[source]

Inplace increase the size of the dimension of ind, the new array entries will be filled with zeros by default.

Parameters:
  • name (str) – Name of the index to expand.

  • size (int, optional) – Size of the expanded index.

  • mode ({None, 'zeros', 'repeat', 'random'}, optional) – How to fill any new array entries. If 'zeros' then fill with zeros, if 'repeat' then repeatedly tile the existing entries. If 'random' then fill with random entries drawn from rand_dist, multiplied by rand_strength. If None then select from zeros or random depening on non-zero rand_strength.

  • rand_strength (float, optional) – If mode='random', a multiplicative scale for the random entries, defaulting to 1.0. If mode is None then supplying a non-zero value here triggers mode='random'.

  • rand_dist ({'normal', 'uniform', 'exp'}, optional) – If mode='random', the distribution to draw the random entries from.

new_ind(name, size=1, axis=0, mode=None, rand_strength=None, rand_dist='normal')[source]

Inplace add a new index - a named dimension. If size is specified to be greater than one then the new array entries will be filled with zeros.

Parameters:
  • name (str) – Name of the new index.

  • size (int, optional) – Size of the new index.

  • axis (int, optional) – Position of the new index.

  • mode ({None, 'zeros', 'repeat', 'random'}, optional) – How to fill any new array entries. If 'zeros' then fill with zeros, if 'repeat' then repeatedly tile the existing entries. If 'random' then fill with random entries drawn from rand_dist, multiplied by rand_strength. If None then select from zeros or random depening on non-zero rand_strength.

  • rand_strength (float, optional) – If mode='random', a multiplicative scale for the random entries, defaulting to 1.0. If mode is None then supplying a non-zero value here triggers mode='random'.

  • rand_dist ({'normal', 'uniform', 'exp'}, optional) – If mode='random', the distribution to draw the random entries from.

new_bond[source]
new_ind_with_identity(name, left_inds, right_inds, axis=0)[source]

Inplace add a new index, where the newly stacked array entries form the identity from left_inds to right_inds. Selecting 0 or 1 for the new index name thus is like ‘turning off’ this tensor if viewed as an operator.

Parameters:
  • name (str) – Name of the new index.

  • left_inds (tuple[str]) – Names of the indices forming the left hand side of the operator.

  • right_inds (tuple[str]) – Names of the indices forming the right hand side of the operator. The dimensions of these must match those of left_inds.

  • axis (int, optional) – Position of the new index.

new_ind_pair_with_identity(new_left_ind, new_right_ind, d, inplace=False)[source]

Expand this tensor with two new indices of size d, by taking an (outer) tensor product with the identity operator. The two new indices are added as axes at the start of the tensor.

Parameters:
  • new_left_ind (str) – Name of the new left index.

  • new_right_ind (str) – Name of the new right index.

  • d (int) – Size of the new indices.

  • inplace (bool, optional) – Whether to perform the expansion inplace.

Return type:

Tensor

new_ind_pair_with_identity_[source]
conj(inplace=False)[source]

Conjugate this tensors data (does nothing to indices).

conj_[source]
property H
Conjugate this tensors data (does nothing to indices).
property shape
The size of each dimension.
property ndim
The number of dimensions.
property size
The total number of array elements.
property dtype
The data type of the array elements.
property backend
The backend inferred from the data.
iscomplex()[source]
astype(dtype, inplace=False)[source]

Change the type of this tensor to dtype.

astype_[source]
max_dim()[source]

Return the maximum size of any dimension, or 1 if scalar.

ind_size(ind)[source]

Return the size of dimension corresponding to ind.

inds_size(inds)[source]

Return the total size of dimensions corresponding to inds.

shared_bond_size(other)[source]

Get the total size of the shared index(es) with other.

inner_inds()[source]

Get all indices that appear on two or more tensors.

transpose(*output_inds, inplace=False)[source]

Transpose this tensor - permuting the order of both the data and the indices. This operation is mainly for ensuring a certain data layout since for most operations the specific order of indices doesn’t matter.

Note to compute the tranditional ‘transpose’ of an operator within a contraction for example, you would just use reindexing not this.

Parameters:
  • output_inds (sequence of str) – The desired output sequence of indices.

  • inplace (bool, optional) – Perform the tranposition inplace.

Returns:

tt – The transposed tensor.

Return type:

Tensor

transpose_[source]
transpose_like(other, inplace=False)[source]

Transpose this tensor to match the indices of other, allowing for one index to be different. E.g. if self.inds = ('a', 'b', 'c', 'x') and other.inds = ('b', 'a', 'd', 'c') then ‘x’ will be aligned with ‘d’ and the output inds will be ('b', 'a', 'x', 'c')

Parameters:
  • other (Tensor) – The tensor to match.

  • inplace (bool, optional) – Perform the tranposition inplace.

Returns:

tt – The transposed tensor.

Return type:

Tensor

See also

transpose

transpose_like_[source]
moveindex(ind, axis, inplace=False)[source]

Move the index ind to position axis. Like transpose, this permutes the order of both the data and the indices and is mainly for ensuring a certain data layout since for most operations the specific order of indices doesn’t matter.

Parameters:
  • ind (str) – The index to move.

  • axis (int) – The new position to move ind to. Can be negative.

  • inplace (bool, optional) – Whether to perform the move inplace or not.

Return type:

Tensor

moveindex_[source]
item()[source]

Return the scalar value of this tensor, if it has a single element.

trace(left_inds, right_inds, preserve_tensor=False, inplace=False)[source]

Trace index or indices left_inds with right_inds, removing them.

Parameters:
  • left_inds (str or sequence of str) – The left indices to trace, order matching right_inds.

  • right_inds (str or sequence of str) – The right indices to trace, order matching left_inds.

  • preserve_tensor (bool, optional) – If True, a tensor will be returned even if no indices remain.

  • inplace (bool, optional) – Perform the trace inplace.

Returns:

z

Return type:

Tensor or scalar

sum_reduce(ind, inplace=False)[source]

Sum over index ind, removing it from this tensor.

Parameters:
  • ind (str) – The index to sum over.

  • inplace (bool, optional) – Whether to perform the reduction inplace.

Return type:

Tensor

sum_reduce_[source]
vector_reduce(ind, v, inplace=False)[source]

Contract the vector v with the index ind of this tensor, removing it.

Parameters:
  • ind (str) – The index to contract.

  • v (array_like) – The vector to contract with.

  • inplace (bool, optional) – Whether to perform the reduction inplace.

Return type:

Tensor

vector_reduce_[source]
collapse_repeated(inplace=False)[source]

Take the diagonals of any repeated indices, such that each index only appears once.

collapse_repeated_[source]
contract(*others, output_inds=None, **opts)[source]
direct_product(other, sum_inds=(), inplace=False)[source]
direct_product_[source]
split(*args, **kwargs)[source]
compute_reduced_factor(side, left_inds, right_inds, **split_opts)[source]
distance(other, **contract_opts)[source]
distance_normalized[source]
gate(G, ind, preserve_inds=True, inplace=False)[source]

Gate this tensor - contract a matrix into one of its indices without changing its indices. Unlike contract, G is a raw array and the tensor remains with the same set of indices.

Parameters:
  • G (2D array_like) – The matrix to gate the tensor index with.

  • ind (str) – Which index to apply the gate to.

Return type:

Tensor

Examples

Create a random tensor of 4 qubits:

>>> t = qtn.rand_tensor(
...    shape=[2, 2, 2, 2],
...    inds=['k0', 'k1', 'k2', 'k3'],
... )

Create another tensor with an X gate applied to qubit 2:

>>> Gt = t.gate(qu.pauli('X'), 'k2')

The contraction of these two tensors is now the expectation of that operator:

>>> t.H @ Gt
-4.108910576149794
gate_[source]
singular_values(left_inds, method='svd')[source]

Return the singular values associated with splitting this tensor according to left_inds.

Parameters:
  • left_inds (sequence of str) – A subset of this tensors indices that defines ‘left’.

  • method ({'svd', 'eig'}) – Whether to use the SVD or eigenvalue decomposition to get the singular values.

Returns:

The singular values.

Return type:

1d-array

entropy(left_inds, method='svd')[source]

Return the entropy associated with splitting this tensor according to left_inds.

Parameters:
  • left_inds (sequence of str) – A subset of this tensors indices that defines ‘left’.

  • method ({'svd', 'eig'}) – Whether to use the SVD or eigenvalue decomposition to get the singular values.

Return type:

float

retag(retag_map, inplace=False)[source]

Rename the tags of this tensor, optionally, in-place.

Parameters:
  • retag_map (dict-like) – Mapping of pairs {old_tag: new_tag, ...}.

  • inplace (bool, optional) – If False (the default), a copy of this tensor with the changed tags will be returned.

retag_[source]
reindex(index_map, inplace=False)[source]

Rename the indices of this tensor, optionally in-place.

Parameters:
  • index_map (dict-like) – Mapping of pairs {old_ind: new_ind, ...}.

  • inplace (bool, optional) – If False (the default), a copy of this tensor with the changed inds will be returned.

reindex_[source]
fuse(fuse_map, inplace=False)[source]

Combine groups of indices into single indices.

Parameters:

fuse_map (dict_like or sequence of tuples.) – Mapping like: {new_ind: sequence of existing inds, ...} or an ordered mapping like [(new_ind_1, old_inds_1), ...] in which case the output tensor’s fused inds will be ordered. In both cases the new indices are created at the minimum axis of any of the indices that will be fused.

Returns:

The transposed, reshaped and re-labeled tensor.

Return type:

Tensor

fuse_[source]
unfuse(unfuse_map, shape_map, inplace=False)[source]

Reshape single indices into groups of multiple indices

Parameters:
  • unfuse_map (dict_like or sequence of tuples.) – Mapping like: {existing_ind: sequence of new inds, ...} or an ordered mapping like [(old_ind_1, new_inds_1), ...] in which case the output tensor’s new inds will be ordered. In both cases the new indices are created at the old index’s position of the tensor’s shape

  • shape_map (dict_like or sequence of tuples) – Mapping like: {old_ind: new_ind_sizes, ...} or an ordered mapping like [(old_ind_1, new_ind_sizes_1), ...].

Returns:

The transposed, reshaped and re-labeled tensor

Return type:

Tensor

unfuse_[source]
to_dense(*inds_seq, to_qarray=False)[source]

Convert this Tensor into an dense array, with a single dimension for each of inds in inds_seqs. E.g. to convert several sites into a density matrix: T.to_dense(('k0', 'k1'), ('b0', 'b1')).

to_qarray[source]
squeeze(include=None, exclude=None, inplace=False)[source]

Drop any singlet dimensions from this tensor.

Parameters:
  • inplace (bool, optional) – Whether modify the original or return a new tensor.

  • include (sequence of str, optional) – Only squeeze dimensions with indices in this list.

  • exclude (sequence of str, optional) – Squeeze all dimensions except those with indices in this list.

  • inplace – Whether to perform the squeeze inplace or not.

Return type:

Tensor

squeeze_[source]
largest_element()[source]

Return the largest element, in terms of absolute magnitude, of this tensor.

idxmin(f=None)[source]

Get the index configuration of the minimum element of this tensor, optionally applying f first.

Parameters:

f (callable or str, optional) – If a callable, apply this function to the tensor data before finding the minimum element. If a string, apply autoray.do(f, data).

Returns:

Mapping of index names to their values at the minimum element.

Return type:

dict[str, int]

idxmax(f=None)[source]

Get the index configuration of the maximum element of this tensor, optionally applying f first.

Parameters:

f (callable or str, optional) – If a callable, apply this function to the tensor data before finding the maximum element. If a string, apply autoray.do(f, data).

Returns:

Mapping of index names to their values at the maximum element.

Return type:

dict[str, int]

norm()[source]

Frobenius norm of this tensor:

\[\|t\|_F = \sqrt{\mathrm{Tr} \left(t^{\dagger} t\right)}\]

where the trace is taken over all indices. Equivalent to the square root of the sum of squared singular values across any partition.

normalize(inplace=False)[source]
normalize_[source]
symmetrize(ind1, ind2, inplace=False)[source]

Hermitian symmetrize this tensor for indices ind1 and ind2. I.e. T = (T + T.conj().T) / 2, where the transpose is taken only over the specified indices.

symmetrize_[source]
isometrize(left_inds=None, method='qr', inplace=False)[source]

Make this tensor unitary (or isometric) with respect to left_inds. The underlying method is set by method.

Parameters:
  • left_inds (sequence of str) – The indices to group together and treat as the left hand side of a matrix.

  • method (str, optional) –

    The method used to generate the isometry. The options are:

    • ”qr”: use the Q factor of the QR decomposition of x with the constraint that the diagonal of R is positive.

    • ”svd”: uses U @ VH of the SVD decomposition of x. This is useful for finding the ‘closest’ isometric matrix to x, such as when it has been expanded with noise etc. But is less stable for differentiation / optimization.

    • ”exp”: use the matrix exponential of x - dag(x), first completing x with zeros if it is rectangular. This is a good parametrization for optimization, but more expensive for non-square x.

    • ”cayley”: use the Cayley transform of x - dag(x), first completing x with zeros if it is rectangular. This is a good parametrization for optimization (one the few compatible with HIPS/autograd e.g.), but more expensive for non-square x.

    • ”householder”: use the Householder reflection method directly. This requires that the backend implements “linalg.householder_product”.

    • ”torch_householder”: use the Householder reflection method directly, using the torch_householder package. This requires that the package is installed and that the backend is "torch". This is generally the best parametrizing method for “torch” if available.

    • ”mgs”: use a python implementation of the modified Gram Schmidt method directly. This is slow if not compiled but a useful reference.

    Not all backends support all methods or differentiating through all methods.

  • inplace (bool, optional) – Whether to perform the unitization inplace.

Return type:

Tensor

isometrize_[source]
unitize[source]
unitize_
randomize(dtype=None, inplace=False, **randn_opts)[source]

Randomize the entries of this tensor.

Parameters:
  • dtype ({None, str}, optional) – The data type of the random entries. If left as the default None, then the data type of the current array will be used.

  • inplace (bool, optional) – Whether to perform the randomization inplace, by default False.

  • randn_opts – Supplied to randn().

Return type:

Tensor

randomize_[source]
flip(ind, inplace=False)[source]

Reverse the axis on this tensor corresponding to ind. Like performing e.g. X[:, :, ::-1, :].

flip_[source]
multiply_index_diagonal(ind, x, inplace=False)[source]

Multiply this tensor by 1D array x as if it were a diagonal tensor being contracted into index ind.

multiply_index_diagonal_[source]
almost_equals(other, **kwargs)[source]

Check if this tensor is almost the same as another.

drop_tags(tags=None)[source]

Drop certain tags, defaulting to all, from this tensor.

bonds(other)[source]

Return a tuple of the shared indices between this tensor and other.

filter_bonds(other)[source]

Sort this tensor’s indices into a list of those that it shares and doesn’t share with another tensor.

Parameters:

other (Tensor) – The other tensor.

Returns:

shared, unshared – The shared and unshared indices.

Return type:

(tuple[str], tuple[str])

__imul__(other)[source]
__itruediv__(other)[source]
__and__(other)[source]

Combine with another Tensor or TensorNetwork into a new TensorNetwork.

__or__(other)[source]

Combine virtually (no copies made) with another Tensor or TensorNetwork into a new TensorNetwork.

__matmul__(other)[source]

Explicitly contract with another tensor. Avoids some slight overhead of calling the full tensor_contract().

negate(inplace=False)[source]

Negate this tensor.

negate_[source]
__neg__()[source]

Negate this tensor.

as_network(virtual=True)[source]

Return a TensorNetwork with only this tensor.

draw(*args, **kwargs)[source]

Plot a graph of this tensor and its indices.

graph[source]
visualize[source]
__getstate__()[source]

Helper for pickle.

__setstate__(state)[source]
_repr_info()[source]

General info to show in various reprs. Sublasses can add more relevant info to this dict.

_repr_info_extra()[source]

General detailed info to show in various reprs. Sublasses can add more relevant info to this dict.

_repr_info_str(normal=True, extra=False)[source]

Render the general info as a string.

_repr_html_()[source]

Render this Tensor as HTML, for Jupyter notebooks.

__str__()[source]

Return str(self).

__repr__()[source]

Return repr(self).

quimb.tensor.circuit.get_tags(ts)[source]

Return all the tags in found in ts.

Parameters:

ts (Tensor, TensorNetwork or sequence of either) – The objects to combine tags from.

quimb.tensor.circuit.oset_union(xs)[source]

Non-variadic ordered set union taking any sequence of iterables.

quimb.tensor.circuit.rand_uuid(base='')[source]

Return a guaranteed unique, shortish identifier, optional appended to base.

Examples

>>> rand_uuid()
'_2e1dae1b'
>>> rand_uuid('virt-bond')
'virt-bond_bf342e68'
quimb.tensor.circuit.tags_to_oset(tags)[source]

Parse a tags argument into an ordered set.

quimb.tensor.circuit.tensor_contract(*tensors, output_inds=None, optimize=None, get=None, backend=None, preserve_tensor=False, drop_tags=False, **contract_opts)[source]

Contract a collection of tensors into a scalar or tensor, automatically aligning their indices and computing an optimized contraction path. The output tensor will have the union of tags from the input tensors.

Parameters:
  • tensors (sequence of Tensor) – The tensors to contract.

  • output_inds (sequence of str) – The output indices. These can be inferred if the contraction has no ‘hyper’ indices, in which case the output indices are those that appear only once in the input indices, and ordered as they appear in the inputs. For hyper indices or a specific ordering, these must be supplied.

  • optimize ({None, str, path_like, PathOptimizer}, optional) –

    The contraction path optimization strategy to use.

    • None: use the default strategy,

    • str: use the preset strategy with the given name,

    • path_like: use this exact path,

    • cotengra.HyperOptimizer: find the contraction using this optimizer, supports slicing,

    • cotengra.ContractionTree: use this exact tree, supports slicing,

    • opt_einsum.PathOptimizer: find the path using this optimizer.

    Contraction with cotengra might be a bit more efficient but the main reason would be to handle sliced contraction automatically, as well as the fact that it uses autoray internally.

  • get (str, optional) –

    What to return. If:

    • None (the default) - return the resulting scalar or Tensor.

    • 'expression' - return a callbable expression that performs the contraction and operates on the raw arrays.

    • 'tree' - return the cotengra.ContractionTree describing the contraction.

    • 'path' - return the raw ‘path’ as a list of tuples.

    • 'symbol-map' - return the dict mapping indices to ‘symbols’ (single unicode letters) used internally by cotengra

    • 'path-info' - return the opt_einsum.PathInfo path object with detailed information such as flop cost. The symbol-map is also added to the quimb_symbol_map attribute.

  • backend ({'auto', 'numpy', 'jax', 'cupy', 'tensorflow', ...}, optional) – Which backend to use to perform the contraction. Supplied to cotengra.

  • preserve_tensor (bool, optional) – Whether to return a tensor regardless of whether the output object is a scalar (has no indices) or not.

  • drop_tags (bool, optional) – Whether to drop all tags from the output tensor. By default the output tensor will keep the union of all tags from the input tensors.

  • contract_opts – Passed to cotengra.array_contract.

Return type:

scalar or Tensor

quimb.tensor.circuit.recursive_stack(x)[source]
quimb.tensor.circuit._convert_ints_and_floats(x)[source]
quimb.tensor.circuit._put_registers_last(x)[source]
quimb.tensor.circuit.parse_qsim_str(contents)[source]

Parse a ‘qsim’ input format string into circuit information.

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

Parameters:

contents (str) – The full string of the qsim file.

Returns:

circuit_info – Information about the circuit:

  • circuit_info[‘n’]: the number of qubits

  • circuit_info[‘n_gates’]: the number of gates in total

  • circuit_info[‘gates’]: list[list[str]], list of gates, each of which is a list of strings read from a line of the qsim file.

Return type:

dict

quimb.tensor.circuit.parse_qsim_file(fname, **kwargs)[source]

Parse a qsim file.

quimb.tensor.circuit.parse_qsim_url(url, **kwargs)[source]

Parse a qsim url.

quimb.tensor.circuit.to_clean_list(s, delimiter)[source]

Split, strip and filter a string by a given character into a list.

quimb.tensor.circuit.multi_replace(s, replacements)[source]

Replace multiple substrings in a string.

quimb.tensor.circuit.get_openqasm2_regexes()[source]
quimb.tensor.circuit.parse_openqasm2_str(contents)[source]

Parse the string contents of an OpenQASM 2.0 file. This parser does not support classical control flow is not guaranteed to check the full openqasm grammar.

quimb.tensor.circuit.parse_openqasm2_file(fname, **kwargs)[source]

Parse an OpenQASM 2.0 file.

quimb.tensor.circuit.parse_openqasm2_url(url, **kwargs)[source]

Parse an OpenQASM 2.0 url.

quimb.tensor.circuit.ALL_GATES
quimb.tensor.circuit.ONE_QUBIT_GATES
quimb.tensor.circuit.TWO_QUBIT_GATES
quimb.tensor.circuit.ALL_PARAM_GATES
quimb.tensor.circuit.ONE_QUBIT_PARAM_GATES
quimb.tensor.circuit.TWO_QUBIT_PARAM_GATES
quimb.tensor.circuit.GATE_TAGS
quimb.tensor.circuit.GATE_SIZE
quimb.tensor.circuit.CONSTANT_GATES
quimb.tensor.circuit.PARAM_GATES
quimb.tensor.circuit.SPECIAL_GATES
quimb.tensor.circuit.register_constant_gate(name, G, num_qubits, tag=None)[source]
quimb.tensor.circuit.register_param_gate(name, param_fn, num_qubits, tag=None)[source]
quimb.tensor.circuit.register_special_gate(name, fn, num_qubits, tag=None, array=None)[source]
quimb.tensor.circuit.rx_gate_param_gen(params)[source]
quimb.tensor.circuit.ry_gate_param_gen(params)[source]
quimb.tensor.circuit.rz_gate_param_gen(params)[source]
quimb.tensor.circuit.u3_gate_param_gen(params)[source]
quimb.tensor.circuit.u2_gate_param_gen(params)[source]
quimb.tensor.circuit.u1_gate_param_gen(params)[source]
quimb.tensor.circuit.cu3_param_gen(params)[source]
quimb.tensor.circuit.cu2_param_gen(params)[source]
quimb.tensor.circuit.cu1_param_gen(params)[source]
quimb.tensor.circuit.crx_param_gen(params)[source]

Parametrized controlled X-rotation.

quimb.tensor.circuit.cry_param_gen(params)[source]

Parametrized controlled Y-rotation.

quimb.tensor.circuit.crz_param_gen(params)[source]

Parametrized controlled Z-rotation.

quimb.tensor.circuit.fsim_param_gen(params)[source]
quimb.tensor.circuit.fsimg_param_gen(params)[source]
quimb.tensor.circuit.givens_param_gen(params)[source]
quimb.tensor.circuit.rxx_param_gen(params)[source]

Parametrized two qubit XX-rotation.

\[\mathrm{RXX}(\theta) = \exp(-i \frac{\theta}{2} X_i X_j)\]
quimb.tensor.circuit.ryy_param_gen(params)[source]

Parametrized two qubit YY-rotation.

\[\mathrm{RYY}(\theta) = \exp(-i \frac{\theta}{2} Y_i Y_j)\]
quimb.tensor.circuit.rzz_param_gen(params)[source]

Parametrized two qubit ZZ-rotation.

\[\mathrm{RZZ}(\theta) = \exp(-i \frac{\theta}{2} Z_i Z_j)\]
quimb.tensor.circuit.su4_gate_param_gen(params)[source]

See https://arxiv.org/abs/quant-ph/0308006 - Fig. 7. params: # theta1, phi1, lamda1, # theta2, phi2, lamda2, # theta3, phi3, lamda3, # theta4, phi4, lamda4, # t1, t2, t3,

quimb.tensor.circuit._MPS_METHODS
quimb.tensor.circuit.apply_swap(psi, i, j, **gate_opts)[source]
quimb.tensor.circuit.build_controlled_gate_htn(ncontrol, gate, upper_inds, lower_inds, tags_each=None, tags_all=None, bond_ind=None)[source]

Build a low rank hyper tensor network (CP-decomp like) representation of a multi controlled gate.

quimb.tensor.circuit._apply_controlled_gate_mps(psi, gate, tags=None, **gate_opts)[source]

Apply a multi-controlled gate to a state represented as an MPS.

quimb.tensor.circuit._apply_controlled_gate_htn(psi, gate, tags=None, propagate_tags='register', **gate_opts)[source]
quimb.tensor.circuit.apply_controlled_gate(psi, gate, tags=None, contract='auto-split-gate', propagate_tags='register', **gate_opts)[source]
quimb.tensor.circuit._cached_param_gate_build(fn, params)[source]
class quimb.tensor.circuit.Gate(label, params, qubits=None, controls=None, round=None, parametrize=False)[source]

A simple class for storing the details of a quantum circuit gate.

Parameters:
  • label (str) – The name or ‘identifier’ of the gate.

  • params (Iterable[float]) – The parameters of the gate.

  • qubits (Iterable[int], optional) – Which qubits the gate acts on.

  • controls (Iterable[int], optional) – Which qubits are the controls.

  • round (int, optional) – If given, which round or layer the gate is part of.

  • parametrize (bool, optional) – Whether the gate will correspond to a parametrized tensor.

__slots__ = ('_label', '_params', '_qubits', '_controls', '_round', '_parametrize', '_tag', '_special',...
classmethod from_raw(U, qubits=None, controls=None, round=None)[source]
copy()[source]
property label
property params
property qubits
property total_qubit_count
property controls
property round
property special
property parametrize
property tag
copy_with(**kwargs)[source]

Take a copy of this gate but with some attributes changed.

build_array()[source]

Build the array representation of the gate. For controlled gates this excludes the control qubits.

property array
build_mpo(L=None, **kwargs)[source]

Build an MPO representation of this gate.

__repr__()[source]

Return repr(self).

quimb.tensor.circuit.sample_bitstring_from_prob_ndarray(p)[source]

Sample a bitstring from n-dimensional tensor p of probabilities.

Examples

>>> import numpy as np
>>> p = np.zeros(shape=(2, 2, 2, 2, 2))
>>> p[0, 1, 0, 1, 1] = 1.0
>>> sample_bitstring_from_prob_ndarray(p)
'01011'
quimb.tensor.circuit.rehearsal_dict(tn, tree)[source]
quimb.tensor.circuit.parse_to_gate(gate_id, *gate_args, params=None, qubits=None, controls=None, gate_round=None, parametrize=None)[source]

Map all types of gate specification into a Gate object.

class quimb.tensor.circuit.Circuit(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{}', to_backend=None)[source]

Class for simulating quantum circuits using tensor networks. The class keeps a list of Gate objects in sync with a tensor network representing the current state of the circuit.

Parameters:
  • N (int, optional) – The number of qubits.

  • psi0 (TensorNetwork1DVector, optional) – The initial state, assumed to be |00000....0> if not given. The state is always copied and the tag PSI0 added.

  • gate_opts (dict_like, optional) – Default keyword arguments to supply to each gate_TN_1D() call during the circuit.

  • gate_contract (str, optional) – Shortcut for setting the default ‘contract’ option in gate_opts.

  • gate_propagate_tags (str, optional) – Shortcut for setting the default ‘propagate_tags’ option in gate_opts.

  • tags (str or sequence of str, optional) – Tag(s) to add to the initial wavefunction tensors (whether these are propagated to the rest of the circuit’s tensors depends on gate_opts).

  • psi0_dtype (str, optional) – Ensure the initial state has this dtype.

  • psi0_tag (str, optional) – Ensure the initial state has this tag.

  • tag_gate_numbers (bool, optional) – Whether to tag each gate tensor with its number in the circuit, like "GATE_{g}". This is required for updating the circuit parameters.

  • gate_tag_id (str, optional) – The format string for tagging each gate tensor, by default e.g. "GATE_{g}".

  • tag_gate_rounds (bool, optional) – Whether to tag each gate tensor with its number in the circuit, like "ROUND_{r}".

  • round_tag_id (str, optional) – The format string for tagging each round of gates, by default e.g. "ROUND_{r}".

  • tag_gate_labels (bool, optional) – Whether to tag each gate tensor with its gate type label, e.g. {"X_1/2", "ISWAP", "CCX", ...}..

  • bra_site_ind_id (str, optional) – Use this to label ‘bra’ site indices when creating certain (mostly internal) intermediate tensor networks.

psi

The current circuit wavefunction as a tensor network.

Type:

TensorNetwork1DVector

uni

The current circuit unitary operator as a tensor network.

Type:

TensorNetwork1DOperator

gates

The gates in the circuit.

Type:

tuple[Gate]

Examples

Create 3-qubit GHZ-state:

>>> qc = qtn.Circuit(3)
>>> gates = [
        ('H', 0),
        ('H', 1),
        ('CNOT', 1, 2),
        ('CNOT', 0, 2),
        ('H', 0),
        ('H', 1),
        ('H', 2),
    ]
>>> qc.apply_gates(gates)
>>> qc.psi
<TensorNetwork1DVector(tensors=12, indices=14, L=3, max_bond=2)>
>>> qc.psi.to_dense().round(4)
qarray([[ 0.7071+0.j],
        [ 0.    +0.j],
        [ 0.    +0.j],
        [-0.    +0.j],
        [-0.    +0.j],
        [ 0.    +0.j],
        [ 0.    +0.j],
        [ 0.7071+0.j]])
>>> for b in qc.sample(10):
...     print(b)
000
000
111
000
111
111
000
111
000
000

See also

Gate

copy()[source]

Copy the circuit and its state.

apply_to_arrays(fn)[source]

Apply a function to all the arrays in the circuit.

get_params()[source]

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

Returns:

A dictionary mapping gate numbers to their parameters.

Return type:

dict[int, tuple]

set_params(params)[source]

Set the parameters of the circuit.

Parameters:

params (dict`) – A dictionary mapping gate numbers to the new parameters.

classmethod from_qsim_str(contents, **circuit_opts)[source]

Generate a Circuit instance from a ‘qsim’ string.

classmethod from_qsim_file(fname, **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, **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, **circuit_opts)[source]

Generate a Circuit instance from an OpenQASM 2.0 string.

classmethod from_openqasm2_file(fname, **circuit_opts)[source]

Generate a Circuit instance from an OpenQASM 2.0 file.

classmethod from_openqasm2_url(url, **circuit_opts)[source]

Generate a Circuit instance from an OpenQASM 2.0 url.

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

_init_state(N, dtype='complex128')[source]
_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]
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]
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]
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]
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]
property psi
Tensor network representation of the wavefunction.
get_uni(transposed=False)[source]

Tensor network representation of the unitary operator (i.e. with the initial state removed).

property uni
get_reverse_lightcone_tags(where)[source]

Get the tags of gates in this circuit corresponding to the ‘reverse’ lightcone propagating backwards from registers in where.

Parameters:

where (int or sequence of int) – The register or register to get the reverse lightcone of.

Returns:

The sequence of gate tags (GATE_{i}, …) corresponding to the lightcone.

Return type:

tuple[str]

get_psi_reverse_lightcone(where, keep_psi0=False)[source]

Get just the bit of the wavefunction in the reverse lightcone of sites in where - i.e. causally linked.

Parameters:
  • where (int, or sequence of int) – The sites to propagate the the lightcone back from, supplied to get_reverse_lightcone_tags().

  • keep_psi0 (bool, optional) – Keep the tensors corresponding to the initial wavefunction regardless of whether they are outside of the lightcone.

Returns:

psi_lc

Return type:

TensorNetwork1DVector

clear_storage()[source]

Clear all cached data.

_maybe_init_storage()[source]
get_psi_simplified(seq='ADCRS', atol=1e-12, equalize_norms=False)[source]

Get the full wavefunction post local tensor network simplification.

Parameters:
  • seq (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

Returns:

psi

Return type:

TensorNetwork1DVector

get_rdm_lightcone_simplified(where, seq='ADCRS', atol=1e-12, equalize_norms=False)[source]

Get a simplified TN of the norm of the wavefunction, with gates outside reverse lightcone of where cancelled, and physical indices within where preserved so that they can be fixed (sliced) or used as output indices.

Parameters:
  • where (int or sequence of int) – The region assumed to be the target density matrix essentially. Supplied to get_reverse_lightcone_tags().

  • seq (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

Return type:

TensorNetwork

amplitude(b, optimize='auto-hq', simplify_sequence='ADCRS', simplify_atol=1e-12, simplify_equalize_norms=False, backend=None, dtype='complex128', rehearse=False)[source]

Get the amplitude coefficient of bitstring b.

\[c_b = \langle b | \psi \rangle\]
Parameters:
  • b (str or sequence of int) – The bitstring to compute the transition amplitude for.

  • optimize (str, optional) – Contraction path optimizer to use for the amplitude, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • backend (str, optional) – Backend to perform the contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

  • rehearse (bool or "tn", optional) – If True, generate and cache the simplified tensor network and contraction tree but don’t actually perform the contraction. Returns a dict with keys "tn" and 'tree' with the tensor network that will be contracted and the corresponding contraction tree if so.

amplitude_rehearse(b='random', simplify_sequence='ADCRS', simplify_atol=1e-12, simplify_equalize_norms=False, optimize='auto-hq', dtype='complex128', rehearse=True)[source]

Perform just the tensor network simplifications and contraction tree finding associated with computing a single amplitude (caching the results) but don’t perform the actual contraction.

Parameters:
  • b ('random', str or sequence of int) – The bitstring to rehearse computing the transition amplitude for, if 'random' (the default) a random bitstring will be used.

  • optimize (str, optional) – Contraction path optimizer to use for the marginal, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • backend (str, optional) – Backend to perform the marginal contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

Return type:

dict

amplitude_tn[source]
partial_trace(keep, optimize='auto-hq', simplify_sequence='ADCRS', simplify_atol=1e-12, simplify_equalize_norms=False, backend=None, dtype='complex128', rehearse=False)[source]

Perform the partial trace on the circuit wavefunction, retaining only qubits in keep, and making use of reverse lightcone cancellation:

\[\rho_{\bar{q}} = Tr_{\bar{p}} |\psi_{\bar{q}} \rangle \langle \psi_{\bar{q}}|\]

Where \(\bar{q}\) is the set of qubits to keep, \(\psi_{\bar{q}}\) is the circuit wavefunction only with gates in the causal cone of this set, and \(\bar{p}\) is the remaining qubits.

Parameters:
  • keep (int or sequence of int) – The qubit(s) to keep as we trace out the rest.

  • optimize (str, optional) – Contraction path optimizer to use for the reduced density matrix, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • backend (str, optional) – Backend to perform the marginal contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

  • rehearse (bool or "tn", optional) – If True, generate and cache the simplified tensor network and contraction tree but don’t actually perform the contraction. Returns a dict with keys "tn" and 'tree' with the tensor network that will be contracted and the corresponding contraction tree if so.

Return type:

array or dict

partial_trace_rehearse[source]
partial_trace_tn[source]
local_expectation(G, where, optimize='auto-hq', simplify_sequence='ADCRS', simplify_atol=1e-12, simplify_equalize_norms=False, backend=None, dtype='complex128', rehearse=False)[source]

Compute the a single expectation value of operator G, acting on sites where, making use of reverse lightcone cancellation.

\[\langle \psi_{\bar{q}} | G_{\bar{q}} | \psi_{\bar{q}} \rangle\]

where \(\bar{q}\) is the set of qubits \(G\) acts one and \(\psi_{\bar{q}}\) is the circuit wavefunction only with gates in the causal cone of this set. If you supply a tuple or list of gates then the expectations will be computed simultaneously.

Parameters:
  • G (array or sequence[array]) – The raw operator(s) to find the expectation of.

  • where (int or sequence of int) – Which qubits the operator acts on.

  • optimize (str, optional) – Contraction path optimizer to use for the local expectation, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • backend (str, optional) – Backend to perform the marginal contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

  • gate_opts (None or dict_like) – Options to use when applying G to the wavefunction.

  • rehearse (bool or "tn", optional) – If True, generate and cache the simplified tensor network and contraction tree but don’t actually perform the contraction. Returns a dict with keys 'tn' and 'tree' with the tensor network that will be contracted and the corresponding contraction tree if so.

Return type:

scalar, tuple[scalar] or dict

local_expectation_rehearse[source]
local_expectation_tn[source]
compute_marginal(where, fix=None, optimize='auto-hq', backend=None, dtype='complex64', simplify_sequence='ADCRS', simplify_atol=1e-06, simplify_equalize_norms=True, rehearse=False)[source]

Compute the probability tensor of qubits in where, given possibly fixed qubits in fix and tracing everything else having removed redundant unitary gates.

Parameters:
  • where (sequence of int) – The qubits to compute the marginal probability distribution of.

  • fix (None or dict[int, str], optional) – Measurement results on other qubits to fix.

  • optimize (str, optional) – Contraction path optimizer to use for the marginal, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • backend (str, optional) – Backend to perform the marginal contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • rehearse (bool or "tn", optional) – Whether to perform the marginal contraction or just return the associated TN and contraction tree.

compute_marginal_rehearse[source]
compute_marginal_tn[source]
calc_qubit_ordering(qubits=None, method='greedy-lightcone')[source]

Get a order to measure qubits in, by greedily choosing whichever has the smallest reverse lightcone followed by whichever expands this lightcone least.

Parameters:

qubits (None or sequence of int) – The qubits to generate a lightcone ordering for, if None, assume all qubits.

Returns:

The order to ‘measure’ qubits in.

Return type:

tuple[int]

_parse_qubits_order(qubits=None, order=None)[source]

Simply initializes the default of measuring all qubits, and the default order, or checks that order is a permutation of qubits.

_group_order(order, group_size=1)[source]

Take the qubit ordering order and batch it in groups of size group_size, sorting the qubits (for caching reasons) within each group.

sample(C, qubits=None, order=None, group_size=1, max_marginal_storage=2**20, seed=None, optimize='auto-hq', backend=None, dtype='complex64', simplify_sequence='ADCRS', simplify_atol=1e-06, simplify_equalize_norms=False)[source]

Sample the circuit given by gates, C times, using lightcone cancelling and caching marginal distribution results. This is a generator. This proceeds as a chain of marginal computations.

Assuming we have group_size=1, and some ordering of the qubits, \(\{q_0, q_1, q_2, q_3, \ldots\}\) we first compute:

\[p(q_0) = \mathrm{diag} \mathrm{Tr}_{1, 2, 3,\ldots} | \psi_{0} \rangle \langle \psi_{0} |\]

I.e. simply the probability distribution on a single qubit, conditioned on nothing. The subscript on \(\psi\) refers to the fact that we only need gates from the causal cone of qubit 0. From this we can sample an outcome, either 0 or 1, if we call this \(r_0\) we can then move on to the next marginal:

\[p(q_1 | r_0) = \mathrm{diag} \mathrm{Tr}_{2, 3,\ldots} \langle r_0 | \psi_{0, 1} \rangle \langle \psi_{0, 1} | r_0 \rangle\]

I.e. the probability distribution of the next qubit, given our prior result. We can sample from this to get \(r_1\). Then we compute:

\[p(q_2 | r_0 r_1) = \mathrm{diag} \mathrm{Tr}_{3,\ldots} \langle r_0 r_1 | \psi_{0, 1, 2} \rangle \langle \psi_{0, 1, 2} | r_0 r_1 \rangle\]

Eventually we will reach the ‘final marginal’, which we can compute as

\[|\langle r_0 r_1 r_2 r_3 \ldots | \psi \rangle|^2\]

since there is nothing left to trace out.

Parameters:
  • C (int) – The number of times to sample.

  • qubits (None or sequence of int, optional) – Which qubits to measure, defaults (None) to all qubits.

  • order (None or sequence of int, optional) – Which order to measure the qubits in, defaults (None) to an order based on greedily expanding the smallest reverse lightcone. If specified it should be a permutation of qubits.

  • group_size (int, optional) – How many qubits to group together into marginals, the larger this is the fewer marginals need to be computed, which can be faster at the cost of higher memory. The marginal themselves will each be of size 2**group_size.

  • max_marginal_storage (int, optional) – The total cumulative number of marginal probabilites to cache, once this is exceeded caching will be turned off.

  • seed (None or int, optional) – A random seed, passed to numpy.random.seed if given.

  • optimize (str, optional) – Contraction path optimizer to use for the marginals, shouldn’t be a non-reusable path optimizer as called on many different TNs. Passed to cotengra.array_contract_tree().

  • backend (str, optional) – Backend to perform the marginal contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

Yields:

bitstrings (sequence of str)

sample_rehearse(qubits=None, order=None, group_size=1, result=None, optimize='auto-hq', simplify_sequence='ADCRS', simplify_atol=1e-06, simplify_equalize_norms=False, rehearse=True, progbar=False)[source]

Perform the preparations and contraction tree findings for sample(), caching various intermedidate objects, but don’t perform the main contractions.

Parameters:
  • qubits (None or sequence of int, optional) – Which qubits to measure, defaults (None) to all qubits.

  • order (None or sequence of int, optional) – Which order to measure the qubits in, defaults (None) to an order based on greedily expanding the smallest reverse lightcone.

  • group_size (int, optional) – How many qubits to group together into marginals, the larger this is the fewer marginals need to be computed, which can be faster at the cost of higher memory. The marginal’s size itself is exponential in group_size.

  • result (None or dict[int, str], optional) – Explicitly check the computational cost of this result, assumed to be all zeros if not given.

  • optimize (str, optional) – Contraction path optimizer to use for the marginals, shouldn’t be a non-reusable path optimizer as called on many different TNs. Passed to cotengra.array_contract_tree().

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • progbar (bool, optional) – Whether to show the progress of finding each contraction tree.

Returns:

One contraction tree object per grouped marginal computation. The keys of the dict are the qubits the marginal is computed for, the values are a dict containing a representative simplified tensor network (key: ‘tn’) and the main contraction tree (key: ‘tree’).

Return type:

dict[tuple[int], dict]

sample_tns[source]
sample_chaotic(C, marginal_qubits, max_marginal_storage=2**20, seed=None, optimize='auto-hq', backend=None, dtype='complex64', simplify_sequence='ADCRS', simplify_atol=1e-06, simplify_equalize_norms=False)[source]

Sample from this circuit, assuming it to be chaotic. Which is to say, only compute and sample correctly from the final marginal, assuming that the distribution on the other qubits is uniform. Given marginal_qubits=5 for instance, for each sample a random bit-string \(r_0 r_1 r_2 \ldots r_{N - 6}\) for the remaining \(N - 5\) qubits will be chosen, then the final marginal will be computed as

\[p(q_{N-5}q_{N-4}q_{N-3}q_{N-2}q_{N-1} | r_0 r_1 r_2 \ldots r_{N-6}) = |\langle r_0 r_1 r_2 \ldots r_{N - 6} | \psi \rangle|^2\]

and then sampled from. Note the expression on the right hand side has 5 open indices here and so is a tensor, however if marginal_qubits is not too big then the cost of contracting this is very similar to a single amplitude.

Note

This method assumes the circuit is chaotic, if its not, then the samples produced will not be an accurate representation of the probability distribution.

Parameters:
  • C (int) – The number of times to sample.

  • marginal_qubits (int or sequence of int) – The number of qubits to treat as marginal, or the actual qubits. If an int is given then the qubits treated as marginal will be circuit.calc_qubit_ordering()[:marginal_qubits].

  • seed (None or int, optional) – A random seed, passed to numpy.random.seed if given.

  • optimize (str, optional) – Contraction path optimizer to use for the marginal, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • backend (str, optional) – Backend to perform the marginal contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

Yields:

str

sample_chaotic_rehearse(marginal_qubits, result=None, optimize='auto-hq', simplify_sequence='ADCRS', simplify_atol=1e-06, simplify_equalize_norms=False, dtype='complex64', rehearse=True)[source]

Rehearse chaotic sampling (perform just the TN simplifications and contraction tree finding).

Parameters:
  • marginal_qubits (int or sequence of int) – The number of qubits to treat as marginal, or the actual qubits. If an int is given then the qubits treated as marginal will be circuit.calc_qubit_ordering()[:marginal_qubits].

  • result (None or dict[int, str], optional) – Explicitly check the computational cost of this result, assumed to be all zeros if not given.

  • optimize (str, optional) – Contraction path optimizer to use for the marginal, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • dtype (str, optional) – Data type to cast the TN to before contraction.

Returns:

The contraction path information for the main computation, the key is the qubits that formed the final marginal. The value is itself a dict with keys 'tn' - a representative tensor network - and 'tree' - the contraction tree.

Return type:

dict[tuple[int], dict]

sample_chaotic_tn[source]
to_dense(reverse=False, optimize='auto-hq', simplify_sequence='R', simplify_atol=1e-12, simplify_equalize_norms=False, backend=None, dtype=None, rehearse=False)[source]

Generate the dense representation of the final wavefunction.

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

  • optimize (str, optional) – Contraction path optimizer to use for the contraction, can be a non-reusable path optimizer as only called once (though path won’t be cached for later use in that case).

  • dtype (str, optional) – If given, convert the tensors to this dtype prior to contraction.

  • simplify_sequence (str, optional) – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • simplify_equalize_norms (bool, optional) – Actively renormalize tensor norms during simplification.

  • backend (str, optional) – Backend to perform the contraction with, e.g. 'numpy', 'cupy' or 'jax'. Passed to cotengra.

  • dtype – Data type to cast the TN to before contraction.

  • rehearse (bool, optional) – If True, generate and cache the simplified tensor network and contraction tree but don’t actually perform the contraction. Returns a dict with keys 'tn' and 'tree' with the tensor network that will be contracted and the corresponding contraction tree if so.

Returns:

psi – The densely represented wavefunction with dtype data.

Return type:

qarray

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

schrodinger_contract(*args, **contract_opts)[source]
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().

xeb_ex(optimize='auto-hq', simplify_sequence='R', simplify_atol=1e-12, simplify_equalize_norms=False, dtype=None, backend=None, autojit=False, progbar=False, **contract_opts)[source]

Compute the exactly expected XEB for this circuit. The main feature here is that if you supply a cotengra optimizer that searches for sliced indices then the XEB will be computed without constructing the full wavefunction.

Parameters:
  • optimize (str or PathOptimizer, optional) – Contraction path optimizer.

  • simplify_sequence (str, optional) – Simplifications to apply to tensor network prior to contraction.

  • simplify_sequence – Which local tensor network simplifications to perform and in which order, see full_simplify().

  • simplify_atol (float, optional) – The tolerance with which to compare to zero when applying full_simplify().

  • dtype (str, optional) – Data type to cast the TN to before contraction.

  • backend (str, optional) – Convert tensors to, and then use contractions from, this library.

  • autojit (bool, optional) – Apply autoray.autojit to the contraciton and map-reduce.

  • progbar (bool, optional) – Show progress in terms of number of wavefunction chunks processed.

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.

__repr__()[source]

Return repr(self).

class quimb.tensor.circuit.CircuitMPS(N=None, *, psi0=None, max_bond=None, cutoff=1e-10, gate_opts=None, gate_contract='auto-mps', **circuit_opts)[source]

Bases: Circuit

Quantum circuit simulation keeping the state always in a MPS form. If you think the circuit will not build up much entanglement, or you just want to keep a rigorous handle on how much entanglement is present, this can be useful.

Parameters:
  • N (int, optional) – The number of qubits in the circuit.

  • psi0 (TensorNetwork1DVector, optional) – The initial state, assumed to be |00000....0> if not given. The state is always copied and the tag PSI0 added.

  • max_bond (int, optional) – The maximum bond dimension to truncate to when applying gates, if any. This is simply a shortcut for setting gate_opts['max_bond'].

  • cutoff (float, optional) – The singular value cutoff to use when truncating the state. This is simply a shortcut for setting gate_opts['cutoff'].

  • gate_opts (dict, optional) – Default options to pass to each gate, for example, “max_bond” and “cutoff” etc.

  • gate_contract (str, optional) –

    The default method for applying gates. Relevant MPS options are:

    • 'auto-mps': automatically choose a method that maintains the MPS form (default). This uses 'swap+split' for 2-qubit gates and 'nonlocal' for 3+ qubit gates.

    • 'swap+split': swap nonlocal qubits to be next to each other, before applying the gate, then swapping them back

    • 'nonlocal': turn the gate into a potentially nonlocal (sub) MPO and apply it directly. See tensor_network_1d_compress().

  • circuit_opts – Supplied to Circuit.

psi

The current state of the circuit, always in MPS form.

Type:

MatrixProductState

Examples

Create a circuit object that always uses the “nonlocal” method for contracting in gates, and the “dm” compression method within that, using a large cutoff and maximum bond dimension:

circ = qtn.CircuitMPS(
    N=56,
    gate_opts=dict(
        contract="nonlocal",
        method="dm",
        max_bond=1024,
        cutoff=1e-3,
    )
)
_init_state(N, dtype='complex128')[source]
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().

property psi
Tensor network representation of the wavefunction.
property uni
calc_qubit_ordering(qubits=None)[source]

MPS already has a natural ordering.

get_psi_reverse_lightcone(where, keep_psi0=False)[source]

Override get_psi_reverse_lightcone as for an MPS the lightcone is not meaningful.

fidelity_estimate()[source]

Estimate the fidelity of the current state based on its norm, which tracks how much the state has been truncated:

\[\tilde{F} = \left| \langle \psi | \psi \rangle \right|^2 \approx \left|\langle \psi_\mathrm{ideal} | \psi \rangle\right|^2\]

See also

error_estimate

error_estimate()[source]

Estimate the error in the current state based on the norm of the discarded part of the state:

\[\epsilon = 1 - \tilde{F}\]
class quimb.tensor.circuit.CircuitPermMPS(N=None, psi0=None, gate_opts=None, gate_contract='swap+split', **circuit_opts)[source]

Bases: CircuitMPS

Quantum circuit simulation keeping the state always in an MPS form, but lazily tracking the qubit ordering rather than ‘swapping back’ qubits after applying non-local gates. This can be useful for circuits with no expectation of locality. The qubit ordering is always tracked in the attribute qubits. The psi attribute returns the TN with the sites reindexed and retagged according to the current qubit ordering, meaning it is no longer an MPS. Use circ.get_psi_unordered() to get the unpermuted MPS and use circ.qubits to get the current qubit ordering if you prefer.

_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).

calc_qubit_ordering(qubits=None)[source]

Given by the current qubit permutation.

get_psi_unordered()[source]

Return the MPS representing the state but without reordering the sites.

property psi
Tensor network representation of the wavefunction.
class quimb.tensor.circuit.CircuitDense(N=None, psi0=None, gate_opts=None, gate_contract=True, tags=None)[source]

Bases: Circuit

Quantum circuit simulation keeping the state in full dense form.

property psi
Tensor network representation of the wavefunction.
property uni
calc_qubit_ordering(qubits=None)[source]

Qubit ordering doesn’t matter for a dense wavefunction.

get_psi_reverse_lightcone(where, keep_psi0=False)[source]

Override get_psi_reverse_lightcone as for a dense wavefunction the lightcone is not meaningful.