graphix.sim.tensornet module

Tensor Network Simulator for MBQC.

class MBQCTensorNet(branch_selector: BranchSelector, graph_nodes: Iterable[int] | None = None, graph_edges: Iterable[tuple[int, int]] | None = None, default_output_nodes: Iterable[int] | None = None, ts: list[TensorNetwork] | TensorNetwork | None = None, virtual: bool = False)[source]

Bases: TensorNetwork

Tensor Network Simulator interface for MBQC patterns, using quimb.tensor.core.TensorNetwork.

__init__(branch_selector: BranchSelector, graph_nodes: Iterable[int] | None = None, graph_edges: Iterable[tuple[int, int]] | None = None, default_output_nodes: Iterable[int] | None = None, ts: list[TensorNetwork] | TensorNetwork | None = None, virtual: bool = False) → None[source]

Initialize MBQCTensorNet.

Parameters:
  • (optional) (ts) – node indices of the graph state.

  • (optional) – edge indices of the graph state.

  • default_output_nodes (list of int) – output node indices at the end of MBQC operations, if known in advance.

  • (optional) – optional initial state.

open_tensor(index: int | str) → NDArray[complex128][source]

Get tensor specified by node index. The tensor has a dangling edge.

Parameters:

index (str) – node index

Returns:

Specified tensor

Return type:

numpy.ndarray

add_qubit(index: int, state: str | NDArray[complex128] = 'plus') → None[source]

Add a single qubit to the network.

Parameters:
  • index (int) – index of the new qubit.

  • (optional) (state) – initial state of the new qubit. “plus”, “minus”, “zero”, “one”, “iplus”, “iminus”, or 1*2 np.ndarray (arbitrary state).

evolve_single(index: int, arr: NDArray[complex128], label: str = 'U') → None[source]

Apply single-qubit operator to a qubit with the given index.

Parameters:
  • index (int) – qubit index.

  • arr (2*2 numpy.ndarray) – single-qubit operator.

  • (optional) (label) – label for the gate.

add_qubits(indices: Sequence[int], states: PrepareState | Iterable[PrepareState] = 'plus') → None[source]

Add qubits to the network.

Parameters:
  • indices (iterator of int) – indices of the new qubits.

  • (optional) (states) – initial state or list of initial states of the new qubits.

measure_single(index: int, basis: str | npt.NDArray[np.complex128] = 'Z', bypass_probability_calculation: bool = True, outcome: Outcome | None = None, rng: Generator | None = None, *, stacklevel: int = 1) → Outcome[source]

Measure a node in specified basis. Note this does not perform the partial trace.

Parameters:
  • index (int) – index of the node to be measured.

  • basis (str or np.ndarray) – default “Z”. measurement basis, “Z” or “X” or “Y” for Pauli basis measurements. 1*2 numpy.ndarray for arbitrary measurement bases.

  • bypass_probability_calculation (bool) – default True. if True, skip the calculation of the probability of the measurement result and use equal probability for each result. if False, calculate the probability of the measurement result from the state.

  • outcome (int (0 or 1)) – User-chosen measurement result, giving the outcome of (-1)^{outcome}.

Returns:

measurement result.

Return type:

int

prepare_graph_state(nodes: Iterable[int], edges: Iterable[tuple[int, int]]) → None[source]

Prepare the graph state without directly applying CZ gates.

Parameters:
  • nodes (iterator of int) – set of the nodes

  • edges (iterator of tuple) – set of the edges

  • seealso: (..) – __init__():

basis_coefficient(basis: int | str, normalize: bool = True, indices: Sequence[int] | None = None) → complex[source]

Calculate the coefficient of a given computational basis.

Parameters:
  • basis (int or str) – computational basis expressed in binary (str) or integer, e.g. 101 or 5.

  • (optional) (indices) – if True, normalize the coefficient by the norm of the entire state.

  • (optional) – target qubit indices to compute the coefficients, default is the MBQC output nodes (self.default_output_nodes).

Returns:

coef – coefficient

Return type:

complex

basis_amplitude(basis: str | int) → float[source]

Calculate the probability amplitude of the specified computational basis state.

Parameters:

basis (int or str) – computational basis expressed in binary (str) or integer, e.g. 101 or 5.

Returns:

the probability amplitude of the specified state.

Return type:

float

to_statevector(indices: Sequence[int] | None = None) → npt.NDArray[np.complex128][source]

Retrieve the statevector from the tensornetwork.

This method tends to be slow however we plan to parallelize this.

Parameters:

(optional) (indices) – target qubit indices. Default is the MBQC output nodes (self.default_output_nodes).

Returns:

statevector

Return type:

numpy.ndarray

flatten() → NDArray[complex128][source]

Return flattened statevector.

norm(optimize: str | PathOptimizer | None = None) → float[source]

Calculate the norm of the state.

Returns:

norm of the state

Return type:

float

expectation_value(op: npt.NDArray[np.complex128], qubit_indices: Sequence[int], output_node_indices: Iterable[int] | None = None, optimize: str | PathOptimizer | None = None) → float[source]

Calculate expectation value of the given operator.

Parameters:
  • op (numpy.ndarray) – single- or multi-qubit Hermitian operator

  • qubit_indices (list of int) – Applied positions of logical qubits.

  • (optional) (output_node_indices) – Indices of nodes in the entire TN, that remain unmeasured after MBQC operations. Default is the output nodes specified in measurement pattern (self.default_output_nodes).

Returns:

Expectation value

Return type:

float

evolve(operator: NDArray[complex128], qubit_indices: list[int], decompose: bool = True) → None[source]

Apply an arbitrary operator to the state.

Parameters:
  • operator (numpy.ndarray) – operator.

  • qubit_indices (list of int) – Applied positions of logical qubits.

  • decompose (bool, optional) – default True whether a given operator will be decomposed or not. If True, operator is decomposed into Matrix Product Operator(MPO)

copy(virtual: bool = False, deep: bool = False) → MBQCTensorNet[source]

Return the copy of this object.

Parameters:

deep (bool, optional) – Defaults to False. Whether to copy the underlying data as well.

Returns:

duplicated object

Return type:

TensorNetworkBackend

class TensorNetworkBackend(pattern: Pattern, graph_prep: str = 'auto', input_state: Data | None = None, branch_selector: BranchSelector | None = None)[source]

Bases: _AbstractTensorNetworkBackend

Tensor Network Simulator for MBQC.

Executes the measurement pattern using TN expression of graph states.

Parameters:
  • pattern (graphix.Pattern)

  • graph_prep (str) –

    ‘parallel’ :

    Faster method for preparing a graph state. The expression of a graph state can be obtained from the graph geometry. See https://journals.aps.org/pra/abstract/10.1103/PhysRevA.76.052315 for detail calculation. Note that ‘N’ and ‘E’ commands in the measurement pattern are ignored.

    ’sequential’ :

    Sequentially execute N and E commands, strictly following the measurement pattern. In this strategy, All N and E commands executed sequentially.

    ’auto’(default) :

    Automatically select a preparation strategy based on the max degree of a graph

  • input_state (preparation for input states (only BasicStates.PLUS is supported for tensor networks yet),)

  • branch_selector (graphix.branch_selector.BranchSelector, optional) – Branch selector to be used for measurements.

__init__(pattern: Pattern, graph_prep: str = 'auto', input_state: Data | None = None, branch_selector: BranchSelector | None = None) → None[source]

Construct a tensor network backend.

add_nodes(nodes: Sequence[int], data: Data = graphix.states.PlanarState(Plane.XY, 0)) → None[source]

Add new nodes (qubits) to the network and initialize them in a specified state.

Parameters:
  • nodes (Sequence[int]) – A list of node indices to add to the backend. These indices can be any integer values but must be fresh: each index must be distinct from all previously added nodes.

  • data (Data, optional) –

    The state in which to initialize the newly added nodes.

    • If a single basic state is provided, all new nodes are initialized in that state.

    • If a list of basic states is provided, it must match the length of nodes, and each node is initialized with its corresponding state.

Notes

Previously existing nodes remain unchanged.

entangle_nodes(edge: tuple[int, int]) → None[source]

Make entanglement between nodes specified by edge.

Parameters:

edge (tuple of int) – edge specifies two target nodes of the CZ gate.

measure(node: int, measurement: Measurement, rng: Generator | None = None, *, stacklevel: int = 1) → Outcome[source]

Perform measurement of the node.

In the context of tensornetwork, performing measurement equals to applying measurement operator to the tensor. Here, directly contracted with the projected state.

Parameters:
  • node (int) – index of the node to measure

  • measurement (Measurement) – measure plane and angle

correct_byproduct(cmd: X | Z) → None[source]

Byproduct correction correct for the X or Z byproduct operators, by applying the X or Z gate.

Note: the simulator is responsible for checking that the measurement outcomes match the domain condition before calling this method.

apply_clifford(node: int, clifford: Clifford) → None[source]

Apply single-qubit Clifford gate.

Parameters:

cmd (list) – clifford command. See https://arxiv.org/pdf/2212.11975.pdf for the detail.

finalize(output_nodes: Iterable[int]) → None[source]

Do nothing.

property nqubit: int

the current number of qubits is not well-defined in the current implementation of the TensorNetworkBackend.

Type:

Raise NotImplementedError

gen_str() → str[source]

Generate dummy string for einsum.

outer_product(vectors: Sequence[npt.NDArray[np.complex128]]) → npt.NDArray[np.complex128][source]

Return the outer product of the given vectors.

Parameters:

vectors (list of vector) – vectors

Returns:

tensor object.

Return type:

numpy.ndarray