Skip to content

Commit

Permalink
Fix reconstruction when subsystem contains no observable
Browse files Browse the repository at this point in the history
  • Loading branch information
garrison committed Oct 23, 2023
1 parent 4997ca2 commit f4dec60
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
3 changes: 2 additions & 1 deletion circuit_knitting/cutting/cutting_reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ..utils.observable_grouping import CommutingObservableGroup, ObservableCollection
from ..utils.bitwise import bit_count
from .cutting_decomposition import decompose_observables
from .cutting_experiments import _get_pauli_indices
from .qpd import WeightType


Expand Down Expand Up @@ -136,7 +137,7 @@ def _process_outcome(
this vector correspond to the elements of ``cog.commuting_observables``,
and each result will be either +1 or -1.
"""
num_meas_bits = len(cog.pauli_indices)
num_meas_bits = len(_get_pauli_indices(cog))

outcome = _outcome_to_int(outcome)
meas_outcomes = outcome & ((1 << num_meas_bits) - 1)
Expand Down
46 changes: 37 additions & 9 deletions test/cutting/test_cutting_roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,28 +179,56 @@ def test_cutting_exact_reconstruction(example_circuit):
assert np.allclose(exact_expvals, simulated_expvals, atol=1e-8)


def test_sampler_with_identity_subobservable(example_circuit):
"""This test ensures that the sampler does not throw an error if you pass it a subcircuit with no observable measurements.
@pytest.mark.parametrize(
"sampler,is_exact_sampler", [(Sampler(), False), (ExactSampler(), True)]
)
def test_sampler_with_identity_subobservable(sampler, is_exact_sampler):
"""This test ensures that the sampler works for a subcircuit with no observable measurements.
Tests temporary workaround to Issue #422.
Specifically, that
This test passes if no exceptions are raised.
- ``Sampler`` does not blow up (Issue #422); and
- ``ExactSampler`` returns correct results
This is related to https://github.com/Qiskit-Extensions/circuit-knitting-toolbox/issues/422.
"""
# Create a circuit to cut
qc = QuantumCircuit(3)
append_random_unitary(qc, [0, 1])
append_random_unitary(qc, [2])
qc.rxx(np.pi / 3, 1, 2)
append_random_unitary(qc, [0, 1])
append_random_unitary(qc, [2])

qc = example_circuit
observable_to_test = PauliList(
# Determine expectation value using cutting
observables = PauliList(
["IIZ"]
) # Without the workaround to Issue #422, this observable causes a Sampler error.
subcircuits, bases, subobservables = partition_problem(
qc, "AAB", observables=observable_to_test
qc, "AAB", observables=observables
)
subexperiments, coefficients = generate_cutting_experiments(
subcircuits, subobservables, num_samples=np.inf
)
samplers = {label: Sampler() for label in subexperiments.keys()}
samplers = {label: sampler for label in subexperiments.keys()}
results = {
label: sampler.run(subexperiments[label]).result()
for label, sampler in samplers.items()
}
_ = results
reconstructed_expvals = reconstruct_expectation_values(
results, coefficients, subobservables
)

if is_exact_sampler:
# Determine exact expectation values
estimator = Estimator()
exact_expvals = (
estimator.run([qc] * len(observables), list(observables)).result().values
)

logger.info(
"Max error: %f", np.max(np.abs(exact_expvals - reconstructed_expvals))
)

# Ensure both methods yielded equivalent expectation values
assert np.allclose(exact_expvals, reconstructed_expvals, atol=1e-8)

0 comments on commit f4dec60

Please sign in to comment.