.. _CircuitToEinsum converter: *********************************** Circuit to tensor network converter *********************************** Introduction ============ Starting cuQuantum Python v22.07, we provide a :class:`CircuitToEinsum` converter that takes either a :class:`qiskit.QuantumCircuit` or a :class:`cirq.Circuit` and generates the corresponding tensor network contraction for the target operation. The goal of the converter is to allow Qiskit and Cirq users to easily explore the functionalities of the cuTensorNet library. As mentioned in the :ref:`tensor network introduction `, quantum circuits can be viewed as tensor networks. For any quantum circuit, :class:`CircuitToEinsum` can construct the corresponding tensor network to compute various quantities of interest. The output tensor network is returned as an Einstein summation expression with tensor operands. We support the following operations: * :meth:`~CircuitToEinsum.state_vector`: The contraction of this Einstein summation expression yields the final state coefficients as an N-dimensional tensor where N is the number of qubits in the circuit. The mode labels of the tensor correspond to the :attr:`CircuitToEinsum.qubits`. * :meth:`~CircuitToEinsum.amplitude`: The contraction of this Einstein summation expression yields the amplitude coefficient for a given bitstring. * :meth:`~CircuitToEinsum.batched_amplitudes`: The contraction of this Einstein summation expression yields the amplitude coefficients for a subset of qubits while the others are fixed at certain states. * :meth:`~CircuitToEinsum.reduced_density_matrix`: The contraction of this Einstein summation expression yields the reduced density matrix for a subset of qubits, optionally with another subset of qubits set to a fixed state. * :meth:`~CircuitToEinsum.expectation`: The contraction of this Einstein summation expression yields the expectation value for a given Pauli string. The :class:`CircuitToEinsum` class also allows user to specify a desired tensor backend (`cupy`, `torch`, `numpy`) via the ``backend`` argument when constructing the converter object. The returned Einstein summation expression and tensor operands can then directly serve as the input arguments for :func:`cuquantum.contract` or the corresponding backend's ``einsum`` function. Usage example ============= .. testcode:: import cirq import cupy from cuquantum import contract, CircuitToEinsum # create a random cirq.Circuit circuit = cirq.testing.random_circuit(qubits=4, n_moments=4, op_density=0.9, random_state=1) # same task can be achieved with qiskit.circuit.random.random_circuit # construct the CircuitToEinsum converter targeting double precision and cupy operands converter = CircuitToEinsum(circuit, dtype='complex128', backend='cupy') # generate the Einstein summation expression and tensor operands for computing the amplitude coefficient of bitstring 0000 expression, operands = converter.amplitude(bitstring='0000') assert all([isinstance(op, cupy.ndarray) for op in operands]) # contract the network to compute the amplitude amplitude = contract(expression, *operands) amplitude_cupy = cupy.einsum(expression, *operands) assert cupy.allclose(amplitude, amplitude_cupy) Multiple Jupyter notebooks are `available `_ for Cirq and Qiskit users to easily build up their tensor network based simulations using cuTensorNet.