Skip to content

Commit

Permalink
generate_cutting_experiments returns coefficients, not weights (#412)
Browse files Browse the repository at this point in the history
  • Loading branch information
garrison authored Sep 11, 2023
1 parent 2053e24 commit eadd0d7
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 17 deletions.
18 changes: 9 additions & 9 deletions circuit_knitting/cutting/cutting_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def generate_cutting_experiments(
list[tuple[float, WeightType]],
]:
r"""
Generate cutting subexperiments and their associated weights.
Generate cutting subexperiments and their associated coefficients.
If the input, ``circuits``, is a :class:`QuantumCircuit` instance, the
output subexperiments will be contained within a 1D array, and ``observables`` is
Expand All @@ -56,7 +56,7 @@ def generate_cutting_experiments(
:math:`[sample_{0}observable_{0}, \ldots, sample_{0}observable_{N}, sample_{1}observable_{0}, \ldots, sample_{M}observable_{N}]`
The weights will always be returned as a 1D array -- one weight for each unique sample.
The coefficients will always be returned as a 1D array -- one coefficient for each unique sample.
Args:
circuits: The circuit(s) to partition and separate
Expand All @@ -65,14 +65,14 @@ def generate_cutting_experiments(
to infinity, the weights will be generated rigorously rather than by sampling from
the distribution.
Returns:
A tuple containing the cutting experiments and their associated weights.
A tuple containing the cutting experiments and their associated coefficients.
If the input circuits is a :class:`QuantumCircuit` instance, the output subexperiments
will be a sequence of circuits -- one for every unique sample and observable. If the
input circuits are represented as a dictionary keyed by partition labels, the output
subexperiments will also be a dictionary keyed by partition labels and containing
the subexperiments for each partition.
The weights are always a sequence of length-2 tuples, where each tuple contains the
weight and the :class:`WeightType`. Each weight corresponds to one unique sample.
The coefficients are always a sequence of length-2 tuples, where each tuple contains the
coefficient and the :class:`WeightType`. Each coefficient corresponds to one unique sample.
Raises:
ValueError: ``num_samples`` must be at least one.
Expand Down Expand Up @@ -134,15 +134,15 @@ def generate_cutting_experiments(
# Sort samples in descending order of frequency
sorted_samples = sorted(random_samples.items(), key=lambda x: x[1][0], reverse=True)

# Generate the output experiments and weights
# Generate the output experiments and their respective coefficients
subexperiments_dict: dict[str | int, list[QuantumCircuit]] = defaultdict(list)
weights: list[tuple[float, WeightType]] = []
coefficients: list[tuple[float, WeightType]] = []
for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples):
actual_coeff = np.prod(
[basis.coeffs[map_id] for basis, map_id in strict_zip(bases, map_ids)]
)
sampled_coeff = (redundancy / num_samples) * (kappa * np.sign(actual_coeff))
weights.append((sampled_coeff, weight_type))
coefficients.append((sampled_coeff, weight_type))
map_ids_tmp = map_ids
for i, (subcircuit, label) in enumerate(
strict_zip(subcircuit_list, sorted(subsystem_observables.keys()))
Expand All @@ -166,7 +166,7 @@ def generate_cutting_experiments(
assert len(subexperiments_out.keys()) == 1
subexperiments_out = list(subexperiments_dict.values())[0]

return subexperiments_out, weights
return subexperiments_out, coefficients


def _get_mapping_ids_by_partition(
Expand Down
16 changes: 8 additions & 8 deletions test/cutting/test_cutting_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ def test_generate_cutting_experiments(self):
TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"),
qargs=[0, 1],
)
comp_weights = [
comp_coeffs = [
(0.5, WeightType.EXACT),
(0.5, WeightType.EXACT),
(0.5, WeightType.EXACT),
(-0.5, WeightType.EXACT),
(0.5, WeightType.EXACT),
(-0.5, WeightType.EXACT),
]
subexperiments, weights = generate_cutting_experiments(
subexperiments, coeffs = generate_cutting_experiments(
qc, PauliList(["ZZ"]), np.inf
)
assert weights == comp_weights
assert len(weights) == len(subexperiments)
assert coeffs == comp_coeffs
assert len(coeffs) == len(subexperiments)
for exp in subexperiments:
assert isinstance(exp, QuantumCircuit)

Expand All @@ -68,19 +68,19 @@ def test_generate_cutting_experiments(self):
),
qargs=[1],
)
comp_weights = [
comp_coeffs = [
(0.5, WeightType.EXACT),
(0.5, WeightType.EXACT),
(0.5, WeightType.EXACT),
(-0.5, WeightType.EXACT),
(0.5, WeightType.EXACT),
(-0.5, WeightType.EXACT),
]
subexperiments, weights = generate_cutting_experiments(
subexperiments, coeffs = generate_cutting_experiments(
{"A": qc}, {"A": PauliList(["ZY"])}, np.inf
)
assert weights == comp_weights
assert len(weights) == len(subexperiments["A"])
assert coeffs == comp_coeffs
assert len(coeffs) == len(subexperiments["A"])
for circ in subexperiments["A"]:
assert isinstance(circ, QuantumCircuit)

Expand Down

0 comments on commit eadd0d7

Please sign in to comment.