diff --git a/src/qc_compiler/cutting.py b/src/qc_compiler/cutting.py index c8ea762..9bbacbc 100644 --- a/src/qc_compiler/cutting.py +++ b/src/qc_compiler/cutting.py @@ -272,6 +272,16 @@ def reconstruct( Uses quasi-probability decomposition to combine subcircuit results. Each cut introduces a sampling overhead factor of 4. + .. warning:: + + This is a simplified placeholder implementation. Proper QPD + reconstruction requires tracking the sign and coefficient of + each term in the decomposition. This method sums all + subcircuit results uniformly and normalizes, which does not + produce correct expectation values when cuts are present. For + accurate results, use a full QPD reconstruction implementation + such as ``circuit_knitting`` from Qiskit Extensions. + Args: subcircuit_results: Results from executing subcircuits. Each element is a dict of {bitstring: count}. @@ -280,6 +290,19 @@ def reconstruct( Returns: Reconstructed expectation values as a dict. """ + import warnings + + if num_cuts > 0: + warnings.warn( + "Circuit cutting reconstruction is a simplified placeholder " + "that does not track QPD term signs or coefficients. " + "Results with cuts present will not be accurate. " + "For proper QPD reconstruction, use circuit_knitting " + "from Qiskit Extensions.", + UserWarning, + stacklevel=2, + ) + if not subcircuit_results: return {} @@ -288,7 +311,7 @@ def reconstruct( return subcircuit_results[0] return {} - sampling_factor = 4 ** num_cuts + sampling_factor = 4**num_cuts combined = {} for result in subcircuit_results: diff --git a/tests/test_cutting.py b/tests/test_cutting.py index f89efbd..4652f21 100644 --- a/tests/test_cutting.py +++ b/tests/test_cutting.py @@ -319,4 +319,25 @@ def test_analyze_estimated_error_non_negative(self, cutter): for i in range(3): qc.cx(i, i + 1) result = cutter.analyze(qc) - assert result.estimated_error_uncut >= 0 \ No newline at end of file + assert result.estimated_error_uncut >= 0 + + +class TestReconstructWarning: + """Regression tests for reconstruct() placeholder warning (issue #44).""" + + def test_reconstruct_zero_cuts_no_warning(self): + cutter = CircuitCutter(cost_model=CostModel()) + result = cutter.reconstruct([{"00": 500, "11": 500}], num_cuts=0) + assert result == {"00": 500, "11": 500} + + def test_reconstruct_with_cuts_warns(self): + cutter = CircuitCutter(cost_model=CostModel()) + sub_results = [{"00": 250, "11": 250}, {"00": 250, "11": 250}] + with pytest.warns(UserWarning, match="simplified placeholder"): + result = cutter.reconstruct(sub_results, num_cuts=1) + assert len(result) > 0 + + def test_reconstruct_empty_results(self): + cutter = CircuitCutter(cost_model=CostModel()) + result = cutter.reconstruct([], num_cuts=0) + assert result == {} \ No newline at end of file