Pattern Simulation¶
graphix.simulator module¶
- class graphix.simulator.PatternSimulator(pattern, backend='statevector', measure_method: MeasureMethod | None = None, noise_model=None, **kwargs)[source]¶
MBQC simulator.
Executes the measurement pattern.
- __init__(pattern, backend='statevector', measure_method: MeasureMethod | None = None, noise_model=None, **kwargs) None[source]¶
Construct a pattern simulator.
- Parameters:
pattern (
graphix.pattern.Patternobject) – MBQC pattern to be simulated.backend (
graphix.sim.backend.Backendobject,) – or ‘statevector’, or ‘densitymatrix’, or ‘tensornetwork’ simulation backend (optional), default is ‘statevector’.noise_model
kwargs (keyword args for specified backend.)
seealso: (..) –
graphix.sim.statevec.StatevectorBackendgraphix.sim.tensornet.TensorNetworkBackendgraphix.sim.density_matrix.DensityMatrixBackend:
Simulator backends¶
Tensor Network¶
- class graphix.sim.tensornet.TensorNetworkBackend(pattern, graph_prep='auto', input_state=graphix.states.PlanarState(Plane.XY, 0.0), rng: Generator | None = None, **kwargs)[source]¶
Tensor Network Simulator for MBQC.
Executes the measurement pattern using TN expression of graph states.
- __init__(pattern, graph_prep='auto', input_state=graphix.states.PlanarState(Plane.XY, 0.0), rng: Generator | None = None, **kwargs)[source]¶
Construct a tensor network backend.
- 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),)
rng (
np.random.Generator(default: None)) – random number generator to use for measurements**kwargs (Additional keyword args to be passed to quimb.tensor.TensorNetwork.)
- add_nodes(nodes, data=graphix.states.PlanarState(Plane.XY, 0.0)) None[source]¶
Add nodes to the network.
- Parameters:
nodes (iterator of int) – index set of the new nodes.
- 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.
- correct_byproduct(cmd: command.X | command.Z, measure_method: MeasureMethod) None[source]¶
Perform byproduct correction.
- Parameters:
cmd (list) – Byproduct command i.e. [‘X’ or ‘Z’, node, signal_domain]
measure_method (MeasureMethod) – The measure method to use
- entangle_nodes(edge) 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) tuple[Backend, int][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
Statevector¶
- class graphix.sim.statevec.StatevectorBackend(**kwargs)[source]¶
MBQC simulator with statevector method.
- class graphix.sim.statevec.Statevec(data: State | Statevec | Iterable[State] | Iterable[Expression | SupportsComplex] = graphix.states.PlanarState(Plane.XY, 0.0), nqubit: int | None = None)[source]¶
Statevector object.
- __init__(data: State | Statevec | Iterable[State] | Iterable[Expression | SupportsComplex] = graphix.states.PlanarState(Plane.XY, 0.0), nqubit: int | None = None)[source]¶
Initialize statevector objects.
data can be: - a single
graphix.states.State(classical description of a quantum state) - an iterable ofgraphix.states.Stateobjects - an iterable of scalars (A 2**n numerical statevector) - a graphix.statevec.Statevec objectIf nqubit is not provided, the number of qubit is inferred from data and checked for consistency. If only one
graphix.states.Stateis provided and nqubit is a valid integer, initialize the statevector in the tensor product state. If both nqubit and data are provided, consistency of the dimensions is checked. If a graphix.statevec.Statevec is passed, returns a copy.- Parameters:
data (Data, optional) – input data to prepare the state. Can be a classical description or a numerical input, defaults to graphix.states.BasicStates.PLUS
nqubit (int, optional) – number of qubits to prepare, defaults to None
- cnot(qubits)[source]¶
Apply CNOT.
- Parameters:
qubits (tuple of int) – (control, target) qubit indices
- entangle(edge: tuple[int, int]) None[source]¶
Connect graph nodes.
- Parameters:
edge (tuple of int) – (control, target) qubit indices
- evolve(op: ndarray, qargs: list[int]) None[source]¶
Apply a multi-qubit operation.
- Parameters:
op (numpy.ndarray) – 2^n*2^n matrix
qargs (list of int) – target qubits’ indices
- evolve_single(op: ndarray[tuple[int, ...], dtype[_ScalarType_co]], i: int) None[source]¶
Apply a single-qubit operation.
- Parameters:
op (numpy.ndarray) – 2*2 matrix
i (int) – qubit index
- expectation_single(op: np.NDArray, loc: int) complex[source]¶
Return the expectation value of single-qubit operator.
- Parameters:
op (numpy.ndarray) – 2*2 operator
loc (int) – target qubit index
- Returns:
complex
- Return type:
expectation value.
- expectation_value(op: np.NDArray, qargs: collections.abc.Iterable[int]) complex[source]¶
Return the expectation value of multi-qubit operator.
- Parameters:
op (numpy.ndarray) – 2^n*2^n operator
qargs (list of int) – target qubit indices
- Returns:
complex
- Return type:
expectation value
- ptrace(qargs) None[source]¶
Perform partial trace of the selected qubits.
Warning
This method currently assumes qubits in qargs to be separable from the rest (checks not implemented for speed). Otherwise, the state returned will be forced to be pure which will result in incorrect output. Correct behaviour will be implemented as soon as the densitymatrix class, currently under development (PR #64), is merged.
- Parameters:
qargs (list of int) – qubit indices to trace over
- remove_qubit(qarg: int) None[source]¶
Remove a separable qubit from the system and assemble a statevector for remaining qubits.
This results in the same result as partial trace, if the qubit qarg is separable from the rest.
For a statevector \(\ket{\psi} = \sum c_i \ket{i}\) with sum taken over \(i \in [ 0 \dots 00,\ 0\dots 01,\ \dots,\ 1 \dots 11 ]\), this method returns
\[\begin{split}\begin{align} \ket{\psi}' =& c_{0 \dots 0_{\mathrm{k-1}}0_{\mathrm{k}}0_{\mathrm{k+1}} \dots 00} \ket{0 \dots 0_{\mathrm{k-1}}0_{\mathrm{k+1}} \dots 00} \\ & + c_{0 \dots 0_{\mathrm{k-1}}0_{\mathrm{k}}0_{\mathrm{k+1}} \dots 01} \ket{0 \dots 0_{\mathrm{k-1}}0_{\mathrm{k+1}} \dots 01} \\ & + c_{0 \dots 0_{\mathrm{k-1}}0_{\mathrm{k}}0_{\mathrm{k+1}} \dots 10} \ket{0 \dots 0_{\mathrm{k-1}}0_{\mathrm{k+1}} \dots 10} \\ & + \dots \\ & + c_{1 \dots 1_{\mathrm{k-1}}0_{\mathrm{k}}1_{\mathrm{k+1}} \dots 11} \ket{1 \dots 1_{\mathrm{k-1}}1_{\mathrm{k+1}} \dots 11}, \end{align}\end{split}\](after normalization) for \(k =\) qarg. If the \(k\) th qubit is in \(\ket{1}\) state, above will return zero amplitudes; in such a case the returned state will be the one above with \(0_{\mathrm{k}}\) replaced with \(1_{\mathrm{k}}\) .
Warning
This method assumes the qubit with index qarg to be separable from the rest, and is implemented as a significantly faster alternative for partial trace to be used after single-qubit measurements. Care needs to be taken when using this method. Checks for separability will be implemented soon as an option.
See also
graphix.sim.statevec.Statevec.ptrace()and warning therein.- Parameters:
qarg (int) – qubit index
- subs(variable: Parameter, substitute: ExpressionOrSupportsFloat) Statevec[source]¶
Return a copy of the state vector where all occurrences of the given variable in measurement angles are substituted by the given value.
- swap(qubits) None[source]¶
Swap qubits.
- Parameters:
qubits (tuple of int) – (control, target) qubit indices
- tensor(other: Statevec) None[source]¶
Tensor product state with other qubits.
Results in self \(\otimes\) other.
- Parameters:
other (
graphix.sim.statevec.Statevec) – statevector to be tensored with self
Density Matrix¶
- class graphix.sim.density_matrix.DensityMatrixBackend(**kwargs)[source]¶
MBQC simulator with density matrix method.
- apply_channel(channel: KrausChannel, qargs: Collection[int]) None[source]¶
Apply channel to the state.
- Parameters:
qargs (list of ints. Target qubits)
- class graphix.sim.density_matrix.DensityMatrix(data: State | DensityMatrix | Statevec | Iterable[State] | Iterable[Expression | SupportsComplex] | Iterable[Iterable[Expression | SupportsComplex]] = graphix.states.PlanarState(Plane.XY, 0.0), nqubit: int | None = None)[source]¶
DensityMatrix object.
- __init__(data: State | DensityMatrix | Statevec | Iterable[State] | Iterable[Expression | SupportsComplex] | Iterable[Iterable[Expression | SupportsComplex]] = graphix.states.PlanarState(Plane.XY, 0.0), nqubit: int | None = None)[source]¶
Initialize density matrix objects.
The behaviour builds on the one of graphix.statevec.Statevec. data can be: - a single
graphix.states.State(classical description of a quantum state) - an iterable ofgraphix.states.Stateobjects - an iterable of iterable of scalars (A 2**n x 2**n numerical density matrix) - a graphix.statevec.DensityMatrix object - a graphix.statevec.Statevector objectIf nqubit is not provided, the number of qubit is inferred from data and checked for consistency. If only one
graphix.states.Stateis provided and nqubit is a valid integer, initialize the statevector in the tensor product state. If both nqubit and data are provided, consistency of the dimensions is checked. If a graphix.statevec.Statevec or graphix.statevec.DensityMatrix is passed, returns a copy.- Parameters:
data (Data) – input data to prepare the state. Can be a classical description or a numerical input, defaults to graphix.states.BasicStates.PLUS
nqubit (int, optional) – number of qubits to prepare, defaults to None
- apply_channel(channel: KrausChannel, qargs: Collection[int]) None[source]¶
Apply a channel to a density matrix.
:param : :type : rho: density matrix. :param channel: KrausChannel to be applied to the density matrix :type channel:
graphix.channel.KrausChannelobject :param qargs: :type qargs: target qubit indices- Return type:
nothing
- Raises:
ValueError – If the final density matrix is not normalized after application of the channel. This shouldn’t happen since
graphix.channel.KrausChannelobjects are normalized by construction..... –
- cnot(edge: tuple[int, int]) None[source]¶
Apply CNOT gate to density matrix.
- Parameters:
edge ((int, int) or [int, int]) – Edge to apply CNOT gate.
- entangle(edge: tuple[int, int]) None[source]¶
Connect graph nodes.
- Parameters:
edge ((int, int) or [int, int]) – (control, target) qubit indices.
- evolve(op: npt.NDArray, qargs: Collection[int]) None[source]¶
Multi-qubit operation.
- Parameters:
op (np.array) – 2^n*2^n matrix
qargs (list of ints) – target qubits’ indexes
- evolve_single(op, i) None[source]¶
Single-qubit operation.
- Parameters:
op (np.ndarray) – 2*2 matrix.
i (int) – Index of qubit to apply operator.
- expectation_single(op: npt.NDArray, i: int) complex[source]¶
Return the expectation value of single-qubit operator.
- Parameters:
op (np.array) – 2*2 Hermite operator
loc (int) – Index of qubit on which to apply operator.
- Returns:
complex
- Return type:
expectation value (real for hermitian ops!).
- fidelity(statevec: Statevec) float[source]¶
Calculate the fidelity against reference statevector.
- Parameters:
statevec (numpy array) – statevector (flattened numpy array) to compare with
- property nqubit: int¶
Return the number of qubits.
- ptrace(qargs: Collection[int] | int) None[source]¶
Partial trace.
- Parameters:
qargs (list of ints or int) – Indices of qubit to trace out.
- subs(variable: Parameter, substitute: ExpressionOrSupportsFloat) DensityMatrix[source]¶
Return a copy of the density matrix where all occurrences of the given variable in measurement angles are substituted by the given value.
- swap(edge: tuple[int, int]) None[source]¶
Swap qubits.
- Parameters:
edge ((int, int) or [int, int]) – (control, target) qubits indices.
- tensor(other: DensityMatrix) None[source]¶
Tensor product state with other density matrix.
Results in self \(\otimes\) other.
- Parameters:
other – DensityMatrix object to be tensored with self.
- xreplace(assignment: Mapping[Parameter, ExpressionOrSupportsFloat]) DensityMatrix[source]¶
Return a copy of the density matrix where all occurrences of the given keys in measurement angles are substituted by the given values in parallel.