tensorcircuit.mpscircuit

Quantum circuit: MPS state simulator

class tensorcircuit.mpscircuit.MPSCircuit(nqubits: int, center_position: int | None = None, tensors: Sequence[Any] | None = None, wavefunction: QuVector | Any | None = None, split: Dict[str, Any] | None = None, dim: int | None = None)[source]

Bases: AbstractCircuit

MPSCircuit class. Simple usage demo below.

mps = tc.MPSCircuit(3)
mps.H(1)
mps.CNOT(0, 1)
mps.rx(2, theta=tc.num_to_tensor(1.))
mps.expectation((tc.gates.z(), 2))
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.

classmethod MPO_to_gate(tensors: Sequence[Any]) Gate[source]

Convert MPO to 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, center_position: int | None = None, tensors: Sequence[Any] | None = None, wavefunction: QuVector | Any | None = None, split: Dict[str, Any] | None = None, dim: int | None = None) None[source]

MPSCircuit object based on state simulator. Do not use this class with d!=2 directly

Parameters:
  • nqubits (int) – The number of qubits in the circuit.

  • dim (If None, the dimension of the circuit will be 2, which is a qubit system.) – The local Hilbert space dimension per site. Qudit is supported for 2 <= d <= 36.

  • center_position (int, optional) – The center position of MPS, default to 0

  • tensors (Sequence[Tensor], optional) – If not None, the initial state of the circuit is taken as tensors instead of \(\vert 0\rangle^n\) qubits, defaults to None. When tensors are specified, if center_position is None, then the tensors are canonicalized, otherwise it is assumed the tensors are already canonicalized at the center_position

  • wavefunction (Tensor) – If not None, it is transformed to the MPS form according to the split rules

  • inputs (Tensor) – alias for the argument wavefunction

  • split (Any) – Split rules

amplitude(l: str) Any[source]
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

Apply a general qubit gate on MPS.

Parameters:
  • gate (Gate) – The Gate to be applied

  • index (int) – Qubit indices of the gate

Raises:

ValueError – “MPS does not support application of gate on > 2 qubits.”

apply_MPO(tensors: Sequence[Any], index_left: int, center_left: bool = True, split: Dict[str, Any] | None = None) None[source]

Apply a Matrix Product Operator (MPO) to the MPS.

The application involves three main steps: 1. Contract the MPO tensors with the corresponding MPS tensors. 2. Canonicalize the resulting tensors by moving the orthogonality center. 3. Truncate the bond dimensions to control complexity.

Parameters:
  • tensors (Sequence[Tensor]) – A sequence of tensors representing the MPO.

  • index_left (int) – The starting index on the MPS where the MPO is applied.

  • center_left (bool, optional) – If True, the final orthogonality center will be at the left end of the MPO. Otherwise, it will be at the right end. Defaults to True.

  • split (Optional[Dict[str, Any]], optional) – Truncation options for bond dimension reduction. Defaults to None.

apply_adjacent_double_gate(gate: Gate, index1: int, index2: int, center_position: int | None = None, split: Dict[str, Any] | None = None) None[source]

Apply a double qubit gate on adjacent qubits of Matrix Product States (MPS).

Parameters:
  • gate (Gate) – The Gate to be applied

  • index1 (int) – The first qubit index of the gate

  • index2 (int) – The second qubit index of the gate

  • center_position (Optional[int]) – Center position of MPS, default is None

apply_double_gate(gate: Gate, index1: int, index2: int, split: Dict[str, Any] | None = None) None[source]

Apply a double qubit gate on MPS.

Parameters:
  • gate (Gate) – The Gate to be applied

  • index1 (int) – The first qubit index of the gate

  • index2 (int) – The second qubit index of the gate

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

Apply a general qubit gate on MPS.

Parameters:
  • gate (Gate) – The Gate to be applied

  • index (int) – Qubit indices of the gate

Raises:

ValueError – “MPS does not support application of gate on > 2 qubits.”

static apply_general_gate_delayed(gatef: Callable[[], Gate], name: str | None = None, mpo: bool = False) Callable[[...], None]
static apply_general_variable_gate_delayed(gatef: Callable[[...], Any], name: str | None = None, mpo: bool = False, diagonal: bool = False) Callable[[...], None]
apply_nqubit_gate(gate: Gate, *index: int, split: Dict[str, Any] | None = None) None[source]

Apply an n-qubit gate to the MPS by converting it to an MPO.

Parameters:
  • gate (Gate) – The n-qubit gate to apply.

  • index (int) – The indices of the qubits to apply the gate to.

  • split (Optional[Dict[str, Any]], optional) – Truncation options for the MPO application. Defaults to None.

apply_single_gate(gate: Gate, index: int) None[source]

Apply a single qubit gate on MPS; no truncation is needed.

Parameters:
  • gate (Gate) – gate to be applied

  • index (int) – Qubit index of the gate

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}\]

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}\]

cond_measure(index: int) 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 qubit for the z-basis measurement

Returns:

0 or 1 for z measurement on up and down freedom

Return type:

Tensor

cond_measurement(index: int) 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 qubit for the z-basis measurement

Returns:

0 or 1 for z measurement on up and down freedom

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

conj() MPSCircuit[source]

Compute the conjugate of the current MPS.

Returns:

The constructed MPS

Return type:

MPSCircuit

consecutive_swap(index_from: int, index_to: int, split: Dict[str, Any] | None = None) None[source]

Apply a series of SWAP gates to move a qubit from index_from to index_to.

Parameters:
  • index_from (int) – The starting index of the qubit.

  • index_to (int) – The destination index of the qubit.

  • split (Optional[Dict[str, Any]], optional) – Truncation options for the SWAP gates. Defaults to None. consistent with the split option of the class.

copy() MPSCircuit[source]

Copy the current MPS.

Returns:

The constructed MPS

Return type:

MPSCircuit

copy_without_tensor() MPSCircuit[source]

Copy the current MPS without the tensors.

Returns:

The constructed MPS

Return type:

MPSCircuit

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}\]

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[Gate, List[int]], reuse: bool = True, other: MPSCircuit | None = None, conj: bool = True, normalize: bool = False, split: Dict[str, Any] | None = None, **kws: Any) Any[source]

Compute the expectation of corresponding operators in the form of tensor.

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

  • reuse (bool, optional) – If True, then the wavefunction tensor is cached for further expectation evaluation, defaults to be true.

  • other (MPSCircuit, optional) – If not None, will be used as bra

  • conj (bool, defaults to be True) – Whether to conjugate the bra state

  • normalize (bool, defaults to be True) – Whether to normalize the MPS

  • split (Any) – Truncation split

Returns:

The expectation of corresponding operators

Return type:

Tensor

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

classmethod gate_to_MPO(gate: Gate | Any, *index: int) Tuple[Sequence[Any], int][source]

Convert gate to MPO form with identities at empty sites

get_bond_dimensions() Any[source]

Get the MPS bond dimensions

Returns:

MPS tensors

Return type:

Tensor

get_center_position() int | None[source]

Get the center position of the MPS

Returns:

center position

Return type:

Optional[int]

get_norm() Any[source]

Get the normalized Center Position.

Returns:

Normalized Center Position.

Return type:

Tensor

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[source]
Get the representation of the output state in the form of QuVector

has to be full contracted in MPS

Returns:

QuVector representation of the output state from the circuit

Return type:

QuVector

get_tensors() List[Any][source]

Get the MPS tensors

Returns:

MPS tensors

Return type:

List[Tensor]

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_mps: bool = True
is_valid() bool[source]

Check whether the circuit is legal.

Returns:

Whether the circuit is legal.

Return type:

bool

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

Take measurement to the given quantum lines.

Parameters:
  • index (int) – Measure on which quantum line.

  • 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

mid_measurement(index: int, keep: int = 0) None[source]

Middle measurement in the z-basis on the circuit, note the wavefunction output is not normalized with mid_measurement involved, one should normalized the state manually if needed.

Parameters:
  • index (int) – The index of qubit that the Z direction postselection applied on

  • keep (int, optional) – 0 for spin up, 1 for spin down, defaults to 0

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.

normalize() None[source]

Normalize MPS Circuit according to the center position.

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.

position(site: int) None[source]

Wrapper of tn.FiniteMPS.position. Set orthogonality center.

Parameters:

site (int) – The orthogonality center

prepend(c: AbstractCircuit) AbstractCircuit

prepend circuit c before

Parameters:

c (BaseCircuit) – The other circuit to be prepended

Returns:

The composed circuit

Return type:

BaseCircuit

proj_with_mps(other: MPSCircuit, conj: bool = True) Any[source]

Compute the projection between other as bra and self as ket.

Parameters:

other (MPSCircuit) – ket of the other MPS, which will be converted to bra automatically

Returns:

The projection in form of tensor

Return type:

Tensor

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.

reduce_dimension(index_left: int, center_left: bool = True, split: Dict[str, Any] | None = None) None[source]

Reduce the bond dimension between two adjacent sites using SVD.

Parameters:
  • index_left (int) – The index of the left tensor of the bond to be truncated.

  • center_left (bool, optional) – If True, the orthogonality center will be on the left tensor after truncation. Otherwise, it will be on the right tensor. Defaults to True.

  • split (Optional[Dict[str, Any]], optional) – Truncation options for the SVD. Defaults to None.

classmethod reduce_tensor_dimension(tensor_left: Any, tensor_right: Any, center_left: bool = True, split: Dict[str, Any] | None = None) Tuple[Any, Any][source]

Reduce the bond dimension between two general tensors by SVD

reduced_density_matrix(subsystem_to_keep: Sequence[int]) Any[source]

Compute the reduced density matrix for the specified qubits.

The output density matrix indices follow the order given by subsystem_to_keep, so passing [3, 1] yields a different index ordering from [1, 3].

Parameters:

subsystem_to_keep (Sequence[int]) – The qubits to keep (all others are traced out).

Returns:

The reduced density matrix.

Return type:

Tensor

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

set_split_rules(split: Dict[str, Any]) None[source]

Set truncation split when double qubit gates are applied. If nothing is specified, no truncation will take place and the bond dimension will keep growing. For more details, refer to split_tensor.

Parameters:

split (Any) – Truncation split

sgates = ['i', 'x', 'y', 'z', 'h', 't', 's', 'td', 'sd', 'wroot', 'cnot', 'cz', 'swap', 'cy', 'ox', 'oy', 'oz', 'toffoli', 'fredkin']
slice(begin: int, end: int) MPSCircuit[source]

Get a slice of the MPS (only for internal use)

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(form: str = 'default') Any

Compute the output wavefunction from the circuit.

Parameters:

form (str, optional) – the str indicating the form of the output wavefunction

Returns:

Tensor with shape [1, -1]

Return type:

Tensor a b ab | | ||

i–A–B–j -> i–XX–j

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

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_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(form: str = 'default') Any[source]

Compute the output wavefunction from the circuit.

Parameters:

form (str, optional) – the str indicating the form of the output wavefunction

Returns:

Tensor with shape [1, -1]

Return type:

Tensor a b ab | | ||

i–A–B–j -> i–XX–j

classmethod wavefunction_to_tensors(wavefunction: Any, dim_phys: int | None = None, norm: bool = True, split: Dict[str, Any] | None = None) List[Any][source]

Construct the MPS tensors from a given wavefunction.

Parameters:
  • wavefunction (Tensor) – The given wavefunction (any shape is OK)

  • split (Dict) – Truncation split

  • dim_phys (int) – Physical dimension, 2 for MPS and 4 for MPO

  • norm (bool) – Whether to normalize the wavefunction

Returns:

The tensors

Return type:

List[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}\]

tensorcircuit.mpscircuit.split_tensor(tensor: Any, center_left: bool = True, split: Dict[str, Any] | None = None) Tuple[Any, Any][source]

Split the tensor by SVD or QR depends on whether a truncation is required.

Parameters:
  • tensor (Tensor) – The input tensor to split.

  • center_left (bool, optional) – Determine the orthogonal center is on the left tensor or the right tensor.

Returns:

Two tensors after splitting

Return type:

Tuple[Tensor, Tensor]