tensorcircuit.quditcircuitΒΆ

Quantum circuit: state simulator for qudits (d-level systems).

This module provides a high-level QuditCircuit API that mirrors tensorcircuit.circuit.Circuit but targets qudits with dimension 3 <= d <= 36. For string-encoded samples/counts, digits use 0-9A-Z where A=10, …, Z=35.

Note

For qubits (d=2) please use tensorcircuit.circuit.Circuit.

class tensorcircuit.quditcircuit.QuditCircuit(nqudits: int, dim: int, inputs: Any | None = None, mps_inputs: QuOperator | None = None, split: Dict[str, Any] | None = None)[source]ΒΆ

Bases: object

The QuditCircuit class provides a d-dimensional state-vector simulator and a thin wrapper around tensorcircuit.circuit.Circuit, exposing a qudit-friendly API and docstrings.

Quick example (d=3):

>>> c = tc.QuditCircuit(2, dim=3)
>>> c.h(0)
>>> c.x(1)
>>> c.csum(0, 1)
>>> c.sample(1024, format="count_dict_bin")

Note

For 3 <= d <= 36, string samples and count keys use base-d characters 0-9A-Z (A=10, …, Z=35).

Parameters:
  • nqudits (int) – Number of qudits (wires) in the circuit.

  • dim (int) – Qudit local dimension d. Must satisfy 3 <= d <= 36.

  • inputs (Optional[Tensor]) – Optional initial state as a wavefunction.

  • mps_inputs (Optional[QuOperator]) – Optional initial state in MPS/MPO-like form.

  • split (Optional[Dict[str, Any]]) – Internal contraction/splitting configuration passed through to Circuit.

Variables:
  • is_dm (bool) – Whether the simulator is a density-matrix simulator (False here).

  • dim (int) – Property for the local dimension d.

  • nqudits (int) – Property for the number of qudits.

CNOT(*indices: int, cv: int | None = None) NoneΒΆ

Apply a generalized controlled-sum gate CSUM (a.k.a. qudit CNOT).

Parameters:
  • indices (int) – Two qudit indices (control, target).

  • cv (Optional[int]) – Optional control value. If None, defaults to 1.

Raises:

ValueError – If arity is not two.

CPHASE(*indices: int, cv: int | None = None) NoneΒΆ

Apply a controlled-phase gate CPHASE.

Parameters:
  • indices (int) – Two qudit indices (control, target).

  • cv (Optional[int]) – Optional control value. If None, defaults to 1.

Raises:

ValueError – If arity is not two.

CSUM(*indices: int, cv: int | None = None) NoneΒΆ

Apply a generalized controlled-sum gate CSUM (a.k.a. qudit CNOT).

Parameters:
  • indices (int) – Two qudit indices (control, target).

  • cv (Optional[int]) – Optional control value. If None, defaults to 1.

Raises:

ValueError – If arity is not two.

H(index: int) NoneΒΆ

Apply the generalized Hadamard-like gate H (DFT on d levels) on the given qudit.

Parameters:

index (int) – Qudit index.

I(index: int) NoneΒΆ

Apply the generalized identity gate I on the given qudit.

Parameters:

index (int) – Qudit index.

RX(index: int, theta: float, j: int = 0, k: int = 1) NoneΒΆ

Single-qudit rotation RX on a selected two-level subspace (j, k).

Parameters:
  • index (int) – Qudit index.

  • theta (float) – Rotation angle.

  • j (int) – Source level of the rotation subspace (0-based).

  • k (int) – Target level of the rotation subspace (0-based).

Raises:

ValueError – If j == k or indices are outside [0, d-1].

RXX(*indices: int, theta: float, j1: int = 0, k1: int = 1, j2: int = 0, k2: int = 1) NoneΒΆ

Two-qudit interaction RXX acting on subspaces (j1, k1) and (j2, k2).

Parameters:
  • indices (int) – Two qudit indices (q1, q2).

  • theta (float) – Interaction angle.

  • j1 (int) – Source level of the first qudit subspace.

  • k1 (int) – Target level of the first qudit subspace.

  • j2 (int) – Source level of the second qudit subspace.

  • k2 (int) – Target level of the second qudit subspace.

Raises:

ValueError – If levels are invalid or the arity is not two.

RY(index: int, theta: float, j: int = 0, k: int = 1) NoneΒΆ

Single-qudit rotation RY on a selected two-level subspace (j, k).

Parameters:
  • index (int) – Qudit index.

  • theta (float) – Rotation angle.

  • j (int) – Source level of the rotation subspace (0-based).

  • k (int) – Target level of the rotation subspace (0-based).

Raises:

ValueError – If j == k or indices are outside [0, d-1].

RZ(index: int, theta: float, j: int = 0) NoneΒΆ

Single-qudit phase rotation RZ applied on level j.

Parameters:
  • index (int) – Qudit index.

  • theta (float) – Phase rotation angle around Z.

  • j (int) – Level where the phase is applied (0-based).

Raises:

ValueError – If j is outside [0, d-1].

RZZ(*indices: int, theta: float, j1: int = 0, k1: int = 1, j2: int = 0, k2: int = 1) NoneΒΆ

Two-qudit interaction RZZ acting on subspaces (j1, k1) and (j2, k2).

Parameters:
  • indices (int) – Two qudit indices (q1, q2).

  • theta (float) – Interaction angle.

  • j1 (int) – Source level of the first qudit subspace.

  • k1 (int) – Target level of the first qudit subspace.

  • j2 (int) – Source level of the second qudit subspace.

  • k2 (int) – Target level of the second qudit subspace.

Raises:

ValueError – If levels are invalid or the arity is not two.

U8(index: int, gamma: float = 2.0, z: float = 1.0, eps: float = 0.0) NoneΒΆ

Apply the parameterized single-qudit gate U8.

Parameters:
  • index (int) – Qudit index.

  • gamma (float) – Gate parameter gamma.

  • z (float) – Gate parameter z.

  • eps (float) – Gate parameter eps.

X(index: int) NoneΒΆ

Apply the generalized shift gate X on the given qudit (adds +1 mod d).

Parameters:

index (int) – Qudit index.

Z(index: int) NoneΒΆ

Apply the generalized phase gate Z on the given qudit (multiplies by omega^k).

Parameters:

index (int) – Qudit index.

__init__(nqudits: int, dim: int, inputs: Any | None = None, mps_inputs: QuOperator | None = None, split: Dict[str, Any] | None = None)[source]ΒΆ
amplitude(l: str | Any) Any[source]ΒΆ

Return the amplitude for a given base-d string l.

For state simulators, this computes \(\langle l \vert \psi \rangle\). For density-matrix simulators, it would compute \(\operatorname{Tr}(\rho \vert l \rangle \langle l \vert)\) (note the square in magnitude differs between the two formalisms).

Example

>>> c = tc.QuditCircuit(2, dim=3)
>>> c.x(0)
>>> c.x(1)
>>> c.amplitude("20")
array(1.+0.j, dtype=complex64)
>>> c.csum(0, 1, cv=2)
>>> c.amplitude("21")
array(1.+0.j, dtype=complex64)
Parameters:

l (Union[str, Tensor]) – Bitstring in base-d using 0-9A-Z.

Returns:

Complex amplitude.

Return type:

Tensor

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

Return the (uncontracted) tensor network nodes for the amplitude of configuration l.

For state simulators, this corresponds to \(\langle l \vert \psi \rangle\). For density-matrix simulators, it would correspond to \(\operatorname{Tr}(\rho \vert l \rangle \langle l \vert)\).

Parameters:

l (Union[str, Tensor]) – Base-d string using 0-9A-Z or an equivalent tensor index.

Returns:

The tensornetwork nodes for the amplitude of the circuit.

Return type:

List[Gate]

any(*indices: int, unitary: Any, name: str | None = None) None[source]ΒΆ

Apply an arbitrary unitary on one or two qudits.

Parameters:
  • indices (int) – Target qudit indices.

  • unitary (Tensor) – Unitary matrix acting on the specified qudit(s), with shape (d, d) or (d^2, d^2).

  • name (str) – Optional label stored in the circuit history.

append(c: Any, indices: List[int] | None = None) QuditCircuit[source]ΒΆ
cnot(*indices: int, cv: int | None = None) NoneΒΆ

Apply a generalized controlled-sum gate CSUM (a.k.a. qudit CNOT).

Parameters:
  • indices (int) – Two qudit indices (control, target).

  • cv (Optional[int]) – Optional control value. If None, defaults to 1.

Raises:

ValueError – If arity is not two.

cphase(*indices: int, cv: int | None = None) None[source]ΒΆ

Apply a controlled-phase gate CPHASE.

Parameters:
  • indices (int) – Two qudit indices (control, target).

  • cv (Optional[int]) – Optional control value. If None, defaults to 1.

Raises:

ValueError – If arity is not two.

csum(*indices: int, cv: int | None = None) None[source]ΒΆ

Apply a generalized controlled-sum gate CSUM (a.k.a. qudit CNOT).

Parameters:
  • indices (int) – Two qudit indices (control, target).

  • cv (Optional[int]) – Optional control value. If None, defaults to 1.

Raises:

ValueError – If arity is not two.

property dim: intΒΆ

dimension of the qudit circuit

expectation(*ops: Tuple[Node, List[int]], reuse: bool = True, enable_lightcone: bool = False, nmc: int = 1000, **kws: Any) Any[source]ΒΆ

Compute expectation(s) of local operators.

Parameters:
  • ops (Tuple[tn.Node, List[int]]) – Pairs of (operator_node, [sites]) specifying where each operator acts.

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

  • enable_lightcone (bool, optional) – whether enable light cone simplification, defaults to False

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

Raises:

ValueError – β€œCannot measure two operators in one index”

Returns:

Tensor with one element

Return type:

Tensor

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

Build (but do not contract) the tensor network for expectation evaluation.

Parameters:

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

Raises:

ValueError – _description_

Returns:

_description_

Return type:

List[tn.Node]

expectation_ps(**kwargs: Any) Any[source]ΒΆ
general_kraus(kraus: Sequence[Gate], *index: int, status: float | None = None, with_prob: bool = False, name: str | None = None) Any[source]ΒΆ

Monte Carlo trajectory simulation of general Kraus channel whose Kraus operators cannot be amplified to unitary operators. For unitary operators composed Kraus channel, unitary_kraus() is much faster.

This function is jittable in theory. But only jax+GPU combination is recommended for jit since the graph building time is too long for other backend options; though the running time of the function is very fast for every case.

Parameters:
  • kraus (Sequence[Gate]) – A list of tn.Node for Kraus operators.

  • index (int) – The qubits index that Kraus channel is applied on.

  • status (Optional[float], optional) – Random tensor uniformly between 0 or 1, defaults to be None, when the random number will be generated automatically

get_circuit_as_quoperator() QuOperatorΒΆ

Get the QuOperator MPO like representation of the circuit unitary without contraction.

Returns:

QuOperator object for the circuit unitary (open indices for the input state)

Return type:

QuOperator

get_quoperator() QuOperator[source]ΒΆ

Get the QuOperator MPO like representation of the circuit unitary without contraction.

Returns:

QuOperator object for the circuit unitary (open indices for the input state)

Return type:

QuOperator

get_quvector() QuVector[source]ΒΆ

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

h(index: int) None[source]ΒΆ

Apply the generalized Hadamard-like gate H (DFT on d levels) on the given qudit.

Parameters:

index (int) – Qudit index.

i(index: int) None[source]ΒΆ

Apply the generalized identity gate I on the given qudit.

Parameters:

index (int) – Qudit index.

inverse() QuditCircuit[source]ΒΆ
is_dm = FalseΒΆ
matrix() Any[source]ΒΆ

Get the unitary matrix for the circuit irrespective with the circuit input state.

Returns:

The circuit unitary matrix

Return type:

Tensor

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!

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_jit(*index: int, with_prob: bool = False, status: Any | None = None) Tuple[Any, Any][source]ΒΆ

Take measurement on the given site indices (computational basis). This method is jittable!

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]

mid_measure(index: int, keep: int = 0) AnyΒΆ

Mid-circuit Z-basis post-selection.

The returned state is not normalized; normalize manually if needed.

Parameters:
  • index (int) – Qudit index where post-selection is applied.

  • keep (int) – Post-selected digit in {0, …, d-1}.

Returns:

Unnormalized post-selected state.

Return type:

Tensor

mid_measurement(index: int, keep: int = 0) Any[source]ΒΆ

Mid-circuit Z-basis post-selection.

The returned state is not normalized; normalize manually if needed.

Parameters:
  • index (int) – Qudit index where post-selection is applied.

  • keep (int) – Post-selected digit in {0, …, d-1}.

Returns:

Unnormalized post-selected state.

Return type:

Tensor

property nqudits: intΒΆ

qudit number of the circuit

post_select(index: int, keep: int = 0) AnyΒΆ

Mid-circuit Z-basis post-selection.

The returned state is not normalized; normalize manually if needed.

Parameters:
  • index (int) – Qudit index where post-selection is applied.

  • keep (int) – Post-selected digit in {0, …, d-1}.

Returns:

Unnormalized post-selected state.

Return type:

Tensor

post_selection(index: int, keep: int = 0) AnyΒΆ

Mid-circuit Z-basis post-selection.

The returned state is not normalized; normalize manually if needed.

Parameters:
  • index (int) – Qudit index where post-selection is applied.

  • keep (int) – Post-selected digit in {0, …, d-1}.

Returns:

Unnormalized post-selected state.

Return type:

Tensor

probability() Any[source]ΒΆ

Get the length-d^n probability vector over the computational basis.

Returns:

Probability vector of shape [dim^n].

Return type:

Tensor

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

remaining wavefunction or density matrix on sites in left, while fixing the other sites to given digits as indicated by traceout.

Parameters:
  • traceout (Tensor) – A tensor encoding digits (0..d-1) for sites to be fixed; jittable.

  • left (Tuple[int, ...]) – Tuple of site indices to keep (non-jittable argument).

Returns:

Remaining wavefunction or density matrix on the kept sites.

Return type:

Tensor

quoperator() QuOperatorΒΆ

Get the QuOperator MPO like representation of the circuit unitary without contraction.

Returns:

QuOperator object for the circuit unitary (open indices for the input state)

Return type:

QuOperator

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

replace_inputs(inputs: Any) None[source]ΒΆ

Replace the input state with the circuit structure unchanged.

Parameters:

inputs (Tensor) – Input wavefunction.

replace_mps_inputs(mps_inputs: QuOperator) None[source]ΒΆ

Replace the input state (keeps circuit structure) using an MPS/MPO-like representation.

Example

>>> c = tc.QuditCircuit(2, dim=3)
>>> c.x(0)
>>> c2 = tc.QuditCircuit(2, dim=3, mps_inputs=c.quvector())
>>> c2.x(0); c2.wavefunction()
array([...], dtype=complex64)
>>> c3 = tc.QuditCircuit(2, dim=3)
>>> c3.x(0)
>>> c3.replace_mps_inputs(c.quvector()); c3.wavefunction()
array([...], dtype=complex64)
Parameters:

mps_inputs (Tuple[Sequence[Gate], Sequence[Edge]]) – (Nodes, dangling Edges) for a MPS like initial wavefunction.

rx(index: int, theta: float, j: int = 0, k: int = 1) None[source]ΒΆ

Single-qudit rotation RX on a selected two-level subspace (j, k).

Parameters:
  • index (int) – Qudit index.

  • theta (float) – Rotation angle.

  • j (int) – Source level of the rotation subspace (0-based).

  • k (int) – Target level of the rotation subspace (0-based).

Raises:

ValueError – If j == k or indices are outside [0, d-1].

rxx(*indices: int, theta: float, j1: int = 0, k1: int = 1, j2: int = 0, k2: int = 1) None[source]ΒΆ

Two-qudit interaction RXX acting on subspaces (j1, k1) and (j2, k2).

Parameters:
  • indices (int) – Two qudit indices (q1, q2).

  • theta (float) – Interaction angle.

  • j1 (int) – Source level of the first qudit subspace.

  • k1 (int) – Target level of the first qudit subspace.

  • j2 (int) – Source level of the second qudit subspace.

  • k2 (int) – Target level of the second qudit subspace.

Raises:

ValueError – If levels are invalid or the arity is not two.

ry(index: int, theta: float, j: int = 0, k: int = 1) None[source]ΒΆ

Single-qudit rotation RY on a selected two-level subspace (j, k).

Parameters:
  • index (int) – Qudit index.

  • theta (float) – Rotation angle.

  • j (int) – Source level of the rotation subspace (0-based).

  • k (int) – Target level of the rotation subspace (0-based).

Raises:

ValueError – If j == k or indices are outside [0, d-1].

rz(index: int, theta: float, j: int = 0) None[source]ΒΆ

Single-qudit phase rotation RZ applied on level j.

Parameters:
  • index (int) – Qudit index.

  • theta (float) – Phase rotation angle around Z.

  • j (int) – Level where the phase is applied (0-based).

Raises:

ValueError – If j is outside [0, d-1].

rzz(*indices: int, theta: float, j1: int = 0, k1: int = 1, j2: int = 0, k2: int = 1) None[source]ΒΆ

Two-qudit interaction RZZ acting on subspaces (j1, k1) and (j2, k2).

Parameters:
  • indices (int) – Two qudit indices (q1, q2).

  • theta (float) – Interaction angle.

  • j1 (int) – Source level of the first qudit subspace.

  • k1 (int) – Target level of the first qudit subspace.

  • j2 (int) – Source level of the second qudit subspace.

  • k2 (int) – Target level of the second qudit subspace.

Raises:

ValueError – If levels are invalid or the arity is not two.

sample(batch: int | None = None, allow_state: bool = False, readout_error: Sequence[Any] | None = None, format: Literal['sample_bin', 'count_dict_bin'] | None = None, random_generator: Any | None = None, status: Any | None = None, jittable: bool = True) Any[source]ΒΆ

Batched sampling from the circuit or final state.

Parameters:
  • batch (Optional[int]) – Number of samples. If None, returns a single draw.

  • allow_state (bool) – If True, sample from the final state (when memory allows). Prefer True for speed.

  • readout_error (Optional[Sequence[Any]]) – Optional readout error model.

  • format (Optional[str]) –

    Output format. See tensorcircuit.quantum.measurement_results().

    Supported formats for qudits include:

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

    ”count_dict_bin”: # {β€œ00”: 2, β€œ01”: 0, β€œ10”: 0, β€œ11”: 0}

    for cases \(d\in [11, 36]\), use 0-9A-Z digits (e.g., β€˜A’ -> 10, …, β€˜Z’ -> 35);

  • 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, nqudits] 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

Raises:

NotImplementedError – For integer-based output formats not suitable for qudits.

state(form: str = 'default') <property object at 0x7d0ef6fdda80>ΒΆ

Compute the output wavefunction from the circuit.

Parameters:

form (str, optional) – The str indicating the form of the output wavefunction. β€œdefault”: [-1], β€œket”: [-1, 1], β€œbra”: [1, -1]

Returns:

Tensor with the corresponding shape.

Return type:

Tensor

u8(index: int, gamma: float = 2.0, z: float = 1.0, eps: float = 0.0) None[source]ΒΆ

Apply the parameterized single-qudit gate U8.

Parameters:
  • index (int) – Qudit index.

  • gamma (float) – Gate parameter gamma.

  • z (float) – Gate parameter z.

  • eps (float) – Gate parameter eps.

unitary(*indices: int, unitary: Any, name: str | None = None) NoneΒΆ

Apply an arbitrary unitary on one or two qudits.

Parameters:
  • indices (int) – Target qudit indices.

  • unitary (Tensor) – Unitary matrix acting on the specified qudit(s), with shape (d, d) or (d^2, d^2).

  • name (str) – Optional label stored in the circuit history.

unitary_kraus(kraus: Sequence[Gate], *index: int, prob: Sequence[float] | None = None, status: float | None = None, name: str | None = None) Any[source]ΒΆ

Apply unitary gates in kraus randomly based on corresponding prob. If prob is None, this is reduced to kraus channel language.

Parameters:
  • kraus (Sequence[Gate]) – List of tc.gates.Gate or just Tensors

  • prob (Optional[Sequence[float]], optional) – prob list with the same size as kraus, defaults to None

  • status (Optional[float], optional) – random seed between 0 to 1, defaults to None

Returns:

shape [] int dtype tensor indicates which kraus gate is actually applied

Return type:

Tensor

wavefunction(form: str = 'default') <property object at 0x7d0ef6fdda80>[source]ΒΆ

Compute the output wavefunction from the circuit.

Parameters:

form (str, optional) – The str indicating the form of the output wavefunction. β€œdefault”: [-1], β€œket”: [-1, 1], β€œbra”: [1, -1]

Returns:

Tensor with the corresponding shape.

Return type:

Tensor

x(index: int) None[source]ΒΆ

Apply the generalized shift gate X on the given qudit (adds +1 mod d).

Parameters:

index (int) – Qudit index.

z(index: int) None[source]ΒΆ

Apply the generalized phase gate Z on the given qudit (multiplies by omega^k).

Parameters:

index (int) – Qudit index.