Simulators
Sometimes when we assemble algorithms, it is useful to check whether or not the resulting state is consistent with our expectation. As the state is not something we have access to with experiment, we need to use a simulator to obtain the exact final output state. In QURI Parts, a simulator is any function that work with the explicit state vector or density matrices.
Qulacs simulators
In the quri_parts.qulacs.simulator
module, we provide 3 simulator features for state vectors.
evaluate_state_to_vector
run_circuit
get_marginal_probability
We introduce their functionalities in the following sections.
evaluate_state_to_vector
evaluate_state_to_vector
is a function that converts any non-parametric states into a QuantumStateVector
with an empty circuit.
from quri_parts.qulacs.simulator import evaluate_state_to_vector
from quri_parts.core.state import quantum_state
Converts a ComputationalBasisState
For example, bits = 2 = 0b10
represents . Note that vectors are arranged as follows: |00>, |01>, |10>, |11>, ... .
comp_state = quantum_state(n_qubits=2, bits=2)
out_state = evaluate_state_to_vector(comp_state)
print("State vector:")
print(out_state.vector)
print("")
print("Circuit:")
print(out_state.circuit.gates)
#output
State vector:
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]
Circuit:
()
Converts a GeneralCircuitQuantumState
from quri_parts.circuit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.add_H_gate(0)
circuit.add_CNOT_gate(0, 1)
bell_state = quantum_state(n_qubits=2, circuit=circuit)
out_state = evaluate_state_to_vector(bell_state)
print("State vector:")
print(out_state.vector)
print("")
print("Circuit:")
print(out_state.circuit.gates)
#output
State vector:
[0.70710678+0.j 0. +0.j 0. +0.j 0.70710678+0.j]
Circuit:
()
Converts a QuantumStateVector
import numpy as np
from scipy.stats import unitary_group
circuit = QuantumCircuit(2)
circuit.add_H_gate(0)
circuit.add_CNOT_gate(0, 1)
init_state_vector = unitary_group.rvs(4)[:, 0]
state = quantum_state(n_qubits=2, vector=init_state_vector, circuit=circuit)
out_state = evaluate_state_to_vector(state)
print("State vector:")
print(out_state.vector)
print("")
print("Circuit:")
print(out_state.circuit.gates)
#output
State vector:
[ 0.18421042+0.45591396j -0.29168606+0.44172833j -0.28458075+0.61735372j
-0.10691909+0.06678914j]
Circuit:
()
run_circuit
run_circuit
is a function that acts a quantum circuit on a state vector represented by a numpy.array
and returns the resulting state vector.
from quri_parts.qulacs.simulator import run_circuit
n_qubits = 2
circuit = QuantumCircuit(n_qubits)
circuit.add_H_gate(0)
circuit.add_CNOT_gate(0, 1)
init_state_vector = unitary_group.rvs(2**n_qubits)[:, 0]
out_state = run_circuit(circuit, init_state_vector)
out_state
#output
array([0.43459926-0.04472012j, 0.18045739+0.10382554j,
0.5202943 -0.51833746j, 0.21666993+0.42361922j])
get_marginal_probability
Sometimes we need to perform partial measurement to a state. get_marginal_probability
returns the probability of obtaining the specified computational basis eigenstate after measuring a subset of the qubits. For example, for a state with 3 qubits, setting measured_values={0: 1, 2: 0}
outputs the probability of obtaining 1 from the 0th qubit and 0 from the 2nd qubit. That is, the probability is obtained from the coefficients of and .
from quri_parts.qulacs.simulator import get_marginal_probability
n_qubits = 3
init_state = unitary_group.rvs(2**n_qubits)[:, 0]
state = quantum_state(n_qubits=n_qubits, vector=init_state)
out_state = evaluate_state_to_vector(state)
print("State vector:")
print(out_state.vector)
print("")
print(
"Probability of measuring 1 from to 0th qubit and 0 from the 2nd qubit:",
get_marginal_probability(init_state, measured_values={0: 1, 2: 0})
)
#output
State vector:
[-0.01264178-0.02125235j 0.3049721 -0.36580166j -0.25013693-0.26850866j
0.03871132-0.15817578j -0.27692887+0.45944717j -0.32775336+0.40284975j
-0.19829442-0.0291523j 0.1171112 -0.00301804j]
Probability of measuring 1 from to 0th qubit and 0 from the 2nd qubit: 0.2533369796205178
Stim simulators
We also provide
evaluate_state_to_vector
run_circuit
in the quri_parts.stim.simulator
module. The functionalities are the same as those in quri_parts.qulacs.simulator
except that they only accept Clifford circuits and performs the circuit execution using Stim.