Skip to content

Commit b0267f9

Browse files
2 parents afed183 + 05202e4 commit b0267f9

File tree

11 files changed

+48
-25
lines changed

11 files changed

+48
-25
lines changed

quantumpytho/validation/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@
5151
"validation_records_to_csv",
5252
"validation_records_to_json",
5353
"validation_records_to_markdown",
54-
]
54+
]

quantumpytho/validation/benchmarks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,4 @@ def reference_benchmarks() -> list[BenchmarkCase]:
8888
ghz_benchmark(),
8989
rotation_layer_benchmark(),
9090
parity_benchmark(),
91-
]
91+
]

quantumpytho/validation/integrations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ def validation_config_from_archive_job(
6868
"result_schema": detail.result_schema,
6969
**(metadata or {}),
7070
},
71-
)
71+
)

quantumpytho/validation/metrics.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ def total_variation_distance(
4545
return 0.5 * sum(abs(dist_a.get(key, 0.0) - dist_b.get(key, 0.0)) for key in keys)
4646

4747

48-
def hellinger_distance(counts_a: Mapping[str, int], counts_b: Mapping[str, int]) -> float:
48+
def hellinger_distance(
49+
counts_a: Mapping[str, int], counts_b: Mapping[str, int]
50+
) -> float:
4951
"""Compute Hellinger distance between two count distributions."""
5052
dist_a, dist_b, keys = _union_probabilities(counts_a, counts_b)
5153
squared = sum(
@@ -60,7 +62,9 @@ def jensen_shannon_divergence(
6062
) -> float:
6163
"""Compute Jensen-Shannon divergence in bits between two distributions."""
6264
dist_a, dist_b, keys = _union_probabilities(counts_a, counts_b)
63-
midpoint = {key: 0.5 * (dist_a.get(key, 0.0) + dist_b.get(key, 0.0)) for key in keys}
65+
midpoint = {
66+
key: 0.5 * (dist_a.get(key, 0.0) + dist_b.get(key, 0.0)) for key in keys
67+
}
6468

6569
def _kl_divergence(left: dict[str, float], right: dict[str, float]) -> float:
6670
divergence = 0.0
@@ -71,7 +75,9 @@ def _kl_divergence(left: dict[str, float], right: dict[str, float]) -> float:
7175
divergence += left_value * math.log2(left_value / right_value)
7276
return divergence
7377

74-
return 0.5 * _kl_divergence(dist_a, midpoint) + 0.5 * _kl_divergence(dist_b, midpoint)
78+
return 0.5 * _kl_divergence(dist_a, midpoint) + 0.5 * _kl_divergence(
79+
dist_b, midpoint
80+
)
7581

7682

7783
def expectation_value_z(counts: Mapping[str, int], qubit_index: int = 0) -> float:
@@ -126,7 +132,9 @@ def energy_error(simulated_energy: float, hardware_energy: float) -> float:
126132
return abs(simulated_energy - hardware_energy)
127133

128134

129-
def hardware_match_score(counts_a: Mapping[str, int], counts_b: Mapping[str, int]) -> float:
135+
def hardware_match_score(
136+
counts_a: Mapping[str, int], counts_b: Mapping[str, int]
137+
) -> float:
130138
"""Convert TVD into a simple customer-facing match score percentage."""
131139
score = (1.0 - total_variation_distance(counts_a, counts_b)) * 100.0
132140
return max(0.0, min(100.0, score))
@@ -141,4 +149,4 @@ def compute_counts_metrics(
141149
"hellinger": hellinger_distance(counts_a, counts_b),
142150
"js_divergence": jensen_shannon_divergence(counts_a, counts_b),
143151
"match_score": hardware_match_score(counts_a, counts_b),
144-
}
152+
}

quantumpytho/validation/provenance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@ def to_dict(self) -> dict[str, Any]:
6464

6565
def utc_now_iso() -> str:
6666
"""Return an ISO-8601 UTC timestamp for validation records."""
67-
return datetime.now(timezone.utc).isoformat()
67+
return datetime.now(timezone.utc).isoformat()

quantumpytho/validation/reporting.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
def validation_records_to_json(records: list[ValidationRecord]) -> str:
1313
"""Serialize validation records to JSON."""
14-
return json.dumps([record.to_dict() for record in records], indent=2, sort_keys=True)
14+
return json.dumps(
15+
[record.to_dict() for record in records], indent=2, sort_keys=True
16+
)
1517

1618

1719
def validation_records_to_csv(records: list[ValidationRecord]) -> str:
@@ -50,4 +52,4 @@ def validation_records_to_markdown(records: list[ValidationRecord]) -> str:
5052
lines.append(
5153
f"| {record.benchmark_id} | {record.backend_name} | {record.tvd_raw:.4f} | {match_score:.2f}% | {record.n_repeats} |"
5254
)
53-
return "\n".join(lines)
55+
return "\n".join(lines)

quantumpytho/validation/runner.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ def _coerce_counts(result: Any) -> dict[str, int]:
7272
counts = result.counts
7373
if isinstance(counts, dict):
7474
return {str(key): int(value) for key, value in counts.items()}
75-
raise TypeError("Executor result must be a counts dict or expose a 'counts' attribute")
75+
raise TypeError(
76+
"Executor result must be a counts dict or expose a 'counts' attribute"
77+
)
7678

7779

7880
def _transpile_shared(
@@ -104,7 +106,9 @@ def run_benchmark_case(
104106
) -> ValidationRecord:
105107
"""Run one benchmark through a shared transpilation pipeline and score agreement."""
106108
logical_hash = _hash_circuit(benchmark.circuit)
107-
transpiled_circuit = _transpile_shared(benchmark.circuit, config, backend, transpiler)
109+
transpiled_circuit = _transpile_shared(
110+
benchmark.circuit, config, backend, transpiler
111+
)
108112
transpiled_hash = _hash_circuit(transpiled_circuit)
109113

110114
sim_counts = _coerce_counts(simulation_executor(transpiled_circuit, config.shots))
@@ -129,7 +133,9 @@ def run_benchmark_case(
129133

130134
metric_mean = mean(raw_metrics)
131135
metric_std = pstdev(raw_metrics) if len(raw_metrics) > 1 else 0.0
132-
ci95_half_width = 1.96 * metric_std / math.sqrt(len(raw_metrics)) if raw_metrics else 0.0
136+
ci95_half_width = (
137+
1.96 * metric_std / math.sqrt(len(raw_metrics)) if raw_metrics else 0.0
138+
)
133139

134140
settings = config.to_transpilation_settings()
135141
return ValidationRecord(
@@ -190,4 +196,4 @@ def run_benchmark_suite(
190196
now_fn=now_fn,
191197
)
192198
for benchmark in benchmarks
193-
]
199+
]

tests/test_validation_integrations.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ def test_build_noisy_simulation_executor_delegates_to_noisy_simulator_engine():
5555
"""Noisy simulation adapter should forward circuit and shot count correctly."""
5656
circuit = QuantumCircuit(1, 1)
5757

58-
with patch("quantumpytho.validation.integrations.NoisySimulatorEngine") as mock_engine_cls:
58+
with patch(
59+
"quantumpytho.validation.integrations.NoisySimulatorEngine"
60+
) as mock_engine_cls:
5961
mock_engine = mock_engine_cls.return_value
6062
mock_engine.run.return_value.counts = {"0": 7, "1": 3}
6163

@@ -109,4 +111,4 @@ def test_validation_config_from_archive_job_uses_archive_metadata(tmp_path):
109111
assert config.optimization_level == 3
110112
assert config.resilience_level == 2
111113
assert config.metadata["archive_job_id"] == "d6vconfig0000000001"
112-
assert config.metadata["workload"] == "bell"
114+
assert config.metadata["workload"] == "bell"

tests/test_validation_metrics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,4 @@ def test_mean_absolute_expectation_error_returns_zero_for_empty_inputs_and_indic
7878

7979

8080
def test_energy_error_is_absolute_difference():
81-
assert energy_error(-1.25, -1.0) == pytest.approx(0.25)
81+
assert energy_error(-1.25, -1.0) == pytest.approx(0.25)

tests/test_validation_runner.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ def simulation_executor(circuit: QuantumCircuit, shots: int) -> dict[str, int]:
3030
seen_circuit_ids.append(("sim", id(circuit), shots, circuit.name))
3131
return {"00": 60, "11": 40}
3232

33-
hardware_runs = iter([
34-
{"00": 58, "11": 42},
35-
{"00": 57, "11": 43},
36-
])
33+
hardware_runs = iter(
34+
[
35+
{"00": 58, "11": 42},
36+
{"00": 57, "11": 43},
37+
]
38+
)
3739

3840
def hardware_executor(circuit: QuantumCircuit, shots: int) -> dict[str, int]:
3941
seen_circuit_ids.append(("hw", id(circuit), shots, circuit.name))
@@ -45,7 +47,10 @@ def hardware_executor(circuit: QuantumCircuit, shots: int) -> dict[str, int]:
4547
optimization_level=3,
4648
basis_gates=["rz", "sx", "x", "cz"],
4749
n_repeats=2,
48-
corrected_counts_resolver=lambda counts: {"00": counts["00"] + 1, "11": counts["11"] - 1},
50+
corrected_counts_resolver=lambda counts: {
51+
"00": counts["00"] + 1,
52+
"11": counts["11"] - 1,
53+
},
4954
)
5055

5156
record = run_benchmark_case(
@@ -172,4 +177,4 @@ def test_run_benchmark_case_clamps_repeat_count_to_one():
172177
assert record.n_repeats == 1
173178
assert record.std_metric == 0.0
174179
assert record.ci95_low == pytest.approx(0.0)
175-
assert record.ci95_high == pytest.approx(0.0)
180+
assert record.ci95_high == pytest.approx(0.0)

0 commit comments

Comments
 (0)