Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modularize DDD functionality #2610

Merged
merged 5 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion mitiq/ddd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
insert_ddd_sequences,
)

from mitiq.ddd.ddd import execute_with_ddd, mitigate_executor, ddd_decorator
from mitiq.ddd.ddd import execute_with_ddd, mitigate_executor, ddd_decorator, generate_circuits_with_ddd, combine_results
57 changes: 50 additions & 7 deletions mitiq/ddd/ddd.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,11 @@ def execute_with_ddd(
if not isinstance(executor, Executor):
executor = Executor(executor)

rule_partial: Callable[[int], QPROGRAM]
rule_partial = partial(rule, **rule_args)

# Insert DDD sequences in (a copy of) the input circuit
circuits_with_ddd = [
insert_ddd_sequences(circuit, rule_partial) for _ in range(num_trials)
]
circuits_with_ddd = generate_circuits_with_ddd(
circuit, rule, rule_args, num_trials
)

results = executor.evaluate(
circuits_with_ddd,
observable,
Expand All @@ -74,7 +72,8 @@ def execute_with_ddd(

assert len(results) == num_trials

ddd_value = np.sum(results) / num_trials
ddd_value = combine_results(results)

if not full_output:
return ddd_value

Expand All @@ -86,6 +85,50 @@ def execute_with_ddd(
return ddd_value, ddd_data


def combine_results(results: list[float]) -> float:
"""Averages over the DDD results to get the expectation value from using
DDD.

Args:
results: Results as obtained from running circuits.

Returns:
The expectation value estimated with DDD.
"""
return float(np.average(results))


def generate_circuits_with_ddd(
circuit: QPROGRAM,
rule: Callable[[int], QPROGRAM],
rule_args: Dict[str, Any] = {},
num_trials: int = 1,
) -> list[QPROGRAM]:
"""Generates a list of circuits with DDD sequences inserted.

Args:
circuit: The quantum circuit to be modified with DD.
rule: A function that takes as main argument a slack length (i.e. the
number of idle moments) of a slack window (i.e. a single-qubit idle
window in a circuit) and returns the DDD sequence of gates to be
applied in that window.
rule_args: An optional dictionary of keyword arguments for ``rule``.
num_trials: The number of circuits to generate with DDD insertions.

Returns:
A list of circuits with DDD inserted.
"""
rule_partial: Callable[[int], QPROGRAM]
rule_partial = partial(rule, **rule_args)

# Insert DDD sequences in (a copy of) the input circuit
circuits_with_ddd = [
insert_ddd_sequences(circuit, rule_partial) for _ in range(num_trials)
]

return circuits_with_ddd


def mitigate_executor(
executor: Callable[[QPROGRAM], QuantumResult],
observable: Optional[Observable] = None,
Expand Down
18 changes: 17 additions & 1 deletion mitiq/ddd/tests/test_ddd.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
from pytest import mark

from mitiq import QPROGRAM, SUPPORTED_PROGRAM_TYPES, Executor
from mitiq.ddd import ddd_decorator, execute_with_ddd, mitigate_executor
from mitiq.ddd import (
ddd_decorator,
execute_with_ddd,
generate_circuits_with_ddd,
mitigate_executor,
)
from mitiq.ddd.rules import xx, xyxy, yy
from mitiq.interface import convert_from_mitiq, convert_to_mitiq
from mitiq.interface.mitiq_cirq import compute_density_matrix
Expand Down Expand Up @@ -226,3 +231,14 @@ def exec_xx_small_spacing(circuit):
# What is important to test is getting different results.
assert not np.isclose(unmitigated, mitigated_small_spacing)
assert not np.isclose(mitigated_large_spacing, mitigated_small_spacing)


@mark.parametrize("num_trials", [1, 3, 5])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this test should be fast (correct me if i'm wrong) can we add a few more trials? Say up to 30?

def test_num_trials_generates_circuits(num_trials: int):
"""Test that the number of generated circuits follows num_trials."""

circuits = generate_circuits_with_ddd(
circuit_cirq_a, rule=xx, num_trials=num_trials
)

assert num_trials == len(circuits)
Loading