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
Empty file added 0
Empty file.
32 changes: 32 additions & 0 deletions tests/test_cutting.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,38 @@ def test_partition_with_cut(self, cutter):
groups = cutter._partition_qubits(qc, cut_points)
assert len(groups) >= 1

def test_partition_no_cuts_returns_all_qubits(self, cutter):
qc = QuantumCircuit(4)
groups = cutter._partition_qubits(qc, [])
all_qubits = set()
for g in groups:
all_qubits.update(g)
assert all_qubits == {0, 1, 2, 3}

def test_partition_single_cut_separates_qubits(self, cutter):
qc = QuantumCircuit(4)
qc.cx(0, 1)
qc.cx(1, 2)
qc.cx(2, 3)
groups = cutter._partition_qubits(qc, [(1, 2)])
assert len(groups) == 2
all_qubits = set()
for g in groups:
all_qubits.update(g)
assert all_qubits == {0, 1, 2, 3}

def test_partition_groups_are_disjoint(self, cutter):
qc = QuantumCircuit(6)
for i in range(5):
qc.cx(i, i + 1)
groups = cutter._partition_qubits(qc, [(1, 2), (3, 4)])
all_qubits = set()
for g in groups:
g_set = set(g)
assert g_set.isdisjoint(all_qubits)
all_qubits.update(g_set)
assert all_qubits == {0, 1, 2, 3, 4, 5}


class TestCuttingEdgeCases:
"""Tests for cutting edge cases and decision paths."""
Expand Down
54 changes: 53 additions & 1 deletion tests/test_fusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,56 @@ def test_three_qubit_multiple_chains(self, fusion):
result = fusion.optimize(qc)
original_unitary = Operator(qc)
fused_unitary = Operator(result.optimized_circuit)
assert process_fidelity(fused_unitary, original_unitary) > 0.99
assert process_fidelity(fused_unitary, original_unitary) > 0.99


class TestFusionUnitaryEquivalence:
"""Comprehensive unitary equivalence tests for gate fusion (issue #55)."""

@pytest.fixture
def fusion(self):
return GateFusion(cost_model=CostModel())

def test_single_qubit_chain_bell(self, fusion):
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
result = fusion.optimize(qc)
assert process_fidelity(Operator(result.optimized_circuit), Operator(qc)) > 0.99

def test_single_qubit_chain_ghz(self, fusion):
qc = QuantumCircuit(4)
qc.h(0)
for i in range(3):
qc.cx(i, i + 1)
result = fusion.optimize(qc)
assert process_fidelity(Operator(result.optimized_circuit), Operator(qc)) > 0.99

def test_rz_chain_preserves_unitary(self, fusion):
qc = QuantumCircuit(2)
qc.h(0)
qc.rz(0.5, 0)
qc.rz(0.3, 0)
qc.cx(0, 1)
result = fusion.optimize(qc)
assert process_fidelity(Operator(result.optimized_circuit), Operator(qc)) > 0.99

def test_multi_qubit_chain_preserves_unitary(self, fusion):
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.h(2)
qc.cx(0, 1)
qc.cx(1, 2)
result = fusion.optimize(qc)
assert process_fidelity(Operator(result.optimized_circuit), Operator(qc)) > 0.99

def test_fusion_preserves_unitary_up_to_global_phase(self, fusion):
qc = QuantumCircuit(1)
qc.h(0)
qc.sx(0)
qc.rz(1.23, 0)
result = fusion.optimize(qc)
original_op = Operator(qc)
fused_op = Operator(result.optimized_circuit)
assert original_op.equiv(fused_op)
73 changes: 72 additions & 1 deletion tests/test_scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,75 @@ def test_alap_delays_gates_with_backend(self):
assert result_alap.depth_alap > 0

assert Operator(qc).equiv(Operator(result_asap.circuit))
assert Operator(qc).equiv(Operator(result_alap.circuit))
assert Operator(qc).equiv(Operator(result_alap.circuit))


class TestSchedulingUnitaryEquivalence:
"""Comprehensive unitary equivalence tests for all scheduling methods (issue #55)."""

@pytest.fixture
def scheduler(self):
return CoherenceAwareScheduler(cost_model=CostModel())

def test_asap_preserves_unitary_bell(self, scheduler):
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
result = scheduler.schedule(qc, method="asap")
assert Operator(qc).equiv(Operator(result.circuit))

def test_alap_preserves_unitary_bell(self, scheduler):
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
result = scheduler.schedule(qc, method="alap")
assert Operator(qc).equiv(Operator(result.circuit))

def test_coherence_aware_preserves_unitary_bell(self, scheduler):
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
result = scheduler.schedule(qc, method="coherence_aware")
assert Operator(qc).equiv(Operator(result.circuit))

def test_asap_preserves_unitary_ghz(self, scheduler):
qc = QuantumCircuit(4)
qc.h(0)
for i in range(3):
qc.cx(i, i + 1)
result = scheduler.schedule(qc, method="asap")
assert Operator(qc).equiv(Operator(result.circuit))

def test_alap_preserves_unitary_ghz(self, scheduler):
qc = QuantumCircuit(4)
qc.h(0)
for i in range(3):
qc.cx(i, i + 1)
result = scheduler.schedule(qc, method="alap")
assert Operator(qc).equiv(Operator(result.circuit))

def test_coherence_aware_preserves_unitary_ghz(self, scheduler):
qc = QuantumCircuit(4)
qc.h(0)
for i in range(3):
qc.cx(i, i + 1)
result = scheduler.schedule(qc, method="coherence_aware")
assert Operator(qc).equiv(Operator(result.circuit))

def test_alap_produces_different_schedule_than_asap(self, scheduler):
qc = QuantumCircuit(3)
qc.h(0)
qc.cx(0, 1)
qc.h(2)
qc.cx(1, 2)
qc.h(1)

asap_result = scheduler.schedule(qc, method="asap")
alap_result = scheduler.schedule(qc, method="alap")

assert Operator(qc).equiv(Operator(asap_result.circuit))
assert Operator(qc).equiv(Operator(alap_result.circuit))

assert asap_result.method == "asap"
assert alap_result.method == "alap"
assert asap_result.method != alap_result.method
Loading