Skip to content

Commit

Permalink
Add a default max_step to processors using the smallest gate time (qu…
Browse files Browse the repository at this point in the history
…tip#2040)

* Add a default max_step using the smallest gate time

* Increase the maximal number of steps allowed in the test
  • Loading branch information
BoxiLi committed Dec 9, 2022
1 parent ee9c200 commit 52b222e
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
1 change: 1 addition & 0 deletions doc/changes/2040.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a default max_step to processors
6 changes: 6 additions & 0 deletions qutip/qip/device/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from qutip.tensor import tensor
from qutip.mesolve import mesolve
from qutip.mcsolve import mcsolve
from qutip import Options
from qutip.qip.circuit import QubitCircuit
from qutip.qip.noise import (
Noise, RelaxationNoise, DecoherenceNoise,
Expand Down Expand Up @@ -738,6 +739,11 @@ def run_state(self, init_state=None, analytical=False, states=None,
else:
kwargs["c_ops"] = sys_c_ops

# set the max step size as 1/2 of the smallest gate time.
options = kwargs.get("options", Options())
if options.max_step == 0.:
options.max_step = np.min(np.diff(self.get_full_tlist())) / 2
kwargs["options"] = options
# choose solver:
if solver == "mesolve":
evo_result = mesolve(
Expand Down
4 changes: 2 additions & 2 deletions qutip/tests/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def test_numerical_evolution(
init_state = qutip.tensor(extra, state)
else:
init_state = state
options = qutip.Options(store_final_state=True, nsteps=50_000)
options = qutip.Options(store_final_state=True, nsteps=100_000)
result = device.run_state(init_state=init_state,
analytical=False,
options=options)
Expand Down Expand Up @@ -138,7 +138,7 @@ def test_numerical_circuit(circuit, device_class, kwargs, schedule_mode):
init_state = qutip.tensor(extra, state)
else:
init_state = state
options = qutip.Options(store_final_state=True, nsteps=50_000)
options = qutip.Options(store_final_state=True, nsteps=100_000)
result = device.run_state(init_state=init_state,
analytical=False,
options=options)
Expand Down
35 changes: 33 additions & 2 deletions qutip/tests/test_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
assert_, run_module_suite, assert_allclose, assert_equal)
import numpy as np

from qutip.qip.device.processor import Processor
from qutip.qip.device import Processor, LinearSpinChain
from qutip.states import basis
from qutip.operators import sigmaz, sigmax, sigmay, identity, destroy
from qutip.qip.operations.gates import hadamard_transform
Expand All @@ -16,6 +16,9 @@
from qutip.qip.qubits import qubit_states
from qutip.metrics import fidelity
from qutip.qip.pulse import Pulse
from qutip.qip.circuit import QubitCircuit

import pytest


class TestCircuitProcessor:
Expand Down Expand Up @@ -322,7 +325,35 @@ def testChooseSolver(self):
result = proc.run_state(init_state=init_state, solver="mcsolve")
assert_allclose(
fidelity(result.states[-1], qubit_states(2, [0, 1, 0, 0])),
1, rtol=1.e-7)
1, rtol=1.e-7)

def test_max_step_size(self):
num_qubits = 2
init_state = tensor([basis(2, 1), basis(2, 1)])
qc = QubitCircuit(2)

# ISWAP acts trivially on the initial states.
# If no max_step are defined,
# the solver will choose a step size too large
# such that the X gate will be skipped.
qc.add_gate("ISWAP", targets=[0, 1])
qc.add_gate("ISWAP", targets=[0, 1])
qc.add_gate("X", targets=[0])
processor = LinearSpinChain(num_qubits)
processor.load_circuit(qc)

# No max_step
final_state = processor.run_state(
init_state, options=Options(max_step=10000) # too large max_step
).states[-1]
expected_state = tensor([basis(2, 0), basis(2, 1)])
assert pytest.approx(fidelity(final_state, expected_state), 0.001) == 0

# With default max_step
final_state = processor.run_state(init_state).states[-1]
expected_state = tensor([basis(2, 0), basis(2, 1)])
assert pytest.approx(fidelity(final_state, expected_state), 0.001) == 1


if __name__ == "__main__":
run_module_suite()

0 comments on commit 52b222e

Please sign in to comment.