From 7d6520c61378aacf0d7b7847f549a1bf76bdbe7a Mon Sep 17 00:00:00 2001 From: Boxi Li Date: Mon, 18 Dec 2023 12:54:43 +0100 Subject: [PATCH] Remove unnecessary use of circuit.propagatos() `QubitCircuit.compute_unitary()` is faster and saves memory. --- src/qutip_qip/qasm.py | 2 +- tests/test_circuit.py | 16 ++++++++-------- tests/test_device.py | 8 ++++---- tests/test_optpulseprocessor.py | 2 +- tests/test_scheduler.py | 10 ++-------- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/qutip_qip/qasm.py b/src/qutip_qip/qasm.py index 7b2fecc4..6403f4e4 100644 --- a/src/qutip_qip/qasm.py +++ b/src/qutip_qip/qasm.py @@ -773,7 +773,7 @@ def _gate_add( self._custom_gate( qc_temp, [command[0], args, [str(i) for i in range(n)]] ) - unitary_mat = gate_sequence_product(qc_temp.propagators()) + unitary_mat = qc_temp.compute_unitary() custom_gates[gate_name] = unitary_mat qc.user_gates = custom_gates diff --git a/tests/test_circuit.py b/tests/test_circuit.py index 346c2878..98032bb2 100644 --- a/tests/test_circuit.py +++ b/tests/test_circuit.py @@ -102,9 +102,9 @@ class TestQubitCircuit: def testresolve(self, gate_from, gate_to, targets, controls): qc1 = QubitCircuit(2) qc1.add_gate(gate_from, targets=targets, controls=controls) - U1 = gate_sequence_product(qc1.propagators()) + U1 = qc1.compute_unitary() qc2 = qc1.resolve_gates(basis=gate_to) - U2 = gate_sequence_product(qc2.propagators()) + U2 = qc2.compute_unitary() assert _op_dist(U1, U2) < 1e-12 def testSNOTdecompose(self): @@ -114,9 +114,9 @@ def testSNOTdecompose(self): """ qc1 = QubitCircuit(1) qc1.add_gate("SNOT", targets=0) - U1 = gate_sequence_product(qc1.propagators()) + U1 = qc1.compute_unitary() qc2 = qc1.resolve_gates() - U2 = gate_sequence_product(qc2.propagators()) + U2 = qc2.compute_unitary() assert _op_dist(U1, U2) < 1e-12 def testFREDKINdecompose(self): @@ -126,9 +126,9 @@ def testFREDKINdecompose(self): """ qc1 = QubitCircuit(3) qc1.add_gate("FREDKIN", targets=[0, 1], controls=[2]) - U1 = gate_sequence_product(qc1.propagators()) + U1 = qc1.compute_unitary() qc2 = qc1.resolve_gates() - U2 = gate_sequence_product(qc2.propagators()) + U2 = qc2.compute_unitary() assert _op_dist(U1, U2) < 1e-12 def testadjacentgates(self): @@ -138,10 +138,10 @@ def testadjacentgates(self): """ qc1 = QubitCircuit(3) qc1.add_gate("ISWAP", targets=[0, 2]) - U1 = gate_sequence_product(qc1.propagators()) + U1 = qc1.compute_unitary() qc0 = qc1.adjacent_gates() qc2 = qc0.resolve_gates(basis="ISWAP") - U2 = gate_sequence_product(qc2.propagators()) + U2 = qc2.compute_unitary() assert _op_dist(U1, U2) < 1e-12 def test_add_gate(self): diff --git a/tests/test_device.py b/tests/test_device.py index 2c734a54..6170f2eb 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -76,7 +76,7 @@ def test_device_against_gate_sequence( circuit = QubitCircuit(num_qubits) for gate in gates: circuit.add_gate(gate) - U_ideal = gate_sequence_product(circuit.propagators()) + U_ideal = circuit.compute_unitary() device = device_class(num_qubits) U_physical = gate_sequence_product(device.run(circuit)) @@ -91,7 +91,7 @@ def test_analytical_evolution(num_qubits, gates, device_class, kwargs): circuit.add_gate(gate) state = qutip.rand_ket(2**num_qubits) state.dims = [[2]*num_qubits, [1]*num_qubits] - ideal = gate_sequence_product([state] + circuit.propagators()) + ideal = circuit.run(state) device = device_class(num_qubits) operators = device.run_state(init_state=state, qc=circuit, analytical=True) result = gate_sequence_product(operators) @@ -112,7 +112,7 @@ def test_numerical_evolution( state = qutip.rand_ket(2**num_qubits) state.dims = [[2]*num_qubits, [1]*num_qubits] - target = gate_sequence_product([state] + circuit.propagators()) + target = circuit.run(state) if isinstance(device, DispersiveCavityQED): num_ancilla = len(device.dims)-num_qubits ancilla_indices = slice(0, num_ancilla) @@ -169,7 +169,7 @@ def test_numerical_circuit(circuit, device_class, kwargs, schedule_mode): state = qutip.rand_ket(2**num_qubits) state.dims = [[2]*num_qubits, [1]*num_qubits] - target = gate_sequence_product([state] + circuit.propagators()) + target = circuit.run(state) if isinstance(device, DispersiveCavityQED): num_ancilla = len(device.dims)-num_qubits ancilla_indices = slice(0, num_ancilla) diff --git a/tests/test_optpulseprocessor.py b/tests/test_optpulseprocessor.py index 828fbcfc..b5fc9dd9 100644 --- a/tests/test_optpulseprocessor.py +++ b/tests/test_optpulseprocessor.py @@ -102,7 +102,7 @@ def test_multi_gates(self): rho0 = rand_ket(4) # use random generated ket state rho0.dims = [[2, 2], [1, 1]] - U = gate_sequence_product(qc.propagators()) + U = qc.compute_unitary() rho1 = U * rho0 result = test.run_state(rho0) assert_(fidelity(result.states[-1], rho1) > 1-1.0e-6) diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py index 58723528..38d1bf5e 100644 --- a/tests/test_scheduler.py +++ b/tests/test_scheduler.py @@ -13,12 +13,12 @@ def _verify_scheduled_circuit(circuit, gate_cycle_indices): The input gate_cycle_indices is the scheduling result, i.e., a list of integers denoting the execution cycle of each gate in the circuit. """ - result0 = gate_sequence_product(circuit.propagators()) + result0 = circuit.compute_unitary() scheduled_gate = [[] for i in range(max(gate_cycle_indices) + 1)] for i, cycles in enumerate(gate_cycle_indices): scheduled_gate[cycles].append(circuit.gates[i]) circuit.gates = sum(scheduled_gate, []) - result1 = gate_sequence_product(circuit.propagators()) + result1 = circuit.compute_unitary() return tracedist(result0 * result1.dag(), qeye(result0.dims[0])) < 1.0e-7 @@ -27,7 +27,6 @@ def test_allow_permutation(): circuit.add_gate("X", 0) circuit.add_gate("CNOT", 0, 1) circuit.add_gate("X", 1) - result0 = gate_sequence_product(circuit.propagators()) scheduler = Scheduler("ASAP", allow_permutation=True) gate_cycle_indices = scheduler.schedule(circuit) @@ -138,7 +137,6 @@ def test_scheduling_gates1( repeat_num = 5 else: repeat_num = 0 - result0 = gate_sequence_product(circuit.propagators()) # run the scheduler scheduler = Scheduler(method) @@ -168,7 +166,6 @@ def test_scheduling_gates2( repeat_num = 5 else: repeat_num = 0 - result0 = gate_sequence_product(circuit.propagators()) # run the scheduler scheduler = Scheduler(method) @@ -200,7 +197,6 @@ def test_scheduling_gates3( repeat_num = 5 else: repeat_num = 0 - result0 = gate_sequence_product(circuit.propagators()) # run the scheduler scheduler = Scheduler(method) @@ -232,7 +228,6 @@ def test_scheduling_gates4( repeat_num = 5 else: repeat_num = 0 - result0 = gate_sequence_product(circuit.propagators()) # run the scheduler scheduler = Scheduler(method) @@ -278,7 +273,6 @@ def test_scheduling_pulse( repeat_num = 5 else: repeat_num = 0 - result0 = gate_sequence_product(circuit.propagators()) # run the scheduler scheduler = Scheduler(method)