# Built-In Simulator¶

After defining a circuit or generating a circuit collection, the next step is to
run it on a simulator or quantum device. For ease of implementation, the
True-Qᵀᴹ SDK includes a built-in `Simulator`

that can
be configured with custom or pre-defined noise models.

- Generate circuits
The first step, before using a

`Simulator`

to simulate a`Circuit`

or`CircuitCollection`

, is to define the ideal version of the circuit(s) to be run. In this example, we will write a custom`Circuit`

with an X gate acting on the \(0^{th}\) qubit, followed by a controlled-Z gate on qubits 1 and 2 at the same time as a Y gate acts on the \(0^{th}\) qubit:import tq as trueq circuit = tq.Circuit(tq.Cycle({(0, ):tq.Gate.x}), tq.Cycle({(0, ): tq.Gate.y, (1, 2):tq.Gate.cz}))

- Initialize a Simulator
The next step is to initialize a

`Simulator`

, and (optionally) add noise. In this example we will not add noise; for a noisy implementation, see the example below. To initialize a simulator, run:sim=tq.Simulator()

- Add Noise (Optional)
To simulate a noisy implementation of a

`Circuit`

or`CircuitCollection`

, a noise process should be added to the simulator prior to running the circuit(s). The following code adds depolarizing noise to the`Simulator`

initialized in step 2.sim.add_depolarizing(p = 0.001)

See Noise for details about the True-Qᵀᴹ SDK suite of noise models.

- Run the Simulation
The final step is to run the

`Circuit`

or`CircuitCollection`

on the simulator. The following line of code runs the simulation and accordingly populates the`results`

of the circuit with 100 random shots.sim.run(circuit, n_shots = 100)

## Noise¶

The True-Qᵀᴹ SDK includes several functions for adding noise to a
`Simulator`

, including several common noise models and the option to
define a custom noise process using Kraus operators. Every function below causes
the specified noise model to act at every location where a circuit acts in a simulator.

- Depolarizing
The

`add_depolarizing`

function adds depolarizing noise to a simulator, so that when a circuit is run on the simulator, depolarizing noise acts independently and isotropically on every location in the circuit. The following code initializes a`Simulator`

with depolarizing noise with depolarizing parameter \(p = 0.03\):sim = tq.Simulator().add_depolarizing(p = 0.03)

- Stochastic Pauli
The

`add_stochastic_pauli`

function adds a stochastic pauli noise to a simulator. The following code initializes a simulator with stochastic pauli noise, where the probability of an \(X\), \(Y\), and \(Z\) error are \(px = 0.01\), \(py = 0.02\), and \(pz = 0.03\), respectively:sim = tq.Simulator().add_stochastic_pauli(px = 0.01, py = 0.02, pz = 0.03)

- Overrotation
The

`add_overrotation`

function adds an overrotation error at every location where a single qubit or multi-qubit gate acts in a simulator. The angle of overrotation can be specified separately for single and multi-qubit gates. The following code initializes a`Simulator`

with an overrotation by \(\epsilon=0.01\) to single qubit gates and \(\epsilon=0.05\) to multi-qubit gates:sim = tq.Simulator().add_overrotation(single_sys = 0.01, multi_sys = 0.05)

- Custom Kraus
The

`add_kraus`

allows users to add custom noise to a simulator, specified by Kraus operators. The following code initializes a`Simulator`

with amplitude damping noise constructed from Kraus operators, with a decay probability of \(p = 0.01\):import numpy as np p = 0.01 kraus_ops = [np.sqrt(np.array([[0, p], [0, 0]])), np.sqrt(np.diag([1, 1-p]))] sim = tq.Simulator().add_kraus(kraus_ops)

## Example¶

```
#
# Noisy simulator example.
# Copyright 2019 Quantum Benchmark Inc.
#
import trueq as tq
import numpy as np
# Define a custom circuit.
circuit = tq.Circuit(
tq.Cycle({(0,): tq.Gate.x, (1,): tq.Gate.y}), tq.Cycle({(0, 1): tq.Gate.cz})
)
circuit.measure_all()
# Initialize a noiseless simulator.
sim0 = tq.Simulator()
# Initialize a simulator with depolarizing noise.
sim1 = tq.Simulator().add_depolarizing(p=0.08)
# Initialize a simulator with pauli noise and overrotation.
sim2 = (
tq.Simulator()
.add_stochastic_pauli(px=0.01, py=0.02)
.add_overrotation(single_sys=0.04)
)
# Initialize a simulator with dephasing noise.
kraus_ops = [np.sqrt(0.99) * np.eye(2), np.sqrt(0.01) * np.diag([1, -1])]
sim3 = tq.Simulator().add_kraus(kraus_ops)
# Run circuit on each of the simulators above and print the results.
sim0.run(circuit)
print(circuit.results)
sim1.run(circuit, overwrite=True)
print(circuit.results)
sim2.run(circuit, overwrite=True)
print(circuit.results)
sim3.run(circuit, overwrite=True)
print(circuit.results)
```

This produces the following output:

```
Results({'11': 50})
Results({'01': 1, '11': 48, '10': 1})
Results({'01': 2, '11': 47, '10': 1})
Results({'11': 50})
```