diff --git a/qumat/amazon_braket_backend.py b/qumat/amazon_braket_backend.py index 3ea9e84129..984d3fbea8 100644 --- a/qumat/amazon_braket_backend.py +++ b/qumat/amazon_braket_backend.py @@ -33,8 +33,12 @@ def initialize_backend(backend_config): return AwsDevice("arn:aws:braket:::device/quantum-simulator/amazon/sv1") -def create_empty_circuit(num_qubits): - return Circuit() +def create_empty_circuit(num_qubits: int | None = None): + circuit = Circuit() + if num_qubits is not None: + for i in range(num_qubits): + circuit.i(i) + return circuit def apply_not_gate(circuit, qubit_index): diff --git a/qumat/cirq_backend.py b/qumat/cirq_backend.py index 81661ee641..2ba5cb2cf4 100644 --- a/qumat/cirq_backend.py +++ b/qumat/cirq_backend.py @@ -31,8 +31,13 @@ def initialize_backend(backend_config): return cirq.Simulator() -def create_empty_circuit(num_qubits): - return cirq.Circuit() +def create_empty_circuit(num_qubits: int | None = None): + circuit = cirq.Circuit() + if num_qubits is not None: + qubits = [cirq.LineQubit(i) for i in range(num_qubits)] + for qubit in qubits: + circuit.append(cirq.I(qubit)) + return circuit def apply_not_gate(circuit, qubit_index): diff --git a/qumat/qiskit_backend.py b/qumat/qiskit_backend.py index ec839bf8de..67043c4b07 100644 --- a/qumat/qiskit_backend.py +++ b/qumat/qiskit_backend.py @@ -27,8 +27,11 @@ def initialize_backend(backend_config): return backend -def create_empty_circuit(num_qubits): - return qiskit.QuantumCircuit(num_qubits) +def create_empty_circuit(num_qubits: int | None = None): + if num_qubits is not None: + return qiskit.QuantumCircuit(num_qubits) + else: + return qiskit.QuantumCircuit() def apply_not_gate(circuit, qubit_index): diff --git a/qumat/qumat.py b/qumat/qumat.py index 395fb934bb..3725db1e28 100644 --- a/qumat/qumat.py +++ b/qumat/qumat.py @@ -28,7 +28,7 @@ def __init__(self, backend_config): self.circuit = None self.parameters = {} - def create_empty_circuit(self, num_qubits): + def create_empty_circuit(self, num_qubits: int | None = None): self.circuit = self.backend_module.create_empty_circuit(num_qubits) def apply_not_gate(self, qubit_index): diff --git a/testing/test_create_circuit.py b/testing/test_create_circuit.py new file mode 100644 index 0000000000..8fb1d43446 --- /dev/null +++ b/testing/test_create_circuit.py @@ -0,0 +1,93 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import pytest + +from .conftest import TESTING_BACKENDS +from qumat import QuMat + + +class TestCreateCircuit: + """Test class for create_empty_circuit functionality.""" + + def get_backend_config(self, backend_name): + """Helper method to get backend configuration.""" + if backend_name == "qiskit": + return { + "backend_name": backend_name, + "backend_options": { + "simulator_type": "aer_simulator", + "shots": 1000, + }, + } + elif backend_name == "cirq": + return { + "backend_name": backend_name, + "backend_options": { + "simulator_type": "default", + "shots": 1000, + }, + } + elif backend_name == "amazon_braket": + return { + "backend_name": backend_name, + "backend_options": { + "simulator_type": "local", + "shots": 1000, + }, + } + + @pytest.mark.parametrize("backend_name", TESTING_BACKENDS) + def test_create_empty_circuit(self, backend_name): + """Test that create_empty_circuit works""" + backend_config = self.get_backend_config(backend_name) + qumat = QuMat(backend_config) + qumat.create_empty_circuit() + + assert qumat.circuit is not None + + @pytest.mark.parametrize("backend_name", TESTING_BACKENDS) + @pytest.mark.parametrize("num_qubits", [1, 3, 5]) + def test_create_circuit_initializes_to_zero(self, backend_name, num_qubits): + """Test that create_empty_circuit properly initializes all qubits to |0⟩.""" + backend_config = self.get_backend_config(backend_name) + qumat = QuMat(backend_config) + + # Create circuit with specified number of qubits + qumat.create_empty_circuit(num_qubits) + + # Execute and verify all qubits measure |0⟩ + results = qumat.execute_circuit() + if isinstance(results, list): + results = results[0] + + total_shots = sum(results.values()) + assert total_shots > 0 + + # Find count for all-zeros state + zero_state_count = 0 + for state, count in results.items(): + if isinstance(state, str): + if state == "0" * num_qubits: + zero_state_count = count + else: + if state == 0: + zero_state_count = count + + assert zero_state_count > 0.95 * total_shots, ( + f"Expected |0...0⟩ state, got {zero_state_count}/{total_shots}" + )