Skip to content

Commit

Permalink
Merge 2121313 into 22c0ebf
Browse files Browse the repository at this point in the history
  • Loading branch information
BoxiLi committed Sep 7, 2022
2 parents 22c0ebf + 2121313 commit 8d4f7dc
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 60 deletions.
4 changes: 2 additions & 2 deletions doc/source/qip-simulator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ and computation proceeds. To demonstrate, we continue with our previous circuit:
.. testcode::

from qutip_qip.circuit import CircuitSimulator

sim = CircuitSimulator(qc, state=zero_state)
sim = CircuitSimulator(qc)
sim.initialize(zero_state)

This initializes the simulator object and carries out any pre-computation
required. There are two ways to carry out state evolution with the simulator.
Expand Down
59 changes: 17 additions & 42 deletions src/qutip_qip/circuit/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,30 +490,19 @@ def run(
final_state : Qobj
output state of the circuit run.
"""

if state.isket:
sim = CircuitSimulator(
self,
state,
cbits,
U_list,
measure_results,
"state_vector_simulator",
precompute_unitary,
)
mode = "state_vector_simulator"
elif state.isoper:
sim = CircuitSimulator(
self,
state,
cbits,
U_list,
measure_results,
"density_matrix_simulator",
precompute_unitary,
)
mode = "density_matrix_simulator"
else:
raise TypeError("State is not a ket or a density matrix.")
return sim.run(state, cbits).get_final_states(0)
sim = CircuitSimulator(
self,
U_list,
mode,
precompute_unitary,
)
return sim.run(state, cbits, measure_results).get_final_states(0)

def run_statistics(
self, state, U_list=None, cbits=None, precompute_unitary=False
Expand All @@ -530,11 +519,6 @@ def run_statistics(
initialization of the classical bits.
U_list: list of Qobj, optional
list of predefined unitaries corresponding to circuit.
measure_results : tuple of ints, optional
optional specification of each measurement result to enable
post-selection. If specified, the measurement results are
set to the tuple of bits (sequentially) instead of being
chosen at random.
precompute_unitary: Boolean, optional
Specify if computation is done by pre-computing and aggregating
gate unitaries. Possibly a faster method in the case of
Expand All @@ -546,27 +530,18 @@ def run_statistics(
Return a CircuitResult object containing
output states and and their probabilities.
"""

if state.isket:
sim = CircuitSimulator(
self,
state,
cbits,
U_list,
mode="state_vector_simulator",
precompute_unitary=precompute_unitary,
)
mode = "state_vector_simulator"
elif state.isoper:
sim = CircuitSimulator(
self,
state,
cbits,
U_list,
mode="density_matrix_simulator",
precompute_unitary=precompute_unitary,
)
mode = "density_matrix_simulator"
else:
raise TypeError("State is not a ket or a density matrix.")
sim = CircuitSimulator(
self,
U_list,
mode,
precompute_unitary,
)
return sim.run_statistics(state, cbits)

def resolve_gates(self, basis=["CNOT", "RX", "RY", "RZ"]):
Expand Down
27 changes: 11 additions & 16 deletions src/qutip_qip/circuit/circuitsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
gate_sequence_product,
)
from qutip import basis, ket2dm, Qobj, tensor
import warnings


__all__ = ["CircuitSimulator", "CircuitResult"]
Expand Down Expand Up @@ -253,12 +254,12 @@ class CircuitSimulator:
def __init__(
self,
qc,
state=None,
cbits=None,
U_list=None,
measure_results=None,
mode="state_vector_simulator",
precompute_unitary=False,
state=None,
cbits=None,
measure_results=None,
):
"""
Simulate state evolution for Quantum Circuits.
Expand All @@ -268,21 +269,9 @@ def __init__(
qc : :class:`.QubitCircuit`
Quantum Circuit to be simulated.
state: ket or oper
ket or density matrix
cbits: list of int, optional
initial value of classical bits
U_list: list of Qobj, optional
list of predefined unitaries corresponding to circuit.
measure_results : tuple of ints, optional
optional specification of each measurement result to enable
post-selection. If specified, the measurement results are
set to the tuple of bits (sequentially) instead of being
chosen at random.
mode: string, optional
Specify if input state (and therefore computation) is in
state-vector mode or in density matrix mode.
Expand Down Expand Up @@ -321,7 +310,13 @@ def __init__(
else:
self._process_ops()

self.initialize(state, cbits, measure_results)
if any(p is not None for p in (state, cbits, measure_results)):
warnings.warn(
"Initializing the quantum state, cbits and measure_results "
"when initializing the simulator is deprecated. "
"The inputs are ignored. "
"They should, instead, be provided when running the simulation."
)

def _process_ops(self):
"""
Expand Down
17 changes: 17 additions & 0 deletions tests/test_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,23 @@ def test_measurement_circuit(self):
else:
assert simulator.cbits[0] != simulator.cbits[1]

def test_circuit_with_selected_measurement_result(self):
qc = QubitCircuit(N=1, num_cbits=1)
qc.add_gate("SNOT", targets=0)
qc.add_measurement("M0", targets=0, classical_store=0)

# We reset the random seed so that
# if we don's select the measurement result,
# the two circuit should return the same value.
np.random.seed(0)
final_state = qc.run(qp.basis(2, 0), cbits=[0], measure_results=[0])
fid = pytest.approx(qp.fidelity(final_state, basis(2, 0)))
assert fid == 1.0
np.random.seed(0)
final_state = qc.run(qp.basis(2, 0), cbits=[0], measure_results=[1])
fid = pytest.approx(qp.fidelity(final_state, basis(2, 1)))
assert fid == 1.0

def test_gate_product(self):

filename = "qft.qasm"
Expand Down

0 comments on commit 8d4f7dc

Please sign in to comment.