StateReader is a useful abstraction designed to retrieve relevant information from states (whenever applicable). Currently, there are three implementations of this trait: StateProbabilityReader, QubitProbabilityReader, and BlochSphereReader. Say, you have the following superposition:

val register = QubitRegister(Qubit.zero("my_qubit_1"), Qubit.zero("my_qubit_2"))

val circuit = Circuit(X(0), H(1), CNOT(0, 1)).withRegister(register)

val sp = QuantumSimulator().run(circuit)


If you apply the state reader to it, (i.e., print(StateProbabilityReader(sp).toHumanString)) the output will look like this:

10: Amplitude: 0.707+0.000i, P: 50.00%
11: Amplitude: 0.707+0.000i, P: 50.00%


The result of print(QubitProbabilityReader(register, sp).toHumanString) will show probabilities for individual qubits:

my_qubit_1: P(0) = 0.0% P(1) = 100.0%
my_qubit_2: P(0) = 50.0% P(1) = 50.0%


Notice how we passed the register to the QubitProbabilityReader and not to the StateProbabilityReader. It’s not a requirement but if you want the readout to include qubit labels then you have to pass the register since it’s the only place that stores qubit labels. The Superposition itself only contains the total state in the form of a vector.

BlochSphereReader can only be used on single-qubit states. It provides $\phi$ and $\theta$ angles and $x$, $y$, and $z$ coordinates of the qubit superposition on the Bloch sphere.

Let’s put a qubit in the superposition state and change it’s phase:

val circuit = Circuit(H(0), PHASE(Math.PI / 8, 0))
val sp = QuantumSimulator().run(circuit)


phi: 22.50°, theta: 90.00°, x: 0.92, y: 0.38, z: 0.00