From 8749f711f21a3c34b59b69df68b9cdbf53931036 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Mon, 1 Dec 2025 15:12:35 +0530 Subject: [PATCH 01/17] Uncomment test_qiskit.py --- tests/test_qiskit.py | 554 +++++++++++++++++++++---------------------- 1 file changed, 277 insertions(+), 277 deletions(-) diff --git a/tests/test_qiskit.py b/tests/test_qiskit.py index 1b9ec1438..c21680215 100644 --- a/tests/test_qiskit.py +++ b/tests/test_qiskit.py @@ -1,277 +1,277 @@ -# import pytest -# import numpy as np -# import random -# from numpy.testing import assert_allclose -# from qutip_qip.circuit import QubitCircuit -# from qutip_qip.device import ( -# LinearSpinChain, -# CircularSpinChain, -# DispersiveCavityQED, -# ) - -# # will skip tests in this entire file -# # if qiskit is not installed -# pytest.importorskip("qiskit") - -# from qiskit import QuantumCircuit -# from qiskit_aer import AerSimulator -# from qutip_qip.qiskit.provider import ( -# QiskitCircuitSimulator, -# QiskitPulseSimulator, -# ) -# from qutip_qip.qiskit.converter import ( -# convert_qiskit_circuit, -# _get_qutip_index, -# ) - - -# class TestConverter: -# """ -# Class for testing only the circuit conversion -# from qiskit to qutip. -# """ - -# def _compare_args(self, req_gate, res_gate): -# """Compare parameters of two gates""" -# res_arg = ( -# ( -# res_gate.arg_value -# if type(res_gate.arg_value) is list -# or type(res_gate.arg_value) is tuple -# else [res_gate.arg_value] -# ) -# if res_gate.arg_value -# else [] -# ) - -# req_arg = ( -# ( -# req_gate.arg_value -# if type(req_gate.arg_value) is list -# or type(req_gate.arg_value) is tuple -# else [req_gate.arg_value] -# ) -# if req_gate.arg_value -# else [] -# ) - -# if len(req_arg) != len(res_arg): -# return False - -# return np.allclose(req_arg, res_arg) - -# def _compare_gate(self, req_gate, res_gate, result_circuit: QubitCircuit): -# """Check whether two gates are equivalent""" -# check_condition = (req_gate.name == res_gate.name) and ( -# req_gate.targets -# == _get_qutip_index(res_gate.targets, result_circuit.N) -# ) -# if not check_condition: -# return False - -# if req_gate.name == "measure": -# check_condition = req_gate.classical_store == _get_qutip_index( -# res_gate.classical_store, result_circuit.num_cbits -# ) -# else: -# # todo: correct for float error in arg_value -# res_controls = ( -# _get_qutip_index(res_gate.controls, result_circuit.N) -# if res_gate.controls -# else None -# ) -# req_controls = req_gate.controls if req_gate.controls else None - -# check_condition = ( -# res_controls == req_controls -# ) and self._compare_args(req_gate, res_gate) - -# return check_condition - -# def _compare_circuit( -# self, result_circuit: QubitCircuit, required_circuit: QubitCircuit -# ) -> bool: -# """ -# Check whether two circuits are equivalent. -# """ -# if result_circuit.N != required_circuit.N or len( -# result_circuit.gates -# ) != len(required_circuit.gates): -# return False - -# for i, res_gate in enumerate(result_circuit.gates): -# req_gate = required_circuit.gates[i] - -# if not self._compare_gate(req_gate, res_gate, result_circuit): -# return False - -# return True - -# def test_single_qubit_conversion(self): -# """ -# Test to check conversion of a circuit -# containing a single qubit gate. -# """ -# qiskit_circuit = QuantumCircuit(1) -# qiskit_circuit.x(0) -# result_circuit = convert_qiskit_circuit(qiskit_circuit) -# required_circuit = QubitCircuit(1) -# required_circuit.add_gate("X", targets=[0]) - -# assert self._compare_circuit(result_circuit, required_circuit) - -# def test_controlled_qubit_conversion(self): -# """ -# Test to check conversion of a circuit -# containing a 2 qubit controlled gate. -# """ -# qiskit_circuit = QuantumCircuit(2) -# qiskit_circuit.cx(1, 0) -# result_circuit = convert_qiskit_circuit(qiskit_circuit) - -# required_circuit = QubitCircuit(2) -# required_circuit.add_gate("CX", targets=[0], controls=[1]) - -# assert self._compare_circuit(result_circuit, required_circuit) - -# def test_rotation_conversion(self): -# """ -# Test to check conversion of a circuit -# containing a single qubit rotation gate. -# """ -# qiskit_circuit = QuantumCircuit(1) -# qiskit_circuit.rx(np.pi / 3, 0) -# result_circuit = convert_qiskit_circuit(qiskit_circuit) -# required_circuit = QubitCircuit(1) -# required_circuit.add_gate("RX", targets=[0], arg_value=np.pi / 3) - -# assert self._compare_circuit(result_circuit, required_circuit) - - -# class TestSimulator: -# """ -# Class for testing whether a simulator -# gives correct results. -# """ - -# def test_circuit_simulator(self): -# """ -# Test whether the circuit_simulator matches the -# results of qiskit's statevector simulator. -# """ - -# # test single qubit operations -# circ1 = QuantumCircuit(2, 2) -# circ1.h(0) -# circ1.h(1) -# self._compare_results(circ1) - -# # test controlled operations -# circ2 = QuantumCircuit(2, 2) -# circ2.h(0) -# circ2.cx(0, 1) -# self._compare_results(circ2) - -# def test_allow_custom_gate(self): -# """ -# Asserts whether execution will fail on running a circuit -# with a custom sub-circuit with the option allow_custom_gate=False -# """ -# with pytest.raises(RuntimeError): -# circ = QuantumCircuit(2, 2) -# circ.h(0) -# # make a custom sub-circuit -# sub_circ = QuantumCircuit(1) -# sub_circ.x(0) -# my_gate = sub_circ.to_gate() -# circ.append(my_gate, [1]) - -# qutip_backend = QiskitCircuitSimulator() -# # running this with allow_custom_gate=False should raise -# # a RuntimeError due to the custom sub-circuit -# qutip_backend.run(circ, allow_custom_gate=False) - -# def test_measurements(self): -# """ -# Tests measurements by setting a predefined seed to -# obtain predetermined results. -# """ -# random.seed(1) -# predefined_counts = {"0": 233, "11": 267, "10": 254, "1": 270} - -# circ = QuantumCircuit(2, 2) -# circ.h(0) -# circ.h(1) -# circ.measure(0, 0) -# circ.measure(1, 1) - -# qutip_backend = QiskitCircuitSimulator() -# qutip_job = qutip_backend.run(circ) -# qutip_result = qutip_job.result() - -# assert qutip_result.get_counts(circ) == predefined_counts - -# def test_lsc_simulator(self): -# """ -# Test whether the pulse backend based on the LinearSpinChain model -# matches predefined correct results. -# """ -# circ, predefined_counts = self._init_pulse_test() - -# result = self._run_pulse_processor(LinearSpinChain(num_qubits=2), circ) -# assert result.get_counts() == predefined_counts - -# def test_csc_simulator(self): -# """ -# Test whether the pulse backend based on the CircularSpinChain model -# matches predefined correct results. -# """ -# circ, predefined_counts = self._init_pulse_test() - -# result = self._run_pulse_processor( -# CircularSpinChain(num_qubits=2), circ -# ) -# assert result.get_counts() == predefined_counts - -# def test_cavityqed_simulator(self): -# """ -# Test whether the pulse backend based on the DispersiveCavityQED -# model matches predefined correct results. -# """ -# circ, predefined_counts = self._init_pulse_test() - -# result = self._run_pulse_processor( -# DispersiveCavityQED(num_qubits=2, num_levels=10), circ -# ) -# assert result.get_counts() == predefined_counts - -# def _compare_results(self, qiskit_circuit: QuantumCircuit): - -# qutip_backend = QiskitCircuitSimulator() -# qutip_job = qutip_backend.run(qiskit_circuit) -# qutip_result = qutip_job.result() -# qutip_sv = qutip_result.data()["statevector"] - -# qiskit_backend = AerSimulator(method="statevector") -# qiskit_circuit.save_state() -# qiskit_job = qiskit_backend.run(qiskit_circuit) -# qiskit_result = qiskit_job.result() -# qiskit_sv = qiskit_result.data()["statevector"] - -# assert_allclose(qutip_sv, qiskit_sv) - -# def _run_pulse_processor(self, processor, circ): -# qutip_backend = QiskitPulseSimulator(processor) -# qutip_job = qutip_backend.run(circ) -# return qutip_job.result() - -# def _init_pulse_test(self): -# random.seed(1) - -# circ = QuantumCircuit(2, 2) -# circ.h(0) -# circ.h(1) - -# predefined_counts = {"0": 233, "11": 267, "1": 254, "10": 270} - -# return circ, predefined_counts +import pytest +import numpy as np +import random +from numpy.testing import assert_allclose +from qutip_qip.circuit import QubitCircuit +from qutip_qip.device import ( + LinearSpinChain, + CircularSpinChain, + DispersiveCavityQED, +) + +# will skip tests in this entire file +# if qiskit is not installed +pytest.importorskip("qiskit") + +from qiskit import QuantumCircuit +from qiskit_aer import AerSimulator +from qutip_qip.qiskit.provider import ( + QiskitCircuitSimulator, + QiskitPulseSimulator, +) +from qutip_qip.qiskit.converter import ( + convert_qiskit_circuit, + _get_qutip_index, +) + + +class TestConverter: + """ + Class for testing only the circuit conversion + from qiskit to qutip. + """ + + def _compare_args(self, req_gate, res_gate): + """Compare parameters of two gates""" + res_arg = ( + ( + res_gate.arg_value + if type(res_gate.arg_value) is list + or type(res_gate.arg_value) is tuple + else [res_gate.arg_value] + ) + if res_gate.arg_value + else [] + ) + + req_arg = ( + ( + req_gate.arg_value + if type(req_gate.arg_value) is list + or type(req_gate.arg_value) is tuple + else [req_gate.arg_value] + ) + if req_gate.arg_value + else [] + ) + + if len(req_arg) != len(res_arg): + return False + + return np.allclose(req_arg, res_arg) + + def _compare_gate(self, req_gate, res_gate, result_circuit: QubitCircuit): + """Check whether two gates are equivalent""" + check_condition = (req_gate.name == res_gate.name) and ( + req_gate.targets + == _get_qutip_index(res_gate.targets, result_circuit.N) + ) + if not check_condition: + return False + + if req_gate.name == "measure": + check_condition = req_gate.classical_store == _get_qutip_index( + res_gate.classical_store, result_circuit.num_cbits + ) + else: + # todo: correct for float error in arg_value + res_controls = ( + _get_qutip_index(res_gate.controls, result_circuit.N) + if res_gate.controls + else None + ) + req_controls = req_gate.controls if req_gate.controls else None + + check_condition = ( + res_controls == req_controls + ) and self._compare_args(req_gate, res_gate) + + return check_condition + + def _compare_circuit( + self, result_circuit: QubitCircuit, required_circuit: QubitCircuit + ) -> bool: + """ + Check whether two circuits are equivalent. + """ + if result_circuit.N != required_circuit.N or len( + result_circuit.gates + ) != len(required_circuit.gates): + return False + + for i, res_gate in enumerate(result_circuit.gates): + req_gate = required_circuit.gates[i] + + if not self._compare_gate(req_gate, res_gate, result_circuit): + return False + + return True + + def test_single_qubit_conversion(self): + """ + Test to check conversion of a circuit + containing a single qubit gate. + """ + qiskit_circuit = QuantumCircuit(1) + qiskit_circuit.x(0) + result_circuit = convert_qiskit_circuit(qiskit_circuit) + required_circuit = QubitCircuit(1) + required_circuit.add_gate("X", targets=[0]) + + assert self._compare_circuit(result_circuit, required_circuit) + + def test_controlled_qubit_conversion(self): + """ + Test to check conversion of a circuit + containing a 2 qubit controlled gate. + """ + qiskit_circuit = QuantumCircuit(2) + qiskit_circuit.cx(1, 0) + result_circuit = convert_qiskit_circuit(qiskit_circuit) + + required_circuit = QubitCircuit(2) + required_circuit.add_gate("CX", targets=[0], controls=[1]) + + assert self._compare_circuit(result_circuit, required_circuit) + + def test_rotation_conversion(self): + """ + Test to check conversion of a circuit + containing a single qubit rotation gate. + """ + qiskit_circuit = QuantumCircuit(1) + qiskit_circuit.rx(np.pi / 3, 0) + result_circuit = convert_qiskit_circuit(qiskit_circuit) + required_circuit = QubitCircuit(1) + required_circuit.add_gate("RX", targets=[0], arg_value=np.pi / 3) + + assert self._compare_circuit(result_circuit, required_circuit) + + +class TestSimulator: + """ + Class for testing whether a simulator + gives correct results. + """ + + def test_circuit_simulator(self): + """ + Test whether the circuit_simulator matches the + results of qiskit's statevector simulator. + """ + + # test single qubit operations + circ1 = QuantumCircuit(2, 2) + circ1.h(0) + circ1.h(1) + self._compare_results(circ1) + + # test controlled operations + circ2 = QuantumCircuit(2, 2) + circ2.h(0) + circ2.cx(0, 1) + self._compare_results(circ2) + + def test_allow_custom_gate(self): + """ + Asserts whether execution will fail on running a circuit + with a custom sub-circuit with the option allow_custom_gate=False + """ + with pytest.raises(RuntimeError): + circ = QuantumCircuit(2, 2) + circ.h(0) + # make a custom sub-circuit + sub_circ = QuantumCircuit(1) + sub_circ.x(0) + my_gate = sub_circ.to_gate() + circ.append(my_gate, [1]) + + qutip_backend = QiskitCircuitSimulator() + # running this with allow_custom_gate=False should raise + # a RuntimeError due to the custom sub-circuit + qutip_backend.run(circ, allow_custom_gate=False) + + def test_measurements(self): + """ + Tests measurements by setting a predefined seed to + obtain predetermined results. + """ + random.seed(1) + predefined_counts = {"0": 233, "11": 267, "10": 254, "1": 270} + + circ = QuantumCircuit(2, 2) + circ.h(0) + circ.h(1) + circ.measure(0, 0) + circ.measure(1, 1) + + qutip_backend = QiskitCircuitSimulator() + qutip_job = qutip_backend.run(circ) + qutip_result = qutip_job.result() + + assert qutip_result.get_counts(circ) == predefined_counts + + def test_lsc_simulator(self): + """ + Test whether the pulse backend based on the LinearSpinChain model + matches predefined correct results. + """ + circ, predefined_counts = self._init_pulse_test() + + result = self._run_pulse_processor(LinearSpinChain(num_qubits=2), circ) + assert result.get_counts() == predefined_counts + + def test_csc_simulator(self): + """ + Test whether the pulse backend based on the CircularSpinChain model + matches predefined correct results. + """ + circ, predefined_counts = self._init_pulse_test() + + result = self._run_pulse_processor( + CircularSpinChain(num_qubits=2), circ + ) + assert result.get_counts() == predefined_counts + + def test_cavityqed_simulator(self): + """ + Test whether the pulse backend based on the DispersiveCavityQED + model matches predefined correct results. + """ + circ, predefined_counts = self._init_pulse_test() + + result = self._run_pulse_processor( + DispersiveCavityQED(num_qubits=2, num_levels=10), circ + ) + assert result.get_counts() == predefined_counts + + def _compare_results(self, qiskit_circuit: QuantumCircuit): + + qutip_backend = QiskitCircuitSimulator() + qutip_job = qutip_backend.run(qiskit_circuit) + qutip_result = qutip_job.result() + qutip_sv = qutip_result.data()["statevector"] + + qiskit_backend = AerSimulator(method="statevector") + qiskit_circuit.save_state() + qiskit_job = qiskit_backend.run(qiskit_circuit) + qiskit_result = qiskit_job.result() + qiskit_sv = qiskit_result.data()["statevector"] + + assert_allclose(qutip_sv, qiskit_sv) + + def _run_pulse_processor(self, processor, circ): + qutip_backend = QiskitPulseSimulator(processor) + qutip_job = qutip_backend.run(circ) + return qutip_job.result() + + def _init_pulse_test(self): + random.seed(1) + + circ = QuantumCircuit(2, 2) + circ.h(0) + circ.h(1) + + predefined_counts = {"0": 233, "11": 267, "1": 254, "10": 270} + + return circ, predefined_counts From 4ec6a0dd03efa95ddaa65a49a50cbd55eef30c46 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Mon, 1 Dec 2025 15:14:16 +0530 Subject: [PATCH 02/17] Update year in License file --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index a2435ceca..3f725a7bf 100755 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011 to 2021 inclusive, QuTiP developers and contributors. +Copyright (c) 2011 to 2025 inclusive, QuTiP developers and contributors. All rights reserved. Redistribution and use in source and binary forms, with or without From ff243cc02ed6a3b45857ccaed87ba75589d75c80 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Mon, 1 Dec 2025 15:19:53 +0530 Subject: [PATCH 03/17] Removed unused imports from /src/qutip-qip/devices --- src/qutip_qip/device/cavityqed.py | 8 ++------ src/qutip_qip/device/circuitqed.py | 1 - src/qutip_qip/device/modelprocessor.py | 6 +----- src/qutip_qip/device/optpulseprocessor.py | 3 +-- src/qutip_qip/device/spinchain.py | 2 -- src/qutip_qip/qasm.py | 2 +- 6 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/qutip_qip/device/cavityqed.py b/src/qutip_qip/device/cavityqed.py index 9fdb269f0..32bb9db0d 100644 --- a/src/qutip_qip/device/cavityqed.py +++ b/src/qutip_qip/device/cavityqed.py @@ -11,14 +11,10 @@ sigmaz, basis, Qobj, - QobjEvo, ) -from ..circuit import QubitCircuit -from ..operations import Gate -from .processor import Processor, Model +from .processor import Model from .modelprocessor import ModelProcessor, _to_array -from ..pulse import Pulse -from ..compiler import GateCompiler, CavityQEDCompiler +from ..compiler import CavityQEDCompiler __all__ = ["DispersiveCavityQED"] diff --git a/src/qutip_qip/device/circuitqed.py b/src/qutip_qip/device/circuitqed.py index c3135ea16..b5984e71f 100644 --- a/src/qutip_qip/device/circuitqed.py +++ b/src/qutip_qip/device/circuitqed.py @@ -8,7 +8,6 @@ from ..transpiler import to_chain_structure from ..compiler import SCQubitsCompiler from ..noise import ZZCrossTalk -from ..operations import expand_operator __all__ = ["SCQubits"] diff --git a/src/qutip_qip/device/modelprocessor.py b/src/qutip_qip/device/modelprocessor.py index a500e7a44..4439914fd 100644 --- a/src/qutip_qip/device/modelprocessor.py +++ b/src/qutip_qip/device/modelprocessor.py @@ -3,12 +3,8 @@ import numpy as np -from qutip import Qobj, QobjEvo, tensor, mesolve, basis -from ..operations import globalphase -from ..circuit import QubitCircuit +from qutip import Qobj, basis from .processor import Processor -from ..compiler import GateCompiler -from ..pulse import Pulse __all__ = ["ModelProcessor"] diff --git a/src/qutip_qip/device/optpulseprocessor.py b/src/qutip_qip/device/optpulseprocessor.py index dbdead4ed..c89dce956 100644 --- a/src/qutip_qip/device/optpulseprocessor.py +++ b/src/qutip_qip/device/optpulseprocessor.py @@ -1,10 +1,9 @@ from collections.abc import Iterable import warnings -import numbers import numpy as np -from qutip import Qobj, identity, tensor, mesolve +from qutip import Qobj, identity from ..circuit import QubitCircuit from .processor import Processor from ..operations import gate_sequence_product, expand_operator diff --git a/src/qutip_qip/device/spinchain.py b/src/qutip_qip/device/spinchain.py index 0a4e350e6..defc556e9 100644 --- a/src/qutip_qip/device/spinchain.py +++ b/src/qutip_qip/device/spinchain.py @@ -3,10 +3,8 @@ import numpy as np from qutip import sigmax, sigmay, sigmaz, tensor -from ..circuit import QubitCircuit from .processor import Model from .modelprocessor import ModelProcessor, _to_array -from ..pulse import Pulse from ..compiler import SpinChainCompiler from ..transpiler import to_chain_structure diff --git a/src/qutip_qip/qasm.py b/src/qutip_qip/qasm.py index 7d3f015bf..90cd73303 100644 --- a/src/qutip_qip/qasm.py +++ b/src/qutip_qip/qasm.py @@ -7,7 +7,7 @@ import warnings import numpy as np -from math import pi +from math import pi # Don't remove from .circuit import QubitCircuit from .operations import ( From df8195c2c93a3d2acd138d0c4120c27c7611ce2c Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Mon, 1 Dec 2025 15:21:09 +0530 Subject: [PATCH 04/17] Removed unused imports from /src/qutip-qip/compiler --- src/qutip_qip/compiler/cavityqedcompiler.py | 3 --- src/qutip_qip/compiler/gatecompiler.py | 1 - src/qutip_qip/compiler/scheduler.py | 1 - src/qutip_qip/compiler/spinchaincompiler.py | 3 --- 4 files changed, 8 deletions(-) diff --git a/src/qutip_qip/compiler/cavityqedcompiler.py b/src/qutip_qip/compiler/cavityqedcompiler.py index e6685f91f..398dd48b3 100644 --- a/src/qutip_qip/compiler/cavityqedcompiler.py +++ b/src/qutip_qip/compiler/cavityqedcompiler.py @@ -1,8 +1,5 @@ -from functools import partial import numpy as np -import scipy -from ..circuit import QubitCircuit from ..operations import Gate from ..compiler import GateCompiler, Instruction diff --git a/src/qutip_qip/compiler/gatecompiler.py b/src/qutip_qip/compiler/gatecompiler.py index a10d9fe4e..4473ad321 100644 --- a/src/qutip_qip/compiler/gatecompiler.py +++ b/src/qutip_qip/compiler/gatecompiler.py @@ -5,7 +5,6 @@ from .instruction import Instruction from .scheduler import Scheduler from ..circuit import QubitCircuit -from ..operations import Gate __all__ = ["GateCompiler"] diff --git a/src/qutip_qip/compiler/scheduler.py b/src/qutip_qip/compiler/scheduler.py index 8464c3053..cd37efafc 100644 --- a/src/qutip_qip/compiler/scheduler.py +++ b/src/qutip_qip/compiler/scheduler.py @@ -1,4 +1,3 @@ -from collections import deque from copy import deepcopy from functools import cmp_to_key from random import shuffle diff --git a/src/qutip_qip/compiler/spinchaincompiler.py b/src/qutip_qip/compiler/spinchaincompiler.py index 2cfda158f..0c477dbca 100644 --- a/src/qutip_qip/compiler/spinchaincompiler.py +++ b/src/qutip_qip/compiler/spinchaincompiler.py @@ -1,8 +1,5 @@ -from functools import partial import numpy as np -from ..circuit import QubitCircuit -from ..operations import Gate from ..compiler import GateCompiler, Instruction From c822de09cd479fbe1b07ccf6d4d6ba03afe9ac32 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Mon, 1 Dec 2025 15:23:22 +0530 Subject: [PATCH 05/17] Removed unused imports from /src/qutip-qip/circuit --- src/qutip_qip/circuit/circuit.py | 1 - src/qutip_qip/circuit/circuitsimulator.py | 2 +- src/qutip_qip/circuit/mat_renderer.py | 3 +-- src/qutip_qip/circuit/texrenderer.py | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/qutip_qip/circuit/circuit.py b/src/qutip_qip/circuit/circuit.py index f855f3e66..c459b6d93 100644 --- a/src/qutip_qip/circuit/circuit.py +++ b/src/qutip_qip/circuit/circuit.py @@ -4,7 +4,6 @@ import inspect from collections.abc import Iterable -from math import pi import numpy as np from copy import deepcopy diff --git a/src/qutip_qip/circuit/circuitsimulator.py b/src/qutip_qip/circuit/circuitsimulator.py index 1e73d3438..806dc330d 100644 --- a/src/qutip_qip/circuit/circuitsimulator.py +++ b/src/qutip_qip/circuit/circuitsimulator.py @@ -8,7 +8,7 @@ Measurement, expand_operator, ) -from qutip import basis, ket2dm, Qobj, tensor +from qutip import ket2dm, Qobj, tensor import warnings diff --git a/src/qutip_qip/circuit/mat_renderer.py b/src/qutip_qip/circuit/mat_renderer.py index 7122e06dc..fd74c8b6b 100644 --- a/src/qutip_qip/circuit/mat_renderer.py +++ b/src/qutip_qip/circuit/mat_renderer.py @@ -2,8 +2,7 @@ Module for rendering a quantum circuit using matplotlib library. """ -from typing import Union, Optional, List, Dict -from dataclasses import dataclass +from typing import Union import numpy as np import matplotlib.pyplot as plt diff --git a/src/qutip_qip/circuit/texrenderer.py b/src/qutip_qip/circuit/texrenderer.py index 94818f0a3..7cb4dac81 100644 --- a/src/qutip_qip/circuit/texrenderer.py +++ b/src/qutip_qip/circuit/texrenderer.py @@ -3,7 +3,6 @@ import shutil import tempfile import warnings -import functools import subprocess import collections From 511b5264bcb0c8b07ada14e2d0163006120741d2 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Mon, 1 Dec 2025 15:26:21 +0530 Subject: [PATCH 06/17] Removed remaining unused imports --- doc/pulse-paper/main_example.py | 3 +-- doc/pulse-paper/qft.py | 3 +-- src/qutip_qip/algorithms/qpe.py | 1 - src/qutip_qip/operations/gateclass.py | 12 ++---------- src/qutip_qip/operations/measurement.py | 3 +-- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/doc/pulse-paper/main_example.py b/doc/pulse-paper/main_example.py index a18d3666e..1cee4b033 100644 --- a/doc/pulse-paper/main_example.py +++ b/doc/pulse-paper/main_example.py @@ -1,8 +1,7 @@ import numpy as np from qutip import basis from qutip_qip.circuit import QubitCircuit -from qutip_qip.device import LinearSpinChain, SpinChainModel, Processor, ModelProcessor -from qutip_qip.compiler import SpinChainCompiler +from qutip_qip.device import LinearSpinChain, SpinChainModel, Processor from qutip_qip.noise import RelaxationNoise qc = QubitCircuit(3) qc.add_gate("X", targets=2) diff --git a/doc/pulse-paper/qft.py b/doc/pulse-paper/qft.py index 66305d37b..1dc3e25a6 100644 --- a/doc/pulse-paper/qft.py +++ b/doc/pulse-paper/qft.py @@ -1,6 +1,5 @@ TEXTWIDTH = 5.93 LINEWIDTH = 3.22 -import matplotlib as mpl import matplotlib.pyplot as plt try: from quantum_plots import global_setup @@ -11,7 +10,7 @@ import numpy as np -from qutip import basis, fidelity, Options +from qutip import basis, fidelity from qutip_qip.device import LinearSpinChain from qutip_qip.algorithms import qft_gate_sequence diff --git a/src/qutip_qip/algorithms/qpe.py b/src/qutip_qip/algorithms/qpe.py index db6211fe4..2add63091 100644 --- a/src/qutip_qip/algorithms/qpe.py +++ b/src/qutip_qip/algorithms/qpe.py @@ -1,5 +1,4 @@ import numpy as np -from qutip import Qobj from qutip_qip.operations import Gate, ControlledGate from qutip_qip.circuit import QubitCircuit from qutip_qip.algorithms import qft_gate_sequence diff --git a/src/qutip_qip/operations/gateclass.py b/src/qutip_qip/operations/gateclass.py index e281b6e16..b756a5941 100644 --- a/src/qutip_qip/operations/gateclass.py +++ b/src/qutip_qip/operations/gateclass.py @@ -1,19 +1,11 @@ import numbers from collections.abc import Iterable -from itertools import product, chain -from functools import partial, reduce -from operator import mul +from functools import partial from typing import Optional -import warnings -import inspect -from copy import deepcopy - import numpy as np -import scipy.sparse as sp - import qutip -from qutip import Qobj, identity, qeye, sigmax, sigmay, sigmaz, tensor, fock_dm +from qutip import Qobj, qeye from .gates import ( rx, ry, diff --git a/src/qutip_qip/operations/measurement.py b/src/qutip_qip/operations/measurement.py index 45e24ba97..ce83aefe3 100644 --- a/src/qutip_qip/operations/measurement.py +++ b/src/qutip_qip/operations/measurement.py @@ -1,11 +1,10 @@ from collections.abc import Iterable import numbers -import os import numpy as np import qutip -from qutip import basis, Qobj +from qutip import basis from qutip.measurement import measurement_statistics from .gates import expand_operator From 3921ddab6c5d133085275fa0ce6d241f5d668760 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Mon, 1 Dec 2025 15:30:14 +0530 Subject: [PATCH 07/17] Removed unused import from /src/tests --- tests/test_circuit.py | 1 - tests/test_compiler.py | 2 +- tests/test_measurement.py | 12 ++++++------ tests/test_model.py | 3 +-- tests/test_pulse.py | 1 - tests/test_qasm.py | 2 +- tests/test_qpe.py | 7 +++---- tests/test_scheduler.py | 4 ++-- tests/test_shor_code.py | 2 -- 9 files changed, 14 insertions(+), 20 deletions(-) diff --git a/tests/test_circuit.py b/tests/test_circuit.py index 88f17168d..8eb22d929 100644 --- a/tests/test_circuit.py +++ b/tests/test_circuit.py @@ -14,7 +14,6 @@ rand_ket, fock_dm, basis, - rand_dm, bell_state, ket2dm, identity, diff --git a/tests/test_compiler.py b/tests/test_compiler.py index a17897313..73f7d8fc9 100644 --- a/tests/test_compiler.py +++ b/tests/test_compiler.py @@ -7,7 +7,7 @@ from qutip_qip.device import ( DispersiveCavityQED, CircularSpinChain, LinearSpinChain) from qutip_qip.compiler import ( - SpinChainCompiler, CavityQEDCompiler, Instruction, GateCompiler + SpinChainCompiler, Instruction, GateCompiler ) from qutip_qip.circuit import QubitCircuit from qutip import basis, fidelity diff --git a/tests/test_measurement.py b/tests/test_measurement.py index b25ac03c1..2d5022fd9 100644 --- a/tests/test_measurement.py +++ b/tests/test_measurement.py @@ -1,13 +1,13 @@ import numpy as np -import scipy import pytest from math import sqrt from qutip_qip.operations import Measurement -from qutip import (Qobj, basis, ket2dm, - sigmax, sigmay, sigmaz, identity, tensor, rand_ket) -from qutip.measurement import (measure_povm, measurement_statistics_povm, - measure_observable, - measurement_statistics_observable) +from qutip import ( + basis, + ket2dm, + tensor, + rand_ket +) import qutip diff --git a/tests/test_model.py b/tests/test_model.py index f2aaede87..3e2bfa531 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -1,10 +1,9 @@ import pytest import numpy as np -from numpy.testing import assert_array_equal, assert_allclose +from numpy.testing import assert_array_equal import qutip from qutip_qip.device import ( - Model, Processor, DispersiveCavityQED, LinearSpinChain, diff --git a/tests/test_pulse.py b/tests/test_pulse.py index 43b0768de..e3c7db29f 100644 --- a/tests/test_pulse.py +++ b/tests/test_pulse.py @@ -1,7 +1,6 @@ import numpy as np from numpy.testing import assert_, assert_allclose -import qutip from qutip import ( Qobj, sigmax, sigmay, sigmaz, identity, tensor, QobjEvo ) diff --git a/tests/test_qasm.py b/tests/test_qasm.py index c469b181b..1161cac03 100644 --- a/tests/test_qasm.py +++ b/tests/test_qasm.py @@ -6,7 +6,7 @@ import qutip from qutip_qip.qasm import read_qasm, circuit_to_qasm_str from qutip_qip.circuit import QubitCircuit -from qutip import tensor, rand_ket, basis, rand_dm, identity +from qutip import tensor, rand_ket, basis, identity from qutip_qip.operations import cnot, ry, Measurement, swap diff --git a/tests/test_qpe.py b/tests/test_qpe.py index 161f18fee..1a4f7c62e 100644 --- a/tests/test_qpe.py +++ b/tests/test_qpe.py @@ -1,9 +1,8 @@ import numpy as np -from numpy.testing import assert_, assert_equal, assert_allclose +from numpy.testing import assert_, assert_equal import unittest -from qutip import Qobj, sigmax, sigmay, sigmaz, identity, basis, tensor -from qutip_qip.circuit import QubitCircuit -from qutip_qip.operations import gate_sequence_product, ControlledGate +from qutip import Qobj, sigmaz, tensor +from qutip_qip.operations import ControlledGate from qutip_qip.algorithms.qpe import qpe, CustomGate, create_controlled_unitary diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py index 38d1bf5ec..36c291ac7 100644 --- a/tests/test_scheduler.py +++ b/tests/test_scheduler.py @@ -3,8 +3,8 @@ from qutip_qip.circuit import QubitCircuit from qutip_qip.compiler import Instruction, Scheduler -from qutip_qip.operations import Gate, gate_sequence_product -from qutip import process_fidelity, qeye, tracedist +from qutip_qip.operations import Gate +from qutip import qeye, tracedist def _verify_scheduled_circuit(circuit, gate_cycle_indices): diff --git a/tests/test_shor_code.py b/tests/test_shor_code.py index bc130e869..a1529fef3 100644 --- a/tests/test_shor_code.py +++ b/tests/test_shor_code.py @@ -1,7 +1,5 @@ import pytest import qutip -import numpy as np -from qutip_qip.circuit import QubitCircuit from qutip_qip.algorithms import ShorCode From 314c67a13f7eb0ebb6e78d169d0cdafaeabcda3d Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 2 Dec 2025 08:10:56 +0530 Subject: [PATCH 08/17] Added version level skip for qiskit --- tests/test_qiskit.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_qiskit.py b/tests/test_qiskit.py index c21680215..b22f079bf 100644 --- a/tests/test_qiskit.py +++ b/tests/test_qiskit.py @@ -13,6 +13,15 @@ # if qiskit is not installed pytest.importorskip("qiskit") +from packaging import version +import qiskit + +if version.parse(qiskit.__version__) >= version.parse("1.0.0"): + pytest.skip( + "qiskit < 1.0.0 required", + allow_module_level=True, + ) + from qiskit import QuantumCircuit from qiskit_aer import AerSimulator from qutip_qip.qiskit.provider import ( From 50eac17fbde5f2119e33569b4ffe0886055d5fbd Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 2 Dec 2025 08:24:37 +0530 Subject: [PATCH 09/17] Separated model into a separate file --- src/qutip_qip/device/__init__.py | 21 ++++- src/qutip_qip/device/model.py | 121 ++++++++++++++++++++++++++ src/qutip_qip/device/processor.py | 135 +----------------------------- tests/test_processor.py | 28 +++---- tests/test_vqa.py | 2 - 5 files changed, 156 insertions(+), 151 deletions(-) create mode 100644 src/qutip_qip/device/model.py diff --git a/src/qutip_qip/device/__init__.py b/src/qutip_qip/device/__init__.py index 468315c77..be445af25 100644 --- a/src/qutip_qip/device/__init__.py +++ b/src/qutip_qip/device/__init__.py @@ -2,13 +2,28 @@ Simulation of quantum hardware. """ -from .processor import Processor, Model +from .cavityqed import DispersiveCavityQED, CavityQEDModel +from .circuitqed import SCQubits, SCQubitsModel +from .model import Model from .modelprocessor import ModelProcessor +from .processor import Processor from .spinchain import ( LinearSpinChain, CircularSpinChain, SpinChainModel, ) -from .cavityqed import DispersiveCavityQED, CavityQEDModel from .optpulseprocessor import OptPulseProcessor -from .circuitqed import SCQubits, SCQubitsModel + +__all__ = [ + "DispersiveCavityQED", + "CavityQEDModel", + "SCQubits", + "SCQubitsModel", + "Model", + "ModelProcessor", + "Processor", + "LinearSpinChain", + "CircularSpinChain", + "SpinChainModel", + "OptPulseProcessor" +] diff --git a/src/qutip_qip/device/model.py b/src/qutip_qip/device/model.py new file mode 100644 index 000000000..51c015db2 --- /dev/null +++ b/src/qutip_qip/device/model.py @@ -0,0 +1,121 @@ +from copy import deepcopy +from typing import List, Tuple, Hashable + +from ..noise import Noise +from qutip import Qobj + +class Model: + """ + Template class for a physical model representing quantum hardware. + The concrete model class does not have to inherit from this, + as long as the following methods are defined. + + Parameters + ---------- + num_qubits: int + The number of qubits. + dims : list, optional + The dimension of each component system. + Default value is a qubit system of ``dim=[2,2,2,...,2]``. + **params : + Hardware parameters for the model. + + Attributes + ---------- + num_qubits: int + The number of qubits. + dims : list, optional + The dimension of each component system. + params : dict + Hardware parameters for the model. + """ + + def __init__(self, num_qubits, dims=None, **params): + self.num_qubits = num_qubits + self.dims = dims if dims is not None else num_qubits * [2] + self.params = deepcopy(params) + self._controls = {} + self._drift = [] + self._noise = [] + + def get_all_drift(self) -> List[Tuple[Qobj, List[int]]]: + """ + Get all the drift Hamiltonians. + + Returns + ------- + drift_hamiltonian_list : list + A list of drift Hamiltonians in the form of + ``[(qobj, targets), ...]``. + """ + return self._drift + + def get_control(self, label: Hashable) -> Tuple[Qobj, List[int]]: + """ + Get the control Hamiltonian corresponding to the label. + + Parameters + ---------- + label : hashable object + A label that identifies the Hamiltonian. + + Returns + ------- + control_hamiltonian : tuple + The control Hamiltonian in the form of ``(qobj, targets)``. + """ + if hasattr(self, "_old_index_label_map"): + _old_index_label_map = self._old_index_label_map + if isinstance(label, int): + label = _old_index_label_map[label] + return self._controls[label] + + def get_control_labels(self) -> List[Hashable]: + """ + Get a list of all available control Hamiltonians. + Optional, required only when plotting the pulses or + using the optimal control algorithm. + + Returns + ------- + label_list : list of hashable objects + A list of hashable objects each corresponds to + an available control Hamiltonian. + """ + return list(self._controls.keys()) + + def get_noise(self) -> List[Noise]: + """ + Get a list of :obj:`.Noise` objects. + Single qubit relaxation (T1, T2) are not included here. + Optional method. + + Returns + ------- + noise_list : list + A list of :obj:`.Noise`. + """ + if not hasattr(self, "_noise"): + return [] + return self._noise + + def _add_drift(self, qobj, targets): + if not hasattr(self, "_drift"): + raise NotImplementedError( + "The model does not support adding drift." + ) + self._drift.append((qobj, targets)) + + def _add_control(self, label, qobj, targets): + if not hasattr(self, "_controls"): + raise NotImplementedError( + "The model does not support adding controls." + ) + self._controls[label] = (qobj, targets) + + def _add_noise(self, noise): + if not hasattr(self, "_noise"): + raise NotImplementedError( + "The model does not support adding noise objects." + ) + self._noise.append(noise) diff --git a/src/qutip_qip/device/processor.py b/src/qutip_qip/device/processor.py index c490d0fb3..b262fc161 100644 --- a/src/qutip_qip/device/processor.py +++ b/src/qutip_qip/device/processor.py @@ -1,8 +1,6 @@ from collections.abc import Iterable import warnings from copy import deepcopy -from typing import List, Tuple, Hashable - import numpy as np import qutip @@ -12,12 +10,10 @@ Noise, process_noise, ) +from .model import Model from ..pulse import Pulse, Drift, _fill_coeff -__all__ = ["Processor"] - - class Processor(object): """ The noisy quantum device simulator using QuTiP dynamic solvers. @@ -37,9 +33,8 @@ class Processor(object): Parameters ---------- - num_qubits : int, optional + num_qubits : int The number of qubits. - It replaces the old API ``N``. dims : list, optional The dimension of each component system. @@ -75,15 +70,13 @@ class Processor(object): def __init__( self, - num_qubits=None, + num_qubits, dims=None, spline_kind="step_func", model=None, - N=None, t1=None, t2=None, ): - num_qubits = num_qubits if num_qubits is not None else N if model is None: self.model = Model(num_qubits=num_qubits, dims=dims, t1=t1, t2=t2) else: @@ -154,10 +147,6 @@ def noise(self): """.coverage""" return self.get_noise() - @property - def N(self): - return self.num_qubits - #################################################################### # Hamiltonian model def get_all_drift(self): @@ -184,7 +173,6 @@ def _get_drift_obj(self): """generate the Drift representation""" drift_obj = Drift() for qobj, targets in self.model.get_all_drift(): - num_qubits = len(qobj.dims[0]) drift_obj.add_drift(qobj, targets) return drift_obj @@ -1249,120 +1237,3 @@ def _pulse_interpolate(pulse, tlist): pulse.tlist, coeff, kind=kind, bounds_error=False, fill_value=0.0 ) return inter(tlist) - - -class Model: - """ - Template class for a physical model representing quantum hardware. - The concrete model class does not have to inherit from this, - as long as the following methods are defined. - - Parameters - ---------- - num_The number of qubits - The number of qubits. - dims : list, optional - The dimension of each component system. - Default value is a qubit system of ``dim=[2,2,2,...,2]``. - **params : - Hardware parameters for the model. - - Attributes - ---------- - num_The number of qubits - The number of qubits. - dims : list, optional - The dimension of each component system. - params : dict - Hardware parameters for the model. - """ - - def __init__(self, num_qubits, dims=None, **params): - self.num_qubits = num_qubits if num_qubits is not None else N - self.dims = dims if dims is not None else num_qubits * [2] - self.params = deepcopy(params) - self._controls = {} - self._drift = [] - self._noise = [] - - def get_all_drift(self) -> List[Tuple[Qobj, List[int]]]: - """ - Get all the drift Hamiltonians. - - Returns - ------- - drift_hamiltonian_list : list - A list of drift Hamiltonians in the form of - ``[(qobj, targets), ...]``. - """ - return self._drift - - def get_control(self, label: Hashable) -> Tuple[Qobj, List[int]]: - """ - Get the control Hamiltonian corresponding to the label. - - Parameters - ---------- - label : hashable object - A label that identifies the Hamiltonian. - - Returns - ------- - control_hamiltonian : tuple - The control Hamiltonian in the form of ``(qobj, targets)``. - """ - if hasattr(self, "_old_index_label_map"): - _old_index_label_map = self._old_index_label_map - if isinstance(label, int): - label = _old_index_label_map[label] - return self._controls[label] - - def get_control_labels(self) -> List[Hashable]: - """ - Get a list of all available control Hamiltonians. - Optional, required only when plotting the pulses or - using the optimal control algorithm. - - Returns - ------- - label_list : list of hashable objects - A list of hashable objects each corresponds to - an available control Hamiltonian. - """ - return list(self._controls.keys()) - - def get_noise(self) -> List[Noise]: - """ - Get a list of :obj:`.Noise` objects. - Single qubit relaxation (T1, T2) are not included here. - Optional method. - - Returns - ------- - noise_list : list - A list of :obj:`.Noise`. - """ - if not hasattr(self, "_noise"): - return [] - return self._noise - - def _add_drift(self, qobj, targets): - if not hasattr(self, "_drift"): - raise NotImplementedError( - "The model does not support adding drift." - ) - self._drift.append((qobj, targets)) - - def _add_control(self, label, qobj, targets): - if not hasattr(self, "_controls"): - raise NotImplementedError( - "The model does not support adding controls." - ) - self._controls[label] = (qobj, targets) - - def _add_noise(self, noise): - if not hasattr(self, "_noise"): - raise NotImplementedError( - "The model does not support adding noise objects." - ) - self._noise.append(noise) diff --git a/tests/test_processor.py b/tests/test_processor.py index 5a682a431..a4e637772 100644 --- a/tests/test_processor.py +++ b/tests/test_processor.py @@ -45,13 +45,13 @@ def test_save_read(self): """ Test for saving and reading a pulse matrix """ - proc = Processor(N=2) + proc = Processor(num_qubits=2) proc.add_control(sigmaz(), label="sz") proc.add_control(sigmax(), label="sx") - proc1 = Processor(N=2) + proc1 = Processor(num_qubits=2) proc1.add_control(sigmaz(), label="sz") proc1.add_control(sigmax(), label="sx") - proc2 = Processor(N=2) + proc2 = Processor(num_qubits=2) proc2.add_control(sigmaz(), label="sz") proc2.add_control(sigmax(), label="sx") # TODO generalize to different tlist @@ -82,7 +82,7 @@ def test_id_evolution(self): Test for identity evolution """ N = 1 - proc = Processor(N=N) + proc = Processor(num_qubits=N) init_state = rand_ket(2) tlist = [0., 1., 2.] proc.add_pulse(Pulse(identity(2), 0, tlist, False)) @@ -145,7 +145,7 @@ def test_plot(self): # step_func tlist = np.linspace(0., 2*np.pi, 20) - processor = Processor(N=1, spline_kind="step_func") + processor = Processor(num_qubits=1, spline_kind="step_func") processor.add_control(sigmaz(), label="sz") processor.set_all_coeffs({"sz": np.array([np.sin(t) for t in tlist])}) processor.set_all_tlist(tlist) @@ -156,7 +156,7 @@ def test_plot(self): # cubic spline tlist = np.linspace(0., 2*np.pi, 20) - processor = Processor(N=1, spline_kind="cubic") + processor = Processor(num_qubits=1, spline_kind="cubic") processor.add_control(sigmaz(), label="sz") processor.set_all_coeffs({"sz": np.array([np.sin(t) for t in tlist])}) processor.set_all_tlist(tlist) @@ -175,7 +175,7 @@ def testSpline(self): tlist = np.array([0, 1, 2, 3], dtype=float) coeff = np.array([0, 1, 2, 3], dtype=float) - processor = Processor(N=1, spline_kind="step_func") + processor = Processor(num_qubits=1, spline_kind="step_func") processor.add_control(sigmaz(), label="sz") processor.set_all_coeffs({"sz": coeff}) processor.set_tlist(tlist) @@ -187,7 +187,7 @@ def testSpline(self): noisy_qobjevo, c_ops = processor.get_qobjevo(noisy=True) assert_allclose(noisy_qobjevo(0.5).data.to_array(), sigmaz().data.to_array() * 0.0) - processor_cubic = Processor(N=1, spline_kind="cubic") + processor_cubic = Processor(num_qubits=1, spline_kind="cubic") processor_cubic.add_control(sigmaz(), label="sz") processor_cubic.set_all_coeffs({"sz": coeff}) processor_cubic.set_all_tlist(tlist) @@ -203,7 +203,7 @@ def testGetObjevo(self): """ tlist = np.array([1, 2, 3, 4, 5, 6], dtype=float) coeff = np.array([1, 1, 1, 1, 1, 1], dtype=float) - processor = Processor(N=1) + processor = Processor(num_qubits=1) processor.add_control(sigmaz(), label="sz") processor.set_all_coeffs({"sz": coeff}) processor.set_all_tlist(tlist) @@ -240,7 +240,7 @@ def testGetObjevo(self): assert_allclose(c_ops[0](1.0).data.to_array(), sigmax().data.to_array()) # With Amplitude Noise - processor = Processor(N=1, spline_kind="cubic") + processor = Processor(num_qubits=1, spline_kind="cubic") processor.add_control(sigmaz(), label="sz") tlist = np.linspace(1, 6, int(5/0.2)) @@ -281,7 +281,7 @@ def testNoise(self): init_state = qubit_states(2, [0, 0, 0, 0]) tlist = np.array([0., np.pi/2.]) a = destroy(2) - proc = Processor(N=2) + proc = Processor(num_qubits=2) proc.add_control(sigmax(), targets=1, label="sx") proc.set_all_coeffs({"sx": np.array([1.])}) proc.set_all_tlist(tlist) @@ -317,7 +317,7 @@ def testMultiLevelSystem(self): Test for processor with multi-level system """ N = 2 - proc = Processor(N=N, dims=[2, 3]) + proc = Processor(num_qubits=N, dims=[2, 3]) proc.add_control(tensor(sigmaz(), rand_dm(3, density=1.)), label="sz0") proc.set_all_coeffs({"sz0": np.array([1, 2])}) proc.set_all_tlist(np.array([0., 1., 2])) @@ -327,7 +327,7 @@ def testDrift(self): """ Test for the drift Hamiltonian """ - processor = Processor(N=1) + processor = Processor(num_qubits=1) processor.add_drift(sigmax() / 2, 0) tlist = np.array([0., np.pi, 2*np.pi, 3*np.pi]) processor.add_pulse(Pulse(None, None, tlist, False)) @@ -347,7 +347,7 @@ def testChooseSolver(self): init_state = qubit_states(2, [0, 0, 0, 0]) tlist = np.linspace(0., np.pi/2., 10) a = destroy(2) - proc = Processor(N=2, t2=100) + proc = Processor(num_qubits=2, t2=100) proc.add_control(sigmax(), targets=1, label="sx") proc.set_all_coeffs({"sx": np.array([1.] * len(tlist))}) proc.set_all_tlist(tlist) diff --git a/tests/test_vqa.py b/tests/test_vqa.py index a7cf41de3..4dc7ef466 100644 --- a/tests/test_vqa.py +++ b/tests/test_vqa.py @@ -1,6 +1,4 @@ import pytest -import functools -import itertools import numpy as np import qutip from qutip_qip.operations import expand_operator From be723e4fe95de1ca2a3318ff67369b8916abfb3e Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 2 Dec 2025 08:36:35 +0530 Subject: [PATCH 10/17] Restructured module imports --- src/qutip_qip/device/cavityqed.py | 3 --- src/qutip_qip/device/circuitqed.py | 3 --- src/qutip_qip/device/model.py | 1 + src/qutip_qip/device/modelprocessor.py | 3 --- src/qutip_qip/device/optpulseprocessor.py | 3 --- src/qutip_qip/device/spinchain.py | 3 --- 6 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/qutip_qip/device/cavityqed.py b/src/qutip_qip/device/cavityqed.py index 32bb9db0d..64a842fa4 100644 --- a/src/qutip_qip/device/cavityqed.py +++ b/src/qutip_qip/device/cavityqed.py @@ -17,9 +17,6 @@ from ..compiler import CavityQEDCompiler -__all__ = ["DispersiveCavityQED"] - - class DispersiveCavityQED(ModelProcessor): """ The processor based on the physical implementation of diff --git a/src/qutip_qip/device/circuitqed.py b/src/qutip_qip/device/circuitqed.py index b5984e71f..29c46d7c4 100644 --- a/src/qutip_qip/device/circuitqed.py +++ b/src/qutip_qip/device/circuitqed.py @@ -10,9 +10,6 @@ from ..noise import ZZCrossTalk -__all__ = ["SCQubits"] - - class SCQubits(ModelProcessor): """ A chain of superconducting qubits with fixed frequency diff --git a/src/qutip_qip/device/model.py b/src/qutip_qip/device/model.py index 51c015db2..bfbde9b0b 100644 --- a/src/qutip_qip/device/model.py +++ b/src/qutip_qip/device/model.py @@ -4,6 +4,7 @@ from ..noise import Noise from qutip import Qobj + class Model: """ Template class for a physical model representing quantum hardware. diff --git a/src/qutip_qip/device/modelprocessor.py b/src/qutip_qip/device/modelprocessor.py index 4439914fd..499095fc9 100644 --- a/src/qutip_qip/device/modelprocessor.py +++ b/src/qutip_qip/device/modelprocessor.py @@ -7,9 +7,6 @@ from .processor import Processor -__all__ = ["ModelProcessor"] - - class ModelProcessor(Processor): """ The base class for a circuit processor simulating a physical device, diff --git a/src/qutip_qip/device/optpulseprocessor.py b/src/qutip_qip/device/optpulseprocessor.py index c89dce956..f4de7c6e2 100644 --- a/src/qutip_qip/device/optpulseprocessor.py +++ b/src/qutip_qip/device/optpulseprocessor.py @@ -9,9 +9,6 @@ from ..operations import gate_sequence_product, expand_operator -__all__ = ["OptPulseProcessor"] - - class OptPulseProcessor(Processor): """ A processor that uses diff --git a/src/qutip_qip/device/spinchain.py b/src/qutip_qip/device/spinchain.py index defc556e9..1feb4f1b6 100644 --- a/src/qutip_qip/device/spinchain.py +++ b/src/qutip_qip/device/spinchain.py @@ -9,9 +9,6 @@ from ..transpiler import to_chain_structure -__all__ = ["SpinChain", "LinearSpinChain", "CircularSpinChain"] - - class SpinChain(ModelProcessor): """ The processor based on the physical implementation of From b44e2a55ea5f9c27d51c35bbfe8cae99b85268b6 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 9 Dec 2025 20:06:17 +0530 Subject: [PATCH 11/17] lint fixes --- src/qutip_qip/device/__init__.py | 2 +- src/qutip_qip/device/processor.py | 2 +- src/qutip_qip/qasm.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qutip_qip/device/__init__.py b/src/qutip_qip/device/__init__.py index be445af25..2347c4459 100644 --- a/src/qutip_qip/device/__init__.py +++ b/src/qutip_qip/device/__init__.py @@ -25,5 +25,5 @@ "LinearSpinChain", "CircularSpinChain", "SpinChainModel", - "OptPulseProcessor" + "OptPulseProcessor", ] diff --git a/src/qutip_qip/device/processor.py b/src/qutip_qip/device/processor.py index b262fc161..9c1903841 100644 --- a/src/qutip_qip/device/processor.py +++ b/src/qutip_qip/device/processor.py @@ -70,7 +70,7 @@ class Processor(object): def __init__( self, - num_qubits, + num_qubits=None, dims=None, spline_kind="step_func", model=None, diff --git a/src/qutip_qip/qasm.py b/src/qutip_qip/qasm.py index 90cd73303..21674350f 100644 --- a/src/qutip_qip/qasm.py +++ b/src/qutip_qip/qasm.py @@ -7,7 +7,7 @@ import warnings import numpy as np -from math import pi # Don't remove +from math import pi # Don't remove from .circuit import QubitCircuit from .operations import ( From 68e7edc7c4d0e0af011d44df320a6b028a1cffcb Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 9 Dec 2025 21:16:19 +0530 Subject: [PATCH 12/17] Changed relative import to absolute in src/circuit and refactored module import structure --- src/qutip_qip/circuit/__init__.py | 11 ++++++++--- src/qutip_qip/circuit/_decompose.py | 2 +- src/qutip_qip/circuit/circuit.py | 10 ++-------- src/qutip_qip/circuit/circuitsimulator.py | 5 +---- src/qutip_qip/circuit/mat_renderer.py | 4 ++-- src/qutip_qip/circuit/texrenderer.py | 2 +- src/qutip_qip/circuit/text_renderer.py | 4 ++-- 7 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/qutip_qip/circuit/__init__.py b/src/qutip_qip/circuit/__init__.py index d0264108e..a7c7adc7a 100644 --- a/src/qutip_qip/circuit/__init__.py +++ b/src/qutip_qip/circuit/__init__.py @@ -2,10 +2,15 @@ import warnings -from .circuit import * -from .circuitsimulator import * -from ..operations import Gate, Measurement +from .circuitsimulator import CircuitResult, CircuitSimulator +from .circuit import QubitCircuit +from qutip_qip.operations import Gate, Measurement +__all__ = [ + "CircuitSimulator", + "CircuitResult", + "QubitCircuit", +] def _add_deprecation(fun, msg): def newfun(*args, **kwargs): diff --git a/src/qutip_qip/circuit/_decompose.py b/src/qutip_qip/circuit/_decompose.py index 2eae07e28..eb21bd3c1 100644 --- a/src/qutip_qip/circuit/_decompose.py +++ b/src/qutip_qip/circuit/_decompose.py @@ -5,7 +5,7 @@ """ import numpy as np -from ..operations import Gate +from qutip_qip.operations import Gate __all__ = ["_resolve_to_universal", "_resolve_2q_basis"] diff --git a/src/qutip_qip/circuit/circuit.py b/src/qutip_qip/circuit/circuit.py index c459b6d93..96a2ee745 100644 --- a/src/qutip_qip/circuit/circuit.py +++ b/src/qutip_qip/circuit/circuit.py @@ -10,13 +10,13 @@ from .texrenderer import TeXRenderer from ._decompose import _resolve_to_universal, _resolve_2q_basis -from ..operations import ( +from qutip_qip.operations import ( Gate, Measurement, expand_operator, GATE_CLASS_MAP, ) -from .circuitsimulator import ( +from qutip_qip.circuit import ( CircuitSimulator, CircuitResult, ) @@ -35,12 +35,6 @@ def DisplaySVG(data, *args, **kwargs): return data -__all__ = [ - "QubitCircuit", - "CircuitResult", -] - - class QubitCircuit: """ Representation of a quantum program/algorithm, maintaining a sequence diff --git a/src/qutip_qip/circuit/circuitsimulator.py b/src/qutip_qip/circuit/circuitsimulator.py index 806dc330d..a45d9809c 100644 --- a/src/qutip_qip/circuit/circuitsimulator.py +++ b/src/qutip_qip/circuit/circuitsimulator.py @@ -3,7 +3,7 @@ from functools import reduce import numpy as np -from ..operations import ( +from qutip_qip.operations import ( Gate, Measurement, expand_operator, @@ -12,9 +12,6 @@ import warnings -__all__ = ["CircuitSimulator", "CircuitResult"] - - def _flatten(lst): """ Helper to flatten lists. diff --git a/src/qutip_qip/circuit/mat_renderer.py b/src/qutip_qip/circuit/mat_renderer.py index fd74c8b6b..51d2cc282 100644 --- a/src/qutip_qip/circuit/mat_renderer.py +++ b/src/qutip_qip/circuit/mat_renderer.py @@ -15,8 +15,8 @@ ) from .base_renderer import BaseRenderer, StyleConfig -from ..operations import Gate, Measurement -from ..circuit import QubitCircuit +from qutip_qip.operations import Gate, Measurement +from qutip_qip.circuit import QubitCircuit __all__ = [ "MatRenderer", diff --git a/src/qutip_qip/circuit/texrenderer.py b/src/qutip_qip/circuit/texrenderer.py index 7cb4dac81..61b11d422 100644 --- a/src/qutip_qip/circuit/texrenderer.py +++ b/src/qutip_qip/circuit/texrenderer.py @@ -6,7 +6,7 @@ import subprocess import collections -from ..operations import Gate +from qutip_qip.operations import Gate __all__ = ["TeXRenderer", "CONVERTERS"] diff --git a/src/qutip_qip/circuit/text_renderer.py b/src/qutip_qip/circuit/text_renderer.py index c7d50f431..dae8c2c9d 100644 --- a/src/qutip_qip/circuit/text_renderer.py +++ b/src/qutip_qip/circuit/text_renderer.py @@ -6,8 +6,8 @@ from typing import List from .base_renderer import BaseRenderer, StyleConfig -from ..operations import Gate, Measurement -from . import QubitCircuit +from qutip_qip.operations import Gate, Measurement +from qutip_qip.circuit import QubitCircuit __all__ = [ "TextRenderer", From ad0e4df24fecc0c12880769a200a54ad8ae9aaf8 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 9 Dec 2025 21:19:10 +0530 Subject: [PATCH 13/17] Changed relative import to absolute in src/compiler and refactored module import structure --- src/qutip_qip/compiler/__init__.py | 12 +++++++++++- src/qutip_qip/compiler/cavityqedcompiler.py | 7 ++----- src/qutip_qip/compiler/circuitqedcompiler.py | 7 ++----- src/qutip_qip/compiler/gatecompiler.py | 9 +++------ src/qutip_qip/compiler/instruction.py | 3 --- src/qutip_qip/compiler/scheduler.py | 6 +++--- src/qutip_qip/compiler/spinchaincompiler.py | 5 +---- 7 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/qutip_qip/compiler/__init__.py b/src/qutip_qip/compiler/__init__.py index b90b0a293..e7ab7c985 100644 --- a/src/qutip_qip/compiler/__init__.py +++ b/src/qutip_qip/compiler/__init__.py @@ -3,6 +3,16 @@ from .instruction import Instruction from .scheduler import Scheduler from .gatecompiler import GateCompiler -from .cavityqedcompiler import CavityQEDCompiler from .spinchaincompiler import SpinChainCompiler +from .cavityqedcompiler import CavityQEDCompiler from .circuitqedcompiler import SCQubitsCompiler + + +__all__ = [ + "Instruction", + "Scheduler", + "GateCompiler", + "SpinChainCompiler", + "CavityQEDCompiler", + "SCQubitsCompiler", +] diff --git a/src/qutip_qip/compiler/cavityqedcompiler.py b/src/qutip_qip/compiler/cavityqedcompiler.py index 398dd48b3..389a431b3 100644 --- a/src/qutip_qip/compiler/cavityqedcompiler.py +++ b/src/qutip_qip/compiler/cavityqedcompiler.py @@ -1,10 +1,7 @@ import numpy as np -from ..operations import Gate -from ..compiler import GateCompiler, Instruction - - -__all__ = ["CavityQEDCompiler"] +from qutip_qip.operations import Gate +from qutip_qip.compiler import GateCompiler, Instruction class CavityQEDCompiler(GateCompiler): diff --git a/src/qutip_qip/compiler/circuitqedcompiler.py b/src/qutip_qip/compiler/circuitqedcompiler.py index 12434a0f8..d54f22755 100644 --- a/src/qutip_qip/compiler/circuitqedcompiler.py +++ b/src/qutip_qip/compiler/circuitqedcompiler.py @@ -1,10 +1,7 @@ import numpy as np -from ..operations import Gate -from ..compiler import GateCompiler, Instruction - - -__all__ = ["SCQubitsCompiler"] +from qutip_qip.operations import Gate +from qutip_qip.compiler import GateCompiler, Instruction class SCQubitsCompiler(GateCompiler): diff --git a/src/qutip_qip/compiler/gatecompiler.py b/src/qutip_qip/compiler/gatecompiler.py index 4473ad321..0afd4cee7 100644 --- a/src/qutip_qip/compiler/gatecompiler.py +++ b/src/qutip_qip/compiler/gatecompiler.py @@ -2,12 +2,9 @@ import numpy as np from scipy import signal -from .instruction import Instruction -from .scheduler import Scheduler -from ..circuit import QubitCircuit - - -__all__ = ["GateCompiler"] +from qutip_qip.compiler import Instruction +from qutip_qip.compiler import Scheduler +from qutip_qip.circuit import QubitCircuit class GateCompiler(object): diff --git a/src/qutip_qip/compiler/instruction.py b/src/qutip_qip/compiler/instruction.py index 91788efca..526e6ac95 100644 --- a/src/qutip_qip/compiler/instruction.py +++ b/src/qutip_qip/compiler/instruction.py @@ -2,9 +2,6 @@ import numpy as np -__all__ = ["Instruction"] - - class Instruction: """ Representation of pulses that implement a quantum gate. diff --git a/src/qutip_qip/compiler/scheduler.py b/src/qutip_qip/compiler/scheduler.py index cd37efafc..2a63ce301 100644 --- a/src/qutip_qip/compiler/scheduler.py +++ b/src/qutip_qip/compiler/scheduler.py @@ -2,9 +2,9 @@ from functools import cmp_to_key from random import shuffle -from ..circuit import QubitCircuit -from ..operations import Gate -from .instruction import Instruction +from qutip_qip.circuit import QubitCircuit +from qutip_qip.operations import Gate +from qutip_qip.compiler import Instruction class InstructionsGraph: diff --git a/src/qutip_qip/compiler/spinchaincompiler.py b/src/qutip_qip/compiler/spinchaincompiler.py index 0c477dbca..446b31d7e 100644 --- a/src/qutip_qip/compiler/spinchaincompiler.py +++ b/src/qutip_qip/compiler/spinchaincompiler.py @@ -1,9 +1,6 @@ import numpy as np -from ..compiler import GateCompiler, Instruction - - -__all__ = ["SpinChainCompiler"] +from qutip_qip.compiler import GateCompiler, Instruction class SpinChainCompiler(GateCompiler): From 6061c0fb8909e260359d961db0a6baee212b6fde Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 9 Dec 2025 21:30:40 +0530 Subject: [PATCH 14/17] Changed relative import to absolute in src/device and refactored module import structure --- src/qutip_qip/device/__init__.py | 6 +++--- src/qutip_qip/device/cavityqed.py | 10 +++++----- src/qutip_qip/device/circuitqed.py | 11 +++++------ src/qutip_qip/device/model.py | 2 +- src/qutip_qip/device/modelprocessor.py | 15 +-------------- src/qutip_qip/device/optpulseprocessor.py | 6 +++--- src/qutip_qip/device/processor.py | 11 ++++------- src/qutip_qip/device/spinchain.py | 8 ++++---- src/qutip_qip/device/utils.py | 12 ++++++++++++ 9 files changed, 38 insertions(+), 43 deletions(-) create mode 100644 src/qutip_qip/device/utils.py diff --git a/src/qutip_qip/device/__init__.py b/src/qutip_qip/device/__init__.py index 2347c4459..bff6b110c 100644 --- a/src/qutip_qip/device/__init__.py +++ b/src/qutip_qip/device/__init__.py @@ -2,16 +2,16 @@ Simulation of quantum hardware. """ -from .cavityqed import DispersiveCavityQED, CavityQEDModel -from .circuitqed import SCQubits, SCQubitsModel from .model import Model -from .modelprocessor import ModelProcessor from .processor import Processor +from .modelprocessor import ModelProcessor from .spinchain import ( LinearSpinChain, CircularSpinChain, SpinChainModel, ) +from .cavityqed import DispersiveCavityQED, CavityQEDModel +from .circuitqed import SCQubits, SCQubitsModel from .optpulseprocessor import OptPulseProcessor __all__ = [ diff --git a/src/qutip_qip/device/cavityqed.py b/src/qutip_qip/device/cavityqed.py index 64a842fa4..3fa9f1592 100644 --- a/src/qutip_qip/device/cavityqed.py +++ b/src/qutip_qip/device/cavityqed.py @@ -1,6 +1,5 @@ -import warnings from copy import deepcopy - +import warnings import numpy as np from qutip import ( @@ -12,9 +11,10 @@ basis, Qobj, ) -from .processor import Model -from .modelprocessor import ModelProcessor, _to_array -from ..compiler import CavityQEDCompiler +from qutip_qip.device import Model +from qutip_qip.device import ModelProcessor +from qutip_qip.compiler import CavityQEDCompiler +from qutip_qip.device.utils import _to_array class DispersiveCavityQED(ModelProcessor): diff --git a/src/qutip_qip/device/circuitqed.py b/src/qutip_qip/device/circuitqed.py index 29c46d7c4..ec38b5c02 100644 --- a/src/qutip_qip/device/circuitqed.py +++ b/src/qutip_qip/device/circuitqed.py @@ -1,13 +1,12 @@ from copy import deepcopy - import numpy as np from qutip import qeye, tensor, destroy, basis -from .processor import Model -from .modelprocessor import ModelProcessor, _to_array -from ..transpiler import to_chain_structure -from ..compiler import SCQubitsCompiler -from ..noise import ZZCrossTalk +from qutip_qip.device import Model, ModelProcessor +from qutip_qip.transpiler import to_chain_structure +from qutip_qip.compiler import SCQubitsCompiler +from qutip_qip.noise import ZZCrossTalk +from qutip_qip.device.utils import _to_array class SCQubits(ModelProcessor): diff --git a/src/qutip_qip/device/model.py b/src/qutip_qip/device/model.py index bfbde9b0b..483615db3 100644 --- a/src/qutip_qip/device/model.py +++ b/src/qutip_qip/device/model.py @@ -1,8 +1,8 @@ from copy import deepcopy from typing import List, Tuple, Hashable -from ..noise import Noise from qutip import Qobj +from qutip_qip.noise import Noise class Model: diff --git a/src/qutip_qip/device/modelprocessor.py b/src/qutip_qip/device/modelprocessor.py index 499095fc9..3bb6c8b00 100644 --- a/src/qutip_qip/device/modelprocessor.py +++ b/src/qutip_qip/device/modelprocessor.py @@ -1,10 +1,7 @@ -from collections.abc import Iterable -import numbers - import numpy as np from qutip import Qobj, basis -from .processor import Processor +from qutip_qip.device import Processor class ModelProcessor(Processor): @@ -274,13 +271,3 @@ def get_final_circuit_state(self, final_processor_state: Qobj) -> Qobj: Return the final state with the dimensions of the circuit. """ return final_processor_state - - -def _to_array(params, num_qubits): - """ - Transfer a parameter to an array. - """ - if isinstance(params, numbers.Real): - return np.asarray([params] * num_qubits) - elif isinstance(params, Iterable): - return np.asarray(params) diff --git a/src/qutip_qip/device/optpulseprocessor.py b/src/qutip_qip/device/optpulseprocessor.py index f4de7c6e2..5da651226 100644 --- a/src/qutip_qip/device/optpulseprocessor.py +++ b/src/qutip_qip/device/optpulseprocessor.py @@ -4,9 +4,9 @@ import numpy as np from qutip import Qobj, identity -from ..circuit import QubitCircuit -from .processor import Processor -from ..operations import gate_sequence_product, expand_operator +from qutip_qip.circuit import QubitCircuit +from qutip_qip.device import Processor +from qutip_qip.operations import gate_sequence_product, expand_operator class OptPulseProcessor(Processor): diff --git a/src/qutip_qip/device/processor.py b/src/qutip_qip/device/processor.py index 9c1903841..01624e3c1 100644 --- a/src/qutip_qip/device/processor.py +++ b/src/qutip_qip/device/processor.py @@ -5,13 +5,10 @@ import qutip from qutip import Qobj, QobjEvo, mesolve, mcsolve -from ..operations import globalphase -from ..noise import ( - Noise, - process_noise, -) -from .model import Model -from ..pulse import Pulse, Drift, _fill_coeff +from qutip_qip.operations import globalphase +from qutip_qip.noise import Noise, process_noise +from qutip_qip.device import Model +from qutip_qip.pulse import Pulse, Drift, _fill_coeff class Processor(object): diff --git a/src/qutip_qip/device/spinchain.py b/src/qutip_qip/device/spinchain.py index 1feb4f1b6..21127728b 100644 --- a/src/qutip_qip/device/spinchain.py +++ b/src/qutip_qip/device/spinchain.py @@ -3,10 +3,10 @@ import numpy as np from qutip import sigmax, sigmay, sigmaz, tensor -from .processor import Model -from .modelprocessor import ModelProcessor, _to_array -from ..compiler import SpinChainCompiler -from ..transpiler import to_chain_structure +from qutip_qip.device import Model, ModelProcessor +from qutip_qip.device.utils import _to_array +from qutip_qip.compiler import SpinChainCompiler +from qutip_qip.transpiler import to_chain_structure class SpinChain(ModelProcessor): diff --git a/src/qutip_qip/device/utils.py b/src/qutip_qip/device/utils.py new file mode 100644 index 000000000..5e4de3fcb --- /dev/null +++ b/src/qutip_qip/device/utils.py @@ -0,0 +1,12 @@ +from collections.abc import Iterable +import numbers +import numpy as np + +def _to_array(params, num_qubits): + """ + Transfer a parameter to an array. + """ + if isinstance(params, numbers.Real): + return np.asarray([params] * num_qubits) + elif isinstance(params, Iterable): + return np.asarray(params) \ No newline at end of file From 49b36c01bb56d69d0f77c95487a77b9f54650514 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 9 Dec 2025 21:51:35 +0530 Subject: [PATCH 15/17] Changed relative import to absolute in src/operators and refactored module import structure --- src/qutip_qip/operations/__init__.py | 161 +++++++++++++++++++++++- src/qutip_qip/operations/gateclass.py | 43 +------ src/qutip_qip/operations/gates.py | 41 ------ src/qutip_qip/operations/measurement.py | 5 +- 4 files changed, 161 insertions(+), 89 deletions(-) diff --git a/src/qutip_qip/operations/__init__.py b/src/qutip_qip/operations/__init__.py index cf82660b6..a16c0fc70 100644 --- a/src/qutip_qip/operations/__init__.py +++ b/src/qutip_qip/operations/__init__.py @@ -2,6 +2,161 @@ Operations on quantum circuits. """ -from .gates import * -from .gateclass import * -from .measurement import * +from .gates import ( + rx, + ry, + rz, + sqrtnot, + snot, + phasegate, + qrot, + x_gate, + y_gate, + z_gate, + cy_gate, + cz_gate, + s_gate, + t_gate, + qasmu_gate, + cs_gate, + ct_gate, + cphase, + cnot, + csign, + berkeley, + swapalpha, + swap, + iswap, + sqrtswap, + sqrtiswap, + fredkin, + molmer_sorensen, + toffoli, + rotation, + controlled_gate, + globalphase, + hadamard_transform, + qubit_clifford_group, + expand_operator, + gate_sequence_product, +) + +from .gateclass import ( + Gate, + GATE_CLASS_MAP, + X, + Y, + Z, + RX, + RY, + RZ, + H, + SNOT, + SQRTNOT, + S, + T, + R, + CNOT, + CX, + CY, + CZ, + CRX, + CRY, + CRZ, + CS, + CT, + CPHASE, + QASMU, + SWAP, + ControlledGate, + ISWAP, + SWAPALPHA, + SQRTISWAP, + SQRTSWAP, + MS, + TOFFOLI, + FREDKIN, + BERKELEY, + CSIGN, + RZX, +) + +from .measurement import Measurement + +__all__ = [ + "Measurement", + "rx", + "ry", + "rz", + "sqrtnot", + "snot", + "phasegate", + "qrot", + "x_gate", + "y_gate", + "z_gate", + "cy_gate", + "cz_gate", + "s_gate", + "t_gate", + "qasmu_gate", + "cs_gate", + "ct_gate", + "cphase", + "cnot", + "csign", + "berkeley", + "swapalpha", + "swap", + "iswap", + "sqrtswap", + "sqrtiswap", + "fredkin", + "molmer_sorensen", + "toffoli", + "rotation", + "controlled_gate", + "globalphase", + "hadamard_transform", + "qubit_clifford_group", + "expand_operator", + "gate_sequence_product", + "Gate", + "GATE_CLASS_MAP", + "X", + "Y", + "Z", + "RX", + "RY", + "RZ", + "H", + "SNOT", + "SQRTNOT", + "S", + "T", + "R", + "QASMU", + "SWAP", + "ControlledGate", + "ISWAP", + "CNOT", + "SQRTSWAP", + "SQRTISWAP", + "SWAPALPHA", + "MS", + "TOFFOLI", + "FREDKIN", + "BERKELEY", + "CNOT", + "CSIGN", + "CRX", + "CRY", + "CRZ", + "CY", + "CX", + "CZ", + "CS", + "CT", + "CPHASE", + "RZX", +] diff --git a/src/qutip_qip/operations/gateclass.py b/src/qutip_qip/operations/gateclass.py index b756a5941..2fb24c0ae 100644 --- a/src/qutip_qip/operations/gateclass.py +++ b/src/qutip_qip/operations/gateclass.py @@ -6,7 +6,7 @@ import numpy as np import qutip from qutip import Qobj, qeye -from .gates import ( +from qutip_qip.operations import ( rx, ry, rz, @@ -41,46 +41,7 @@ expand_operator, ) -__all__ = [ - "Gate", - "GATE_CLASS_MAP", - "X", - "Y", - "Z", - "RX", - "RY", - "RZ", - "H", - "SNOT", - "SQRTNOT", - "S", - "T", - "R", - "QASMU", - "SWAP", - "ControlledGate", - "ISWAP", - "CNOT", - "SQRTSWAP", - "SQRTISWAP", - "SWAPALPHA", - "MS", - "TOFFOLI", - "FREDKIN", - "BERKELEY", - "CNOT", - "CSIGN", - "CRX", - "CRY", - "CRZ", - "CY", - "CX", - "CZ", - "CS", - "CT", - "CPHASE", - "RZX", -] + """ .. testsetup:: diff --git a/src/qutip_qip/operations/gates.py b/src/qutip_qip/operations/gates.py index 10553451c..ff69be7a5 100644 --- a/src/qutip_qip/operations/gates.py +++ b/src/qutip_qip/operations/gates.py @@ -11,49 +11,8 @@ import qutip from qutip import Qobj, identity, qeye, sigmax, sigmay, sigmaz, tensor, fock_dm -__all__ = [ - "rx", - "ry", - "rz", - "sqrtnot", - "snot", - "phasegate", - "qrot", - "x_gate", - "y_gate", - "z_gate", - "cy_gate", - "cz_gate", - "s_gate", - "t_gate", - "qasmu_gate", - "cs_gate", - "ct_gate", - "cphase", - "cnot", - "csign", - "berkeley", - "swapalpha", - "swap", - "iswap", - "sqrtswap", - "sqrtiswap", - "fredkin", - "molmer_sorensen", - "toffoli", - "rotation", - "controlled_gate", - "globalphase", - "hadamard_transform", - "qubit_clifford_group", - "expand_operator", - "gate_sequence_product", -] - -# # Single Qubit Gates -# def _deprecation_warnings_gate_expansion(): warnings.warn( "The expansion of output gate matrix is no longer included " diff --git a/src/qutip_qip/operations/measurement.py b/src/qutip_qip/operations/measurement.py index ce83aefe3..c1e06d42d 100644 --- a/src/qutip_qip/operations/measurement.py +++ b/src/qutip_qip/operations/measurement.py @@ -6,10 +6,7 @@ import qutip from qutip import basis from qutip.measurement import measurement_statistics -from .gates import expand_operator - - -__all__ = ["Measurement"] +from qutip_qip.operations import expand_operator class Measurement: From 1f646930181e77b9107775d69c2c5ab450bddaa8 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 9 Dec 2025 21:52:48 +0530 Subject: [PATCH 16/17] Changed relative import to absolute and refactored module import structure for remaining files --- src/qutip_qip/algorithms/qft.py | 6 +++--- src/qutip_qip/decompose/__init__.py | 6 +++++- src/qutip_qip/decompose/decompose_single_qubit_gate.py | 3 --- src/qutip_qip/noise.py | 2 +- src/qutip_qip/pulse.py | 2 +- src/qutip_qip/transpiler/__init__.py | 6 +++++- src/qutip_qip/transpiler/chain.py | 7 ++----- src/qutip_qip/vqa.py | 2 +- 8 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/qutip_qip/algorithms/qft.py b/src/qutip_qip/algorithms/qft.py index e9329a126..5d3b61f0d 100644 --- a/src/qutip_qip/algorithms/qft.py +++ b/src/qutip_qip/algorithms/qft.py @@ -3,10 +3,10 @@ """ import numpy as np -from ..operations import Gate, snot, cphase, swap, expand_operator -from ..circuit import QubitCircuit +from qutip_qip.operations import Gate, snot, cphase, swap, expand_operator +from qutip_qip.circuit import QubitCircuit from qutip import Qobj -from ..decompose import decompose_one_qubit_gate +from qutip_qip.decompose import decompose_one_qubit_gate __all__ = ["qft", "qft_steps", "qft_gate_sequence"] diff --git a/src/qutip_qip/decompose/__init__.py b/src/qutip_qip/decompose/__init__.py index 0f4e40353..f4724a2ea 100644 --- a/src/qutip_qip/decompose/__init__.py +++ b/src/qutip_qip/decompose/__init__.py @@ -1,3 +1,7 @@ """Unitary decomposition. (experimental)""" -from .decompose_single_qubit_gate import * +from .decompose_single_qubit_gate import decompose_one_qubit_gate + +__all__ = [ + "decompose_one_qubit_gate", +] diff --git a/src/qutip_qip/decompose/decompose_single_qubit_gate.py b/src/qutip_qip/decompose/decompose_single_qubit_gate.py index a00ca5abe..77292b36a 100644 --- a/src/qutip_qip/decompose/decompose_single_qubit_gate.py +++ b/src/qutip_qip/decompose/decompose_single_qubit_gate.py @@ -11,9 +11,6 @@ from qutip_qip.operations import Gate -__all__ = ["decompose_one_qubit_gate"] - - def _angles_for_ZYZ(input_gate): """Finds and returns the angles for ZYZ rotation matrix. These are used to change ZYZ to other combinations. diff --git a/src/qutip_qip/noise.py b/src/qutip_qip/noise.py index 9837a3f73..ec47b22af 100644 --- a/src/qutip_qip/noise.py +++ b/src/qutip_qip/noise.py @@ -7,7 +7,7 @@ import numpy as np from qutip import Qobj, basis, destroy, num, qeye, tensor -from .pulse import Pulse +from qutip_qip.pulse import Pulse __all__ = [ diff --git a/src/qutip_qip/pulse.py b/src/qutip_qip/pulse.py index dcf8db451..2247a2a73 100644 --- a/src/qutip_qip/pulse.py +++ b/src/qutip_qip/pulse.py @@ -4,7 +4,7 @@ from scipy.interpolate import CubicSpline from qutip import QobjEvo, Qobj, identity -from .operations import expand_operator +from qutip_qip.operations import expand_operator __all__ = ["Pulse", "Drift"] diff --git a/src/qutip_qip/transpiler/__init__.py b/src/qutip_qip/transpiler/__init__.py index 5a9365a93..4a203ec22 100644 --- a/src/qutip_qip/transpiler/__init__.py +++ b/src/qutip_qip/transpiler/__init__.py @@ -1 +1,5 @@ -from .chain import * +from .chain import to_chain_structure + +__all__ = [ + "to_chain_structure", +] diff --git a/src/qutip_qip/transpiler/chain.py b/src/qutip_qip/transpiler/chain.py index bc614ae87..3bc10e679 100644 --- a/src/qutip_qip/transpiler/chain.py +++ b/src/qutip_qip/transpiler/chain.py @@ -1,11 +1,8 @@ from copy import deepcopy -from ..circuit import QubitCircuit +from qutip_qip.circuit import QubitCircuit -__all__ = ["to_chain_structure"] - - -def to_chain_structure(qc, setup="linear"): +def to_chain_structure(qc: QubitCircuit, setup="linear"): """ Method to resolve 2 qubit gates with non-adjacent control/s or target/s in terms of gates with adjacent interactions for linear/circular spin diff --git a/src/qutip_qip/vqa.py b/src/qutip_qip/vqa.py index f9839ccef..a129c8c5f 100644 --- a/src/qutip_qip/vqa.py +++ b/src/qutip_qip/vqa.py @@ -7,7 +7,7 @@ from qutip_qip.circuit import QubitCircuit from scipy.optimize import minimize from scipy.linalg import expm_frechet -from .operations import gate_sequence_product +from qutip_qip.operations import gate_sequence_product class VQA: From 08a18269c48cb3973d42b98bc17b164bcf1b2176 Mon Sep 17 00:00:00 2001 From: Mayank Goel Date: Tue, 9 Dec 2025 21:58:37 +0530 Subject: [PATCH 17/17] lint fixes --- src/qutip_qip/circuit/__init__.py | 12 +++++++----- src/qutip_qip/device/utils.py | 3 ++- src/qutip_qip/operations/gateclass.py | 1 - 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/qutip_qip/circuit/__init__.py b/src/qutip_qip/circuit/__init__.py index a7c7adc7a..9e3159c36 100644 --- a/src/qutip_qip/circuit/__init__.py +++ b/src/qutip_qip/circuit/__init__.py @@ -6,11 +6,6 @@ from .circuit import QubitCircuit from qutip_qip.operations import Gate, Measurement -__all__ = [ - "CircuitSimulator", - "CircuitResult", - "QubitCircuit", -] def _add_deprecation(fun, msg): def newfun(*args, **kwargs): @@ -34,3 +29,10 @@ def newfun(*args, **kwargs): "The class Measurement has been moved to qutip_qip.operations." "Please use update the import statement.\n", ) + + +__all__ = [ + "CircuitSimulator", + "CircuitResult", + "QubitCircuit", +] diff --git a/src/qutip_qip/device/utils.py b/src/qutip_qip/device/utils.py index 5e4de3fcb..d9b4cc71d 100644 --- a/src/qutip_qip/device/utils.py +++ b/src/qutip_qip/device/utils.py @@ -2,6 +2,7 @@ import numbers import numpy as np + def _to_array(params, num_qubits): """ Transfer a parameter to an array. @@ -9,4 +10,4 @@ def _to_array(params, num_qubits): if isinstance(params, numbers.Real): return np.asarray([params] * num_qubits) elif isinstance(params, Iterable): - return np.asarray(params) \ No newline at end of file + return np.asarray(params) diff --git a/src/qutip_qip/operations/gateclass.py b/src/qutip_qip/operations/gateclass.py index 2fb24c0ae..b9aaab758 100644 --- a/src/qutip_qip/operations/gateclass.py +++ b/src/qutip_qip/operations/gateclass.py @@ -42,7 +42,6 @@ ) - """ .. testsetup::