This is an automated email from the ASF dual-hosted git repository.

guanmingchiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/mahout.git


The following commit(s) were added to refs/heads/main by this push:
     new e15d13a7d MAHOUT-604 Add test for single qubit gates - part 2 (#610)
e15d13a7d is described below

commit e15d13a7d395992b6c45aa9c77a0273f47a46fdf
Author: GUAN-HAO HUANG <[email protected]>
AuthorDate: Mon Nov 10 14:47:51 2025 +0800

    MAHOUT-604 Add test for single qubit gates - part 2 (#610)
    
    * Add test for single qubit gates
    
    * fix ruff error
---
 testing/test_single_qubit_gates.py | 225 +++++++++++++++++++++++++++++++++++++
 1 file changed, 225 insertions(+)

diff --git a/testing/test_single_qubit_gates.py 
b/testing/test_single_qubit_gates.py
index 10975f87e..0f880d00a 100644
--- a/testing/test_single_qubit_gates.py
+++ b/testing/test_single_qubit_gates.py
@@ -15,6 +15,7 @@
 # limitations under the License.
 #
 
+import math
 import pytest
 
 from .utils import TESTING_BACKENDS, get_backend_config
@@ -64,6 +65,42 @@ def get_state_probability(results, target_state, 
num_qubits=1):
     return target_count / total_shots
 
 
+def get_superposition_probabilities(results, num_qubits=1):
+    """
+    Calculate probabilities for |0⟩ and |1⟩ states in a superposition.
+
+    Args:
+        results: Dictionary of measurement results from execute_circuit()
+        num_qubits: Number of qubits in the circuit
+
+    Returns:
+        Tuple of (prob_zero, prob_one)
+    """
+    if isinstance(results, list):
+        results = results[0]
+
+    total_shots = sum(results.values())
+
+    zero_count = 0
+    one_count = 0
+    for state, count in results.items():
+        if isinstance(state, str):
+            if state == "0" * num_qubits:
+                zero_count = count
+            elif state == "1" * num_qubits:
+                one_count = count
+        else:
+            if state == 0:
+                zero_count = count
+            elif state == (2**num_qubits - 1):
+                one_count = count
+
+    prob_zero = zero_count / total_shots if total_shots > 0 else 0.0
+    prob_one = one_count / total_shots if total_shots > 0 else 0.0
+
+    return prob_zero, prob_one
+
+
 @pytest.mark.parametrize("backend_name", TESTING_BACKENDS)
 class TestPauliXGate:
     """Test class for Pauli X gate functionality."""
@@ -187,6 +224,170 @@ class TestPauliYGate:
         )
 
 
[email protected]("backend_name", TESTING_BACKENDS)
+class TestHadamardGate:
+    """Test class for Hadamard gate functionality."""
+
+    @pytest.mark.parametrize(
+        "initial_state, num_applications",
+        [
+            ("0", 1),  # |0⟩ -> H -> |+⟩ (superposition)
+            ("1", 1),  # |1⟩ -> H -> |-⟩ (superposition)
+            ("0", 2),  # |0⟩ -> H -> H -> |0⟩ (H² = I)
+            ("1", 2),  # |1⟩ -> H -> H -> |1⟩ (H² = I)
+        ],
+    )
+    def test_hadamard_state_transitions(
+        self, backend_name, initial_state, num_applications
+    ):
+        """Test Hadamard gate state transitions with parametrized test 
cases."""
+        backend_config = get_backend_config(backend_name)
+        qumat = QuMat(backend_config)
+        qumat.create_empty_circuit(num_qubits=1)
+
+        # Prepare initial state: |0⟩ -> |initial_state⟩
+        if initial_state == "1":
+            qumat.apply_pauli_x_gate(0)  # |0⟩ -> |1⟩
+
+        # Apply Hadamard gate specified number of times
+        # This transforms |initial_state⟩ -> |expected_state⟩
+        for _ in range(num_applications):
+            qumat.apply_hadamard_gate(0)
+
+        # Execute circuit
+        results = qumat.execute_circuit()
+
+        if num_applications == 1:
+            # Single application creates superposition
+            prob_zero, prob_one = get_superposition_probabilities(results, 
num_qubits=1)
+            assert 0.45 < prob_zero < 0.55, (
+                f"Expected ~0.5 probability for |0⟩ after Hadamard on 
|{initial_state}⟩, "
+                f"got {prob_zero}"
+            )
+            assert 0.45 < prob_one < 0.55, (
+                f"Expected ~0.5 probability for |1⟩ after Hadamard on 
|{initial_state}⟩, "
+                f"got {prob_one}"
+            )
+        else:
+            # Double application returns to original state
+            prob = get_state_probability(results, initial_state, num_qubits=1)
+            assert prob > 0.95, (
+                f"Backend: {backend_name}, "
+                f"Initial state: |{initial_state}⟩, "
+                f"Gate applications: {num_applications}, "
+                f"Expected: |{initial_state}⟩, "
+                f"Got probability: {prob:.4f}"
+            )
+
+
[email protected]("backend_name", TESTING_BACKENDS)
+class TestNOTGate:
+    """Test class for NOT gate functionality."""
+
+    @pytest.mark.parametrize(
+        "initial_state, num_applications, expected_state",
+        [
+            ("0", 1, "1"),  # |0⟩ -> NOT -> |1⟩ (equivalent to Pauli X)
+            ("1", 1, "0"),  # |1⟩ -> NOT -> |0⟩
+            ("0", 2, "0"),  # |0⟩ -> NOT -> NOT -> |0⟩
+            ("1", 2, "1"),  # |1⟩ -> NOT -> NOT -> |1⟩
+        ],
+    )
+    def test_not_gate_state_transitions(
+        self, backend_name, initial_state, num_applications, expected_state
+    ):
+        """Test NOT gate state transitions with parametrized test cases."""
+        backend_config = get_backend_config(backend_name)
+        qumat = QuMat(backend_config)
+        qumat.create_empty_circuit(num_qubits=1)
+
+        # Prepare initial state: |0⟩ -> |initial_state⟩
+        if initial_state == "1":
+            qumat.apply_not_gate(0)  # |0⟩ -> |1⟩
+
+        # Apply NOT gate specified number of times
+        # This transforms |initial_state⟩ -> |expected_state⟩
+        for _ in range(num_applications):
+            qumat.apply_not_gate(0)
+
+        # Execute circuit
+        results = qumat.execute_circuit()
+
+        # Calculate probability of expected state
+        prob = get_state_probability(results, expected_state, num_qubits=1)
+
+        assert prob > 0.95, (
+            f"Backend: {backend_name}, "
+            f"Initial state: |{initial_state}⟩, "
+            f"Gate applications: {num_applications}, "
+            f"Expected: |{expected_state}⟩, "
+            f"Got probability: {prob:.4f}"
+        )
+
+
[email protected]("backend_name", TESTING_BACKENDS)
+class TestUGate:
+    """Test class for U gate (universal single-qubit gate) functionality."""
+
+    @pytest.mark.parametrize(
+        "theta, phi, lambd, expected_behavior",
+        [
+            (0, 0, 0, "identity"),  # U(0, 0, 0) should be identity
+            (
+                math.pi,
+                0,
+                math.pi,
+                "pauli_x",
+            ),  # U(π, 0, π) should be equivalent to Pauli X
+            (
+                math.pi / 2,
+                0,
+                math.pi,
+                "hadamard",
+            ),  # U(π/2, 0, π) should be equivalent to Hadamard
+        ],
+    )
+    def test_u_gate_operations(
+        self, backend_name, theta, phi, lambd, expected_behavior
+    ):
+        """Test U gate with different parameters using parametrized test 
cases."""
+        backend_config = get_backend_config(backend_name)
+        qumat = QuMat(backend_config)
+        qumat.create_empty_circuit(num_qubits=1)
+
+        # Apply U gate with specified parameters
+        qumat.apply_u_gate(0, theta=theta, phi=phi, lambd=lambd)
+
+        # Execute circuit
+        results = qumat.execute_circuit()
+
+        if expected_behavior == "identity":
+            # Should measure |0⟩ with high probability
+            prob = get_state_probability(results, "0", num_qubits=1)
+            assert prob > 0.95, (
+                f"Backend: {backend_name}, "
+                f"Expected |0⟩ state after U({theta},{phi},{lambd}), got 
probability {prob:.4f}"
+            )
+        elif expected_behavior == "pauli_x":
+            # Should measure |1⟩ with high probability
+            prob = get_state_probability(results, "1", num_qubits=1)
+            assert prob > 0.95, (
+                f"Backend: {backend_name}, "
+                f"Expected |1⟩ state after U({theta},{phi},{lambd}), got 
probability {prob:.4f}"
+            )
+        elif expected_behavior == "hadamard":
+            # Should have approximately equal probability for |0⟩ and |1⟩
+            prob_zero, prob_one = get_superposition_probabilities(results, 
num_qubits=1)
+            assert 0.45 < prob_zero < 0.55, (
+                f"Expected ~0.5 probability for |0⟩ after 
U({theta},{phi},{lambd}), "
+                f"got {prob_zero}"
+            )
+            assert 0.45 < prob_one < 0.55, (
+                f"Expected ~0.5 probability for |1⟩ after 
U({theta},{phi},{lambd}), "
+                f"got {prob_one}"
+            )
+
+
 @pytest.mark.parametrize("backend_name", TESTING_BACKENDS)
 class TestPauliZGate:
     """Test class for Pauli Z gate functionality."""
@@ -230,3 +431,27 @@ class TestPauliZGate:
             f"Expected: |{expected_state}⟩, "
             f"Got probability: {prob:.4f}"
         )
+
+    def test_pauli_z_with_hadamard(self, backend_name):
+        """Test Pauli Z gate with Hadamard to verify phase flip effect."""
+        backend_config = get_backend_config(backend_name)
+        qumat = QuMat(backend_config)
+        qumat.create_empty_circuit(num_qubits=1)
+
+        # Create |+⟩ state with Hadamard
+        qumat.apply_hadamard_gate(0)
+        # Apply Pauli Z (should flip to |-⟩)
+        qumat.apply_pauli_z_gate(0)
+        # Apply Hadamard again (should convert |-⟩ to |1⟩)
+        qumat.apply_hadamard_gate(0)
+
+        # Execute circuit
+        results = qumat.execute_circuit()
+
+        # Calculate probability of |1⟩ state
+        prob = get_state_probability(results, "1", num_qubits=1)
+
+        assert prob > 0.95, (
+            f"Backend: {backend_name}, "
+            f"Expected |1⟩ state after H-Z-H sequence, got probability 
{prob:.4f}"
+        )

Reply via email to