Statistical Operations#
Statistical operations are simulator specific mathematical operations allowing you to compute properties of the simulated quantum state without making it collapse. All statistical operations will result in a real or complex number that will be stored in the Z-Register, and can be accessed from the results of the simulation through the zstates option, see Circuits and cloud execution page.
On this page you will find all statistical operations available on MIMIQ with explanations and examples.
Contents#
Expectation value#
Mathematical definition#
An expectation value for a pure state \(| \psi \rangle\) is defined as
where \(O\) is an operator. With respect to a density matrix \(\rho\) it’s given by
Usage on MIMIQ#
First we need to define the operator \(O\) of which we will compute the expectation value
>>> op = SigmaPlus()
SigmaPlus
is only one of the many operators available. Of course, every gate can be used as an operator, for example op = GateZ().
However, MIMIQ also supports many non-unitary operators such as SigmaPlus
, more about this on the Operators page.
To ask MIMIQ to compute the expectation value for a circuit you can create an ExpectationValue
object and push()
it to the circuit like this:
>>> circuit = Circuit()
>>> circuit.push(GateH(), 0)
1-qubit circuit with 1 instructions:
└── H @ q[0]
>>> # Ask to compute the expectation value
>>> ev = ExpectationValue(op)
>>> circuit.push(ev, 0, 0)
1-qubit circuit with 2 instructions:
├── H @ q[0]
└── ⟨SigmaPlus(1)⟩ @ q[0], z[0]
push()
function always follow the order of quantum register index first, classical register second (none in this case), and Z-register index last.0
is the index for the first qubit of the quantum register and the second 0
is the index of the Z-Register.Notice that the expectation value will be computed with respect to the quantum state of the system at the point in the circuit where the ExpectationValue
is added.
Entanglement#
MIMIQ supports statistical operations on entanglement for ordered bipartitions. For instance, for qubits [1...N]
MIMIQ can compute the entanglement between the bipartitions [1...k-1]
and [k...N]
.
For this reason when you push()
an entanglement operation to a circuit, you need to give it the qubit index k
that separates the two bipartitions, as well as the Z-register to store the result.
Warning
The following functions can only be used with the MPS backend.
Von Neumann Entropy#
Mathematical definition#
The entanglement entropy for a bipartition into subsystems A and B is defined for a pure state \(\rho = | \psi \rangle\langle \psi\) | as
where \(\rho_A = \mathrm{Tr}_B(\rho)\) is the reduced density matrix. A product state has \(\mathcal{S}(\rho_A)=0\) and a maximally entangled state between A and B gives \(\mathcal{S}(\rho_A)=1\).
We only consider bipartitions where \(A=\{1,\ldots,k-1\}\) and \(B=\{k,\ldots,N\}\),
for some k
and where N
is the total number of qubits.
Usage on MIMIQ#
VonNeumannEntropy
function.VonNeumannEntropy
. To indicate where to create the separation into two subsystems MIMIQ will use the first qubit index given to the push()
function, here is an example:>>> circuit = Circuit()
>>> # Asking to compute the Von Neumann entropy between the two subsystems separated between qubit 1 and 2
>>> circuit.push(VonNeumannEntropy(), 2, 0)
3-qubit circuit with 1 instructions:
└── VonNeumannEntropy @ q[2], z[1]
Here we compute the Von neumann entropy between the two subsystems [1,2]
and [3...N]
and write the results into the index 0
of the Z-register.
Note
For k=1
, A is empty and the Von Neumann entropy will always return 1.
Bond Dimension#
Mathematical definition#
The bond dimension is only defined for a matrix-product state (MPS), which can be written as (with \(i_1=i_{N+1}=1\))
Here, \(\chi_k`\) is the bond dimension, i.e. the dimension of the index \(i_k\). The first and last bond dimensions are dummies, \(chi_1=chi_{N+1}=1\). A bond dimension of 1 means there is no entanglement between the two halves of the system.
Usage on MIMIQ#
To compute the bond dimension between two halves of a system you can use the BondDim
operator and push()
to the circuit like any entanglement measure:
>>> circuit = Circuit()
>>> # Asking to compute the BondDim between the second and third qubits
>>> circuit.push(BondDim(), 2, 0)
3-qubit circuit with 1 instructions:
└── BondDim @ q[2], z[0]
Here we compute the bond dimension between the two subsystems [1,2]
and [3...N]
and write the results into index 0
of the Z-Register.
Note
For k=1
the bond dimension returned will always be 1.
Schmidt Rank#
Mathematical definition#
A Schmidt decomposition for a bipartition into subsystems A and B is defined for a pure state as
where \(|\alpha_i\rangle (|\beta_i\rangle)\) are orthonormal states acting on A
(B). The Schmidt rank is the number of terms r
in the sum. A product state
gives r=1
and r>1
signals entanglement.
We only consider bipartitions where \(A=\{1,\ldots,k-1\}\) and \(B=\{k,\ldots,N\}\),
for some k
and where N
is the total number of qubits.
Usage on MIMIQ#
To compute the Schmidt rank of a bipartition you can use the SchmidtRank
operator and push()
like all entanglement measures:
>>> circuit = Circuit()
>>> # Asking to compute the Schmidt rank between the two subsystems separated between qubits 1 and 2
>>> circuit.push(SchmidtRank(), 2, 0)
3-qubit circuit with 1 instructions:
└── SchmidtRank @ q[2], z[0]
Here we compute the Schmidt rank between the two subsystems [1,2]
and [3...N]
and write the results into index 0
of the Z-Register.
Note
For k=1, A is empty and the Schmidt rank will always return 1.
Amplitude#
Amplitude
.You can add the Amplitude
object to the circuit exactly like any other gate:
>>> mystery_circuit = Circuit()
>>> mystery_circuit.push(GateH(), range(0, 3))
3-qubit circuit with 3 instructions:
├── H @ q[0]
├── H @ q[1]
└── H @ q[2]
>>> # Define the Amplitude operator
>>> amp = Amplitude(BitString("101"))
>>> # Add the amplitude operator to the circuit and write the result in the first complex number of the Z-Register
>>> mystery_circuit.push(amp, 0)
3-qubit circuit with 4 instructions:
├── H @ q[0]
├── H @ q[1]
├── H @ q[2]
└── Amplitude(bs"101") @ z[0]
This will extract the amplitude of the basis state \(\ket{101}\). When adding the amplitude operation you do not need to give it any specific qubit target, the only index needed is for the Z-register to use for storing the result.