Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions qumat/cirq_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,9 @@ def apply_u_gate(circuit, qubit_index, theta, phi, lambd):
circuit.append(cirq.rz(lambd).on(qubit))
circuit.append(cirq.ry(phi).on(qubit))
circuit.append(cirq.rx(theta).on(qubit))


def get_final_state_vector(circuit, backend, backend_config):
simulator = cirq.Simulator()
result = simulator.simulate(circuit)
return result.final_state_vector
64 changes: 64 additions & 0 deletions testing/cirq_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#
# 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 cirq
import numpy as np


def get_qumat_backend_config(test_type: str = "get_final_state_vector"):
if test_type == "get_final_state_vector":
qumat_backend_config = {
"backend_name": "cirq",
"backend_options": {"simulator_type": "default", "shots": 1},
}
else:
pass

return qumat_backend_config


def get_native_example_final_state_vector(
initial_state_ket_str: str = "000",
) -> np.ndarray:
n_qubits = len(initial_state_ket_str)
assert n_qubits == 3, "The current cirq native testing example is strictly 3 qubits"

qubits = cirq.LineQubit.range(n_qubits)
circuit = cirq.Circuit()

# Initialize to desired state
for i, bit in enumerate(initial_state_ket_str):
if bit == "1":
circuit.append(cirq.X(qubits[i]))

# Create entanglement between qubits 1 and 2
circuit.append(cirq.H(qubits[1]))
circuit.append(cirq.CNOT(qubits[1], qubits[2]))

# Prepare the state to be teleported on qubit 0
circuit.append(cirq.H(qubits[0]))
circuit.append(cirq.Z(qubits[0]))

# Perform Bell measurement on qubits 0 and 1
circuit.append(cirq.CNOT(qubits[0], qubits[1]))
circuit.append(cirq.H(qubits[0]))

# Simulate the circuit
simulator = cirq.Simulator()
result = simulator.simulate(circuit)

return result.final_state_vector
5 changes: 4 additions & 1 deletion testing/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

# Define backends to test - used by both parametrize and fixture
TESTING_BACKENDS = ["qiskit", "cirq"] # Can be expanded to include "braket" when ready


@pytest.fixture(scope="session")
def testing_backends():
"""Fixture to provide the list of backends to test."""
return ["qiskit"] # Can be expanded to include "cirq", "braket" when ready
return TESTING_BACKENDS
6 changes: 4 additions & 2 deletions testing/qiskit_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ def get_native_example_final_state_vector(

qc = QuantumCircuit(n_qubits)

initial_state = Statevector.from_label(initial_state_ket_str)
qc.initialize(initial_state, range(n_qubits))
# Initialize state using X gates (backend-agnostic)
for i, bit in enumerate(initial_state_ket_str):
if bit == "1":
qc.x(i)

# Create entanglement between qubits 1 and 2
qc.h(1) # Apply Hadamard gate on qubit 1
Expand Down
7 changes: 5 additions & 2 deletions testing/qumat_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@ def get_qumat_example_final_state_vector(
qumat_instance = QuMat(backend_config)

qumat_instance.create_empty_circuit(num_qubits=3)
initial_state = create_np_computational_basis_state(initial_state_ket_str)
qumat_instance.circuit.initialize(initial_state, range(n_qubits))

# Initialize state using X gates (backend-agnostic)
for i, bit in enumerate(initial_state_ket_str):
if bit == "1":
qumat_instance.apply_pauli_x_gate(qubit_index=i)

qumat_instance.apply_hadamard_gate(qubit_index=1)
qumat_instance.apply_cnot_gate(control_qubit_index=1, target_qubit_index=2)
Expand Down
9 changes: 4 additions & 5 deletions testing/test_final_quantum_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,17 @@
import numpy as np
from importlib import import_module


from .conftest import TESTING_BACKENDS
from .qumat_helpers import get_qumat_example_final_state_vector


class TestFinalQuantumStates:
"""Test class for final quantum state comparisons between QuMat and native implementations."""

@pytest.mark.parametrize("backend_name", TESTING_BACKENDS)
@pytest.mark.parametrize("initial_ket_str", ["000", "001", "010", "011"])
def test_qiskit_final_state_vector(self, initial_ket_str):
"""Test that QuMat produces same final state as native Qiskit implementation."""
backend_name = "qiskit"

def test_backend_final_state_vector(self, backend_name, initial_ket_str):
"""Test that QuMat produces same final state as native backend implementation."""
# Import backend-specific helpers
backend_module = import_module(f".{backend_name}_helpers", package="testing")

Expand Down