View source on GitHub |
A simulator for density matrices and noisy quantum circuits.
Inherits From: SimulatorBase
, SimulatesIntermediateState
, SimulatesFinalState
, SimulatesSamples
, Sampler
, SimulatesExpectationValues
cirq.DensityMatrixSimulator(
*,
dtype: Type[np.complexfloating] = np.complex64,
noise: 'cirq.NOISE_MODEL_LIKE' = None,
seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
split_untangled_states: bool = True
)
Used in the notebooks
Used in the guide | Used in the tutorials |
---|---|
This simulator can be applied on circuits that are made up of operations that have:
* a `_kraus_` method for a Kraus representation of a quantum channel.
* a `_mixture_` method for a probabilistic combination of unitary gates.
* a `_unitary_` method for a unitary gate.
* a `_has_unitary_` and `_apply_unitary_` method.
* measurements
* a `_decompose_` that eventually yields one of the above
That is, the circuit must have elements that follow on of the protocols:
* cirq.SupportsKraus
* cirq.SupportsMixture
* cirq.SupportsConsistentApplyUnitary
* cirq.SupportsUnitary
* cirq.SupportsDecompose
or is a measurement.
This simulator supports three types of simulation.
Run simulations which mimic running on actual quantum hardware. These simulations do not give access to the density matrix (like actual hardware). There are two variations of run methods, one which takes in a single (optional) way to resolve parameterized circuits, and a second which takes in a list or sweep of parameter resolver:
run(circuit, param_resolver, repetitions)
run_sweep(circuit, params, repetitions)
These methods return Result
s which contain both the measurement
results, but also the parameters used for the parameterized
circuit operations. The initial state of a run is always the all 0s state
in the computational basis.
By contrast the simulate methods of the simulator give access to the density
matrix of the simulation at the end of the simulation of the circuit.
Note that if the circuit contains measurements then the density matrix
is that result for those particular measurement results. For example
if there is one measurement, then the simulation may result in the
measurement result for this measurement, and the density matrix will
be that conditional on that result. It will not be the density matrix formed
by summing over the different measurements and their probabilities.
The simulate methods take in two parameters that the run methods do not: a
qubit order and an initial state. The qubit order is necessary because an
ordering must be chosen for the kronecker product (see
DensityMatrixTrialResult
for details of this ordering). The initial
state can be either the full density matrix, the full wave function (for
pure states), or an integer which represents the initial state of being
in a computational basis state for the binary representation of that
integer. Similar to run methods, there are two simulate methods that run
for single simulations or for sweeps across different parameters:
simulate(circuit, param_resolver, qubit_order, initial_state)
simulate_sweep(circuit, params, qubit_order, initial_state)
The simulate methods in contrast to the run methods do not perform
repetitions. The result of these simulations is a
DensityMatrixTrialResult
which contains, in addition to measurement
results and information about the parameters that were used in the
simulation, access to the density matrix via the density_matrix
method.
If one wishes to perform simulations that have access to the
density matrix as one steps through running the circuit there is a generator
which can be iterated over and each step is an object that gives access
to the density matrix. This stepping through a Circuit
is done on a
Moment
by Moment
manner.
simulate_moment_steps(circuit, param_resolver, qubit_order,
initial_state)
One can iterate over the moments with the following
(replace 'sim' with your Simulator
object):
for step_result in sim.simulate_moment_steps(circuit):
# do something with the density matrix via
# step_result.density_matrix()
Raises | |
---|---|
ValueError
|
If the supplied dtype is not np.complex64 or
np.complex128 .
|
Attributes | |
---|---|
noise
|
Methods
run
run(
program: 'cirq.AbstractCircuit',
param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
repetitions: int = 1
) -> 'cirq.Result'
Samples from the given Circuit
.
This mode of operation for a sampler will provide results
in the form of measurement outcomes. It will not provide
access to state vectors (even if the underlying
sampling mechanism is a simulator). This method will substitute
parameters in the param_resolver
attributes for sympy.Symbols
used within the Circuit. This circuit will be executed a number
of times specified in the repetitions
attribute, though some
simulated implementations may instead sample from the final
distribution rather than execute the circuit each time.
Args | |
---|---|
program
|
The circuit to sample from. |
param_resolver
|
Parameters to run with the program. |
repetitions
|
The number of times to sample. |
Returns | |
---|---|
cirq.Result that contains all the measurements for a run.
|
run_async
run_async(
program, param_resolver=None, repetitions=1
)
Asynchronously samples from the given Circuit.
Provides measurement outcomes as a cirq.Result
object. This
interface will operate in a similar way to the run
method
except for executing asynchronously.
Args | |
---|---|
program
|
The circuit to sample from. |
param_resolver
|
Parameters to run with the program. |
repetitions
|
The number of times to sample. |
Returns | |
---|---|
Result for a run. |
run_batch
run_batch(
programs: Sequence['cirq.AbstractCircuit'],
params_list: Optional[Sequence['cirq.Sweepable']] = None,
repetitions: Union[int, Sequence[int]] = 1
) -> Sequence[Sequence['cirq.Result']]
Runs the supplied circuits.
Each circuit provided in programs
will pair with the optional
associated parameter sweep provided in the params_list
, and be run
with the associated repetitions provided in repetitions
(if
repetitions
is an integer, then all runs will have that number of
repetitions). If params_list
is specified, then the number of
circuits is required to match the number of sweeps. Similarly, when
repetitions
is a list, the number of circuits is required to match
the length of this list.
By default, this method simply invokes run_sweep
sequentially for
each (circuit, parameter sweep, repetitions) tuple. Child classes that
are capable of sampling batches more efficiently should override it to
use other strategies. Note that child classes may have certain
requirements that must be met in order for a speedup to be possible,
such as a constant number of repetitions being used for all circuits.
Refer to the documentation of the child class for any such requirements.
Args | |
---|---|
programs
|
The circuits to execute as a batch. |
params_list
|
Parameter sweeps to use with the circuits. The number of sweeps should match the number of circuits and will be paired in order with the circuits. |
repetitions
|
Number of circuit repetitions to run. Can be specified as a single value to use for all runs, or as a list of values, one for each circuit. |
Returns | |
---|---|
A list of lists of TrialResults. The outer list corresponds to the circuits, while each inner list contains the TrialResults for the corresponding circuit, in the order imposed by the associated parameter sweep. |
Raises | |
---|---|
ValueError
|
If length of programs is not equal to the length
of params_list or the length of repetitions .
|
run_batch_async
run_batch_async(
programs, params_list=None, repetitions=1
)
Runs the supplied circuits asynchronously.
See docs for cirq.Sampler.run_batch
.
run_sweep
run_sweep(
program: 'cirq.AbstractCircuit',
params: 'cirq.Sweepable',
repetitions: int = 1
) -> Sequence['cirq.Result']
Samples from the given Circuit.
This allows for sweeping over different parameter values,
unlike the run
method. The params
argument will provide a
mapping from sympy.Symbol
s used within the circuit to a set of
values. Unlike the run
method, which specifies a single
mapping from symbol to value, this method allows a "sweep" of
values. This allows a user to specify execution of a family of
related circuits efficiently.
Args | |
---|---|
program
|
The circuit to sample from. |
params
|
Parameters to run with the program. |
repetitions
|
The number of times to sample. |
Returns | |
---|---|
Result list for this run; one for each possible parameter resolver. |
run_sweep_async
run_sweep_async(
program, params, repetitions=1
)
Asynchronously samples from the given Circuit.
By default, this method invokes run_sweep
synchronously and simply
exposes its result is an awaitable. Child classes that are capable of
true asynchronous sampling should override it to use other strategies.
Args | |
---|---|
program
|
The circuit to sample from. |
params
|
Parameters to run with the program. |
repetitions
|
The number of times to sample. |
Returns | |
---|---|
Result list for this run; one for each possible parameter resolver. |
run_sweep_iter
run_sweep_iter(
program: 'cirq.AbstractCircuit',
params: 'cirq.Sweepable',
repetitions: int = 1
) -> Iterator['cirq.Result']
Runs the supplied Circuit, mimicking quantum hardware.
In contrast to run, this allows for sweeping over different parameter values.
Args | |
---|---|
program
|
The circuit to simulate. |
params
|
Parameters to run with the program. |
repetitions
|
The number of repetitions to simulate. |
Returns | |
---|---|
Result list for this run; one for each possible parameter resolver. |
Raises | |
---|---|
ValueError
|
If the circuit has no measurements. |
sample
sample(
program: 'cirq.AbstractCircuit',
*,
repetitions: int = 1,
params: 'cirq.Sweepable' = None
) -> 'pd.DataFrame'
Samples the given Circuit, producing a pandas data frame.
This interface will operate in a similar way to the run
method
except that it returns a pandas data frame rather than a cirq.Result
object.
Args | |
---|---|
program
|
The circuit to sample from. |
repetitions
|
The number of times to sample the program, for each parameter mapping. |
params
|
Maps symbols to one or more values. This argument can be
a dictionary, a list of dictionaries, a cirq.Sweep , a list of
cirq.Sweep , etc. The program will be sampled repetition
times for each mapping. Defaults to a single empty mapping.
|
Returns | |
---|---|
A pandas.DataFrame with a row for each sample, and a column for
each measurement key as well as a column for each symbolic
parameter. Measurement results are stored as a big endian integer
representation with one bit for each measured qubit in the key.
See cirq.big_endian_int_to_bits and similar functions for how
to convert this integer into bits.
There is an also index column containing the repetition number,
for each parameter assignment.
|
Raises | |
---|---|
ValueError
|
If a supplied sweep is invalid. |
Examples | |
---|---|
|
sample_expectation_values
sample_expectation_values(
program: 'cirq.AbstractCircuit',
observables: Union['cirq.PauliSumLike', List['cirq.PauliSumLike']],
*,
num_samples: int,
params: 'cirq.Sweepable' = None,
permit_terminal_measurements: bool = False
) -> Sequence[Sequence[float]]
Calculates estimated expectation values from samples of a circuit.
Please see also cirq.work.observable_measurement.measure_observables
for more control over how to measure a suite of observables.
This method can be run on any device or simulator that supports circuit sampling. Compare
with simulate_expectation_values
in simulator.py, which is limited to simulators
but provides exact results.
Args | |
---|---|
program
|
The circuit which prepares a state from which we sample expectation values. |
observables
|
A list of observables for which to calculate expectation values. |
num_samples
|
The number of samples to take. Increasing this value increases the statistical accuracy of the estimate. |
params
|
Parameters to run with the program. |
permit_terminal_measurements
|
If the provided circuit ends in a measurement, this method will generate an error unless this is set to True. This is meant to prevent measurements from ruining expectation value calculations. |
Returns | |
---|---|
A list of expectation-value lists. The outer index determines the sweep, and the inner index determines the observable. For instance, results[1][3] would select the fourth observable measured in the second sweep. |
Raises | |
---|---|
ValueError
|
If the number of samples was not positive, if empty observables were
supplied, or if the provided circuit has terminal measurements and
permit_terminal_measurements is true.
|
simulate
simulate(
program: 'cirq.AbstractCircuit',
param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
qubit_order: 'cirq.QubitOrderOrList' = cirq.QubitOrder.DEFAULT
,
initial_state: Any = None
) -> TSimulationTrialResult
Simulates the supplied Circuit.
This method returns a result which allows access to the entire simulator's final state.
Args | |
---|---|
program
|
The circuit to simulate. |
param_resolver
|
Parameters to run with the program. |
qubit_order
|
Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. |
initial_state
|
The initial state for the simulation. The form of this state depends on the simulation implementation. See documentation of the implementing class for details. |
Returns | |
---|---|
SimulationTrialResults for the simulation. Includes the final state. |
simulate_expectation_values
simulate_expectation_values(
program: 'cirq.AbstractCircuit',
observables: Union['cirq.PauliSumLike', List['cirq.PauliSumLike']],
param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
qubit_order: 'cirq.QubitOrderOrList' = cirq.QubitOrder.DEFAULT
,
initial_state: Any = None,
permit_terminal_measurements: bool = False
) -> List[float]
Simulates the supplied circuit and calculates exact expectation values for the given observables on its final state.
This method has no perfect analogy in hardware. Instead compare with Sampler.sample_expectation_values, which calculates estimated expectation values by sampling multiple times.
Args | |
---|---|
program
|
The circuit to simulate. |
observables
|
An observable or list of observables. |
param_resolver
|
Parameters to run with the program. |
qubit_order
|
Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. |
initial_state
|
The initial state for the simulation. The form of this state depends on the simulation implementation. See documentation of the implementing class for details. |
permit_terminal_measurements
|
If the provided circuit ends with measurement(s), this method will generate an error unless this is set to True. This is meant to prevent measurements from ruining expectation value calculations. |
Returns | |
---|---|
A list of expectation values, with the value at index n
corresponding to observables[n] from the input.
|
Raises | |
---|---|
ValueError if 'program' has terminal measurement(s) and 'permit_terminal_measurements' is False. |
simulate_expectation_values_sweep
simulate_expectation_values_sweep(
program: 'cirq.AbstractCircuit',
observables: Union['cirq.PauliSumLike', List['cirq.PauliSumLike']],
params: 'cirq.Sweepable',
qubit_order: 'cirq.QubitOrderOrList' = cirq.QubitOrder.DEFAULT
,
initial_state: Any = None,
permit_terminal_measurements: bool = False
) -> List[List[float]]
Wraps computed expectation values in a list.
Prefer overriding simulate_expectation_values_sweep_iter
.
simulate_expectation_values_sweep_iter
simulate_expectation_values_sweep_iter(
program: 'cirq.AbstractCircuit',
observables: Union['cirq.PauliSumLike', List['cirq.PauliSumLike']],
params: 'cirq.Sweepable',
qubit_order: 'cirq.QubitOrderOrList' = cirq.QubitOrder.DEFAULT
,
initial_state: Any = None,
permit_terminal_measurements: bool = False
) -> Iterator[List[float]]
Simulates the supplied circuit and calculates exact expectation values for the given observables on its final state, sweeping over the given params.
This method has no perfect analogy in hardware. Instead compare with Sampler.sample_expectation_values, which calculates estimated expectation values by sampling multiple times.
Args | |
---|---|
program
|
The circuit to simulate. |
observables
|
An observable or list of observables. |
params
|
Parameters to run with the program. |
qubit_order
|
Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. |
initial_state
|
The initial state for the simulation. The form of this state depends on the simulation implementation. See documentation of the implementing class for details. |
permit_terminal_measurements
|
If the provided circuit ends in a measurement, this method will generate an error unless this is set to True. This is meant to prevent measurements from ruining expectation value calculations. |
Returns | |
---|---|
An Iterator over expectation-value lists. The outer index determines the sweep, and the inner index determines the observable. For instance, results[1][3] would select the fourth observable measured in the second sweep. |
Raises | |
---|---|
ValueError if 'program' has terminal measurement(s) and 'permit_terminal_measurements' is False. |
simulate_moment_steps
simulate_moment_steps(
circuit: 'cirq.AbstractCircuit',
param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
qubit_order: 'cirq.QubitOrderOrList' = cirq.QubitOrder.DEFAULT
,
initial_state: Any = None
) -> Iterator[TStepResult]
Returns an iterator of StepResults for each moment simulated.
If the circuit being simulated is empty, a single step result should be returned with the state being set to the initial state.
Args | |
---|---|
circuit
|
The Circuit to simulate. |
param_resolver
|
A ParamResolver for determining values of Symbols. |
qubit_order
|
Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. |
initial_state
|
The initial state for the simulation. This can be
either a raw state or a TSimulationState . The form of the
raw state depends on the simulation implementation. See
documentation of the implementing class for details.
|
Returns | |
---|---|
Iterator that steps through the simulation, simulating each moment and returning a StepResult for each moment. |
simulate_sweep
simulate_sweep(
program: 'cirq.AbstractCircuit',
params: 'cirq.Sweepable',
qubit_order: 'cirq.QubitOrderOrList' = cirq.QubitOrder.DEFAULT
,
initial_state: Any = None
) -> List[TSimulationTrialResult]
Wraps computed states in a list.
Prefer overriding simulate_sweep_iter
.
simulate_sweep_iter
simulate_sweep_iter(
program: 'cirq.AbstractCircuit',
params: 'cirq.Sweepable',
qubit_order: 'cirq.QubitOrderOrList' = cirq.QubitOrder.DEFAULT
,
initial_state: Any = None
) -> Iterator[TSimulationTrialResult]
Simulates the supplied Circuit.
This particular implementation overrides the base implementation such that an unparameterized prefix circuit is simulated and fed into the parameterized suffix circuit.
Args | |
---|---|
program
|
The circuit to simulate. |
params
|
Parameters to run with the program. |
qubit_order
|
Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. |
initial_state
|
The initial state for the simulation. This can be
either a raw state or an SimulationStateBase . The form of the
raw state depends on the simulation implementation. See
documentation of the implementing class for details.
|
Returns | |
---|---|
List of SimulationTrialResults for this run, one for each possible parameter resolver. |