mm.lab_dev.simulator.Simulator¶
- class mrmustard.lab_dev.simulator.Simulator[source]¶
Bases:
object
A simulator for quantum circuits.
Circuits can be simulated by using the
run
method ofSimulator
:>>> from mrmustard.lab_dev import * >>> import numpy as np >>> # initialize a circuit >>> state = Number(modes=[0, 1], n=[2, 0], cutoffs=2) >>> gate = BSgate([0, 1], theta=np.pi/4) >>> proj1 = Number(modes=[1], n=[0]).dual >>> circuit = Circuit([state, gate, proj1]) >>> # run the simulation >>> result = Simulator().run(circuit) >>> # the simulator returns a component that can be potentially be plugged >>> # into another circuit >>> assert isinstance(result, CircuitComponent)
The simulation is carried out by contracting the components of the given circuit in pairs, until only one component is left and returned. In the examples above, the contractions happen in a “left-to-right” fashion, meaning that the left-most component in the circuit (
state
) is contracted with the one in its right (gate
), and finally the resulting component is contracted with the projector. This provides a simple and convenient way to run simulations, but for large circuits, different contraction paths may be more efficient.The
path
attribute ofCircuit
s allows customising the contraction order and potentially speeding up the simulation. When apath
of the type[(i, j), (l, m), ...]
is given, the simulator creates a dictionary of the type{0: c0, ..., N: cN}
, where[c0, .., cN]
is thecircuit.component
list. Then:The two components
ci
andcj
in positionsi
andj
are contracted.ci
is replaced by the resulting componentcj >> cj
, whilecj
is popped.The two components
cl
andcm
in positionsl
andm
are contracted.cl
is replaced by the resulting componentcl >> cm
, whilecm
is popped.Et cetera.
Below is an example where a circuit is simulated in a “right-to-left” fashion:
>>> from mrmustard.lab_dev import * >>> import numpy as np >>> state = Number(modes=[0, 1], n=[2, 0], cutoffs=2) >>> gate = BSgate([0, 1], theta=np.pi/4) >>> proj01 = Number(modes=[0, 1], n=[2, 0]).dual >>> # initialize the circuit and specify a custom path >>> circuit = Circuit([state, gate, proj01]) >>> circuit.path = [(1, 2), (0, 1)] >>> result = Simulator().run(circuit)
The setter for
path
also validates the path using thevalidate_path
function ofCircuit
.Methods
run
(circuit)Runs the simulations of the given circuit.