quimb.tensor.circuit.mps

Matrix-product-state circuit simulators.

Classes

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

CircuitMPSLazy

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

Module Contents

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

Bases: quimb.tensor.circuit.core.CircuitBase

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

  • dtype (str, optional) – The data type to use for the state tensor.

  • to_backend (callable, optional) – A function to convert tensor data to a particular backend.

  • convert_eager (bool, optional) – Whether to eagerly perform dtype casting and application of to_backend as gates are supplied, or wait until after the necessary TNs for a particular task such as sampling are formed and simplified. Eager conversion (convert_eager=True) is the default mode for MPS simulation, unlike full contraction.

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

get_psi()[source]

Get a copy of the current matrix product state.

abstract property uni
abstractmethod schrodinger_contract(*args, **kwargs)[source]
to_dense(reverse=False, optimize='auto-hq', backend=None, dtype=None)[source]

Contract the MPS into a dense wavefunction, a column-vector qarray of length 2**N. Contracts self.psi directly (already in MPS/qubit order), with no exact-TN simplification.

amplitude(b, optimize='auto-hq', backend=None, dtype=None)[source]

Compute the amplitude <b|psi> of bitstring b by projecting each physical index of self.psi and contracting the resulting single-layer (scalar) network, rather than forming the full state.

partial_trace(keep, optimize='auto-hq', backend=None, dtype=None)[source]

Reduced density matrix on the qubits in keep, tracing out the rest. Forms the double-layer network from the full state self.psi and contracts it.

Parameters:

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

compute_marginal(where, fix=None, optimize='auto-hq', backend=None, dtype=None)[source]

Compute the probability tensor of qubits in where, given possibly fixed qubits in fix, tracing out the rest. Forms the single or double layer network directly from the full state self.psi.

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.

  • backend (str, optional) – Backend to perform the marginal contraction with.

  • dtype (str, optional) – If given, ensure the TN is cast to this dtype before contracting.

sample_chaotic(C, marginal_qubits, fix=None, max_marginal_storage=2**20, seed=None, optimize='auto-hq', backend=None, dtype=None)[source]

Sample from this circuit, assuming it to be chaotic: only the marginal on marginal_qubits is computed and sampled correctly, with the remaining qubits sampled uniformly and conditioned on. See sample_chaotic() for a full description.

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

  • fix (None or dict[int, str], optional) – Measurement results on other qubits to fix. These will be randomly sampled if fix is not given or a qubit is missing.

  • seed (None or int, optional) – A random seed for the uniformly sampled qubits.

Yields:

str

calc_qubit_ordering(qubits=None)[source]

MPS already has a natural ordering.

sample(C, seed=None, dtype=None, *, qubits=None, order=None, group_size=None, max_marginal_storage=None, optimize=None, backend=None, simplify_sequence=None, simplify_atol=None, simplify_equalize_norms=None)[source]

Sample the MPS circuit C times.

Parameters:
  • C (int) – The number of samples to generate.

  • seed (None, int, or generator, optional) – A random seed or generator to use for reproducibility.

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}\]
local_expectation(G, where, normalized=False, dtype=None, *, simplify_sequence=None, simplify_atol=None, simplify_equalize_norms=None, backend=None, rehearse=None, **contract_opts)[source]

Compute the local expectation value of a local operator at where (via forming the reduced density matrix). Note this moves the orthogonality around inplace, and records it in info.

Parameters:
  • G (Tensor) – The local operator tensor.

  • where (int) – The qubit to compute the expectation value at.

  • normalized (bool, optional) – Whether to normalize the expectation value by the norm of the state.

  • dtype (dtype, optional) – If given, ensure the TN is cast to this dtype before contracting.

Return type:

float

class quimb.tensor.circuit.mps.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.

qubits
copy()[source]

Copy the circuit and its state.

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

sample(C, seed=None, dtype=None, *, qubits=None, order=None, group_size=None, max_marginal_storage=None, optimize=None, backend=None, simplify_sequence=None, simplify_atol=None, simplify_equalize_norms=None)[source]

Sample the PermMPS circuit C times.

Parameters:
  • C (int) – The number of samples to generate.

  • seed (None, int, or generator, optional) – A random seed or generator to use for reproducibility.

Yields:

str – The next sample bitstring.

get_psi()[source]

Get the current state, reindexed and retagged into logical qubit order, meaning it is no longer generally an MPS.

local_expectation(G, where, *args, **kwargs)[source]

Compute the local expectation value of a local operator at where (via forming the reduced density matrix). Note this moves the orthogonality around inplace, and records it in info.

Parameters:
  • G (Tensor) – The local operator tensor.

  • where (int) – The qubit to compute the expectation value at.

  • normalized (bool, optional) – Whether to normalize the expectation value by the norm of the state.

  • dtype (dtype, optional) – If given, ensure the TN is cast to this dtype before contracting.

Return type:

float

class quimb.tensor.circuit.mps.CircuitMPSLazy(N=None, *, psi0=None, max_bond=None, cutoff=1e-10, compress_opts=None, method='dm', compress_every=2, dtype=None, to_backend=None, convert_eager=True, **circuit_opts)[source]

Bases: CircuitMPS

Quantum circuit simulation keeping the state always in an MPS form, but lazily applying gates (via sub-MPO representation) and regularly contracting and compressing the gates with the state using tensor_network_1d_compress(). This is in contrast to the TEBD approach of eagerly applying gates and then compressing which is used in CircuitMPS.

The periodicity of compression is arbitrary and can be tuned with compress_every, and one can find a goldilocks point for fastest runtime. This circuit class is best utilized for long-range gates, and provides a speedup over CircuitMPS when using "src" compression method.

Note gate_contract is obsolete for this class as 2+ qubit gates are lazily applied via "nonlocal" and 1 qubit gates are eagerly applied via True.

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.

  • compress_opts (dict, optional) – Default options to pass to tensor_network_1d_compress(), for example, “method”, “max_bond” and “cutoff” etc.

  • method (str, optional) – The method to use for compressing the state with the gates, passed to tensor_network_1d_compress(), e.g. "dm" for density matrix truncation, "src" for successive randomized compression, or "direct" for direct SVD truncation.

  • compress_every (int, optional) – How many gates to apply to any qubit before contracting and compressing the state with the gates.

  • dtype (str, optional) – The data type to use for the state tensor.

  • to_backend (callable, optional) – A function to convert tensor data to a particular backend.

  • convert_eager (bool, optional) – Whether to eagerly perform dtype casting and application of to_backend as gates are supplied, or wait until after the necessary TNs for a particular task such as sampling are formed and simplified. Eager conversion (convert_eager=True) is the default mode for MPS simulation, unlike full contraction.

  • 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 “src” compression method using maximum bond dimension and compressing when 5 gates are applied to any qubit:

circ = qtn.CircuitMPSLazy(
    N=56,
    max_bond=1024,
    cutoff=0.0,
    compress_every=5,
    method="src",
)
compress_opts
_uncompressed_sites
compress_every = 2
property max_bond
property cutoff
property method
copy()[source]

Copy the circuit and its state.

_compress()[source]

Compress the current state by contracting in all gates and then applying the specified compression method via tensor_network_1d_compress().

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

get_psi()[source]

Get a copy of the current matrix product state.

sample(C, *args, **kwargs)[source]

Sample the MPS circuit C times.

Parameters:
  • C (int) – The number of samples to generate.

  • seed (None, int, or generator, optional) – A random seed or generator to use for reproducibility.

local_expectation(G, where, *args, **kwargs)[source]

Compute the local expectation value of a local operator at where (via forming the reduced density matrix). Note this moves the orthogonality around inplace, and records it in info.

Parameters:
  • G (Tensor) – The local operator tensor.

  • where (int) – The qubit to compute the expectation value at.

  • normalized (bool, optional) – Whether to normalize the expectation value by the norm of the state.

  • dtype (dtype, optional) – If given, ensure the TN is cast to this dtype before contracting.

Return type:

float

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