# Simulators¶

Quantum states and their dynamics are simulated by classes belonging to the namespace `simulators`

. PECOS contains a stabilizer simulator called `StabSim`

.

## Expected Methods¶

The set of gates allowed by a simulator may differ (the standard set for PECOS is given in Standard Gates; however, each simulator is expected to have a set of standard methods. I will describe them in this section.

When initializing a simulator, the first argument is expected to be the number of qudits to be simulated. This reserves the size of the quantum registry:

```
>>> from pecos.simulators import StabSim
>>> state = StabSim(4)
```

Note, for all simulators, the initial state of each qudit is the state \(|0\rangle\).

The only other method expected is the `run_gate`

method. This method can be used to apply gates to a `simulator`

instance by using the `run_gate`

method:

```
>>> # Continuing from the previous Listing.
>>> state.run_gate('X', {0, 1})
{}
```

Here the first argument is a gate symbol that is recognized by the `simulator`

and the second argument is a set of gate locations. Other keywords and arguments may be supplied if it is allowed by the `simulator`

. Such arguments could be used to change the behavior of the gate. For example, arguments could be used to define gate rotation-angles.

If measurements are made then a dictionary indicating the measurement results is returned by `run_gate`

:

```
>>> # Continuing from the previous Listing.
>>> state.run_gate('measure Z', {0, 1, 3})
{0: 1, 1: 1}
```

Here we see that the keys of the results dictionary are the qudit locations of the measurements, and the values are the corresponding measurement results except that zero results are not returned.

Classes in the `circuit_runners`

namespace combine `QuantumCircuits`

and simulators to apply gates to simulated quantum states. For a discussion about these classes see Circuit Runners.

## StabSim¶

Methods that specific to `StabSim`

will now be described.

The `print_stabs`

method prints a stabilizer table corresponding to the state currently store in the simulator:

```
>>> state = StabSim(3)
>>> state.run_gate('CNOT', {(0, 1)})
{}
>>> state.run_gate('X', {0})
{}
>>> state.print_stabs()
-ZII
-ZZI
IIZ
-------------------------------
XXI
IXI
IIX
([' -ZII', ' -ZZI', ' IIZ'], [' XXI', ' IXI', ' IIX'])
```

Here in the print output stabilizer generators are indicated by the strings above the dashed lines, while destabilizer generators are indicated by the strings below.

The `logical_sign`

method can be used to determine the sign of stabilizer generators. As the stabilizer simulators represent stabilizer states, logical basis-states are stabilized by logical operators. Therefore, this method is useful in Monte Carlo simulations to determine if logical errors have flipped the sign of logical operators.

An example of using the`logical_sign`

method is seen in the following:

```
>>> # Continuing with the following example:
>>> from pecos.circuits import QuantumCircuit
>>> stab = QuantumCircuit([{'Z': {0, 1}}])
>>> state.logical_sign(stab)
1
>>> stab = QuantumCircuit([{'Z': {2}}])
>>> state.logical_sign(stab)
0
```

A \(1\) is returned if the phase of the stabilizer is \(-1\), and a \(0\) is returned if the phase is \(+1\). If the stabilizer supplied to `logical_sign`

is not a stabilizer of the state, then an exception will be raised.

## Extensions¶

Todo

Discuss the simulator extensions when finished…