Getting started: Your First Simulation
In this tutorial, you will learn the complete, end-to-end workflow for
simulating a quantum circuit with pyrauli
. We will build a Bell state, one
of the most fundamental entangled states in quantum computing, and measure a
property of it.
By the end, you will understand how to construct circuits, define observables, and interpret the results of a simulation that uses the Heisenberg picture.
Installation
pyrauli
requires Python 3.9 or later. You can install it directly from PyPI
using pip.
Standard Installation
For core functionality, install the package as follows:
pip install pyrauli
Installation with Qiskit Support
To use pyrauli
as a Qiskit backend, install it with the [qiskit]
extra:
pip install 'pyrauli[qiskit]'
Simulating a Bell State
Let’s simulate a 2-qubit circuit that prepares a Bell state. This circuit first applies a Hadamard gate to create a superposition, then entangles the qubits with a CNOT gate. Finally, we will calculate the expectation value of the \(Z \otimes I\) observable.
This example demonstrates the complete basic workflow:
Initialize a
Circuit
: We start by defining the number of qubits our circuit will have.Add quantum operations: We add gates to the circuit in the order they should be applied.
Define an
Observable
: We specify the physical quantity we want to measure at the end of the computation.Run the simulation: This is where
pyrauli
’s unique approach comes into play. Instead of evolving the state, we evolve the observable.Retrieve the final expectation value: We calculate the expectation value of the final, evolved observable with respect to the initial \(|00...0\rangle\) state.
Here is the complete code:
# Create a 2-qubit circuit
qc = pyrauli.Circuit(2)
# Add gates
qc.add_operation("H", 0)
qc.add_operation("CX", 0, 1)
# Define an observable and run the circuit
observable = pyrauli.Observable("ZI")
final_observable = qc.run(observable)
print(f"Expectation value of ZI: {final_observable.expectation_value()}")
Dissecting the Simulation
Let’s look at the key lines more closely.
observable = pyrauli.Observable("ZI")
Here, we define the physical quantity we want to measure. The string "ZI"
tells pyrauli
that we are interested in the Pauli-Z operator acting on qubit 0 and the identity operator acting on all other qubits (in this case, qubit 1).
In the standard Schrödinger picture, this would be the measurement we perform at the end of the circuit. In the Heisenberg picture used by pyrauli
, this observable is our starting point.
final_observable = circuit.run(observable)
This is the core of the pyrauli
simulation. Instead of evolving a state vector forward through the circuit, the run()
method evolves our observable backward.
The final_observable
represents what our initial observable ZI
becomes after being transformed by all the gates in the circuit.
expectation_value = final_observable.expectation_value()
The final step is to calculate the expectation value of this transformed
observable with respect to the simple, known initial state of all qubits in
the \(|0\rangle\) state. The result, 0.0
, is the same value you would
get from a statevector simulation.
Next Steps
You now have a foundational understanding of the pyrauli
workflow. To learn
how to solve specific problems, head to our Build and Run Circuits.
To understand the theory behind the Heisenberg picture and Pauli
back-propagation, see our Core Concepts.