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:
TensorNetworkTensor 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.
- 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:
- add_qubit(index: int, state: str | NDArray[complex128] = 'plus') None[source]¶
Add a single qubit to the network.
- 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:
- 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:
- basis_amplitude(basis: str | int) float[source]¶
Calculate the probability amplitude of the specified computational basis state.
- 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:
- norm(optimize: str | PathOptimizer | None = None) float[source]¶
Calculate the norm of the state.
- Returns:
norm of the state
- Return type:
- 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:
- 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)
- class TensorNetworkBackend(pattern: Pattern, graph_prep: str = 'auto', input_state: Data | None = None, branch_selector: BranchSelector | None = None)[source]¶
Bases:
_AbstractTensorNetworkBackendTensor 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.
- 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.