CircuitToEinsum#

class cuquantum.tensornet.CircuitToEinsum(
circuit,
*,
dtype='complex128',
backend='auto',
options=None,
)[source]#

Create a converter object that can generate Einstein summation expressions and tensor operands for a given circuit.

The supported circuit types include cirq.Circuit and qiskit.QuantumCircuit. The input circuit must be fully parameterized and can not contain operations that are not well-defined in tensor network simulation, for instance, resetting the quantum state or performing any intermediate measurement.

The converter automatically targets a density-matrix (mixed-state) network when the input circuit contains quantum channels (Kraus/general and unitary channels), and a state-vector (pure-state) network otherwise. In the mixed case, the accessors return density-matrix quantities; see density_matrix(), amplitude(), and batched_amplitudes() for details. For trajectory-based noisy simulation of a pure state, use from_circuit() instead.

Parameters:
  • circuit – A fully parameterized cirq.Circuit or qiskit.QuantumCircuit object.

  • dtype – The datatype for the output tensor operands. Currently supports 'float32', 'float64', 'complex64', and 'complex128'. If not specified, double complex is used. Note that real dtype should only be used when all gate operands are expected to be real.

  • backend – A string specifying the ndarray backend for the output tensor operands. Currently supports 'auto' (default), 'numpy', 'cupy', and 'torch'. If 'auto', 'cupy' is used when it is available, otherwise 'numpy' is used.

  • options – Specify the parser options as a CirqParserOptions for cirq.Circuit or a QiskitParserOptions for qiskit.QuantumCircuit. Alternatively, a dict containing the parameters for the CirqParserOptions or QiskitParserOptions constructor can also be provided. If not specified, the value will be set to the default-constructed CirqParserOptions or QiskitParserOptions based on the circuit type.

Examples

Examples using Qiskit:

>>> import qiskit.circuit.random
>>> from cuquantum.tensornet import contract, CircuitToEinsum

Generate a random quantum circuit:

>>> qc = qiskit.circuit.random.random_circuit(num_qubits=8, depth=7)

Create a CircuitToEinsum object:

>>> converter = CircuitToEinsum(qc, backend='cupy')

Find the Einstein summation expression and tensor operands for the state vector:

>>> expression, operands = converter.state_vector()

Contract the equation above to compute the state vector:

>>> sv = contract(expression, *operands)
>>> print(sv.shape)
(2, 2, 2, 2, 2, 2, 2, 2)

Find the Einstein summation expression and tensor operands for computing the probability amplitude of bitstring 00000000:

>>> expression, operands = converter.amplitude('00000000')

Contract the equation above to compute the amplitude:

>>> amplitude = contract(expression, *operands)

Find the Einstein summation expression and tensor operands for computing reduced density matrix on the first two qubits with the condition that the last qubit is fixed at state 1:

>>> where = qc.qubits[:2]
>>> fixed = {qc.qubits[-1]: '1'}
>>> expression, operands = converter.reduced_density_matrix(where, fixed=fixed)

Contract the equation above to compute the reduced density matrix:

>>> rdm = contract(expression, *operands)
>>> print(rdm.shape)
(2, 2, 2, 2)

Methods

__init__(
circuit,
*,
dtype='complex128',
backend='auto',
options=None,
)[source]#
amplitude(bitstring)[source]#

Generate the Einstein summation expression and tensor operands to compute a single element of the underlying state tensor for the input circuit.

For channel-free (pure-state) circuits, returns the complex amplitude \(\langle \text{bitstring} | \psi \rangle\).

For circuits with channels (mixed states), returns the density matrix element \(\langle \text{ket\_bitstring} | \rho | \text{bra\_bitstring} \rangle\). Use the same bitstring on both sides to extract a diagonal element (probability).

Parameters:

bitstring

  • For pure-state (channel-free) circuits, a sequence of 0/1 specifying the desired measured state.

  • For mixed-state (channel-containing) circuits, either a single length-N sequence of 0/1 – interpreted symmetrically as ket == bra to extract a diagonal element (probability) – or a 2-tuple (ket_bitstring, bra_bitstring) of length-N sequences specifying the row (ket) and column (bra) indices of the density matrix element to compute.

The order of the bitstring(s) is consistent with CircuitToEinsum.qubits. For cirq.Circuit, this order corresponds to all qubits in the circuit sorted in ascending order. For qiskit.QuantumCircuit, this order is the same as qiskit.QuantumCircuit.qubits.

Returns:

The Einstein summation expression and a list of tensor operands

batched_amplitudes(fixed)[source]#

Generate the Einstein summation expression and tensor operands to compute a slice of the underlying state tensor for the input circuit.

For channel-free (pure-state) circuits, returns a slice of the state vector \(\langle \text{bs} | \psi \rangle\) over the open ket modes.

For circuits with channels (mixed states), returns a slice of the density matrix with the requested ket and bra modes projected independently. Output modes are ordered as (open_ket_modes, open_bra_modes) (each in CircuitToEinsum.qubits order).

Parameters:

fixed

A dictionary mapping qubits to fixed states; qubits absent from the dictionary are left open.

  • For pure-state (channel-free) circuits, each value is a single state 0 or 1 (as int or '0'/'1' str).

  • For mixed-state (channel-containing) circuits, each value selects the ket and bra index for that qubit and may be either

    • a single state 0/1 – shorthand for fixing the ket and bra to the same value (a diagonal/symmetric projection), or

    • a 2-tuple (ket, bra) where each entry is 0/1 or None; None leaves that side open, enabling independent ket/bra projection (e.g. (0, None) fixes only the ket).

Returns:

The Einstein summation expression and a list of tensor operands. The order of the output mode labels is consistent with CircuitToEinsum.qubits. For cirq.Circuit, this order corresponds to all qubits in the circuit sorted in ascending order. For qiskit.QuantumCircuit, this order is the same as qiskit.QuantumCircuit.qubits.

density_matrix()[source]#

Generate the Einstein summation expression and tensor operands to compute the full density matrix for the input circuit.

This is supported for both channel-free circuits (where it yields :math:\rho = |\psi\rangle\langle\psi|) and circuits with channels (mixed states). For a channel-free circuit, state_vector() is the cheaper rank-N alternative.

Returns:

The Einstein summation expression and a list of tensor operands. The output shape is (d_0, ..., d_{N-1}, d_0, ..., d_{N-1}) where the first N modes are ket (row) indices and the last N modes are bra (column) indices, each in CircuitToEinsum.qubits order. For cirq.Circuit, this order corresponds to all qubits in the circuit sorted in ascending order. For qiskit.QuantumCircuit, this order is the same as qiskit.QuantumCircuit.qubits.

expectation(pauli_string, lightcone=True)[source]#

Generate the Einstein summation expression and tensor operands to compute the expectation value of a Pauli string for the input circuit. This is supported for both channel-free (pure-state) circuits and circuits with channels, in which case the expectation value \(\mathrm{Tr}(\rho P)\) is computed from the mixed state \(\rho\).

Unitary reverse lightcone cancellation refers to removing the identity formed by a unitary gate (from the ket state) and its inverse (from the bra state) when there exists no additional operators in-between. One can take advantage of this technique to reduce the effective network size by only including the causal gates (gates residing in the lightcone).

Parameters:
  • pauli_string

    The Pauli string for expectation value computation. It can be:

    • a sequence of characters 'I'/'X'/'Y'/'Z'. The length must be equal to the number of qubits.

    • a dictionary mapping the selected qubits to Pauli characters. Qubits not specified are assumed to be applied with the identity operator 'I'.

  • lightcone – Whether to apply the unitary reverse lightcone cancellation technique to reduce the number of tensors in expectation value computation.

Returns:

The Einstein summation expression and a list of tensor operands.

Note

When lightcone=True, the identity Pauli operators will be omitted in the output operands. The unitary reverse lightcone cancellation technique is then applied based on the remaining causal qubits to further reduce the size of the network. The reduction effect depends on the circuit topology and the input Pauli string (so the contraction path cannot be reused for the contraction of different Pauli strings). When lightcone=False, the identity Pauli operators are preserved in the output operands such that the output tensor network has the identical topology for different Pauli strings, and the contraction path only needs to be computed once and can be reused for all Pauli strings.

Note

When the underlying dtype is real, Pauli Y operator is not supported.

marginal_probability(
where,
fixed=None,
lightcone=True,
)[source]#

Generate the Einstein summation expression and tensor operands to compute the marginal probability for the input circuit.

Unitary reverse lightcone cancellation refers to removing the identity formed by a unitary gate (from the ket state) and its inverse (from the bra state) when there exists no additional operators in-between. One can take advantage of this technique to reduce the effective network size by only including the causal gates (gates residing in the lightcone).

Parameters:
  • where – A sequence of qubits specifying where the marginal probability are computed.

  • fixed – Optional, a dictionary that maps certain qubits to the corresponding fixed states 0 or 1.

  • lightcone – Whether to apply the unitary reverse lightcone cancellation technique to reduce the number of tensors in marginal probability computation.

Returns:

The Einstein summation expression and a list of tensor operands. The mode labels for output of the expression has the same order as the where argument.

Note

The marginal probability resulting from the contraction may be a complex tensor with zero imaginary part depending on the underlying data type.

Note

This is functionally equivalent to reduced_density_matrix() with diagonal=True.

reduced_density_matrix(
where,
fixed=None,
lightcone=True,
diagonal=False,
)[source]#

Generate the Einstein summation expression and tensor operands to compute the reduced density matrix for the input circuit. This is supported for both channel-free (pure-state) circuits and circuits with channels, in which case the reduced density matrix is obtained from the mixed state \(\rho\).

Unitary reverse lightcone cancellation refers to removing the identity formed by a unitary gate (from the ket state) and its inverse (from the bra state) when there exists no additional operators in-between. One can take advantage of this technique to reduce the effective network size by only including the causal gates (gates residing in the lightcone).

Parameters:
  • where – A sequence of qubits specifying where the density matrix are reduced onto.

  • fixed – Optional, a dictionary that maps certain qubits to the corresponding fixed states 0 or 1.

  • lightcone – Whether to apply the unitary reverse lightcone cancellation technique to reduce the number of tensors in density matrix computation.

  • diagonal – If False (default), the full reduced density matrix is computed. If True, the bra modes are contracted onto the ket modes so that only the diagonal of the reduced density matrix is computed, i.e. the marginal probability distribution over where. With diagonal=True this is functionally equivalent to marginal_probability().

Returns:

The Einstein summation expression and a list of tensor operands. With diagonal=False the mode labels for the output of the expression has the same order as the where argument. For example, if where = (\(a, b\)), the mode labels for the reduced density matrix would be (:math:a, b, a^{\prime}, b^{\prime}). With diagonal=True the output carries only the ket modes (e.g. (\(a, b\))), holding the diagonal entries.

state_vector()[source]#

Generate the Einstein summation expression and tensor operands to compute the statevector for the input circuit.

This is only supported for channel-free (pure-state) circuits. For circuits containing quantum channels (which are simulated as mixed states) use density_matrix() to obtain the full density matrix.

Returns:

The Einstein summation expression and a list of tensor operands. The output shape is (d_0, d_1, ..., d_{N-1}) and the order of the output mode labels is consistent with CircuitToEinsum.qubits. For cirq.Circuit, this order corresponds to all qubits in the circuit sorted in ascending order. For qiskit.QuantumCircuit, this order is the same as qiskit.QuantumCircuit.qubits.

Attributes

gates#

A sequence of 2-tuple (gate_operand, qubits) representing all gates and quantum channels in the circuit:

Returns:

  • gate_operand: Always a single ndarray-like tensor object (never a list). For a unitary gate acting on k qubits it is a rank-2k tensor whose modes are ordered as AB...ab..., where AB... denotes all output modes and ab... denotes all input modes. For a quantum channel (present only when the circuit is noisy) it is a rank-(2k+1) tensor stacking the m Kraus operators along a leading mode, i.e. shape (m, AB...ab...). Unitary channels are returned in Kraus form \(\sqrt{p_k}\, K_k\), so the stacked tensor fully describes the channel action :math:\sum_k K_k \rho K_k^\dagger (the individual probabilities \(p_k\) are not returned separately). Gate operands therefore have even rank 2k and channel operands odd rank 2k+1; the parity of gate_operand.ndim distinguishes the two.

  • qubits: A list of arrays corresponding to all the qubits and gate tensor operands.

Return type:

  • tuple gates

qubits#

A sequence of all qubits in the circuit.