tensorcircuit.densitymatrix

Quantum circuit class but with density matrix simulator

class tensorcircuit.densitymatrix.DMCircuit(nqubits: int, empty: bool = False, inputs: Any | None = None, mps_inputs: QuOperator | None = None, tensors: Sequence[Any] | None = None, dminputs: Any | None = None, mpo_dminputs: QuOperator | None = None, split: Dict[str, Any] | None = None, dim: int | None = None)[source]

Bases: BaseCircuit

ANY(*index: int, **vars: Any) None

Apply ANY gate with parameters on the circuit. See tensorcircuit.gates.any_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CMZ(*index: int, **vars: Any) None

Apply cmz gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.cmz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CNOT(*index: int, **kws: Any) None

Apply CNOT gate on the circuit. See tensorcircuit.gates.cnot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

CPHASE(*index: int, **vars: Any) None

Apply CPHASE gate with parameters on the circuit. See tensorcircuit.gates.cphase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CR(*index: int, **vars: Any) None

Apply CR gate with parameters on the circuit. See tensorcircuit.gates.cr_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CRX(*index: int, **vars: Any) None

Apply CRX gate with parameters on the circuit. See tensorcircuit.gates.crx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CRY(*index: int, **vars: Any) None

Apply CRY gate with parameters on the circuit. See tensorcircuit.gates.cry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CRZ(*index: int, **vars: Any) None

Apply CRZ gate with parameters on the circuit. See tensorcircuit.gates.crz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CU(*index: int, **vars: Any) None

Apply CU gate with parameters on the circuit. See tensorcircuit.gates.cu_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CY(*index: int, **kws: Any) None

Apply CY gate on the circuit. See tensorcircuit.gates.cy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.-1.j\\ 0.+0.j & 0.+0.j & 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

CZ(*index: int, **kws: Any) None

Apply CZ gate on the circuit. See tensorcircuit.gates.cz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]

DIAGONAL(*index: int, **vars: Any) None

Apply diagonal gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.diagonal_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

EXP(*index: int, **vars: Any) None

Apply EXP gate with parameters on the circuit. See tensorcircuit.gates.exp_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

EXP1(*index: int, **vars: Any) None

Apply EXP1 gate with parameters on the circuit. See tensorcircuit.gates.exp1_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

FREDKIN(*index: int, **kws: Any) None

Apply FREDKIN gate on the circuit. See tensorcircuit.gates.fredkin_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

H(*index: int, **kws: Any) None

Apply H gate on the circuit. See tensorcircuit.gates.h_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & 0.70710677+0.j\\ 0.70710677+0.j & -0.70710677+0.j \end{bmatrix}\end{split}\]

I(*index: int, **kws: Any) None

Apply I gate on the circuit. See tensorcircuit.gates.i_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

ISWAP(*index: int, **vars: Any) None

Apply ISWAP gate with parameters on the circuit. See tensorcircuit.gates.iswap_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

MPO(*index: int, **vars: Any) None

Apply mpo gate in MPO format on the circuit. See tensorcircuit.gates.mpo_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

MULTICONTROL(*index: int, **vars: Any) None

Apply multicontrol gate in MPO format on the circuit. See tensorcircuit.gates.multicontrol_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ORX(*index: int, **vars: Any) None

Apply ORX gate with parameters on the circuit. See tensorcircuit.gates.orx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ORY(*index: int, **vars: Any) None

Apply ORY gate with parameters on the circuit. See tensorcircuit.gates.ory_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ORZ(*index: int, **vars: Any) None

Apply ORZ gate with parameters on the circuit. See tensorcircuit.gates.orz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

OX(*index: int, **kws: Any) None

Apply OX gate on the circuit. See tensorcircuit.gates.ox_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

OY(*index: int, **kws: Any) None

Apply OY gate on the circuit. See tensorcircuit.gates.oy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j & 0.+0.j & 0.+0.j\\ 0.+1.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

OZ(*index: int, **kws: Any) None

Apply OZ gate on the circuit. See tensorcircuit.gates.oz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

PHASE(*index: int, **vars: Any) None

Apply PHASE gate with parameters on the circuit. See tensorcircuit.gates.phase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

R(*index: int, **vars: Any) None

Apply R gate with parameters on the circuit. See tensorcircuit.gates.r_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RX(*index: int, **vars: Any) None

Apply RX gate with parameters on the circuit. See tensorcircuit.gates.rx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RXX(*index: int, **vars: Any) None

Apply RXX gate with parameters on the circuit. See tensorcircuit.gates.rxx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RY(*index: int, **vars: Any) None

Apply RY gate with parameters on the circuit. See tensorcircuit.gates.ry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RYY(*index: int, **vars: Any) None

Apply RYY gate with parameters on the circuit. See tensorcircuit.gates.ryy_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RZ(*index: int, **vars: Any) None

Apply RZ gate with parameters on the circuit. See tensorcircuit.gates.rz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RZM(*index: int, **vars: Any) None

Apply rzm gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.rzm_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RZZ(*index: int, **vars: Any) None

Apply RZZ gate with parameters on the circuit. See tensorcircuit.gates.rzz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

S(*index: int, **kws: Any) None

Apply S gate on the circuit. See tensorcircuit.gates.s_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+1.j \end{bmatrix}\end{split}\]

SD(*index: int, **kws: Any) None

Apply SD gate on the circuit. See tensorcircuit.gates.sd_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.-1.j \end{bmatrix}\end{split}\]

SU4(*index: int, **vars: Any) None

Apply SU4 gate with parameters on the circuit. See tensorcircuit.gates.su4_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

SWAP(*index: int, **kws: Any) None

Apply SWAP gate on the circuit. See tensorcircuit.gates.swap_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

T(*index: int, **kws: Any) None

Apply T gate on the circuit. See tensorcircuit.gates.t_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677+0.70710677j \end{bmatrix}\end{split}\]

TD(*index: int, **kws: Any) None

Apply TD gate on the circuit. See tensorcircuit.gates.td_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677-0.70710677j \end{bmatrix}\end{split}\]

TOFFOLI(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

U(*index: int, **vars: Any) None

Apply U gate with parameters on the circuit. See tensorcircuit.gates.u_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

WROOT(*index: int, **kws: Any) None

Apply WROOT gate on the circuit. See tensorcircuit.gates.wroot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & -0.5 & -0.5j\\ 0.5 & -0.5j & 0.70710677+0.j \end{bmatrix}\end{split}\]

X(*index: int, **kws: Any) None

Apply X gate on the circuit. See tensorcircuit.gates.x_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j\\ 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

Y(*index: int, **kws: Any) None

Apply Y gate on the circuit. See tensorcircuit.gates.y_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j\\ 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

Z(*index: int, **kws: Any) None

Apply Z gate on the circuit. See tensorcircuit.gates.z_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]

__init__(nqubits: int, empty: bool = False, inputs: Any | None = None, mps_inputs: QuOperator | None = None, tensors: Sequence[Any] | None = None, dminputs: Any | None = None, mpo_dminputs: QuOperator | None = None, split: Dict[str, Any] | None = None, dim: int | None = None) None[source]

The density matrix simulator based on tensornetwork engine. Do not use this class with d!=2 directly

Parameters:
  • nqubits (int) – Number of qubits

  • empty (bool, optional) – if True, nothing initialized, only for internal use, defaults to False

  • inputs (Optional[Tensor], optional) – the state input for the circuit, defaults to None

  • mps_inputs (Optional[QuOperator]) – QuVector for a MPS like initial pure state.

  • tensors (Optional[Sequence[Tensor]]) – Sequence of tensors for a MPS like initial pure state. The order of legs for each tensor is assumed to be (bond-left, physical, bond-right).

  • dminputs (Optional[Tensor], optional) – the density matrix input for the circuit, defaults to None

  • mpo_dminputs (Optional[QuOperator]) – QuOperator for a MPO like initial density matrix.

  • split (Optional[Dict[str, Any]]) – dict if two qubit gate is ready for split, including parameters for at least one of max_singular_values and max_truncation_err.

static all_zero_nodes(n: int, prefix: str = 'qb-', dim: int = 2) List[Node]
amplitude(l: str | Any) Any

Returns the amplitude of the circuit given the bitstring l. For state simulator, it computes \(\langle l\vert \psi\rangle\), for density matrix simulator, it computes \(Tr(\rho \vert l\rangle \langle 1\vert)\) Note how these two are different up to a square operation.

Example:

>>> c = tc.Circuit(2)
>>> c.X(0)
>>> c.amplitude("10")
array(1.+0.j, dtype=complex64)
>>> c.CNOT(0, 1)
>>> c.amplitude("11")
array(1.+0.j, dtype=complex64)
Parameters:

l (Union[str, Tensor]) – The bitstring of 0 and 1s.

Returns:

The amplitude of the circuit.

Return type:

tn.Node.tensor

amplitude_before(l: str | Any) List[Gate]

Returns the tensornetwor nodes for the amplitude of the circuit given the bitstring l. For state simulator, it computes \(\langle l\vert \psi\rangle\), for density matrix simulator, it computes \(Tr(\rho \vert l\rangle \langle 1\vert)\) Note how these two are different up to a square operation.

Parameters:

l (Union[str, Tensor]) – The bitstring of 0 and 1s.

Returns:

The tensornetwork nodes for the amplitude of the circuit.

Return type:

List[Gate]

amplitudedamping(*index: int, **vars: float) None

Apply amplitudedamping quantum channel on the circuit. See tensorcircuit.channels.amplitudedampingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

any(*index: int, **vars: Any) None

Apply ANY gate with parameters on the circuit. See tensorcircuit.gates.any_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

append(c: AbstractCircuit, indices: List[int] | None = None) AbstractCircuit

append circuit c before

Example:

>>> c1 = tc.Circuit(2)
>>> c1.H(0)
>>> c1.H(1)
>>> c2 = tc.Circuit(2)
>>> c2.cnot(0, 1)
>>> c1.append(c2)
<tensorcircuit.circuit.Circuit object at 0x7f8402968970>
>>> c1.draw()
    ┌───┐
q_0:┤ H ├──■──
    ├───┤┌─┴─┐
q_1:┤ H ├┤ X ├
    └───┘└───┘
Parameters:
  • c (BaseCircuit) – The other circuit to be appended

  • indices (Optional[List[int]], optional) – the qubit indices to which c is appended on. Defaults to None, which means plain concatenation.

Returns:

The composed circuit

Return type:

BaseCircuit

append_from_qir(qir: List[Dict[str, Any]]) None

Apply the ciurict in form of quantum intermediate representation after the current cirucit.

Example:

>>> c = tc.Circuit(3)
>>> c.H(0)
>>> c.to_qir()
[{'gatef': h, 'gate': Gate(...), 'index': (0,), 'name': 'h', 'split': None, 'mpo': False}]
>>> c2 = tc.Circuit(3)
>>> c2.CNOT(0, 1)
>>> c2.to_qir()
[{'gatef': cnot, 'gate': Gate(...), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
>>> c.append_from_qir(c2.to_qir())
>>> c.to_qir()
[{'gatef': h, 'gate': Gate(...), 'index': (0,), 'name': 'h', 'split': None, 'mpo': False},
 {'gatef': cnot, 'gate': Gate(...), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
Parameters:

qir (List[Dict[str, Any]]) – The quantum intermediate representation.

apply(gate: Gate | QuOperator, *index: int, name: str | None = None, split: Dict[str, Any] | None = None, mpo: bool = False, diagonal: bool = False, ir_dict: Dict[str, Any] | None = None) None

An implementation of this method should also append gate directionary to self._qir

apply_general_gate(gate: Gate | QuOperator, *index: int, name: str | None = None, split: Dict[str, Any] | None = None, mpo: bool = False, diagonal: bool = False, ir_dict: Dict[str, Any] | None = None) None

An implementation of this method should also append gate directionary to self._qir

static apply_general_gate_delayed(gatef: Callable[[], Gate], name: str | None = None, mpo: bool = False) Callable[[...], None]
apply_general_kraus(kraus: Sequence[Gate], index: Sequence[Tuple[int, ...]], **kws: Any) None[source]
static apply_general_kraus_delayed(krausf: Callable[[...], Sequence[Gate]]) Callable[[...], None][source]
static apply_general_variable_gate_delayed(gatef: Callable[[...], Any], name: str | None = None, mpo: bool = False, diagonal: bool = False) Callable[[...], None]
barrier_instruction(*index: List[int]) None

add a barrier instruction flag, no effect on numerical simulation

Parameters:

index (List[int]) – the corresponding qubits

ccnot(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

ccx(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

static check_density_matrix(dm: Any) None[source]
static check_kraus(kraus: Sequence[Gate]) bool[source]

Check if Kraus operators satisfy the completeness relation: \(\sum_i K_i^\dagger K_i = I\)

Parameters:

kraus (Sequence[Gate]) – Sequence of Kraus operators

Returns:

True if completeness relation is satisfied within tolerance

Return type:

bool

Raises:

ValueError – If completeness relation is not satisfied

circuit_param: Dict[str, Any]
cmz(*index: int, **vars: Any) None

Apply cmz gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.cmz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cnot(*index: int, **kws: Any) None

Apply CNOT gate on the circuit. See tensorcircuit.gates.cnot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

static coloring_copied_nodes(nodes: Sequence[Node], nodes0: Sequence[Node], is_dagger: bool = True, flag: str = 'inputs') None

Tag copied nodes while preserving the original node’s identity for lightcone cancellation.

Parameters:
  • nodes (Sequence[tn.Node]) – A sequence of newly copied nodes.

  • nodes0 (Sequence[tn.Node]) – The sequence of original nodes from which nodes were copied.

  • is_dagger (bool, optional) – Whether the copied nodes represent conjugate operations, defaults to True.

  • flag (str, optional) – A label for the node type, defaults to “inputs”.

static coloring_nodes(nodes: Sequence[Node], is_dagger: bool = False, flag: str = 'inputs') None

Tag nodes with metadata used for casual lightcone simplification and tracing.

Parameters:
  • nodes (Sequence[tn.Node]) – A sequence of tensornetwork nodes to tag.

  • is_dagger (bool, optional) – Whether the nodes represent conjugate operations (U^dagger), defaults to False.

  • flag (str, optional) – A label for the node type (e.g., “gate”, “inputs”, “operator”), defaults to “inputs”.

cond_measure(index: int, status: float | None = None) Any

Measurement on z basis at index qubit based on quantum amplitude (not post-selection). The highlight is that this method can return the measured result as a int Tensor and thus maintained a jittable pipeline.

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> r = c.cond_measurement(0)
>>> c.conditional_gate(r, [tc.gates.i(), tc.gates.x()], 1)
>>> c.expectation([tc.gates.z(), [0]]), c.expectation([tc.gates.z(), [1]])
# two possible outputs: (1, 1) or (-1, -1)

Note

In terms of DMCircuit, this method returns nothing and the density matrix after this method is kept in mixed state without knowing the measuremet resuslts

Parameters:

index (int) – the site index for the Z-basis measurement

Returns:

0 or 1 for Z-basis measurement outcome

Return type:

Tensor

cond_measurement(index: int, status: float | None = None) Any

Measurement on z basis at index qubit based on quantum amplitude (not post-selection). The highlight is that this method can return the measured result as a int Tensor and thus maintained a jittable pipeline.

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> r = c.cond_measurement(0)
>>> c.conditional_gate(r, [tc.gates.i(), tc.gates.x()], 1)
>>> c.expectation([tc.gates.z(), [0]]), c.expectation([tc.gates.z(), [1]])
# two possible outputs: (1, 1) or (-1, -1)

Note

In terms of DMCircuit, this method returns nothing and the density matrix after this method is kept in mixed state without knowing the measuremet resuslts

Parameters:

index (int) – the site index for the Z-basis measurement

Returns:

0 or 1 for Z-basis measurement outcome

Return type:

Tensor

conditional_gate(which: Any, kraus: Sequence[Gate], *index: int) None

Apply which-th gate from kraus list, i.e. apply kraus[which]

Parameters:
  • which (Tensor) – Tensor of shape [] and dtype int

  • kraus (Sequence[Gate]) – A list of gate in the form of tc.gate or Tensor

  • index (int) – the qubit lines the gate applied on

copy() AbstractCircuit
static copy_nodes(nodes: Sequence[Node], dangling: Sequence[Edge] | None = None, conj: bool | None = False) Tuple[List[Node], List[Edge]]

copy all nodes and dangling edges correspondingly

Returns:

cphase(*index: int, **vars: Any) None

Apply CPHASE gate with parameters on the circuit. See tensorcircuit.gates.cphase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cr(*index: int, **vars: Any) None

Apply CR gate with parameters on the circuit. See tensorcircuit.gates.cr_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

crx(*index: int, **vars: Any) None

Apply CRX gate with parameters on the circuit. See tensorcircuit.gates.crx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cry(*index: int, **vars: Any) None

Apply CRY gate with parameters on the circuit. See tensorcircuit.gates.cry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

crz(*index: int, **vars: Any) None

Apply CRZ gate with parameters on the circuit. See tensorcircuit.gates.crz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cswap(*index: int, **kws: Any) None

Apply FREDKIN gate on the circuit. See tensorcircuit.gates.fredkin_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

cu(*index: int, **vars: Any) None

Apply CU gate with parameters on the circuit. See tensorcircuit.gates.cu_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cx(*index: int, **kws: Any) None

Apply CNOT gate on the circuit. See tensorcircuit.gates.cnot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

cy(*index: int, **kws: Any) None

Apply CY gate on the circuit. See tensorcircuit.gates.cy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.-1.j\\ 0.+0.j & 0.+0.j & 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

cz(*index: int, **kws: Any) None

Apply CZ gate on the circuit. See tensorcircuit.gates.cz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]

densitymatrix(check: bool = False, reuse: bool = True) Any[source]

Return the output density matrix of the circuit.

Parameters:
  • check (bool, optional) – check whether the final return is a legal density matrix, defaults to False

  • reuse (bool, optional) – whether to reuse previous results, defaults to True

Returns:

The output densitymatrix in 2D shape tensor form

Return type:

Tensor

depolarizing(*index: int, **vars: float) None

Apply depolarizing quantum channel on the circuit. See tensorcircuit.channels.depolarizingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

diaggates = ['diagonal', 'rzm', 'cmz']
diagonal(*index: int, **vars: Any) None

Apply diagonal gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.diagonal_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

draw(**kws: Any) Any

Visualise the circuit. This method recevies the keywords as same as qiskit.circuit.QuantumCircuit.draw. More details can be found here: https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.draw.html. Interesting kws options include: ``idle_wires``(bool)

Example:

>>> c = tc.Circuit(3)
>>> c.H(1)
>>> c.X(2)
>>> c.CNOT(0, 1)
>>> c.draw(output='text')
q_0: ───────■──
     ┌───┐┌─┴─┐
q_1: ┤ H ├┤ X ├
     ├───┤└───┘
q_2: ┤ X ├─────
     └───┘
exp(*index: int, **vars: Any) None

Apply EXP gate with parameters on the circuit. See tensorcircuit.gates.exp_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

exp1(*index: int, **vars: Any) None

Apply EXP1 gate with parameters on the circuit. See tensorcircuit.gates.exp1_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

expectation(*ops: Tuple[Node, List[int]], reuse: bool = True, noise_conf: Any | None = None, status: Any | None = None, **kws: Any) <property object at 0x71d553bb4b30>[source]

Compute the expectation of corresponding operators.

Parameters:
  • ops (Tuple[tn.Node, List[int]]) – Operator and its position on the circuit, eg. (tc.gates.z(), [1, ]), (tc.gates.x(), [2, ]) is for operator \(Z_1X_2\).

  • reuse (bool) – whether contract the density matrix in advance, defaults to True

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • status (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

Tensor with one element

Return type:

Tensor

expectation_before(*ops: Tuple[Node, List[int]], reuse: bool = True, **kws: Any) List[Node]

Get the tensor network in the form of a list of nodes for the expectation calculation before the real contraction

Parameters:

reuse (bool, optional) – _description_, defaults to True

Raises:

ValueError – _description_

Returns:

_description_

Return type:

List[tn.Node]

expectation_ps(x: Sequence[int] | None = None, y: Sequence[int] | None = None, z: Sequence[int] | None = None, ps: Sequence[int] | None = None, reuse: bool = True, noise_conf: Any | None = None, nmc: int = 1000, status: Any | None = None, **kws: Any) Any

Shortcut for Pauli string expectation. x, y, z list are for X, Y, Z positions

Example:

>>> c = tc.Circuit(2)
>>> c.X(0)
>>> c.H(1)
>>> c.expectation_ps(x=[1], z=[0])
array(-0.99999994+0.j, dtype=complex64)
>>> c = tc.Circuit(2)
>>> c.cnot(0, 1)
>>> c.rx(0, theta=0.4)
>>> c.rx(1, theta=0.8)
>>> c.h(0)
>>> c.h(1)
>>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
>>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2)
>>> noise_conf = NoiseConf()
>>> noise_conf.add_noise("rx", error1)
>>> noise_conf.add_noise("cnot", [error2], [[0, 1]])
>>> c.expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000)
(0.46274087-3.764033e-09j)
Parameters:
  • x (Optional[Sequence[int]], optional) – sites to apply X gate, defaults to None

  • y (Optional[Sequence[int]], optional) – sites to apply Y gate, defaults to None

  • z (Optional[Sequence[int]], optional) – sites to apply Z gate, defaults to None

  • ps (Optional[Sequence[int]], optional) – or one can apply a ps structures instead of x, y, z, e.g. [0, 1, 3, 0, 2, 2] for X_1Z_2Y_4Y_5 defaults to None, ps can overwrite x, y and z

  • reuse (bool, optional) – whether to cache and reuse the wavefunction, defaults to True

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • nmc (int, optional) – repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000

  • status (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

Expectation value

Return type:

Tensor

fredkin(*index: int, **kws: Any) None

Apply FREDKIN gate on the circuit. See tensorcircuit.gates.fredkin_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

classmethod from_cirq(qc: Any, n: int | None = None, inputs: List[float] | None = None, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

Import Cirq Circuit object as a tc.Circuit object.

Example:

>>> import cirq
>>> c = cirq.Circuit()
>>> q = cirq.LineQubit.range(3)
>>> c.append(cirq.H(q[0]))
>>> c.append(cirq.CNOT(q[0], q[1]))
>>> tc_c = tc.Circuit.from_cirq(c)
Parameters:
  • qc (cirq.Circuit) – Cirq Circuit object

  • n (int) – The number of qubits for the circuit

  • inputs (Optional[List[float]], optional) – possible input wavefunction for tc.Circuit, defaults to None

  • circuit_params (Optional[Dict[str, Any]]) – kwargs given in Circuit.__init__ construction function, default to None.

Returns:

The same circuit but as tensorcircuit object

Return type:

Circuit

classmethod from_json(jsonstr: str, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

load json str as a Circuit

Parameters:
  • jsonstr (str) – _description_

  • circuit_params (Optional[Dict[str, Any]], optional) – Extra circuit parameters in the format of __init__, defaults to None

Returns:

_description_

Return type:

AbstractCircuit

classmethod from_json_file(file: str, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

load json file and convert it to a circuit

Parameters:
  • file (str) – filename

  • circuit_params (Optional[Dict[str, Any]], optional) – _description_, defaults to None

Returns:

_description_

Return type:

AbstractCircuit

classmethod from_openqasm(qasmstr: str, circuit_params: Dict[str, Any] | None = None, keep_measure_order: bool = False) AbstractCircuit
classmethod from_openqasm_file(file: str, circuit_params: Dict[str, Any] | None = None, keep_measure_order: bool = False) AbstractCircuit
classmethod from_qir(qir: List[Dict[str, Any]], circuit_params: Dict[str, Any] | None = None) AbstractCircuit

Restore the circuit from the quantum intermediate representation.

Example:

>>> c = tc.Circuit(3)
>>> c.H(0)
>>> c.rx(1, theta=tc.array_to_tensor(0.7))
>>> c.exp1(0, 1, unitary=tc.gates._zz_matrix, theta=tc.array_to_tensor(-0.2), split=split)
>>> len(c)
7
>>> c.expectation((tc.gates.z(), [1]))
array(0.764842+0.j, dtype=complex64)
>>> qirs = c.to_qir()
>>>
>>> c = tc.Circuit.from_qir(qirs, circuit_params={"nqubits": 3})
>>> len(c._nodes)
7
>>> c.expectation((tc.gates.z(), [1]))
array(0.764842+0.j, dtype=complex64)
Parameters:
  • qir (List[Dict[str, Any]]) – The quantum intermediate representation of a circuit.

  • circuit_params (Optional[Dict[str, Any]]) – Extra circuit parameters.

Returns:

The circuit have same gates in the qir.

Return type:

Circuit

classmethod from_qiskit(qc: Any, n: int | None = None, inputs: List[float] | None = None, circuit_params: Dict[str, Any] | None = None, binding_params: Sequence[float] | Dict[Any, float] | None = None) AbstractCircuit

Import Qiskit QuantumCircuit object as a tc.Circuit object.

Example:

>>> from qiskit import QuantumCircuit
>>> qisc = QuantumCircuit(3)
>>> qisc.h(2)
>>> qisc.cswap(1, 2, 0)
>>> qisc.swap(0, 1)
>>> c = tc.Circuit.from_qiskit(qisc)
Parameters:
  • qc (QuantumCircuit in Qiskit) – Qiskit Circuit object

  • n (int) – The number of qubits for the circuit

  • inputs (Optional[List[float]], optional) – possible input wavefunction for tc.Circuit, defaults to None

  • circuit_params (Optional[Dict[str, Any]]) – kwargs given in Circuit.__init__ construction function, default to None.

  • binding_params (Optional[Union[Sequence[float], Dict[Any, float]]]) – (variational) parameters for the circuit. Could be either a sequence or dictionary depending on the type of parameters in the Qiskit circuit. For ParameterVectorElement use sequence. For Parameter use dictionary

Returns:

The same circuit but as tensorcircuit object

Return type:

Circuit

classmethod from_qsim_file(file: str, circuit_params: Dict[str, Any] | None = None) AbstractCircuit
static front_from_nodes(nodes: List[Node]) List[Edge]
gate_aliases = [['cnot', 'cx'], ['fredkin', 'cswap'], ['toffoli', 'ccnot'], ['toffoli', 'ccx'], ['any', 'unitary'], ['sd', 'sdg'], ['td', 'tdg']]
gate_count(gate_list: str | Sequence[str] | None = None) int

count the gate number of the circuit

Example:

>>> c = tc.Circuit(3)
>>> c.h(0)
>>> c.multicontrol(0, 1, 2, ctrl=[0, 1], unitary=tc.gates._x_matrix)
>>> c.toffolli(1, 2, 0)
>>> c.gate_count()
3
>>> c.gate_count(["multicontrol", "toffoli"])
2
Parameters:

gate_list (Optional[Sequence[str]], optional) – gate name or gate name list to be counted, defaults to None (counting all gates)

Returns:

the total number of all gates or gates in the gate_list

Return type:

int

gate_count_by_condition(cond_func: Callable[[Dict[str, Any]], bool]) int

count the number of gates that satisfy certain condition

Example:

>>> c = tc.Circuit(3)
>>> c.x(0)
>>> c.h(0)
>>> c.multicontrol(0, 1, 2, ctrl=[0, 1], unitary=tc.gates._x_matrix)
>>> c.gate_count_by_condition(lambda qir: qir["index"] == (0, ))
2
>>> c.gate_count_by_condition(lambda qir: qir["mpo"])
1
Parameters:

cond_func (Callable[[Dict[str, Any]], bool]) – the condition for counting the gate

Returns:

the total number of all gates which satisfy the condition

Return type:

int

gate_summary() Dict[str, int]

return the summary dictionary on gate type - gate count pair

Returns:

the gate count dict by gate type

Return type:

Dict[str, int]

general_kraus(kraus: Sequence[Gate], index: Sequence[Tuple[int, ...]], **kws: Any) None
generaldepolarizing(*index: int, **vars: float) None

Apply generaldepolarizing quantum channel on the circuit. See tensorcircuit.channels.generaldepolarizingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

get_dm_as_quoperator() QuOperator[source]

Get the representation of the output state in the form of QuOperator while maintaining the circuit uncomputed

Returns:

QuOperator representation of the output state from the circuit

Return type:

QuOperator

get_dm_as_quvector() QuVector

Get the representation of the output state in the form of QuVector while maintaining the circuit uncomputed

Returns:

QuVector representation of the output state from the circuit

Return type:

QuVector

get_positional_logical_mapping() Dict[int, int]

Get positional logical mapping dict based on measure instruction. This function is useful when we only measure part of the qubits in the circuit, to process the count result from partial measurement, we must be aware of the mapping, i.e. for each position in the count bitstring, what is the corresponding qubits (logical) defined on the circuit

Returns:

positional_logical_mapping

Return type:

Dict[int, int]

get_quvector() QuVector

Get the representation of the output state in the form of QuVector while maintaining the circuit uncomputed

Returns:

QuVector representation of the output state from the circuit

Return type:

QuVector

h(*index: int, **kws: Any) None

Apply H gate on the circuit. See tensorcircuit.gates.h_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & 0.70710677+0.j\\ 0.70710677+0.j & -0.70710677+0.j \end{bmatrix}\end{split}\]

i(*index: int, **kws: Any) None

Apply I gate on the circuit. See tensorcircuit.gates.i_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

initial_mapping(logical_physical_mapping: Dict[int, int], n: int | None = None, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

generate a new circuit with the qubit mapping given by logical_physical_mapping

Parameters:
  • logical_physical_mapping (Dict[int, int]) – how to map logical qubits to the physical qubits on the new circuit

  • n (Optional[int], optional) – number of qubit of the new circuit, can be different from the original one, defaults to None

  • circuit_params (Optional[Dict[str, Any]], optional) – _description_, defaults to None

Returns:

_description_

Return type:

AbstractCircuit

inputs: Any
inverse(circuit_params: Dict[str, Any] | None = None) AbstractCircuit

inverse the circuit, return a new inversed circuit

EXAMPLE:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> c.rzz(1, 2, theta=0.8)
>>> c1 = c.inverse()
Parameters:

circuit_params (Optional[Dict[str, Any]], optional) – keywords dict for initialization the new circuit, defaults to None

Returns:

the inversed circuit

Return type:

Circuit

is_dm: bool = True
is_mps: bool = False
isotropicdepolarizing(*index: int, **vars: float) None

Apply isotropicdepolarizing quantum channel on the circuit. See tensorcircuit.channels.isotropicdepolarizingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

iswap(*index: int, **vars: Any) None

Apply ISWAP gate with parameters on the circuit. See tensorcircuit.gates.iswap_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

measure(*index: int, with_prob: bool = False, status: Any | None = None) Tuple[Any, Any]

Take measurement on the given site indices (computational basis). This method is jittable is and about 100 times faster than unjit version!

Parameters:
  • index (int) – Measure on which site (wire) index.

  • with_prob (bool, optional) – If true, theoretical probability is also returned.

  • status (Optional[Tensor]) – external randomness, with shape [index], defaults to None

Returns:

The sample output and probability (optional) of the quantum line.

Return type:

Tuple[Tensor, Tensor]

measure_instruction(*index: int) None

add a measurement instruction flag, no effect on numerical simulation

Parameters:

index (int) – the corresponding qubits

measure_jit(*index: int, with_prob: bool = False, status: Any | None = None) Tuple[Any, Any]

Take measurement on the given site indices (computational basis). This method is jittable is and about 100 times faster than unjit version!

Parameters:
  • index (int) – Measure on which site (wire) index.

  • with_prob (bool, optional) – If true, theoretical probability is also returned.

  • status (Optional[Tensor]) – external randomness, with shape [index], defaults to None

Returns:

The sample output and probability (optional) of the quantum line.

Return type:

Tuple[Tensor, Tensor]

mpo(*index: int, **vars: Any) None

Apply mpo gate in MPO format on the circuit. See tensorcircuit.gates.mpo_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

mpogates = ['multicontrol', 'mpo']
multicontrol(*index: int, **vars: Any) None

Apply multicontrol gate in MPO format on the circuit. See tensorcircuit.gates.multicontrol_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

orx(*index: int, **vars: Any) None

Apply ORX gate with parameters on the circuit. See tensorcircuit.gates.orx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ory(*index: int, **vars: Any) None

Apply ORY gate with parameters on the circuit. See tensorcircuit.gates.ory_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

orz(*index: int, **vars: Any) None

Apply ORZ gate with parameters on the circuit. See tensorcircuit.gates.orz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ox(*index: int, **kws: Any) None

Apply OX gate on the circuit. See tensorcircuit.gates.ox_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

oy(*index: int, **kws: Any) None

Apply OY gate on the circuit. See tensorcircuit.gates.oy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j & 0.+0.j & 0.+0.j\\ 0.+1.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

oz(*index: int, **kws: Any) None

Apply OZ gate on the circuit. See tensorcircuit.gates.oz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

perfect_sampling(status: Any | None = None) Tuple[str, float]

Sampling base-d strings (0-9A-Z when d <= 36) from the circuit output based on quantum amplitudes. Reference: arXiv:1201.3974.

Parameters:

status (Optional[Tensor]) – external randomness, with shape [nqubits], defaults to None

Returns:

Sampled base-d string and the corresponding theoretical probability.

Return type:

Tuple[str, float]

phase(*index: int, **vars: Any) None

Apply PHASE gate with parameters on the circuit. See tensorcircuit.gates.phase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

phasedamping(*index: int, **vars: float) None

Apply phasedamping quantum channel on the circuit. See tensorcircuit.channels.phasedampingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

prepend(c: AbstractCircuit) AbstractCircuit

prepend circuit c before

Parameters:

c (BaseCircuit) – The other circuit to be prepended

Returns:

The composed circuit

Return type:

BaseCircuit

probability() Any

get the d^n length probability vector over computational basis

Returns:

probability vector of shape [dim**n]

Return type:

Tensor

projected_subsystem(traceout: Any, left: Tuple[int, ...]) Any

remaining wavefunction or density matrix on sites in left, with other sites fixed to given digits (0..d-1) as indicated by traceout

Parameters:
  • traceout (Tensor) – can be jitted

  • left (Tuple) – cannot be jitted

Returns:

_description_

Return type:

Tensor

quvector() QuVector

Get the representation of the output state in the form of QuVector while maintaining the circuit uncomputed

Returns:

QuVector representation of the output state from the circuit

Return type:

QuVector

r(*index: int, **vars: Any) None

Apply R gate with parameters on the circuit. See tensorcircuit.gates.r_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

readouterror_bs(readout_error: Sequence[Any] | None = None, p: Any | None = None) Any

Apply readout error to original probabilities of bit string and return the noisy probabilities.

Example:

>>> readout_error = []
>>> readout_error.append([0.9,0.75])  # readout error for qubit 0, [p0|0,p1|1]
>>> readout_error.append([0.4,0.7])   # readout error for qubit 1, [p0|0,p1|1]
Parameters:
  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – list of readout error for each qubits.

  • p (Optional[Any]) – probabilities of bit string

Return type:

Tensor

replace_inputs(inputs: Any) None

Replace the input state with the circuit structure unchanged.

Parameters:

inputs (Tensor) – Input wavefunction.

reset(*index: int, **vars: float) None

Apply reset quantum channel on the circuit. See tensorcircuit.channels.resetchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

reset_instruction(*index: int) None

add a reset instruction flag, no effect on numerical simulation

Parameters:

index (int) – the corresponding qubits

rx(*index: int, **vars: Any) None

Apply RX gate with parameters on the circuit. See tensorcircuit.gates.rx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rxx(*index: int, **vars: Any) None

Apply RXX gate with parameters on the circuit. See tensorcircuit.gates.rxx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ry(*index: int, **vars: Any) None

Apply RY gate with parameters on the circuit. See tensorcircuit.gates.ry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ryy(*index: int, **vars: Any) None

Apply RYY gate with parameters on the circuit. See tensorcircuit.gates.ryy_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rz(*index: int, **vars: Any) None

Apply RZ gate with parameters on the circuit. See tensorcircuit.gates.rz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rzm(*index: int, **vars: Any) None

Apply rzm gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.rzm_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rzz(*index: int, **vars: Any) None

Apply RZZ gate with parameters on the circuit. See tensorcircuit.gates.rzz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

s(*index: int, **kws: Any) None

Apply S gate on the circuit. See tensorcircuit.gates.s_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+1.j \end{bmatrix}\end{split}\]

sample(batch: int | None = None, allow_state: bool = False, readout_error: Sequence[Any] | None = None, format: str | None = None, random_generator: Any | None = None, status: Any | None = None, jittable: bool = True) Any

batched sampling from state or circuit tensor network directly

Parameters:
  • batch (Optional[int], optional) – number of samples, defaults to None

  • allow_state (bool, optional) – if true, we sample from the final state if memory allows, True is preferred, defaults to False

  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – readout_error, defaults to None

  • format (Optional[str]) –

    sample format, defaults to None as backward compatibility check the doc in tensorcircuit.quantum.measurement_results() Six formats of measurement counts results:

    ”sample_int”: # np.array([0, 0])

    ”sample_bin”: # [np.array([1, 0]), np.array([1, 0])]

    ”count_vector”: # np.array([2, 0, 0, 0])

    ”count_tuple”: # (np.array([0]), np.array([2]))

    ”count_dict_bin”: # {“00”: 2, “01”: 0, “10”: 0, “11”: 0}

    for cases din [11, 36], use 0-9A-Z digits (e.g., ‘A’ -> 10, …, ‘Z’ -> 35);

    ”count_dict_int”: # {0: 2, 1: 0, 2: 0, 3: 0}

  • format – alias for the argument format

  • random_generator (Optional[Any], optional) – random generator, defaults to None

  • status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator, shape [batch] for allow_state=True and shape [batch, nqubits] for allow_state=False using perfect sampling implementation

  • jittable (bool, defaults true) – when converting to count, whether keep the full size. if false, may be conflict external jit, if true, may fail for large scale system with actual limited count results

Returns:

List (if batch) of tuple (binary configuration tensor and corresponding probability) if the format is None, and consistent with format when given

Return type:

Any

sample_expectation_ps(x: Sequence[int] | None = None, y: Sequence[int] | None = None, z: Sequence[int] | None = None, shots: int | None = None, random_generator: Any | None = None, status: Any | None = None, readout_error: Sequence[Any] | None = None, noise_conf: Any | None = None, nmc: int = 1000, statusc: Any | None = None, **kws: Any) Any

Compute the expectation with given Pauli string with measurement shots numbers

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> c.rx(1, theta=np.pi/2)
>>> c.sample_expectation_ps(x=[0], y=[1])
-0.99999976
>>> readout_error = []
>>> readout_error.append([0.9,0.75])
>>> readout_error.append([0.4,0.7])
>>> c.sample_expectation_ps(x=[0], y=[1],readout_error = readout_error)
>>> c = tc.Circuit(2)
>>> c.cnot(0, 1)
>>> c.rx(0, theta=0.4)
>>> c.rx(1, theta=0.8)
>>> c.h(0)
>>> c.h(1)
>>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
>>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2)
>>> readout_error = [[0.9, 0.75],[0.4, 0.7]]
>>> noise_conf = NoiseConf()
>>> noise_conf.add_noise("rx", error1)
>>> noise_conf.add_noise("cnot", [error2], [[0, 1]])
>>> noise_conf.add_noise("readout", readout_error)
>>> c.sample_expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000)
0.44766843
Parameters:
  • x (Optional[Sequence[int]], optional) – index for Pauli X, defaults to None

  • y (Optional[Sequence[int]], optional) – index for Pauli Y, defaults to None

  • z (Optional[Sequence[int]], optional) – index for Pauli Z, defaults to None

  • shots (Optional[int], optional) – number of measurement shots, defaults to None, indicating analytical result

  • random_generator (Optional[Any]) – random_generator, defaults to None

  • status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator

  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – readout_error, defaults to None. Overrided if noise_conf is provided.

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • nmc (int, optional) – repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000

  • statusc (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

[description]

Return type:

Tensor

sd(*index: int, **kws: Any) None

Apply SD gate on the circuit. See tensorcircuit.gates.sd_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.-1.j \end{bmatrix}\end{split}\]

sdg(*index: int, **kws: Any) None

Apply SD gate on the circuit. See tensorcircuit.gates.sd_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.-1.j \end{bmatrix}\end{split}\]

select_gate(which: Any, kraus: Sequence[Gate], *index: int) None

Apply which-th gate from kraus list, i.e. apply kraus[which]

Parameters:
  • which (Tensor) – Tensor of shape [] and dtype int

  • kraus (Sequence[Gate]) – A list of gate in the form of tc.gate or Tensor

  • index (int) – the qubit lines the gate applied on

sexpps(x: Sequence[int] | None = None, y: Sequence[int] | None = None, z: Sequence[int] | None = None, shots: int | None = None, random_generator: Any | None = None, status: Any | None = None, readout_error: Sequence[Any] | None = None, noise_conf: Any | None = None, nmc: int = 1000, statusc: Any | None = None, **kws: Any) Any

Compute the expectation with given Pauli string with measurement shots numbers

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> c.rx(1, theta=np.pi/2)
>>> c.sample_expectation_ps(x=[0], y=[1])
-0.99999976
>>> readout_error = []
>>> readout_error.append([0.9,0.75])
>>> readout_error.append([0.4,0.7])
>>> c.sample_expectation_ps(x=[0], y=[1],readout_error = readout_error)
>>> c = tc.Circuit(2)
>>> c.cnot(0, 1)
>>> c.rx(0, theta=0.4)
>>> c.rx(1, theta=0.8)
>>> c.h(0)
>>> c.h(1)
>>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
>>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2)
>>> readout_error = [[0.9, 0.75],[0.4, 0.7]]
>>> noise_conf = NoiseConf()
>>> noise_conf.add_noise("rx", error1)
>>> noise_conf.add_noise("cnot", [error2], [[0, 1]])
>>> noise_conf.add_noise("readout", readout_error)
>>> c.sample_expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000)
0.44766843
Parameters:
  • x (Optional[Sequence[int]], optional) – index for Pauli X, defaults to None

  • y (Optional[Sequence[int]], optional) – index for Pauli Y, defaults to None

  • z (Optional[Sequence[int]], optional) – index for Pauli Z, defaults to None

  • shots (Optional[int], optional) – number of measurement shots, defaults to None, indicating analytical result

  • random_generator (Optional[Any]) – random_generator, defaults to None

  • status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator

  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – readout_error, defaults to None. Overrided if noise_conf is provided.

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • nmc (int, optional) – repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000

  • statusc (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

[description]

Return type:

Tensor

sgates = ['i', 'x', 'y', 'z', 'h', 't', 's', 'td', 'sd', 'wroot', 'cnot', 'cz', 'swap', 'cy', 'ox', 'oy', 'oz', 'toffoli', 'fredkin']
split: Dict[str, Any] | None
static standardize_gate(name: str) str

standardize the gate name to tc common gate sets

Parameters:

name (str) – non-standard gate name

Returns:

the standard gate name

Return type:

str

state(check: bool = False, reuse: bool = True) Any

Return the output density matrix of the circuit.

Parameters:
  • check (bool, optional) – check whether the final return is a legal density matrix, defaults to False

  • reuse (bool, optional) – whether to reuse previous results, defaults to True

Returns:

The output densitymatrix in 2D shape tensor form

Return type:

Tensor

su4(*index: int, **vars: Any) None

Apply SU4 gate with parameters on the circuit. See tensorcircuit.gates.su4_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

swap(*index: int, **kws: Any) None

Apply SWAP gate on the circuit. See tensorcircuit.gates.swap_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

t(*index: int, **kws: Any) None

Apply T gate on the circuit. See tensorcircuit.gates.t_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677+0.70710677j \end{bmatrix}\end{split}\]

td(*index: int, **kws: Any) None

Apply TD gate on the circuit. See tensorcircuit.gates.td_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677-0.70710677j \end{bmatrix}\end{split}\]

tdg(*index: int, **kws: Any) None

Apply TD gate on the circuit. See tensorcircuit.gates.td_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677-0.70710677j \end{bmatrix}\end{split}\]

tex(**kws: Any) str

Generate latex string based on quantikz latex package

Returns:

Latex string that can be directly compiled via, e.g. latexit

Return type:

str

thermalrelaxation(*index: int, **vars: float) None

Apply thermalrelaxation quantum channel on the circuit. See tensorcircuit.channels.thermalrelaxationchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

to_circuit(circuit_params: Dict[str, Any] | None = None) Circuit[source]

convert into state simulator (current implementation ignores all noise channels)

Parameters:

circuit_params (Optional[Dict[str, Any]], optional) – kws to initialize circuit object, defaults to None

Returns:

Circuit with no noise

Return type:

Circuit

to_cirq(enable_instruction: bool = False) Any

Translate tc.Circuit to a cirq circuit object.

Parameters:

enable_instruction (bool, defaults to False) – whether also export measurement and reset instructions

Returns:

A cirq circuit of this circuit.

to_graphviz(graph: Graph | None = None, include_all_names: bool = False, engine: str = 'neato') Graph

Not an ideal visualization for quantum circuit, but reserve here as a general approach to show the tensornetwork [Deprecated, use Circuit.vis_tex or Circuit.draw instead]

to_json(file: str | None = None, simplified: bool = False) Any

circuit dumps to json

Parameters:
  • file (Optional[str], optional) – file str to dump the json to, defaults to None, return the json str

  • simplified (bool) – If False, keep all info for each gate, defaults to be False. If True, suitable for IO since less information is required

Returns:

None if dumps to file otherwise the json str

Return type:

Any

to_openqasm(**kws: Any) str

transform circuit to openqasm via qiskit circuit, see https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.qasm.html for usage on possible options for kws

Returns:

circuit representation in openqasm format

Return type:

str

to_openqasm_file(file: str, **kws: Any) None

save the circuit to openqasm file

Parameters:

file (str) – the file path to save the circuit

to_qir() List[Dict[str, Any]]

Return the quantum intermediate representation of the circuit.

Example:

>>> c = tc.Circuit(2)
>>> c.CNOT(0, 1)
>>> c.to_qir()
[{'gatef': cnot, 'gate': Gate(
    name: 'cnot',
    tensor:
        array([[[[1.+0.j, 0.+0.j],
                [0.+0.j, 0.+0.j]],

                [[0.+0.j, 1.+0.j],
                [0.+0.j, 0.+0.j]]],


            [[[0.+0.j, 0.+0.j],
                [0.+0.j, 1.+0.j]],

                [[0.+0.j, 0.+0.j],
                [1.+0.j, 0.+0.j]]]], dtype=complex64),
    edges: [
        Edge(Dangling Edge)[0],
        Edge(Dangling Edge)[1],
        Edge('cnot'[2] -> 'qb-1'[0] ),
        Edge('cnot'[3] -> 'qb-2'[0] )
    ]), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
Returns:

The quantum intermediate representation of the circuit.

Return type:

List[Dict[str, Any]]

to_qiskit(enable_instruction: bool = False, enable_inputs: bool = False) Any

Translate tc.Circuit to a qiskit QuantumCircuit object.

Parameters:
  • enable_instruction (bool, defaults to False) – whether also export measurement and reset instructions

  • enable_inputs (bool, defaults to False) – whether also export the inputs

Returns:

A qiskit object of this circuit.

toffoli(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

u(*index: int, **vars: Any) None

Apply U gate with parameters on the circuit. See tensorcircuit.gates.u_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

unitary(*index: int, **vars: Any) None

Apply ANY gate with parameters on the circuit. See tensorcircuit.gates.any_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

vgates = ['r', 'cr', 'u', 'cu', 'rx', 'ry', 'rz', 'phase', 'rxx', 'ryy', 'rzz', 'cphase', 'crx', 'cry', 'crz', 'orx', 'ory', 'orz', 'iswap', 'any', 'exp', 'exp1', 'su4']
vis_tex(**kws: Any) str

Generate latex string based on quantikz latex package

Returns:

Latex string that can be directly compiled via, e.g. latexit

Return type:

str

wavefunction() Any[source]

get the wavefunction of outputs, raise error if the final state is not purified [Experimental: the phase factor is not fixed for different backend]

Returns:

wavefunction vector

Return type:

Tensor

wroot(*index: int, **kws: Any) None

Apply WROOT gate on the circuit. See tensorcircuit.gates.wroot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & -0.5 & -0.5j\\ 0.5 & -0.5j & 0.70710677+0.j \end{bmatrix}\end{split}\]

x(*index: int, **kws: Any) None

Apply X gate on the circuit. See tensorcircuit.gates.x_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j\\ 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

y(*index: int, **kws: Any) None

Apply Y gate on the circuit. See tensorcircuit.gates.y_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j\\ 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

z(*index: int, **kws: Any) None

Apply Z gate on the circuit. See tensorcircuit.gates.z_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]

class tensorcircuit.densitymatrix.DMCircuit2(nqubits: int, empty: bool = False, inputs: Any | None = None, mps_inputs: QuOperator | None = None, tensors: Sequence[Any] | None = None, dminputs: Any | None = None, mpo_dminputs: QuOperator | None = None, split: Dict[str, Any] | None = None, dim: int | None = None)[source]

Bases: DMCircuit

ANY(*index: int, **vars: Any) None

Apply ANY gate with parameters on the circuit. See tensorcircuit.gates.any_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CMZ(*index: int, **vars: Any) None

Apply cmz gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.cmz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CNOT(*index: int, **kws: Any) None

Apply CNOT gate on the circuit. See tensorcircuit.gates.cnot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

CPHASE(*index: int, **vars: Any) None

Apply CPHASE gate with parameters on the circuit. See tensorcircuit.gates.cphase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CR(*index: int, **vars: Any) None

Apply CR gate with parameters on the circuit. See tensorcircuit.gates.cr_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CRX(*index: int, **vars: Any) None

Apply CRX gate with parameters on the circuit. See tensorcircuit.gates.crx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CRY(*index: int, **vars: Any) None

Apply CRY gate with parameters on the circuit. See tensorcircuit.gates.cry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CRZ(*index: int, **vars: Any) None

Apply CRZ gate with parameters on the circuit. See tensorcircuit.gates.crz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CU(*index: int, **vars: Any) None

Apply CU gate with parameters on the circuit. See tensorcircuit.gates.cu_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

CY(*index: int, **kws: Any) None

Apply CY gate on the circuit. See tensorcircuit.gates.cy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.-1.j\\ 0.+0.j & 0.+0.j & 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

CZ(*index: int, **kws: Any) None

Apply CZ gate on the circuit. See tensorcircuit.gates.cz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]

DIAGONAL(*index: int, **vars: Any) None

Apply diagonal gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.diagonal_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

EXP(*index: int, **vars: Any) None

Apply EXP gate with parameters on the circuit. See tensorcircuit.gates.exp_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

EXP1(*index: int, **vars: Any) None

Apply EXP1 gate with parameters on the circuit. See tensorcircuit.gates.exp1_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

FREDKIN(*index: int, **kws: Any) None

Apply FREDKIN gate on the circuit. See tensorcircuit.gates.fredkin_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

H(*index: int, **kws: Any) None

Apply H gate on the circuit. See tensorcircuit.gates.h_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & 0.70710677+0.j\\ 0.70710677+0.j & -0.70710677+0.j \end{bmatrix}\end{split}\]

I(*index: int, **kws: Any) None

Apply I gate on the circuit. See tensorcircuit.gates.i_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

ISWAP(*index: int, **vars: Any) None

Apply ISWAP gate with parameters on the circuit. See tensorcircuit.gates.iswap_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

MPO(*index: int, **vars: Any) None

Apply mpo gate in MPO format on the circuit. See tensorcircuit.gates.mpo_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

MULTICONTROL(*index: int, **vars: Any) None

Apply multicontrol gate in MPO format on the circuit. See tensorcircuit.gates.multicontrol_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ORX(*index: int, **vars: Any) None

Apply ORX gate with parameters on the circuit. See tensorcircuit.gates.orx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ORY(*index: int, **vars: Any) None

Apply ORY gate with parameters on the circuit. See tensorcircuit.gates.ory_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ORZ(*index: int, **vars: Any) None

Apply ORZ gate with parameters on the circuit. See tensorcircuit.gates.orz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

OX(*index: int, **kws: Any) None

Apply OX gate on the circuit. See tensorcircuit.gates.ox_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

OY(*index: int, **kws: Any) None

Apply OY gate on the circuit. See tensorcircuit.gates.oy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j & 0.+0.j & 0.+0.j\\ 0.+1.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

OZ(*index: int, **kws: Any) None

Apply OZ gate on the circuit. See tensorcircuit.gates.oz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

PHASE(*index: int, **vars: Any) None

Apply PHASE gate with parameters on the circuit. See tensorcircuit.gates.phase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

R(*index: int, **vars: Any) None

Apply R gate with parameters on the circuit. See tensorcircuit.gates.r_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RX(*index: int, **vars: Any) None

Apply RX gate with parameters on the circuit. See tensorcircuit.gates.rx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RXX(*index: int, **vars: Any) None

Apply RXX gate with parameters on the circuit. See tensorcircuit.gates.rxx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RY(*index: int, **vars: Any) None

Apply RY gate with parameters on the circuit. See tensorcircuit.gates.ry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RYY(*index: int, **vars: Any) None

Apply RYY gate with parameters on the circuit. See tensorcircuit.gates.ryy_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RZ(*index: int, **vars: Any) None

Apply RZ gate with parameters on the circuit. See tensorcircuit.gates.rz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RZM(*index: int, **vars: Any) None

Apply rzm gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.rzm_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

RZZ(*index: int, **vars: Any) None

Apply RZZ gate with parameters on the circuit. See tensorcircuit.gates.rzz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

S(*index: int, **kws: Any) None

Apply S gate on the circuit. See tensorcircuit.gates.s_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+1.j \end{bmatrix}\end{split}\]

SD(*index: int, **kws: Any) None

Apply SD gate on the circuit. See tensorcircuit.gates.sd_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.-1.j \end{bmatrix}\end{split}\]

SU4(*index: int, **vars: Any) None

Apply SU4 gate with parameters on the circuit. See tensorcircuit.gates.su4_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

SWAP(*index: int, **kws: Any) None

Apply SWAP gate on the circuit. See tensorcircuit.gates.swap_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

T(*index: int, **kws: Any) None

Apply T gate on the circuit. See tensorcircuit.gates.t_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677+0.70710677j \end{bmatrix}\end{split}\]

TD(*index: int, **kws: Any) None

Apply TD gate on the circuit. See tensorcircuit.gates.td_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677-0.70710677j \end{bmatrix}\end{split}\]

TOFFOLI(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

U(*index: int, **vars: Any) None

Apply U gate with parameters on the circuit. See tensorcircuit.gates.u_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

WROOT(*index: int, **kws: Any) None

Apply WROOT gate on the circuit. See tensorcircuit.gates.wroot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & -0.5 & -0.5j\\ 0.5 & -0.5j & 0.70710677+0.j \end{bmatrix}\end{split}\]

X(*index: int, **kws: Any) None

Apply X gate on the circuit. See tensorcircuit.gates.x_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j\\ 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

Y(*index: int, **kws: Any) None

Apply Y gate on the circuit. See tensorcircuit.gates.y_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j\\ 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

Z(*index: int, **kws: Any) None

Apply Z gate on the circuit. See tensorcircuit.gates.z_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]

__init__(nqubits: int, empty: bool = False, inputs: Any | None = None, mps_inputs: QuOperator | None = None, tensors: Sequence[Any] | None = None, dminputs: Any | None = None, mpo_dminputs: QuOperator | None = None, split: Dict[str, Any] | None = None, dim: int | None = None) None

The density matrix simulator based on tensornetwork engine. Do not use this class with d!=2 directly

Parameters:
  • nqubits (int) – Number of qubits

  • empty (bool, optional) – if True, nothing initialized, only for internal use, defaults to False

  • inputs (Optional[Tensor], optional) – the state input for the circuit, defaults to None

  • mps_inputs (Optional[QuOperator]) – QuVector for a MPS like initial pure state.

  • tensors (Optional[Sequence[Tensor]]) – Sequence of tensors for a MPS like initial pure state. The order of legs for each tensor is assumed to be (bond-left, physical, bond-right).

  • dminputs (Optional[Tensor], optional) – the density matrix input for the circuit, defaults to None

  • mpo_dminputs (Optional[QuOperator]) – QuOperator for a MPO like initial density matrix.

  • split (Optional[Dict[str, Any]]) – dict if two qubit gate is ready for split, including parameters for at least one of max_singular_values and max_truncation_err.

static all_zero_nodes(n: int, prefix: str = 'qb-', dim: int = 2) List[Node]
amplitude(l: str | Any) Any

Returns the amplitude of the circuit given the bitstring l. For state simulator, it computes \(\langle l\vert \psi\rangle\), for density matrix simulator, it computes \(Tr(\rho \vert l\rangle \langle 1\vert)\) Note how these two are different up to a square operation.

Example:

>>> c = tc.Circuit(2)
>>> c.X(0)
>>> c.amplitude("10")
array(1.+0.j, dtype=complex64)
>>> c.CNOT(0, 1)
>>> c.amplitude("11")
array(1.+0.j, dtype=complex64)
Parameters:

l (Union[str, Tensor]) – The bitstring of 0 and 1s.

Returns:

The amplitude of the circuit.

Return type:

tn.Node.tensor

amplitude_before(l: str | Any) List[Gate]

Returns the tensornetwor nodes for the amplitude of the circuit given the bitstring l. For state simulator, it computes \(\langle l\vert \psi\rangle\), for density matrix simulator, it computes \(Tr(\rho \vert l\rangle \langle 1\vert)\) Note how these two are different up to a square operation.

Parameters:

l (Union[str, Tensor]) – The bitstring of 0 and 1s.

Returns:

The tensornetwork nodes for the amplitude of the circuit.

Return type:

List[Gate]

amplitudedamping(*index: int, **vars: float) None

Apply amplitudedamping quantum channel on the circuit. See tensorcircuit.channels.amplitudedampingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

any(*index: int, **vars: Any) None

Apply ANY gate with parameters on the circuit. See tensorcircuit.gates.any_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

append(c: AbstractCircuit, indices: List[int] | None = None) AbstractCircuit

append circuit c before

Example:

>>> c1 = tc.Circuit(2)
>>> c1.H(0)
>>> c1.H(1)
>>> c2 = tc.Circuit(2)
>>> c2.cnot(0, 1)
>>> c1.append(c2)
<tensorcircuit.circuit.Circuit object at 0x7f8402968970>
>>> c1.draw()
    ┌───┐
q_0:┤ H ├──■──
    ├───┤┌─┴─┐
q_1:┤ H ├┤ X ├
    └───┘└───┘
Parameters:
  • c (BaseCircuit) – The other circuit to be appended

  • indices (Optional[List[int]], optional) – the qubit indices to which c is appended on. Defaults to None, which means plain concatenation.

Returns:

The composed circuit

Return type:

BaseCircuit

append_from_qir(qir: List[Dict[str, Any]]) None

Apply the ciurict in form of quantum intermediate representation after the current cirucit.

Example:

>>> c = tc.Circuit(3)
>>> c.H(0)
>>> c.to_qir()
[{'gatef': h, 'gate': Gate(...), 'index': (0,), 'name': 'h', 'split': None, 'mpo': False}]
>>> c2 = tc.Circuit(3)
>>> c2.CNOT(0, 1)
>>> c2.to_qir()
[{'gatef': cnot, 'gate': Gate(...), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
>>> c.append_from_qir(c2.to_qir())
>>> c.to_qir()
[{'gatef': h, 'gate': Gate(...), 'index': (0,), 'name': 'h', 'split': None, 'mpo': False},
 {'gatef': cnot, 'gate': Gate(...), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
Parameters:

qir (List[Dict[str, Any]]) – The quantum intermediate representation.

apply(gate: Gate | QuOperator, *index: int, name: str | None = None, split: Dict[str, Any] | None = None, mpo: bool = False, diagonal: bool = False, ir_dict: Dict[str, Any] | None = None) None

An implementation of this method should also append gate directionary to self._qir

apply_general_gate(gate: Gate | QuOperator, *index: int, name: str | None = None, split: Dict[str, Any] | None = None, mpo: bool = False, diagonal: bool = False, ir_dict: Dict[str, Any] | None = None) None

An implementation of this method should also append gate directionary to self._qir

static apply_general_gate_delayed(gatef: Callable[[], Gate], name: str | None = None, mpo: bool = False) Callable[[...], None]
apply_general_kraus(kraus: Sequence[Gate], *index: int, **kws: Any) None[source]
static apply_general_kraus_delayed(krausf: Callable[[...], Sequence[Gate]]) Callable[[...], None][source]
static apply_general_variable_gate_delayed(gatef: Callable[[...], Any], name: str | None = None, mpo: bool = False, diagonal: bool = False) Callable[[...], None]
barrier_instruction(*index: List[int]) None

add a barrier instruction flag, no effect on numerical simulation

Parameters:

index (List[int]) – the corresponding qubits

ccnot(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

ccx(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

static check_density_matrix(dm: Any) None
static check_kraus(kraus: Sequence[Gate]) bool

Check if Kraus operators satisfy the completeness relation: \(\sum_i K_i^\dagger K_i = I\)

Parameters:

kraus (Sequence[Gate]) – Sequence of Kraus operators

Returns:

True if completeness relation is satisfied within tolerance

Return type:

bool

Raises:

ValueError – If completeness relation is not satisfied

circuit_param: Dict[str, Any]
cmz(*index: int, **vars: Any) None

Apply cmz gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.cmz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cnot(*index: int, **kws: Any) None

Apply CNOT gate on the circuit. See tensorcircuit.gates.cnot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

static coloring_copied_nodes(nodes: Sequence[Node], nodes0: Sequence[Node], is_dagger: bool = True, flag: str = 'inputs') None

Tag copied nodes while preserving the original node’s identity for lightcone cancellation.

Parameters:
  • nodes (Sequence[tn.Node]) – A sequence of newly copied nodes.

  • nodes0 (Sequence[tn.Node]) – The sequence of original nodes from which nodes were copied.

  • is_dagger (bool, optional) – Whether the copied nodes represent conjugate operations, defaults to True.

  • flag (str, optional) – A label for the node type, defaults to “inputs”.

static coloring_nodes(nodes: Sequence[Node], is_dagger: bool = False, flag: str = 'inputs') None

Tag nodes with metadata used for casual lightcone simplification and tracing.

Parameters:
  • nodes (Sequence[tn.Node]) – A sequence of tensornetwork nodes to tag.

  • is_dagger (bool, optional) – Whether the nodes represent conjugate operations (U^dagger), defaults to False.

  • flag (str, optional) – A label for the node type (e.g., “gate”, “inputs”, “operator”), defaults to “inputs”.

cond_measure(index: int, status: float | None = None) Any

Measurement on z basis at index qubit based on quantum amplitude (not post-selection). The highlight is that this method can return the measured result as a int Tensor and thus maintained a jittable pipeline.

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> r = c.cond_measurement(0)
>>> c.conditional_gate(r, [tc.gates.i(), tc.gates.x()], 1)
>>> c.expectation([tc.gates.z(), [0]]), c.expectation([tc.gates.z(), [1]])
# two possible outputs: (1, 1) or (-1, -1)

Note

In terms of DMCircuit, this method returns nothing and the density matrix after this method is kept in mixed state without knowing the measuremet resuslts

Parameters:

index (int) – the site index for the Z-basis measurement

Returns:

0 or 1 for Z-basis measurement outcome

Return type:

Tensor

cond_measurement(index: int, status: float | None = None) Any

Measurement on z basis at index qubit based on quantum amplitude (not post-selection). The highlight is that this method can return the measured result as a int Tensor and thus maintained a jittable pipeline.

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> r = c.cond_measurement(0)
>>> c.conditional_gate(r, [tc.gates.i(), tc.gates.x()], 1)
>>> c.expectation([tc.gates.z(), [0]]), c.expectation([tc.gates.z(), [1]])
# two possible outputs: (1, 1) or (-1, -1)

Note

In terms of DMCircuit, this method returns nothing and the density matrix after this method is kept in mixed state without knowing the measuremet resuslts

Parameters:

index (int) – the site index for the Z-basis measurement

Returns:

0 or 1 for Z-basis measurement outcome

Return type:

Tensor

conditional_gate(which: Any, kraus: Sequence[Gate], *index: int) None

Apply which-th gate from kraus list, i.e. apply kraus[which]

Parameters:
  • which (Tensor) – Tensor of shape [] and dtype int

  • kraus (Sequence[Gate]) – A list of gate in the form of tc.gate or Tensor

  • index (int) – the qubit lines the gate applied on

copy() AbstractCircuit
static copy_nodes(nodes: Sequence[Node], dangling: Sequence[Edge] | None = None, conj: bool | None = False) Tuple[List[Node], List[Edge]]

copy all nodes and dangling edges correspondingly

Returns:

cphase(*index: int, **vars: Any) None

Apply CPHASE gate with parameters on the circuit. See tensorcircuit.gates.cphase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cr(*index: int, **vars: Any) None

Apply CR gate with parameters on the circuit. See tensorcircuit.gates.cr_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

crx(*index: int, **vars: Any) None

Apply CRX gate with parameters on the circuit. See tensorcircuit.gates.crx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cry(*index: int, **vars: Any) None

Apply CRY gate with parameters on the circuit. See tensorcircuit.gates.cry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

crz(*index: int, **vars: Any) None

Apply CRZ gate with parameters on the circuit. See tensorcircuit.gates.crz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cswap(*index: int, **kws: Any) None

Apply FREDKIN gate on the circuit. See tensorcircuit.gates.fredkin_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

cu(*index: int, **vars: Any) None

Apply CU gate with parameters on the circuit. See tensorcircuit.gates.cu_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

cx(*index: int, **kws: Any) None

Apply CNOT gate on the circuit. See tensorcircuit.gates.cnot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

cy(*index: int, **kws: Any) None

Apply CY gate on the circuit. See tensorcircuit.gates.cy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.-1.j\\ 0.+0.j & 0.+0.j & 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

cz(*index: int, **kws: Any) None

Apply CZ gate on the circuit. See tensorcircuit.gates.cz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]

densitymatrix(check: bool = False, reuse: bool = True) Any

Return the output density matrix of the circuit.

Parameters:
  • check (bool, optional) – check whether the final return is a legal density matrix, defaults to False

  • reuse (bool, optional) – whether to reuse previous results, defaults to True

Returns:

The output densitymatrix in 2D shape tensor form

Return type:

Tensor

depolarizing(*index: int, **vars: float) None

Apply depolarizing quantum channel on the circuit. See tensorcircuit.channels.depolarizingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

diaggates = ['diagonal', 'rzm', 'cmz']
diagonal(*index: int, **vars: Any) None

Apply diagonal gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.diagonal_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

draw(**kws: Any) Any

Visualise the circuit. This method recevies the keywords as same as qiskit.circuit.QuantumCircuit.draw. More details can be found here: https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.draw.html. Interesting kws options include: ``idle_wires``(bool)

Example:

>>> c = tc.Circuit(3)
>>> c.H(1)
>>> c.X(2)
>>> c.CNOT(0, 1)
>>> c.draw(output='text')
q_0: ───────■──
     ┌───┐┌─┴─┐
q_1: ┤ H ├┤ X ├
     ├───┤└───┘
q_2: ┤ X ├─────
     └───┘
exp(*index: int, **vars: Any) None

Apply EXP gate with parameters on the circuit. See tensorcircuit.gates.exp_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

exp1(*index: int, **vars: Any) None

Apply EXP1 gate with parameters on the circuit. See tensorcircuit.gates.exp1_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

expectation(*ops: Tuple[Node, List[int]], reuse: bool = True, noise_conf: Any | None = None, status: Any | None = None, **kws: Any) <property object at 0x71d553bb4b30>

Compute the expectation of corresponding operators.

Parameters:
  • ops (Tuple[tn.Node, List[int]]) – Operator and its position on the circuit, eg. (tc.gates.z(), [1, ]), (tc.gates.x(), [2, ]) is for operator \(Z_1X_2\).

  • reuse (bool) – whether contract the density matrix in advance, defaults to True

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • status (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

Tensor with one element

Return type:

Tensor

expectation_before(*ops: Tuple[Node, List[int]], reuse: bool = True, **kws: Any) List[Node]

Get the tensor network in the form of a list of nodes for the expectation calculation before the real contraction

Parameters:

reuse (bool, optional) – _description_, defaults to True

Raises:

ValueError – _description_

Returns:

_description_

Return type:

List[tn.Node]

expectation_ps(x: Sequence[int] | None = None, y: Sequence[int] | None = None, z: Sequence[int] | None = None, ps: Sequence[int] | None = None, reuse: bool = True, noise_conf: Any | None = None, nmc: int = 1000, status: Any | None = None, **kws: Any) Any

Shortcut for Pauli string expectation. x, y, z list are for X, Y, Z positions

Example:

>>> c = tc.Circuit(2)
>>> c.X(0)
>>> c.H(1)
>>> c.expectation_ps(x=[1], z=[0])
array(-0.99999994+0.j, dtype=complex64)
>>> c = tc.Circuit(2)
>>> c.cnot(0, 1)
>>> c.rx(0, theta=0.4)
>>> c.rx(1, theta=0.8)
>>> c.h(0)
>>> c.h(1)
>>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
>>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2)
>>> noise_conf = NoiseConf()
>>> noise_conf.add_noise("rx", error1)
>>> noise_conf.add_noise("cnot", [error2], [[0, 1]])
>>> c.expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000)
(0.46274087-3.764033e-09j)
Parameters:
  • x (Optional[Sequence[int]], optional) – sites to apply X gate, defaults to None

  • y (Optional[Sequence[int]], optional) – sites to apply Y gate, defaults to None

  • z (Optional[Sequence[int]], optional) – sites to apply Z gate, defaults to None

  • ps (Optional[Sequence[int]], optional) – or one can apply a ps structures instead of x, y, z, e.g. [0, 1, 3, 0, 2, 2] for X_1Z_2Y_4Y_5 defaults to None, ps can overwrite x, y and z

  • reuse (bool, optional) – whether to cache and reuse the wavefunction, defaults to True

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • nmc (int, optional) – repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000

  • status (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

Expectation value

Return type:

Tensor

fredkin(*index: int, **kws: Any) None

Apply FREDKIN gate on the circuit. See tensorcircuit.gates.fredkin_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

classmethod from_cirq(qc: Any, n: int | None = None, inputs: List[float] | None = None, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

Import Cirq Circuit object as a tc.Circuit object.

Example:

>>> import cirq
>>> c = cirq.Circuit()
>>> q = cirq.LineQubit.range(3)
>>> c.append(cirq.H(q[0]))
>>> c.append(cirq.CNOT(q[0], q[1]))
>>> tc_c = tc.Circuit.from_cirq(c)
Parameters:
  • qc (cirq.Circuit) – Cirq Circuit object

  • n (int) – The number of qubits for the circuit

  • inputs (Optional[List[float]], optional) – possible input wavefunction for tc.Circuit, defaults to None

  • circuit_params (Optional[Dict[str, Any]]) – kwargs given in Circuit.__init__ construction function, default to None.

Returns:

The same circuit but as tensorcircuit object

Return type:

Circuit

classmethod from_json(jsonstr: str, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

load json str as a Circuit

Parameters:
  • jsonstr (str) – _description_

  • circuit_params (Optional[Dict[str, Any]], optional) – Extra circuit parameters in the format of __init__, defaults to None

Returns:

_description_

Return type:

AbstractCircuit

classmethod from_json_file(file: str, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

load json file and convert it to a circuit

Parameters:
  • file (str) – filename

  • circuit_params (Optional[Dict[str, Any]], optional) – _description_, defaults to None

Returns:

_description_

Return type:

AbstractCircuit

classmethod from_openqasm(qasmstr: str, circuit_params: Dict[str, Any] | None = None, keep_measure_order: bool = False) AbstractCircuit
classmethod from_openqasm_file(file: str, circuit_params: Dict[str, Any] | None = None, keep_measure_order: bool = False) AbstractCircuit
classmethod from_qir(qir: List[Dict[str, Any]], circuit_params: Dict[str, Any] | None = None) AbstractCircuit

Restore the circuit from the quantum intermediate representation.

Example:

>>> c = tc.Circuit(3)
>>> c.H(0)
>>> c.rx(1, theta=tc.array_to_tensor(0.7))
>>> c.exp1(0, 1, unitary=tc.gates._zz_matrix, theta=tc.array_to_tensor(-0.2), split=split)
>>> len(c)
7
>>> c.expectation((tc.gates.z(), [1]))
array(0.764842+0.j, dtype=complex64)
>>> qirs = c.to_qir()
>>>
>>> c = tc.Circuit.from_qir(qirs, circuit_params={"nqubits": 3})
>>> len(c._nodes)
7
>>> c.expectation((tc.gates.z(), [1]))
array(0.764842+0.j, dtype=complex64)
Parameters:
  • qir (List[Dict[str, Any]]) – The quantum intermediate representation of a circuit.

  • circuit_params (Optional[Dict[str, Any]]) – Extra circuit parameters.

Returns:

The circuit have same gates in the qir.

Return type:

Circuit

classmethod from_qiskit(qc: Any, n: int | None = None, inputs: List[float] | None = None, circuit_params: Dict[str, Any] | None = None, binding_params: Sequence[float] | Dict[Any, float] | None = None) AbstractCircuit

Import Qiskit QuantumCircuit object as a tc.Circuit object.

Example:

>>> from qiskit import QuantumCircuit
>>> qisc = QuantumCircuit(3)
>>> qisc.h(2)
>>> qisc.cswap(1, 2, 0)
>>> qisc.swap(0, 1)
>>> c = tc.Circuit.from_qiskit(qisc)
Parameters:
  • qc (QuantumCircuit in Qiskit) – Qiskit Circuit object

  • n (int) – The number of qubits for the circuit

  • inputs (Optional[List[float]], optional) – possible input wavefunction for tc.Circuit, defaults to None

  • circuit_params (Optional[Dict[str, Any]]) – kwargs given in Circuit.__init__ construction function, default to None.

  • binding_params (Optional[Union[Sequence[float], Dict[Any, float]]]) – (variational) parameters for the circuit. Could be either a sequence or dictionary depending on the type of parameters in the Qiskit circuit. For ParameterVectorElement use sequence. For Parameter use dictionary

Returns:

The same circuit but as tensorcircuit object

Return type:

Circuit

classmethod from_qsim_file(file: str, circuit_params: Dict[str, Any] | None = None) AbstractCircuit
static front_from_nodes(nodes: List[Node]) List[Edge]
gate_aliases = [['cnot', 'cx'], ['fredkin', 'cswap'], ['toffoli', 'ccnot'], ['toffoli', 'ccx'], ['any', 'unitary'], ['sd', 'sdg'], ['td', 'tdg']]
gate_count(gate_list: str | Sequence[str] | None = None) int

count the gate number of the circuit

Example:

>>> c = tc.Circuit(3)
>>> c.h(0)
>>> c.multicontrol(0, 1, 2, ctrl=[0, 1], unitary=tc.gates._x_matrix)
>>> c.toffolli(1, 2, 0)
>>> c.gate_count()
3
>>> c.gate_count(["multicontrol", "toffoli"])
2
Parameters:

gate_list (Optional[Sequence[str]], optional) – gate name or gate name list to be counted, defaults to None (counting all gates)

Returns:

the total number of all gates or gates in the gate_list

Return type:

int

gate_count_by_condition(cond_func: Callable[[Dict[str, Any]], bool]) int

count the number of gates that satisfy certain condition

Example:

>>> c = tc.Circuit(3)
>>> c.x(0)
>>> c.h(0)
>>> c.multicontrol(0, 1, 2, ctrl=[0, 1], unitary=tc.gates._x_matrix)
>>> c.gate_count_by_condition(lambda qir: qir["index"] == (0, ))
2
>>> c.gate_count_by_condition(lambda qir: qir["mpo"])
1
Parameters:

cond_func (Callable[[Dict[str, Any]], bool]) – the condition for counting the gate

Returns:

the total number of all gates which satisfy the condition

Return type:

int

gate_summary() Dict[str, int]

return the summary dictionary on gate type - gate count pair

Returns:

the gate count dict by gate type

Return type:

Dict[str, int]

general_kraus(kraus: Sequence[Gate], *index: int, **kws: Any) None
generaldepolarizing(*index: int, **vars: float) None

Apply generaldepolarizing quantum channel on the circuit. See tensorcircuit.channels.generaldepolarizingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

get_dm_as_quoperator() QuOperator

Get the representation of the output state in the form of QuOperator while maintaining the circuit uncomputed

Returns:

QuOperator representation of the output state from the circuit

Return type:

QuOperator

get_dm_as_quvector() QuVector

Get the representation of the output state in the form of QuVector while maintaining the circuit uncomputed

Returns:

QuVector representation of the output state from the circuit

Return type:

QuVector

get_positional_logical_mapping() Dict[int, int]

Get positional logical mapping dict based on measure instruction. This function is useful when we only measure part of the qubits in the circuit, to process the count result from partial measurement, we must be aware of the mapping, i.e. for each position in the count bitstring, what is the corresponding qubits (logical) defined on the circuit

Returns:

positional_logical_mapping

Return type:

Dict[int, int]

get_quvector() QuVector

Get the representation of the output state in the form of QuVector while maintaining the circuit uncomputed

Returns:

QuVector representation of the output state from the circuit

Return type:

QuVector

h(*index: int, **kws: Any) None

Apply H gate on the circuit. See tensorcircuit.gates.h_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & 0.70710677+0.j\\ 0.70710677+0.j & -0.70710677+0.j \end{bmatrix}\end{split}\]

i(*index: int, **kws: Any) None

Apply I gate on the circuit. See tensorcircuit.gates.i_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

initial_mapping(logical_physical_mapping: Dict[int, int], n: int | None = None, circuit_params: Dict[str, Any] | None = None) AbstractCircuit

generate a new circuit with the qubit mapping given by logical_physical_mapping

Parameters:
  • logical_physical_mapping (Dict[int, int]) – how to map logical qubits to the physical qubits on the new circuit

  • n (Optional[int], optional) – number of qubit of the new circuit, can be different from the original one, defaults to None

  • circuit_params (Optional[Dict[str, Any]], optional) – _description_, defaults to None

Returns:

_description_

Return type:

AbstractCircuit

inputs: Any
inverse(circuit_params: Dict[str, Any] | None = None) AbstractCircuit

inverse the circuit, return a new inversed circuit

EXAMPLE:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> c.rzz(1, 2, theta=0.8)
>>> c1 = c.inverse()
Parameters:

circuit_params (Optional[Dict[str, Any]], optional) – keywords dict for initialization the new circuit, defaults to None

Returns:

the inversed circuit

Return type:

Circuit

is_dm: bool = True
is_mps: bool = False
isotropicdepolarizing(*index: int, **vars: float) None

Apply isotropicdepolarizing quantum channel on the circuit. See tensorcircuit.channels.isotropicdepolarizingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

iswap(*index: int, **vars: Any) None

Apply ISWAP gate with parameters on the circuit. See tensorcircuit.gates.iswap_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

measure(*index: int, with_prob: bool = False, status: Any | None = None) Tuple[Any, Any]

Take measurement on the given site indices (computational basis). This method is jittable is and about 100 times faster than unjit version!

Parameters:
  • index (int) – Measure on which site (wire) index.

  • with_prob (bool, optional) – If true, theoretical probability is also returned.

  • status (Optional[Tensor]) – external randomness, with shape [index], defaults to None

Returns:

The sample output and probability (optional) of the quantum line.

Return type:

Tuple[Tensor, Tensor]

measure_instruction(*index: int) None

add a measurement instruction flag, no effect on numerical simulation

Parameters:

index (int) – the corresponding qubits

measure_jit(*index: int, with_prob: bool = False, status: Any | None = None) Tuple[Any, Any]

Take measurement on the given site indices (computational basis). This method is jittable is and about 100 times faster than unjit version!

Parameters:
  • index (int) – Measure on which site (wire) index.

  • with_prob (bool, optional) – If true, theoretical probability is also returned.

  • status (Optional[Tensor]) – external randomness, with shape [index], defaults to None

Returns:

The sample output and probability (optional) of the quantum line.

Return type:

Tuple[Tensor, Tensor]

mpo(*index: int, **vars: Any) None

Apply mpo gate in MPO format on the circuit. See tensorcircuit.gates.mpo_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

mpogates = ['multicontrol', 'mpo']
multicontrol(*index: int, **vars: Any) None

Apply multicontrol gate in MPO format on the circuit. See tensorcircuit.gates.multicontrol_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

orx(*index: int, **vars: Any) None

Apply ORX gate with parameters on the circuit. See tensorcircuit.gates.orx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ory(*index: int, **vars: Any) None

Apply ORY gate with parameters on the circuit. See tensorcircuit.gates.ory_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

orz(*index: int, **vars: Any) None

Apply ORZ gate with parameters on the circuit. See tensorcircuit.gates.orz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ox(*index: int, **kws: Any) None

Apply OX gate on the circuit. See tensorcircuit.gates.ox_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

oy(*index: int, **kws: Any) None

Apply OY gate on the circuit. See tensorcircuit.gates.oy_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j & 0.+0.j & 0.+0.j\\ 0.+1.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

oz(*index: int, **kws: Any) None

Apply OZ gate on the circuit. See tensorcircuit.gates.oz_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

perfect_sampling(status: Any | None = None) Tuple[str, float]

Sampling base-d strings (0-9A-Z when d <= 36) from the circuit output based on quantum amplitudes. Reference: arXiv:1201.3974.

Parameters:

status (Optional[Tensor]) – external randomness, with shape [nqubits], defaults to None

Returns:

Sampled base-d string and the corresponding theoretical probability.

Return type:

Tuple[str, float]

phase(*index: int, **vars: Any) None

Apply PHASE gate with parameters on the circuit. See tensorcircuit.gates.phase_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

phasedamping(*index: int, **vars: float) None

Apply phasedamping quantum channel on the circuit. See tensorcircuit.channels.phasedampingchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

prepend(c: AbstractCircuit) AbstractCircuit

prepend circuit c before

Parameters:

c (BaseCircuit) – The other circuit to be prepended

Returns:

The composed circuit

Return type:

BaseCircuit

probability() Any

get the d^n length probability vector over computational basis

Returns:

probability vector of shape [dim**n]

Return type:

Tensor

projected_subsystem(traceout: Any, left: Tuple[int, ...]) Any

remaining wavefunction or density matrix on sites in left, with other sites fixed to given digits (0..d-1) as indicated by traceout

Parameters:
  • traceout (Tensor) – can be jitted

  • left (Tuple) – cannot be jitted

Returns:

_description_

Return type:

Tensor

quvector() QuVector

Get the representation of the output state in the form of QuVector while maintaining the circuit uncomputed

Returns:

QuVector representation of the output state from the circuit

Return type:

QuVector

r(*index: int, **vars: Any) None

Apply R gate with parameters on the circuit. See tensorcircuit.gates.r_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

readouterror_bs(readout_error: Sequence[Any] | None = None, p: Any | None = None) Any

Apply readout error to original probabilities of bit string and return the noisy probabilities.

Example:

>>> readout_error = []
>>> readout_error.append([0.9,0.75])  # readout error for qubit 0, [p0|0,p1|1]
>>> readout_error.append([0.4,0.7])   # readout error for qubit 1, [p0|0,p1|1]
Parameters:
  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – list of readout error for each qubits.

  • p (Optional[Any]) – probabilities of bit string

Return type:

Tensor

replace_inputs(inputs: Any) None

Replace the input state with the circuit structure unchanged.

Parameters:

inputs (Tensor) – Input wavefunction.

reset(*index: int, **vars: float) None

Apply reset quantum channel on the circuit. See tensorcircuit.channels.resetchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

reset_instruction(*index: int) None

add a reset instruction flag, no effect on numerical simulation

Parameters:

index (int) – the corresponding qubits

rx(*index: int, **vars: Any) None

Apply RX gate with parameters on the circuit. See tensorcircuit.gates.rx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rxx(*index: int, **vars: Any) None

Apply RXX gate with parameters on the circuit. See tensorcircuit.gates.rxx_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ry(*index: int, **vars: Any) None

Apply RY gate with parameters on the circuit. See tensorcircuit.gates.ry_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

ryy(*index: int, **vars: Any) None

Apply RYY gate with parameters on the circuit. See tensorcircuit.gates.ryy_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rz(*index: int, **vars: Any) None

Apply RZ gate with parameters on the circuit. See tensorcircuit.gates.rz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rzm(*index: int, **vars: Any) None

Apply rzm gate on the circuit using hyperedge support for digonal gates. See tensorcircuit.gates.rzm_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

rzz(*index: int, **vars: Any) None

Apply RZZ gate with parameters on the circuit. See tensorcircuit.gates.rzz_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

s(*index: int, **kws: Any) None

Apply S gate on the circuit. See tensorcircuit.gates.s_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.+1.j \end{bmatrix}\end{split}\]

sample(batch: int | None = None, allow_state: bool = False, readout_error: Sequence[Any] | None = None, format: str | None = None, random_generator: Any | None = None, status: Any | None = None, jittable: bool = True) Any

batched sampling from state or circuit tensor network directly

Parameters:
  • batch (Optional[int], optional) – number of samples, defaults to None

  • allow_state (bool, optional) – if true, we sample from the final state if memory allows, True is preferred, defaults to False

  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – readout_error, defaults to None

  • format (Optional[str]) –

    sample format, defaults to None as backward compatibility check the doc in tensorcircuit.quantum.measurement_results() Six formats of measurement counts results:

    ”sample_int”: # np.array([0, 0])

    ”sample_bin”: # [np.array([1, 0]), np.array([1, 0])]

    ”count_vector”: # np.array([2, 0, 0, 0])

    ”count_tuple”: # (np.array([0]), np.array([2]))

    ”count_dict_bin”: # {“00”: 2, “01”: 0, “10”: 0, “11”: 0}

    for cases din [11, 36], use 0-9A-Z digits (e.g., ‘A’ -> 10, …, ‘Z’ -> 35);

    ”count_dict_int”: # {0: 2, 1: 0, 2: 0, 3: 0}

  • format – alias for the argument format

  • random_generator (Optional[Any], optional) – random generator, defaults to None

  • status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator, shape [batch] for allow_state=True and shape [batch, nqubits] for allow_state=False using perfect sampling implementation

  • jittable (bool, defaults true) – when converting to count, whether keep the full size. if false, may be conflict external jit, if true, may fail for large scale system with actual limited count results

Returns:

List (if batch) of tuple (binary configuration tensor and corresponding probability) if the format is None, and consistent with format when given

Return type:

Any

sample_expectation_ps(x: Sequence[int] | None = None, y: Sequence[int] | None = None, z: Sequence[int] | None = None, shots: int | None = None, random_generator: Any | None = None, status: Any | None = None, readout_error: Sequence[Any] | None = None, noise_conf: Any | None = None, nmc: int = 1000, statusc: Any | None = None, **kws: Any) Any

Compute the expectation with given Pauli string with measurement shots numbers

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> c.rx(1, theta=np.pi/2)
>>> c.sample_expectation_ps(x=[0], y=[1])
-0.99999976
>>> readout_error = []
>>> readout_error.append([0.9,0.75])
>>> readout_error.append([0.4,0.7])
>>> c.sample_expectation_ps(x=[0], y=[1],readout_error = readout_error)
>>> c = tc.Circuit(2)
>>> c.cnot(0, 1)
>>> c.rx(0, theta=0.4)
>>> c.rx(1, theta=0.8)
>>> c.h(0)
>>> c.h(1)
>>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
>>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2)
>>> readout_error = [[0.9, 0.75],[0.4, 0.7]]
>>> noise_conf = NoiseConf()
>>> noise_conf.add_noise("rx", error1)
>>> noise_conf.add_noise("cnot", [error2], [[0, 1]])
>>> noise_conf.add_noise("readout", readout_error)
>>> c.sample_expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000)
0.44766843
Parameters:
  • x (Optional[Sequence[int]], optional) – index for Pauli X, defaults to None

  • y (Optional[Sequence[int]], optional) – index for Pauli Y, defaults to None

  • z (Optional[Sequence[int]], optional) – index for Pauli Z, defaults to None

  • shots (Optional[int], optional) – number of measurement shots, defaults to None, indicating analytical result

  • random_generator (Optional[Any]) – random_generator, defaults to None

  • status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator

  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – readout_error, defaults to None. Overrided if noise_conf is provided.

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • nmc (int, optional) – repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000

  • statusc (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

[description]

Return type:

Tensor

sd(*index: int, **kws: Any) None

Apply SD gate on the circuit. See tensorcircuit.gates.sd_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.-1.j \end{bmatrix}\end{split}\]

sdg(*index: int, **kws: Any) None

Apply SD gate on the circuit. See tensorcircuit.gates.sd_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & 0.-1.j \end{bmatrix}\end{split}\]

select_gate(which: Any, kraus: Sequence[Gate], *index: int) None

Apply which-th gate from kraus list, i.e. apply kraus[which]

Parameters:
  • which (Tensor) – Tensor of shape [] and dtype int

  • kraus (Sequence[Gate]) – A list of gate in the form of tc.gate or Tensor

  • index (int) – the qubit lines the gate applied on

sexpps(x: Sequence[int] | None = None, y: Sequence[int] | None = None, z: Sequence[int] | None = None, shots: int | None = None, random_generator: Any | None = None, status: Any | None = None, readout_error: Sequence[Any] | None = None, noise_conf: Any | None = None, nmc: int = 1000, statusc: Any | None = None, **kws: Any) Any

Compute the expectation with given Pauli string with measurement shots numbers

Example:

>>> c = tc.Circuit(2)
>>> c.H(0)
>>> c.rx(1, theta=np.pi/2)
>>> c.sample_expectation_ps(x=[0], y=[1])
-0.99999976
>>> readout_error = []
>>> readout_error.append([0.9,0.75])
>>> readout_error.append([0.4,0.7])
>>> c.sample_expectation_ps(x=[0], y=[1],readout_error = readout_error)
>>> c = tc.Circuit(2)
>>> c.cnot(0, 1)
>>> c.rx(0, theta=0.4)
>>> c.rx(1, theta=0.8)
>>> c.h(0)
>>> c.h(1)
>>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
>>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2)
>>> readout_error = [[0.9, 0.75],[0.4, 0.7]]
>>> noise_conf = NoiseConf()
>>> noise_conf.add_noise("rx", error1)
>>> noise_conf.add_noise("cnot", [error2], [[0, 1]])
>>> noise_conf.add_noise("readout", readout_error)
>>> c.sample_expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000)
0.44766843
Parameters:
  • x (Optional[Sequence[int]], optional) – index for Pauli X, defaults to None

  • y (Optional[Sequence[int]], optional) – index for Pauli Y, defaults to None

  • z (Optional[Sequence[int]], optional) – index for Pauli Z, defaults to None

  • shots (Optional[int], optional) – number of measurement shots, defaults to None, indicating analytical result

  • random_generator (Optional[Any]) – random_generator, defaults to None

  • status (Optional[Tensor]) – external randomness given by tensor uniformly from [0, 1], if set, can overwrite random_generator

  • readout_error (Optional[Sequence[Any]]. Tensor, List, Tuple) – readout_error, defaults to None. Overrided if noise_conf is provided.

  • noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None

  • nmc (int, optional) – repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000

  • statusc (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling

Returns:

[description]

Return type:

Tensor

sgates = ['i', 'x', 'y', 'z', 'h', 't', 's', 'td', 'sd', 'wroot', 'cnot', 'cz', 'swap', 'cy', 'ox', 'oy', 'oz', 'toffoli', 'fredkin']
split: Dict[str, Any] | None
static standardize_gate(name: str) str

standardize the gate name to tc common gate sets

Parameters:

name (str) – non-standard gate name

Returns:

the standard gate name

Return type:

str

state(check: bool = False, reuse: bool = True) Any

Return the output density matrix of the circuit.

Parameters:
  • check (bool, optional) – check whether the final return is a legal density matrix, defaults to False

  • reuse (bool, optional) – whether to reuse previous results, defaults to True

Returns:

The output densitymatrix in 2D shape tensor form

Return type:

Tensor

su4(*index: int, **vars: Any) None

Apply SU4 gate with parameters on the circuit. See tensorcircuit.gates.su4_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

swap(*index: int, **kws: Any) None

Apply SWAP gate on the circuit. See tensorcircuit.gates.swap_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j \end{bmatrix}\end{split}\]

t(*index: int, **kws: Any) None

Apply T gate on the circuit. See tensorcircuit.gates.t_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677+0.70710677j \end{bmatrix}\end{split}\]

td(*index: int, **kws: Any) None

Apply TD gate on the circuit. See tensorcircuit.gates.td_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677-0.70710677j \end{bmatrix}\end{split}\]

tdg(*index: int, **kws: Any) None

Apply TD gate on the circuit. See tensorcircuit.gates.td_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1. & +0.j & 0. & +0.j\\ 0. & +0.j & 0.70710677-0.70710677j \end{bmatrix}\end{split}\]

tex(**kws: Any) str

Generate latex string based on quantikz latex package

Returns:

Latex string that can be directly compiled via, e.g. latexit

Return type:

str

thermalrelaxation(*index: int, **vars: float) None

Apply thermalrelaxation quantum channel on the circuit. See tensorcircuit.channels.thermalrelaxationchannel()

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the channel.

to_circuit(circuit_params: Dict[str, Any] | None = None) Circuit

convert into state simulator (current implementation ignores all noise channels)

Parameters:

circuit_params (Optional[Dict[str, Any]], optional) – kws to initialize circuit object, defaults to None

Returns:

Circuit with no noise

Return type:

Circuit

to_cirq(enable_instruction: bool = False) Any

Translate tc.Circuit to a cirq circuit object.

Parameters:

enable_instruction (bool, defaults to False) – whether also export measurement and reset instructions

Returns:

A cirq circuit of this circuit.

to_graphviz(graph: Graph | None = None, include_all_names: bool = False, engine: str = 'neato') Graph

Not an ideal visualization for quantum circuit, but reserve here as a general approach to show the tensornetwork [Deprecated, use Circuit.vis_tex or Circuit.draw instead]

to_json(file: str | None = None, simplified: bool = False) Any

circuit dumps to json

Parameters:
  • file (Optional[str], optional) – file str to dump the json to, defaults to None, return the json str

  • simplified (bool) – If False, keep all info for each gate, defaults to be False. If True, suitable for IO since less information is required

Returns:

None if dumps to file otherwise the json str

Return type:

Any

to_openqasm(**kws: Any) str

transform circuit to openqasm via qiskit circuit, see https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.qasm.html for usage on possible options for kws

Returns:

circuit representation in openqasm format

Return type:

str

to_openqasm_file(file: str, **kws: Any) None

save the circuit to openqasm file

Parameters:

file (str) – the file path to save the circuit

to_qir() List[Dict[str, Any]]

Return the quantum intermediate representation of the circuit.

Example:

>>> c = tc.Circuit(2)
>>> c.CNOT(0, 1)
>>> c.to_qir()
[{'gatef': cnot, 'gate': Gate(
    name: 'cnot',
    tensor:
        array([[[[1.+0.j, 0.+0.j],
                [0.+0.j, 0.+0.j]],

                [[0.+0.j, 1.+0.j],
                [0.+0.j, 0.+0.j]]],


            [[[0.+0.j, 0.+0.j],
                [0.+0.j, 1.+0.j]],

                [[0.+0.j, 0.+0.j],
                [1.+0.j, 0.+0.j]]]], dtype=complex64),
    edges: [
        Edge(Dangling Edge)[0],
        Edge(Dangling Edge)[1],
        Edge('cnot'[2] -> 'qb-1'[0] ),
        Edge('cnot'[3] -> 'qb-2'[0] )
    ]), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
Returns:

The quantum intermediate representation of the circuit.

Return type:

List[Dict[str, Any]]

to_qiskit(enable_instruction: bool = False, enable_inputs: bool = False) Any

Translate tc.Circuit to a qiskit QuantumCircuit object.

Parameters:
  • enable_instruction (bool, defaults to False) – whether also export measurement and reset instructions

  • enable_inputs (bool, defaults to False) – whether also export the inputs

Returns:

A qiskit object of this circuit.

toffoli(*index: int, **kws: Any) None

Apply TOFFOLI gate on the circuit. See tensorcircuit.gates.toffoli_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j & 0.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j\\ 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 0.+0.j & 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

u(*index: int, **vars: Any) None

Apply U gate with parameters on the circuit. See tensorcircuit.gates.u_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

unitary(*index: int, **vars: Any) None

Apply ANY gate with parameters on the circuit. See tensorcircuit.gates.any_gate().

Parameters:
  • index (int.) – Qubit number that the gate applies on.

  • vars (float.) – Parameters for the gate.

vgates = ['r', 'cr', 'u', 'cu', 'rx', 'ry', 'rz', 'phase', 'rxx', 'ryy', 'rzz', 'cphase', 'crx', 'cry', 'crz', 'orx', 'ory', 'orz', 'iswap', 'any', 'exp', 'exp1', 'su4']
vis_tex(**kws: Any) str

Generate latex string based on quantikz latex package

Returns:

Latex string that can be directly compiled via, e.g. latexit

Return type:

str

wavefunction() Any

get the wavefunction of outputs, raise error if the final state is not purified [Experimental: the phase factor is not fixed for different backend]

Returns:

wavefunction vector

Return type:

Tensor

wroot(*index: int, **kws: Any) None

Apply WROOT gate on the circuit. See tensorcircuit.gates.wroot_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.70710677+0.j & -0.5 & -0.5j\\ 0.5 & -0.5j & 0.70710677+0.j \end{bmatrix}\end{split}\]

x(*index: int, **kws: Any) None

Apply X gate on the circuit. See tensorcircuit.gates.x_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 1.+0.j\\ 1.+0.j & 0.+0.j \end{bmatrix}\end{split}\]

y(*index: int, **kws: Any) None

Apply Y gate on the circuit. See tensorcircuit.gates.y_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 0.+0.j & 0.-1.j\\ 0.+1.j & 0.+0.j \end{bmatrix}\end{split}\]

z(*index: int, **kws: Any) None

Apply Z gate on the circuit. See tensorcircuit.gates.z_gate().

Parameters:

index (int.) –

Qubit number that the gate applies on. The matrix for the gate is

\[\begin{split}\begin{bmatrix} 1.+0.j & 0.+0.j\\ 0.+0.j & -1.+0.j \end{bmatrix}\end{split}\]