diff options
| author | YurenHao0426 <Blackhao0426@gmail.com> | 2026-08-29 18:34:49 -0500 |
|---|---|---|
| committer | YurenHao0426 <Blackhao0426@gmail.com> | 2026-08-29 18:34:49 -0500 |
| commit | 3562fd83ef8fc7f1ebede7571301224f2b5368c7 (patch) | |
| tree | 7a9613117068ba2e9da6ae85c4eaf98376a12955 | |
| parent | 2509cbf0eed13ab1ab0eaf83a65b920384988d80 (diff) | |
figure: consolidate hardware-realistic CLLN evidence
| -rw-r--r-- | experiments/plot_physical_hardware_evidence.py | 423 | ||||
| -rw-r--r-- | results/figs/figure_physical_hardware_evidence.pdf | bin | 0 -> 19174 bytes | |||
| -rw-r--r-- | results/figs/figure_physical_hardware_evidence.png | bin | 0 -> 152686 bytes | |||
| -rw-r--r-- | results/figs/figure_physical_hardware_evidence.svg | 1082 | ||||
| -rw-r--r-- | results/physical_bias/p10_hardware_evidence_analysis.json | 308 | ||||
| -rw-r--r-- | results/physical_bias/p10_hardware_evidence_source.csv | 25 | ||||
| -rw-r--r-- | visual-composer/physical-hardware-evidence.md | 40 | ||||
| -rw-r--r-- | visual-composer/qa-ledger.md | 13 |
8 files changed, 1891 insertions, 0 deletions
diff --git a/experiments/plot_physical_hardware_evidence.py b/experiments/plot_physical_hardware_evidence.py new file mode 100644 index 0000000..6a38b60 --- /dev/null +++ b/experiments/plot_physical_hardware_evidence.py @@ -0,0 +1,423 @@ +#!/usr/bin/env python3 +"""Build the hardware-realistic CLLN evidence figure from frozen results.""" + +from __future__ import annotations + +import argparse +import csv +import json +from pathlib import Path + +import matplotlib as mpl +import matplotlib.pyplot as plt +import numpy as np + + +METHODS = ( + ("clean", "Clean", "#222222"), + ("raw", "Raw", "#D55E00"), + ("constant", "Static\ncalibration", "#777777"), + ("overclamp", "Overclamp", "#E69F00"), + ("sdil", "SDIL", "#0072B2"), + ("overclamp_sdil", "Overclamp\n+ SDIL", "#56B4E9"), +) + +COMBINED_CONDITIONS = ( + ("ideal_cds", "Ideal\nCDS"), + ("common_pedestal_10", "Common\npedestal"), + ("sample_noise_1", "Sample\nnoise"), + ("refresh_every_4", "Refresh\nevery 4"), + ("combined_mild_refresh4", "Mild\ncombined"), + ("combined_strong", "Strong\ncombined"), + ("overclamp_plus_combined_mild", "Overclamp\n+ mild"), +) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument( + "--physical", + type=Path, + default=Path( + "results/physical_bias/p5_full_grid_bias_crossover.json"), + ) + parser.add_argument( + "--sampler", + type=Path, + default=Path( + "results/physical_bias/p9_grid_correlated_autozero.json"), + ) + parser.add_argument( + "--spice", + type=Path, + default=Path( + "results/physical_bias/p8_spice_autozero_primitive.json"), + ) + parser.add_argument( + "--output-analysis", + type=Path, + default=Path( + "results/physical_bias/p10_hardware_evidence_analysis.json"), + ) + parser.add_argument( + "--output-csv", + type=Path, + default=Path( + "results/physical_bias/p10_hardware_evidence_source.csv"), + ) + parser.add_argument( + "--output-figure", + type=Path, + default=Path("results/figs/figure_physical_hardware_evidence"), + ) + parser.add_argument("--bootstrap-replicates", type=int, default=20000) + parser.add_argument("--bootstrap-seed", type=int, default=20260829) + return parser.parse_args() + + +def clustered_summary( + records: list[dict], + value, + *, + rng: np.random.Generator, + replicates: int, +) -> dict: + tasks = sorted({record["task_index"] for record in records}) + task_means = np.asarray([ + np.mean([value(record) for record in records + if record["task_index"] == task]) + for task in tasks + ]) + samples = rng.integers( + 0, len(task_means), size=(replicates, len(task_means))) + bootstrap = np.mean(task_means[samples], axis=1) + return { + "mean": float(np.mean(task_means)), + "task_bootstrap_95ci": [ + float(bound) for bound in np.percentile(bootstrap, (2.5, 97.5)) + ], + "task_clusters": len(tasks), + "trials": len(records), + } + + +def physical_method_summaries( + report: dict, rng: np.random.Generator, replicates: int +) -> dict: + output = {} + for method, _, _ in METHODS: + output[method] = clustered_summary( + report["records"], + lambda record, name=method: record["methods"][name][ + "classification_error"], + rng=rng, + replicates=replicates, + ) + return output + + +def sampler_condition_summary( + report: dict, + condition: str, + rng: np.random.Generator, + replicates: int, +) -> dict: + selected = [ + record for record in report["records"] + if record["condition"] == condition + ] + summary = clustered_summary( + selected, + lambda record: record["classification_error"], + rng=rng, + replicates=replicates, + ) + summary["zero_error_fraction"] = float(np.mean([ + record["classification_error"] == 0.0 for record in selected + ])) + summary["solver_failure_fraction"] = float(np.mean([ + record["status"] != "completed" for record in selected + ])) + finite_rmse = [ + record["applied_rate_rmse_v_per_s"] for record in selected + if record["applied_rate_rmse_v_per_s"] is not None + ] + summary["median_applied_rate_rmse_v_per_s"] = float(np.median([ + value for value in finite_rmse + ])) + return summary + + +def build_analysis( + physical: dict, + sampler: dict, + spice: dict, + *, + replicates: int, + seed: int, +) -> dict: + rng = np.random.default_rng(seed) + sampler_conditions = { + condition["name"] for condition in sampler["protocol"]["conditions"] + } + required_conditions = { + name for name, _ in COMBINED_CONDITIONS + } | { + f"pedestal_mismatch_{value:g}" + for value in (0.01, 0.025, 0.05, 0.1, 0.25, 0.5) + } | { + f"gain_mismatch_{value:g}" + for value in (0.001, 0.005, 0.01, 0.025, 0.05) + } + missing = required_conditions - sampler_conditions + if missing: + raise ValueError(f"sampler report is missing {sorted(missing)}") + condition_summaries = { + condition: sampler_condition_summary( + sampler, condition, rng, replicates) + for condition in sorted(required_conditions) + } + return { + "analysis": "physical_clln_hardware_evidence_figure", + "confirmatory": False, + "bootstrap": { + "unit": "task; four device draws averaged within task", + "task_clusters": 40, + "replicates": replicates, + "seed": seed, + "interval": "percentile 95%", + }, + "physical_methods": physical_method_summaries( + physical, rng, replicates), + "sampler_conditions": condition_summaries, + "spice_primitive": { + "publication_evidence": spice["publication_evidence"], + "scope": spice["scope"], + "configuration_count": spice["configuration_count"], + "fraction_below_1_percent_error_at_start": spice[ + "fraction_below_1_percent_error_at_start"], + "fraction_below_1_percent_error_at_end": spice[ + "fraction_below_1_percent_error_at_end"], + "reference_configuration": spice["reference_configuration"], + }, + } + + +def write_csv(path: Path, analysis: dict) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", newline="") as stream: + writer = csv.writer(stream) + writer.writerow(( + "panel", "series", "condition", "x", "x_unit", "mean_error", + "ci_low", "ci_high", "zero_error_fraction", + )) + for method, label, _ in METHODS: + summary = analysis["physical_methods"][method] + writer.writerow(( + "a", "physical_method", label.replace("\n", " "), "", "", + summary["mean"], *summary["task_bootstrap_95ci"], "", + )) + for family, values in ( + ("pedestal mismatch", (0.01, 0.025, 0.05, 0.1, 0.25, 0.5)), + ("gain mismatch", (0.001, 0.005, 0.01, 0.025, 0.05)), + ): + prefix = family.replace(" ", "_") + for value in values: + summary = analysis["sampler_conditions"][f"{prefix}_{value:g}"] + writer.writerow(( + "b", family, f"{prefix}_{value:g}", + summary["median_applied_rate_rmse_v_per_s"], "V/s", + summary["mean"], *summary["task_bootstrap_95ci"], + summary["zero_error_fraction"], + )) + for condition, label in COMBINED_CONDITIONS: + summary = analysis["sampler_conditions"][condition] + writer.writerow(( + "c", "sampling condition", label.replace("\n", " "), "", "", + summary["mean"], *summary["task_bootstrap_95ci"], + summary["zero_error_fraction"], + )) + + +def errorbar(axis, x, summaries, **kwargs) -> None: + means = np.asarray([summary["mean"] for summary in summaries]) * 100.0 + intervals = np.asarray([ + summary["task_bootstrap_95ci"] for summary in summaries + ]) * 100.0 + axis.errorbar( + x, + means, + yerr=np.vstack((means - intervals[:, 0], intervals[:, 1] - means)), + capsize=2.2, + **kwargs, + ) + + +def plot(path: Path, analysis: dict) -> None: + mpl.rcParams.update({ + "font.family": "DejaVu Sans", + "font.size": 8.5, + "axes.labelsize": 9, + "axes.titlesize": 9.5, + "legend.fontsize": 7.5, + "xtick.labelsize": 7.7, + "ytick.labelsize": 8, + "axes.spines.top": False, + "axes.spines.right": False, + "svg.fonttype": "none", + "pdf.fonttype": 42, + "figure.facecolor": "white", + "axes.facecolor": "white", + }) + figure, axes = plt.subplots(1, 3, figsize=(10.7, 3.15)) + + method_summaries = [ + analysis["physical_methods"][method] for method, _, _ in METHODS + ] + method_means = np.asarray([ + summary["mean"] for summary in method_summaries]) * 100.0 + method_intervals = np.asarray([ + summary["task_bootstrap_95ci"] for summary in method_summaries + ]) * 100.0 + positions = np.arange(len(METHODS))[::-1] + axes[0].barh( + positions, + method_means, + color=[color for _, _, color in METHODS], + height=0.70, + edgecolor="white", + linewidth=0.4, + ) + axes[0].errorbar( + method_means, + positions, + xerr=np.vstack(( + method_means - method_intervals[:, 0], + method_intervals[:, 1] - method_means, + )), + fmt="none", + ecolor="#222222", + elinewidth=0.8, + capsize=2.2, + ) + axes[0].set_yticks( + positions, [label.replace("\n", " ") for _, label, _ in METHODS]) + axes[0].set_xlabel("Final classification error (%)") + axes[0].set_title("(a) Nonlinear CLLN with component errors") + + sweep_specs = ( + ("pedestal_mismatch", (0.01, 0.025, 0.05, 0.1, 0.25, 0.5), + "Pedestal mismatch", "#D55E00", "o"), + ("gain_mismatch", (0.001, 0.005, 0.01, 0.025, 0.05), + "Gain mismatch", "#0072B2", "D"), + ) + for prefix, values, label, color, marker in sweep_specs: + summaries = [ + analysis["sampler_conditions"][f"{prefix}_{value:g}"] + for value in values + ] + x = np.asarray([ + summary["median_applied_rate_rmse_v_per_s"] + for summary in summaries + ]) + errorbar( + axes[1], x, summaries, color=color, marker=marker, + markersize=4.5, linewidth=1.35, label=label, + ) + axes[1].set_xscale("log") + axes[1].set_xlabel("Residual sampling error (V/s, RMSE)") + axes[1].set_ylabel("Final classification error (%)") + axes[1].set_title("(b) Local sample-path mismatch") + axes[1].legend(frameon=False, loc="upper left") + + combined = [ + analysis["sampler_conditions"][condition] + for condition, _ in COMBINED_CONDITIONS + ] + combined_means = np.asarray([ + summary["mean"] for summary in combined]) * 100.0 + combined_intervals = np.asarray([ + summary["task_bootstrap_95ci"] for summary in combined + ]) * 100.0 + positions = np.arange(len(COMBINED_CONDITIONS))[::-1] + axes[2].barh( + positions, + combined_means, + color="#0072B2", + height=0.70, + edgecolor="white", + linewidth=0.4, + ) + axes[2].errorbar( + combined_means, + positions, + xerr=np.vstack(( + combined_means - combined_intervals[:, 0], + combined_intervals[:, 1] - combined_means, + )), + fmt="none", + ecolor="#222222", + elinewidth=0.8, + capsize=2.2, + ) + axes[2].set_yticks( + positions, + [label.replace("\n", " ") for _, label in COMBINED_CONDITIONS], + ) + axes[2].set_xlabel("Final classification error (%)") + axes[2].set_title("(c) Nonideal local sampling") + + axes[0].set_xlim(-0.8, 32.0) + axes[1].set_ylim(-0.8, 32.0) + axes[2].set_xlim(-0.8, 32.0) + for index, axis in enumerate(axes): + axis.grid( + axis="y" if index == 1 else "x", + color="#D9D9D9", linewidth=0.55, alpha=0.8) + axis.tick_params(length=3) + figure.text( + 0.995, + 0.005, + "40 tasks × 4 device draws; error bars are task-bootstrap 95% intervals", + ha="right", + va="bottom", + fontsize=7, + color="#666666", + ) + figure.tight_layout(rect=(0.0, 0.065, 1.0, 1.0), w_pad=2.0) + path.parent.mkdir(parents=True, exist_ok=True) + figure.savefig(path.with_suffix(".svg"), bbox_inches="tight") + figure.savefig(path.with_suffix(".pdf"), bbox_inches="tight") + figure.savefig(path.with_suffix(".png"), dpi=240, bbox_inches="tight") + plt.close(figure) + + +def main() -> None: + args = parse_args() + physical = json.loads(args.physical.read_text()) + sampler = json.loads(args.sampler.read_text()) + spice = json.loads(args.spice.read_text()) + analysis = build_analysis( + physical, + sampler, + spice, + replicates=args.bootstrap_replicates, + seed=args.bootstrap_seed, + ) + analysis["sources"] = [ + str(args.physical), str(args.sampler), str(args.spice)] + args.output_analysis.parent.mkdir(parents=True, exist_ok=True) + args.output_analysis.write_text(json.dumps(analysis, indent=2) + "\n") + write_csv(args.output_csv, analysis) + plot(args.output_figure, analysis) + print(json.dumps({ + "physical_methods": analysis["physical_methods"], + "combined_strong": analysis["sampler_conditions"]["combined_strong"], + }, indent=2)) + print(f"wrote {args.output_analysis}") + print(f"wrote {args.output_csv}") + print(f"wrote {args.output_figure}.svg/.pdf/.png") + + +if __name__ == "__main__": + main() diff --git a/results/figs/figure_physical_hardware_evidence.pdf b/results/figs/figure_physical_hardware_evidence.pdf Binary files differnew file mode 100644 index 0000000..6e3aeac --- /dev/null +++ b/results/figs/figure_physical_hardware_evidence.pdf diff --git a/results/figs/figure_physical_hardware_evidence.png b/results/figs/figure_physical_hardware_evidence.png Binary files differnew file mode 100644 index 0000000..d78f8ea --- /dev/null +++ b/results/figs/figure_physical_hardware_evidence.png diff --git a/results/figs/figure_physical_hardware_evidence.svg b/results/figs/figure_physical_hardware_evidence.svg new file mode 100644 index 0000000..9efa4a8 --- /dev/null +++ b/results/figs/figure_physical_hardware_evidence.svg @@ -0,0 +1,1082 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="771.54175pt" height="230.904516pt" viewBox="0 0 771.54175 230.904516" xmlns="http://www.w3.org/2000/svg" version="1.1"> + <metadata> + <rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2026-08-29T18:34:08.451813</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.10.8, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> + <defs> + <style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 230.904516 +L 771.54175 230.904516 +L 771.54175 0 +L 0 0 +z +" style="fill: #ffffff"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 87.00375 171.120516 +L 246.560417 171.120516 +L 246.560417 20.418516 +L 87.00375 20.418516 +z +" style="fill: #ffffff"/> + </g> + <g id="patch_3"> + <path d="M 90.895376 44.093391 +L 90.895376 44.093391 +L 90.895376 27.268607 +L 90.895376 27.268607 +z +" clip-path="url(#pf3ff1facc5)" style="fill: #222222; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_4"> + <path d="M 90.895376 68.128798 +L 216.689147 68.128798 +L 216.689147 51.304013 +L 90.895376 51.304013 +z +" clip-path="url(#pf3ff1facc5)" style="fill: #d55e00; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_5"> + <path d="M 90.895376 92.164205 +L 109.137373 92.164205 +L 109.137373 75.33942 +L 90.895376 75.33942 +z +" clip-path="url(#pf3ff1facc5)" style="fill: #777777; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_6"> + <path d="M 90.895376 116.199611 +L 114.077914 116.199611 +L 114.077914 99.374827 +L 90.895376 99.374827 +z +" clip-path="url(#pf3ff1facc5)" style="fill: #e69f00; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_7"> + <path d="M 90.895376 140.235018 +L 90.895376 140.235018 +L 90.895376 123.410233 +L 90.895376 123.410233 +z +" clip-path="url(#pf3ff1facc5)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_8"> + <path d="M 90.895376 164.270425 +L 90.895376 164.270425 +L 90.895376 147.44564 +L 90.895376 147.44564 +z +" clip-path="url(#pf3ff1facc5)" style="fill: #56b4e9; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <path d="M 90.895376 171.120516 +L 90.895376 20.418516 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_2"> + <defs> + <path id="m5974431c5e" d="M 0 0 +L 0 3 +" style="stroke: #000000; stroke-width: 0.8"/> + </defs> + <g> + <use xlink:href="#m5974431c5e" x="90.895376" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_1"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="90.895376" y="183.471313" transform="rotate(-0 90.895376 183.471313)">0</text> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_3"> + <path d="M 139.540701 171.120516 +L 139.540701 20.418516 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_4"> + <g> + <use xlink:href="#m5974431c5e" x="139.540701" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_2"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="139.540701" y="183.471313" transform="rotate(-0 139.540701 183.471313)">10</text> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_5"> + <path d="M 188.186026 171.120516 +L 188.186026 20.418516 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_6"> + <g> + <use xlink:href="#m5974431c5e" x="188.186026" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_3"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="188.186026" y="183.471313" transform="rotate(-0 188.186026 183.471313)">20</text> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_7"> + <path d="M 236.831352 171.120516 +L 236.831352 20.418516 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_8"> + <g> + <use xlink:href="#m5974431c5e" x="236.831352" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_4"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="236.831352" y="183.471313" transform="rotate(-0 236.831352 183.471313)">30</text> + </g> + </g> + <g id="text_5"> + <text style="font-size: 9px; font-family: 'DejaVu Sans'; text-anchor: middle" x="166.782083" y="195.911266" transform="rotate(-0 166.782083 195.911266)">Final classification error (%)</text> + </g> + </g> + <g id="matplotlib.axis_2"> + <g id="ytick_1"> + <g id="line2d_9"> + <defs> + <path id="m2ade93fa71" d="M 0 0 +L -3 0 +" style="stroke: #000000; stroke-width: 0.8"/> + </defs> + <g> + <use xlink:href="#m2ade93fa71" x="87.00375" y="35.680999" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_6"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="80.50375" y="38.720374" transform="rotate(-0 80.50375 38.720374)">Clean</text> + </g> + </g> + <g id="ytick_2"> + <g id="line2d_10"> + <g> + <use xlink:href="#m2ade93fa71" x="87.00375" y="59.716406" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_7"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="80.50375" y="62.755781" transform="rotate(-0 80.50375 62.755781)">Raw</text> + </g> + </g> + <g id="ytick_3"> + <g id="line2d_11"> + <g> + <use xlink:href="#m2ade93fa71" x="87.00375" y="83.751812" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_8"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="80.50375" y="86.791187" transform="rotate(-0 80.50375 86.791187)">Static calibration</text> + </g> + </g> + <g id="ytick_4"> + <g id="line2d_12"> + <g> + <use xlink:href="#m2ade93fa71" x="87.00375" y="107.787219" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_9"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="80.50375" y="110.826594" transform="rotate(-0 80.50375 110.826594)">Overclamp</text> + </g> + </g> + <g id="ytick_5"> + <g id="line2d_13"> + <g> + <use xlink:href="#m2ade93fa71" x="87.00375" y="131.822626" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_10"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="80.50375" y="134.862001" transform="rotate(-0 80.50375 134.862001)">SDIL</text> + </g> + </g> + <g id="ytick_6"> + <g id="line2d_14"> + <g> + <use xlink:href="#m2ade93fa71" x="87.00375" y="155.858032" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_11"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="80.50375" y="158.897407" transform="rotate(-0 80.50375 158.897407)">Overclamp + SDIL</text> + </g> + </g> + </g> + <g id="LineCollection_1"> + <path d="M 90.895376 35.680999 +L 90.895376 35.680999 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 199.207233 59.716406 +L 234.931144 59.716406 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 100.016374 83.751812 +L 119.398496 83.751812 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 100.016374 107.787219 +L 131.179786 107.787219 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 90.895376 131.822626 +L 90.895376 131.822626 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 90.895376 155.858032 +L 90.895376 155.858032 +" clip-path="url(#pf3ff1facc5)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + </g> + <g id="line2d_15"> + <defs> + <path id="mc120802246" d="M 0 2.2 +L 0 -2.2 +" style="stroke: #222222"/> + </defs> + <g clip-path="url(#pf3ff1facc5)"> + <use xlink:href="#mc120802246" x="90.895376" y="35.680999" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="199.207233" y="59.716406" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="100.016374" y="83.751812" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="100.016374" y="107.787219" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="90.895376" y="131.822626" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="90.895376" y="155.858032" style="fill: #1f77b4; stroke: #222222"/> + </g> + </g> + <g id="line2d_16"> + <g clip-path="url(#pf3ff1facc5)"> + <use xlink:href="#mc120802246" x="90.895376" y="35.680999" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="234.931144" y="59.716406" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="119.398496" y="83.751812" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="131.179786" y="107.787219" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="90.895376" y="131.822626" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="90.895376" y="155.858032" style="fill: #1f77b4; stroke: #222222"/> + </g> + </g> + <g id="patch_9"> + <path d="M 87.00375 171.120516 +L 87.00375 20.418516 +" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/> + </g> + <g id="patch_10"> + <path d="M 87.00375 171.120516 +L 246.560417 171.120516 +" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/> + </g> + <g id="text_12"> + <text style="font-size: 9.5px; font-family: 'DejaVu Sans'; text-anchor: middle" x="166.782083" y="14.418516" transform="rotate(-0 166.782083 14.418516)">(a) Nonlinear CLLN with component errors</text> + </g> + </g> + <g id="axes_2"> + <g id="patch_11"> + <path d="M 343.230417 171.120516 +L 502.787083 171.120516 +L 502.787083 20.418516 +L 343.230417 20.418516 +z +" style="fill: #ffffff"/> + </g> + <g id="matplotlib.axis_3"> + <g id="xtick_5"> + <g id="line2d_17"> + <g> + <use xlink:href="#m5974431c5e" x="391.550804" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_13"> + <!-- $\mathdefault{10^{-2}}$ --> + <g transform="translate(382.503304 183.471313)"> + <text> + <tspan x="0" y="-0.78125" style="font-size: 7.7px; font-family: 'DejaVu Sans'">1</tspan> + <tspan x="4.930786" y="-0.78125" style="font-size: 7.7px; font-family: 'DejaVu Sans'">0</tspan> + <tspan x="9.938135" y="-3.84375" style="font-size: 5.39px; font-family: 'DejaVu Sans'">−</tspan> + <tspan x="14.483691" y="-3.84375" style="font-size: 5.39px; font-family: 'DejaVu Sans'">2</tspan> + </text> + </g> + </g> + </g> + <g id="xtick_6"> + <g id="line2d_18"> + <g> + <use xlink:href="#m5974431c5e" x="452.749266" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_14"> + <!-- $\mathdefault{10^{-1}}$ --> + <g transform="translate(443.701766 183.471313)"> + <text> + <tspan x="0" y="-0.857813" style="font-size: 7.7px; font-family: 'DejaVu Sans'">1</tspan> + <tspan x="4.930786" y="-0.857813" style="font-size: 7.7px; font-family: 'DejaVu Sans'">0</tspan> + <tspan x="9.938135" y="-3.920313" style="font-size: 5.39px; font-family: 'DejaVu Sans'">−</tspan> + <tspan x="14.483691" y="-3.920313" style="font-size: 5.39px; font-family: 'DejaVu Sans'">1</tspan> + </text> + </g> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_19"> + <defs> + <path id="m1f6c4797ec" d="M 0 0 +L 0 2 +" style="stroke: #000000; stroke-width: 0.6"/> + </defs> + <g> + <use xlink:href="#m1f6c4797ec" x="348.774916" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_8"> + <g id="line2d_20"> + <g> + <use xlink:href="#m1f6c4797ec" x="359.55143" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_9"> + <g id="line2d_21"> + <g> + <use xlink:href="#m1f6c4797ec" x="367.197488" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_10"> + <g id="line2d_22"> + <g> + <use xlink:href="#m1f6c4797ec" x="373.128232" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_11"> + <g id="line2d_23"> + <g> + <use xlink:href="#m1f6c4797ec" x="377.974002" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_12"> + <g id="line2d_24"> + <g> + <use xlink:href="#m1f6c4797ec" x="382.071043" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_13"> + <g id="line2d_25"> + <g> + <use xlink:href="#m1f6c4797ec" x="385.620061" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_14"> + <g id="line2d_26"> + <g> + <use xlink:href="#m1f6c4797ec" x="388.750516" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_15"> + <g id="line2d_27"> + <g> + <use xlink:href="#m1f6c4797ec" x="409.973377" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_16"> + <g id="line2d_28"> + <g> + <use xlink:href="#m1f6c4797ec" x="420.749891" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_17"> + <g id="line2d_29"> + <g> + <use xlink:href="#m1f6c4797ec" x="428.39595" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_18"> + <g id="line2d_30"> + <g> + <use xlink:href="#m1f6c4797ec" x="434.326693" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_19"> + <g id="line2d_31"> + <g> + <use xlink:href="#m1f6c4797ec" x="439.172464" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_20"> + <g id="line2d_32"> + <g> + <use xlink:href="#m1f6c4797ec" x="443.269504" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_21"> + <g id="line2d_33"> + <g> + <use xlink:href="#m1f6c4797ec" x="446.818522" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_22"> + <g id="line2d_34"> + <g> + <use xlink:href="#m1f6c4797ec" x="449.948978" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_23"> + <g id="line2d_35"> + <g> + <use xlink:href="#m1f6c4797ec" x="471.171838" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_24"> + <g id="line2d_36"> + <g> + <use xlink:href="#m1f6c4797ec" x="481.948352" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_25"> + <g id="line2d_37"> + <g> + <use xlink:href="#m1f6c4797ec" x="489.594411" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_26"> + <g id="line2d_38"> + <g> + <use xlink:href="#m1f6c4797ec" x="495.525155" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="xtick_27"> + <g id="line2d_39"> + <g> + <use xlink:href="#m1f6c4797ec" x="500.370925" y="171.120516" style="stroke: #000000; stroke-width: 0.6"/> + </g> + </g> + </g> + <g id="text_15"> + <text style="font-size: 9px; font-family: 'DejaVu Sans'; text-anchor: middle" x="423.00875" y="195.911266" transform="rotate(-0 423.00875 195.911266)">Residual sampling error (V/s, RMSE)</text> + </g> + </g> + <g id="matplotlib.axis_4"> + <g id="ytick_7"> + <g id="line2d_40"> + <path d="M 343.230417 167.444857 +L 502.787083 167.444857 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_41"> + <g> + <use xlink:href="#m2ade93fa71" x="343.230417" y="167.444857" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_16"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="336.730417" y="170.484232" transform="rotate(-0 336.730417 170.484232)">0</text> + </g> + </g> + <g id="ytick_8"> + <g id="line2d_42"> + <path d="M 343.230417 144.471991 +L 502.787083 144.471991 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_43"> + <g> + <use xlink:href="#m2ade93fa71" x="343.230417" y="144.471991" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_17"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="336.730417" y="147.511366" transform="rotate(-0 336.730417 147.511366)">5</text> + </g> + </g> + <g id="ytick_9"> + <g id="line2d_44"> + <path d="M 343.230417 121.499125 +L 502.787083 121.499125 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_45"> + <g> + <use xlink:href="#m2ade93fa71" x="343.230417" y="121.499125" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_18"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="336.730417" y="124.5385" transform="rotate(-0 336.730417 124.5385)">10</text> + </g> + </g> + <g id="ytick_10"> + <g id="line2d_46"> + <path d="M 343.230417 98.52626 +L 502.787083 98.52626 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_47"> + <g> + <use xlink:href="#m2ade93fa71" x="343.230417" y="98.52626" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_19"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="336.730417" y="101.565635" transform="rotate(-0 336.730417 101.565635)">15</text> + </g> + </g> + <g id="ytick_11"> + <g id="line2d_48"> + <path d="M 343.230417 75.553394 +L 502.787083 75.553394 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_49"> + <g> + <use xlink:href="#m2ade93fa71" x="343.230417" y="75.553394" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_20"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="336.730417" y="78.592769" transform="rotate(-0 336.730417 78.592769)">20</text> + </g> + </g> + <g id="ytick_12"> + <g id="line2d_50"> + <path d="M 343.230417 52.580528 +L 502.787083 52.580528 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_51"> + <g> + <use xlink:href="#m2ade93fa71" x="343.230417" y="52.580528" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_21"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="336.730417" y="55.619903" transform="rotate(-0 336.730417 55.619903)">25</text> + </g> + </g> + <g id="ytick_13"> + <g id="line2d_52"> + <path d="M 343.230417 29.607662 +L 502.787083 29.607662 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_53"> + <g> + <use xlink:href="#m2ade93fa71" x="343.230417" y="29.607662" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_22"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="336.730417" y="32.647037" transform="rotate(-0 336.730417 32.647037)">30</text> + </g> + </g> + <g id="text_23"> + <text style="font-size: 9px; font-family: 'DejaVu Sans'; text-anchor: middle" x="320.678698" y="95.769516" transform="rotate(-90 320.678698 95.769516)">Final classification error (%)</text> + </g> + </g> + <g id="LineCollection_2"> + <path d="M 391.560157 167.444857 +L 391.560157 167.444857 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d55e00; stroke-width: 1.35"/> + <path d="M 415.913474 167.444857 +L 415.913474 167.444857 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d55e00; stroke-width: 1.35"/> + <path d="M 434.336046 167.444857 +L 434.336046 167.444857 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d55e00; stroke-width: 1.35"/> + <path d="M 452.758619 166.726955 +L 452.758619 161.701641 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d55e00; stroke-width: 1.35"/> + <path d="M 477.111935 158.11213 +L 477.111935 133.344509 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d55e00; stroke-width: 1.35"/> + <path d="M 495.534508 140.164579 +L 495.534508 103.910525 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d55e00; stroke-width: 1.35"/> + </g> + <g id="line2d_54"> + <defs> + <path id="m12af69966a" d="M 2.2 0 +L -2.2 -0 +" style="stroke: #d55e00"/> + </defs> + <g clip-path="url(#p800f26f182)"> + <use xlink:href="#m12af69966a" x="391.560157" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="415.913474" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="434.336046" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="452.758619" y="166.726955" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="477.111935" y="158.11213" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="495.534508" y="140.164579" style="fill: #d55e00; stroke: #d55e00"/> + </g> + </g> + <g id="line2d_55"> + <g clip-path="url(#p800f26f182)"> + <use xlink:href="#m12af69966a" x="391.560157" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="415.913474" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="434.336046" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="452.758619" y="161.701641" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="477.111935" y="133.344509" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m12af69966a" x="495.534508" y="103.910525" style="fill: #d55e00; stroke: #d55e00"/> + </g> + </g> + <g id="LineCollection_3"> + <path d="M 350.482992 167.444857 +L 350.482992 167.444857 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #0072b2; stroke-width: 1.35"/> + <path d="M 393.255515 167.444857 +L 393.255515 167.444857 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #0072b2; stroke-width: 1.35"/> + <path d="M 411.690885 167.444857 +L 411.690885 167.444857 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #0072b2; stroke-width: 1.35"/> + <path d="M 436.061444 167.444857 +L 436.061444 165.650102 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #0072b2; stroke-width: 1.35"/> + <path d="M 454.660843 167.085906 +L 454.660843 161.34269 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #0072b2; stroke-width: 1.35"/> + </g> + <g id="line2d_56"> + <defs> + <path id="m529fa2b800" d="M 2.2 0 +L -2.2 -0 +" style="stroke: #0072b2"/> + </defs> + <g clip-path="url(#p800f26f182)"> + <use xlink:href="#m529fa2b800" x="350.482992" y="167.444857" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="393.255515" y="167.444857" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="411.690885" y="167.444857" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="436.061444" y="167.444857" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="454.660843" y="167.085906" style="fill: #0072b2; stroke: #0072b2"/> + </g> + </g> + <g id="line2d_57"> + <g clip-path="url(#p800f26f182)"> + <use xlink:href="#m529fa2b800" x="350.482992" y="167.444857" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="393.255515" y="167.444857" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="411.690885" y="167.444857" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="436.061444" y="165.650102" style="fill: #0072b2; stroke: #0072b2"/> + <use xlink:href="#m529fa2b800" x="454.660843" y="161.34269" style="fill: #0072b2; stroke: #0072b2"/> + </g> + </g> + <g id="line2d_58"> + <path d="M 391.560157 167.444857 +L 415.913474 167.444857 +L 434.336046 167.444857 +L 452.758619 164.573249 +L 477.111935 146.984648 +L 495.534508 122.934929 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #d55e00; stroke-width: 1.35; stroke-linecap: square"/> + <defs> + <path id="m9c08e3ae10" d="M 0 2.25 +C 0.596707 2.25 1.169055 2.012926 1.59099 1.59099 +C 2.012926 1.169055 2.25 0.596707 2.25 0 +C 2.25 -0.596707 2.012926 -1.169055 1.59099 -1.59099 +C 1.169055 -2.012926 0.596707 -2.25 0 -2.25 +C -0.596707 -2.25 -1.169055 -2.012926 -1.59099 -1.59099 +C -2.012926 -1.169055 -2.25 -0.596707 -2.25 0 +C -2.25 0.596707 -2.012926 1.169055 -1.59099 1.59099 +C -1.169055 2.012926 -0.596707 2.25 0 2.25 +z +" style="stroke: #d55e00"/> + </defs> + <g clip-path="url(#p800f26f182)"> + <use xlink:href="#m9c08e3ae10" x="391.560157" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m9c08e3ae10" x="415.913474" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m9c08e3ae10" x="434.336046" y="167.444857" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m9c08e3ae10" x="452.758619" y="164.573249" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m9c08e3ae10" x="477.111935" y="146.984648" style="fill: #d55e00; stroke: #d55e00"/> + <use xlink:href="#m9c08e3ae10" x="495.534508" y="122.934929" style="fill: #d55e00; stroke: #d55e00"/> + </g> + </g> + <g id="line2d_59"> + <path d="M 350.482992 167.444857 +L 393.255515 167.444857 +L 411.690885 167.444857 +L 436.061444 166.726955 +L 454.660843 164.573249 +" clip-path="url(#p800f26f182)" style="fill: none; stroke: #0072b2; stroke-width: 1.35; stroke-linecap: square"/> + <defs> + <path id="m4be6bd8158" d="M -0 3.181981 +L 3.181981 0 +L 0 -3.181981 +L -3.181981 -0 +z +" style="stroke: #0072b2; stroke-linejoin: miter"/> + </defs> + <g clip-path="url(#p800f26f182)"> + <use xlink:href="#m4be6bd8158" x="350.482992" y="167.444857" style="fill: #0072b2; stroke: #0072b2; stroke-linejoin: miter"/> + <use xlink:href="#m4be6bd8158" x="393.255515" y="167.444857" style="fill: #0072b2; stroke: #0072b2; stroke-linejoin: miter"/> + <use xlink:href="#m4be6bd8158" x="411.690885" y="167.444857" style="fill: #0072b2; stroke: #0072b2; stroke-linejoin: miter"/> + <use xlink:href="#m4be6bd8158" x="436.061444" y="166.726955" style="fill: #0072b2; stroke: #0072b2; stroke-linejoin: miter"/> + <use xlink:href="#m4be6bd8158" x="454.660843" y="164.573249" style="fill: #0072b2; stroke: #0072b2; stroke-linejoin: miter"/> + </g> + </g> + <g id="patch_12"> + <path d="M 343.230417 171.120516 +L 343.230417 20.418516 +" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/> + </g> + <g id="patch_13"> + <path d="M 343.230417 171.120516 +L 502.787083 171.120516 +" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/> + </g> + <g id="text_24"> + <text style="font-size: 9.5px; font-family: 'DejaVu Sans'; text-anchor: middle" x="423.00875" y="14.418516" transform="rotate(-0 423.00875 14.418516)">(b) Local sample-path mismatch</text> + </g> + <g id="legend_1"> + <g id="LineCollection_4"> + <path d="M 357.480417 33.992344 +L 357.480417 26.492344 +" style="fill: none; stroke: #d55e00; stroke-width: 1.35"/> + </g> + <g id="line2d_60"> + <g> + <use xlink:href="#m12af69966a" x="357.480417" y="33.992344" style="fill: #d55e00; stroke: #d55e00"/> + </g> + </g> + <g id="line2d_61"> + <g> + <use xlink:href="#m12af69966a" x="357.480417" y="26.492344" style="fill: #d55e00; stroke: #d55e00"/> + </g> + </g> + <g id="line2d_62"> + <path d="M 349.980417 30.242344 +L 364.980417 30.242344 +" style="fill: none; stroke: #d55e00; stroke-width: 1.35; stroke-linecap: square"/> + </g> + <g id="line2d_63"> + <g> + <use xlink:href="#m9c08e3ae10" x="357.480417" y="30.242344" style="fill: #d55e00; stroke: #d55e00"/> + </g> + </g> + <g id="text_25"> + <text style="font-size: 7.5px; font-family: 'DejaVu Sans'; text-anchor: start" x="370.980417" y="32.867344" transform="rotate(-0 370.980417 32.867344)">Pedestal mismatch</text> + </g> + <g id="LineCollection_5"> + <path d="M 357.480417 45.000938 +L 357.480417 37.500938 +" style="fill: none; stroke: #0072b2; stroke-width: 1.35"/> + </g> + <g id="line2d_64"> + <g> + <use xlink:href="#m529fa2b800" x="357.480417" y="45.000938" style="fill: #0072b2; stroke: #0072b2"/> + </g> + </g> + <g id="line2d_65"> + <g> + <use xlink:href="#m529fa2b800" x="357.480417" y="37.500938" style="fill: #0072b2; stroke: #0072b2"/> + </g> + </g> + <g id="line2d_66"> + <path d="M 349.980417 41.250938 +L 364.980417 41.250938 +" style="fill: none; stroke: #0072b2; stroke-width: 1.35; stroke-linecap: square"/> + </g> + <g id="line2d_67"> + <g> + <use xlink:href="#m4be6bd8158" x="357.480417" y="41.250938" style="fill: #0072b2; stroke: #0072b2; stroke-linejoin: miter"/> + </g> + </g> + <g id="text_26"> + <text style="font-size: 7.5px; font-family: 'DejaVu Sans'; text-anchor: start" x="370.980417" y="43.875938" transform="rotate(-0 370.980417 43.875938)">Gain mismatch</text> + </g> + </g> + </g> + <g id="axes_3"> + <g id="patch_14"> + <path d="M 599.457083 171.120516 +L 759.01375 171.120516 +L 759.01375 20.418516 +L 599.457083 20.418516 +z +" style="fill: #ffffff"/> + </g> + <g id="patch_15"> + <path d="M 603.348709 41.582229 +L 603.348709 41.582229 +L 603.348709 27.268607 +L 603.348709 27.268607 +z +" clip-path="url(#p6d538e60d8)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_16"> + <path d="M 603.348709 62.030262 +L 603.348709 62.030262 +L 603.348709 47.716639 +L 603.348709 47.716639 +z +" clip-path="url(#p6d538e60d8)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_17"> + <path d="M 603.348709 82.478294 +L 603.348709 82.478294 +L 603.348709 68.164672 +L 603.348709 68.164672 +z +" clip-path="url(#p6d538e60d8)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_18"> + <path d="M 603.348709 102.926327 +L 603.348709 102.926327 +L 603.348709 88.612704 +L 603.348709 88.612704 +z +" clip-path="url(#p6d538e60d8)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_19"> + <path d="M 603.348709 123.37436 +L 603.348709 123.37436 +L 603.348709 109.060737 +L 603.348709 109.060737 +z +" clip-path="url(#p6d538e60d8)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_20"> + <path d="M 603.348709 143.822392 +L 606.009001 143.822392 +L 606.009001 129.508769 +L 603.348709 129.508769 +z +" clip-path="url(#p6d538e60d8)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="patch_21"> + <path d="M 603.348709 164.270425 +L 603.348709 164.270425 +L 603.348709 149.956802 +L 603.348709 149.956802 +z +" clip-path="url(#p6d538e60d8)" style="fill: #0072b2; stroke: #ffffff; stroke-width: 0.4; stroke-linejoin: miter"/> + </g> + <g id="matplotlib.axis_5"> + <g id="xtick_28"> + <g id="line2d_68"> + <path d="M 603.348709 171.120516 +L 603.348709 20.418516 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_69"> + <g> + <use xlink:href="#m5974431c5e" x="603.348709" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_27"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="603.348709" y="183.471313" transform="rotate(-0 603.348709 183.471313)">0</text> + </g> + </g> + <g id="xtick_29"> + <g id="line2d_70"> + <path d="M 651.994035 171.120516 +L 651.994035 20.418516 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_71"> + <g> + <use xlink:href="#m5974431c5e" x="651.994035" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_28"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="651.994035" y="183.471313" transform="rotate(-0 651.994035 183.471313)">10</text> + </g> + </g> + <g id="xtick_30"> + <g id="line2d_72"> + <path d="M 700.63936 171.120516 +L 700.63936 20.418516 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_73"> + <g> + <use xlink:href="#m5974431c5e" x="700.63936" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_29"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="700.63936" y="183.471313" transform="rotate(-0 700.63936 183.471313)">20</text> + </g> + </g> + <g id="xtick_31"> + <g id="line2d_74"> + <path d="M 749.284685 171.120516 +L 749.284685 20.418516 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #d9d9d9; stroke-opacity: 0.8; stroke-width: 0.55; stroke-linecap: square"/> + </g> + <g id="line2d_75"> + <g> + <use xlink:href="#m5974431c5e" x="749.284685" y="171.120516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_30"> + <text style="font-size: 7.7px; font-family: 'DejaVu Sans'; text-anchor: middle" x="749.284685" y="183.471313" transform="rotate(-0 749.284685 183.471313)">30</text> + </g> + </g> + <g id="text_31"> + <text style="font-size: 9px; font-family: 'DejaVu Sans'; text-anchor: middle" x="679.235417" y="195.911266" transform="rotate(-0 679.235417 195.911266)">Final classification error (%)</text> + </g> + </g> + <g id="matplotlib.axis_6"> + <g id="ytick_14"> + <g id="line2d_76"> + <g> + <use xlink:href="#m2ade93fa71" x="599.457083" y="34.425418" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_32"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="592.957083" y="37.464793" transform="rotate(-0 592.957083 37.464793)">Ideal CDS</text> + </g> + </g> + <g id="ytick_15"> + <g id="line2d_77"> + <g> + <use xlink:href="#m2ade93fa71" x="599.457083" y="54.87345" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_33"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="592.957083" y="57.912825" transform="rotate(-0 592.957083 57.912825)">Common pedestal</text> + </g> + </g> + <g id="ytick_16"> + <g id="line2d_78"> + <g> + <use xlink:href="#m2ade93fa71" x="599.457083" y="75.321483" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_34"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="592.957083" y="78.360858" transform="rotate(-0 592.957083 78.360858)">Sample noise</text> + </g> + </g> + <g id="ytick_17"> + <g id="line2d_79"> + <g> + <use xlink:href="#m2ade93fa71" x="599.457083" y="95.769516" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_35"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="592.957083" y="98.808891" transform="rotate(-0 592.957083 98.808891)">Refresh every 4</text> + </g> + </g> + <g id="ytick_18"> + <g id="line2d_80"> + <g> + <use xlink:href="#m2ade93fa71" x="599.457083" y="116.217548" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_36"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="592.957083" y="119.256923" transform="rotate(-0 592.957083 119.256923)">Mild combined</text> + </g> + </g> + <g id="ytick_19"> + <g id="line2d_81"> + <g> + <use xlink:href="#m2ade93fa71" x="599.457083" y="136.665581" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_37"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="592.957083" y="139.704956" transform="rotate(-0 592.957083 139.704956)">Strong combined</text> + </g> + </g> + <g id="ytick_20"> + <g id="line2d_82"> + <g> + <use xlink:href="#m2ade93fa71" x="599.457083" y="157.113613" style="stroke: #000000; stroke-width: 0.8"/> + </g> + </g> + <g id="text_38"> + <text style="font-size: 8px; font-family: 'DejaVu Sans'; text-anchor: end" x="592.957083" y="160.152988" transform="rotate(-0 592.957083 160.152988)">Overclamp + mild</text> + </g> + </g> + </g> + <g id="LineCollection_6"> + <path d="M 603.348709 34.425418 +L 603.348709 34.425418 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 603.348709 54.87345 +L 603.348709 54.87345 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 603.348709 75.321483 +L 603.348709 75.321483 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 603.348709 95.769516 +L 603.348709 95.769516 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 603.348709 116.217548 +L 603.348709 116.217548 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 603.728751 136.665581 +L 609.049333 136.665581 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + <path d="M 603.348709 157.113613 +L 603.348709 157.113613 +" clip-path="url(#p6d538e60d8)" style="fill: none; stroke: #222222; stroke-width: 0.8"/> + </g> + <g id="line2d_83"> + <g clip-path="url(#p6d538e60d8)"> + <use xlink:href="#mc120802246" x="603.348709" y="34.425418" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="54.87345" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="75.321483" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="95.769516" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="116.217548" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.728751" y="136.665581" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="157.113613" style="fill: #1f77b4; stroke: #222222"/> + </g> + </g> + <g id="line2d_84"> + <g clip-path="url(#p6d538e60d8)"> + <use xlink:href="#mc120802246" x="603.348709" y="34.425418" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="54.87345" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="75.321483" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="95.769516" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="116.217548" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="609.049333" y="136.665581" style="fill: #1f77b4; stroke: #222222"/> + <use xlink:href="#mc120802246" x="603.348709" y="157.113613" style="fill: #1f77b4; stroke: #222222"/> + </g> + </g> + <g id="patch_22"> + <path d="M 599.457083 171.120516 +L 599.457083 20.418516 +" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/> + </g> + <g id="patch_23"> + <path d="M 599.457083 171.120516 +L 759.01375 171.120516 +" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/> + </g> + <g id="text_39"> + <text style="font-size: 9.5px; font-family: 'DejaVu Sans'; text-anchor: middle" x="679.235417" y="14.418516" transform="rotate(-0 679.235417 14.418516)">(c) Nonideal local sampling</text> + </g> + </g> + <g id="text_40"> + <text style="font-size: 7px; font-family: 'DejaVu Sans'; text-anchor: end; fill: #666666" x="764.34175" y="222.248734" transform="rotate(-0 764.34175 222.248734)">40 tasks × 4 device draws; error bars are task-bootstrap 95% intervals</text> + </g> + </g> + <defs> + <clipPath id="pf3ff1facc5"> + <rect x="87.00375" y="20.418516" width="159.556667" height="150.702"/> + </clipPath> + <clipPath id="p800f26f182"> + <rect x="343.230417" y="20.418516" width="159.556667" height="150.702"/> + </clipPath> + <clipPath id="p6d538e60d8"> + <rect x="599.457083" y="20.418516" width="159.556667" height="150.702"/> + </clipPath> + </defs> +</svg> diff --git a/results/physical_bias/p10_hardware_evidence_analysis.json b/results/physical_bias/p10_hardware_evidence_analysis.json new file mode 100644 index 0000000..9811f5c --- /dev/null +++ b/results/physical_bias/p10_hardware_evidence_analysis.json @@ -0,0 +1,308 @@ +{ + "analysis": "physical_clln_hardware_evidence_figure", + "confirmatory": false, + "bootstrap": { + "unit": "task; four device draws averaged within task", + "task_clusters": 40, + "replicates": 20000, + "seed": 20260829, + "interval": "percentile 95%" + }, + "physical_methods": { + "clean": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160 + }, + "raw": { + "mean": 0.25859375, + "task_bootstrap_95ci": [ + 0.22265625, + 0.29609375 + ], + "task_clusters": 40, + "trials": 160 + }, + "constant": { + "mean": 0.0375, + "task_bootstrap_95ci": [ + 0.01875, + 0.05859375 + ], + "task_clusters": 40, + "trials": 160 + }, + "overclamp": { + "mean": 0.04765625, + "task_bootstrap_95ci": [ + 0.01875, + 0.0828125 + ], + "task_clusters": 40, + "trials": 160 + }, + "sdil": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160 + }, + "overclamp_sdil": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160 + } + }, + "sampler_conditions": { + "combined_mild_refresh4": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.46660538253621064 + }, + "combined_strong": { + "mean": 0.00546875, + "task_bootstrap_95ci": [ + 0.00078125, + 0.01171875 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 0.96875, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.36811707519239995 + }, + "common_pedestal_10": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 7.092845963015098e-16 + }, + "gain_mismatch_0.001": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.0021327524546310593 + }, + "gain_mismatch_0.005": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.010662411888727154 + }, + "gain_mismatch_0.01": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.021335094097404632 + }, + "gain_mismatch_0.025": { + "mean": 0.0015625, + "task_bootstrap_95ci": [ + 0.0, + 0.00390625 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 0.9875, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.05337234986008901 + }, + "gain_mismatch_0.05": { + "mean": 0.00625, + "task_bootstrap_95ci": [ + 0.00078125, + 0.01328125 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 0.9625, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.10745724630761008 + }, + "ideal_cds": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.0 + }, + "overclamp_plus_combined_mild": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.14562285807356745 + }, + "pedestal_mismatch_0.01": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.010003519663837685 + }, + "pedestal_mismatch_0.025": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.02500879915959358 + }, + "pedestal_mismatch_0.05": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.05001759831918712 + }, + "pedestal_mismatch_0.1": { + "mean": 0.00625, + "task_bootstrap_95ci": [ + 0.0015625, + 0.0125 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 0.95625, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.10003519663837424 + }, + "pedestal_mismatch_0.25": { + "mean": 0.04453125, + "task_bootstrap_95ci": [ + 0.0203125, + 0.07421875 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 0.825, + "solver_failure_fraction": 0.00625, + "median_applied_rate_rmse_v_per_s": 0.25008799159594736 + }, + "pedestal_mismatch_0.5": { + "mean": 0.096875, + "task_bootstrap_95ci": [ + 0.059375, + 0.13828125 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 0.70625, + "solver_failure_fraction": 0.0125, + "median_applied_rate_rmse_v_per_s": 0.5001759831918947 + }, + "refresh_every_4": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 0.4399296286060528 + }, + "sample_noise_1": { + "mean": 0.0, + "task_bootstrap_95ci": [ + 0.0, + 0.0 + ], + "task_clusters": 40, + "trials": 160, + "zero_error_fraction": 1.0, + "solver_failure_fraction": 0.0, + "median_applied_rate_rmse_v_per_s": 1.4156351463196133 + } + }, + "spice_primitive": { + "publication_evidence": false, + "scope": "Generic switch-capacitor acquisition and droop sanity check; this is not the complete CLLN edge circuit.", + "configuration_count": 48, + "fraction_below_1_percent_error_at_start": 0.4166666666666667, + "fraction_below_1_percent_error_at_end": 0.4166666666666667, + "reference_configuration": { + "acquisition_seconds": 1e-06, + "switch_resistance_ohm": 200.0, + "hold_capacitance_f": 1e-09, + "leakage_resistance_ohm": 1000000000.0, + "held_at_switch_open_v": 0.004966396, + "residual_at_learning_start_v": 0.001033604, + "residual_at_learning_end_v": 0.001034101, + "start_relative_error": 0.03360400000000001, + "end_relative_error": 0.03410099999999992 + } + }, + "sources": [ + "results/physical_bias/p5_full_grid_bias_crossover.json", + "results/physical_bias/p9_grid_correlated_autozero.json", + "results/physical_bias/p8_spice_autozero_primitive.json" + ] +} diff --git a/results/physical_bias/p10_hardware_evidence_source.csv b/results/physical_bias/p10_hardware_evidence_source.csv new file mode 100644 index 0000000..a2aec46 --- /dev/null +++ b/results/physical_bias/p10_hardware_evidence_source.csv @@ -0,0 +1,25 @@ +panel,series,condition,x,x_unit,mean_error,ci_low,ci_high,zero_error_fraction
+a,physical_method,Clean,,,0.0,0.0,0.0,
+a,physical_method,Raw,,,0.25859375,0.22265625,0.29609375,
+a,physical_method,Static calibration,,,0.0375,0.01875,0.05859375,
+a,physical_method,Overclamp,,,0.04765625,0.01875,0.0828125,
+a,physical_method,SDIL,,,0.0,0.0,0.0,
+a,physical_method,Overclamp + SDIL,,,0.0,0.0,0.0,
+b,pedestal mismatch,pedestal_mismatch_0.01,0.010003519663837685,V/s,0.0,0.0,0.0,1.0
+b,pedestal mismatch,pedestal_mismatch_0.025,0.02500879915959358,V/s,0.0,0.0,0.0,1.0
+b,pedestal mismatch,pedestal_mismatch_0.05,0.05001759831918712,V/s,0.0,0.0,0.0,1.0
+b,pedestal mismatch,pedestal_mismatch_0.1,0.10003519663837424,V/s,0.00625,0.0015625,0.0125,0.95625
+b,pedestal mismatch,pedestal_mismatch_0.25,0.25008799159594736,V/s,0.04453125,0.0203125,0.07421875,0.825
+b,pedestal mismatch,pedestal_mismatch_0.5,0.5001759831918947,V/s,0.096875,0.059375,0.13828125,0.70625
+b,gain mismatch,gain_mismatch_0.001,0.0021327524546310593,V/s,0.0,0.0,0.0,1.0
+b,gain mismatch,gain_mismatch_0.005,0.010662411888727154,V/s,0.0,0.0,0.0,1.0
+b,gain mismatch,gain_mismatch_0.01,0.021335094097404632,V/s,0.0,0.0,0.0,1.0
+b,gain mismatch,gain_mismatch_0.025,0.05337234986008901,V/s,0.0015625,0.0,0.00390625,0.9875
+b,gain mismatch,gain_mismatch_0.05,0.10745724630761008,V/s,0.00625,0.00078125,0.01328125,0.9625
+c,sampling condition,Ideal CDS,,,0.0,0.0,0.0,1.0
+c,sampling condition,Common pedestal,,,0.0,0.0,0.0,1.0
+c,sampling condition,Sample noise,,,0.0,0.0,0.0,1.0
+c,sampling condition,Refresh every 4,,,0.0,0.0,0.0,1.0
+c,sampling condition,Mild combined,,,0.0,0.0,0.0,1.0
+c,sampling condition,Strong combined,,,0.00546875,0.00078125,0.01171875,0.96875
+c,sampling condition,Overclamp + mild,,,0.0,0.0,0.0,1.0
diff --git a/visual-composer/physical-hardware-evidence.md b/visual-composer/physical-hardware-evidence.md new file mode 100644 index 0000000..b271127 --- /dev/null +++ b/visual-composer/physical-hardware-evidence.md @@ -0,0 +1,40 @@ +# Visual contract: hardware-realistic CLLN evidence + +- **Artifact:** three-panel quantitative result figure. +- **Target venue / format:** ICLR two-column paper, full-width figure. +- **Core claim:** local innovation subtraction restores nonlinear CLLN + learning under published component imperfections and remains effective with + nonideal local sampling. +- **Reviewer question:** does the method survive component mismatch, sampler + mismatch, noise, stale refresh, and their combination at the task endpoint? +- **Evidence layer:** hardware-realistic simulation; no fabricated-chip claim. +- **Source data:** + `results/physical_bias/p5_full_grid_bias_crossover.json`, + `results/physical_bias/p9_grid_correlated_autozero.json`, and + `results/physical_bias/p8_spice_autozero_primitive.json`. +- **Statistics / uncertainty:** four device draws are averaged within each of + 40 tasks; tasks are resampled for percentile 95% bootstrap intervals. +- **Figure prototype:** horizontal method comparison, mismatch response curves, + and horizontal nonideality comparison. +- **Panel map:** + - (a) nonlinear CLLN final error across clean, raw, calibration, + overclamping, SDIL, and their combination; + - (b) final error against measured local sampling-error RMSE for pedestal + and gain mismatch sweeps; + - (c) final error under common pedestal, sampling noise, stale neutral + refresh, and combined nonidealities. +- **Exact label inventory:** nonlinear CLLN, component errors, sample-path + mismatch, residual sampling error, nonideal local sampling, final + classification error. +- **Caption role:** identify the published component-error scale, the local + correlated-double-sampling operation, task/device counts, and the boundary + between simulation and fabricated hardware. +- **Manuscript placement:** Part 3, after the digital scaling result. +- **Output formats:** editable SVG, vector PDF, PNG preview, analysis JSON, and + source CSV. +- **Traceability:** every plotted aggregate is regenerated by + `experiments/plot_physical_hardware_evidence.py`; the SPICE primitive is + carried in the analysis manifest and reserved for supplementary evidence. +- **Constraint:** circuit-solver failures remain classification failures. + Sampler RMSE excludes the missing diagnostic value on failed solves, while + the task endpoint includes every trial. diff --git a/visual-composer/qa-ledger.md b/visual-composer/qa-ledger.md index 319c1f2..c9e66e5 100644 --- a/visual-composer/qa-ledger.md +++ b/visual-composer/qa-ledger.md @@ -13,3 +13,16 @@ detached source note at 2,556-by-778 PNG resolution. The next QA pass replaces the pilot source with the frozen multi-task, multi-device confirmation without changing the plot grammar. +## Hardware-realistic CLLN figure + +| Issue | Artifact | Severity | Fix | Status | +|:--|:--|:--|:--|:--| +| Method and condition labels collided | Panels (a) and (c) | High | Replaced vertical bars with horizontal bars and single-line labels | Resolved | +| Different mismatch units were not directly comparable | Panel (b) | High | Used measured residual local-rate RMSE as the common x-axis and retained mismatch family as series | Resolved | +| Zero-error conditions were visually ambiguous | Panels (a) and (c) | Low | Kept a small x-axis margin below zero so zero-valued error bars remain visible | Resolved | +| Generic SPICE primitive could be read as a full-circuit simulation | Figure scope | High | Excluded it from the main plotted panels and recorded its limited scope in the analysis and visual contract | Resolved | +| Color-only distinctions could fail in print | Panel (b) | Medium | Added distinct circle and diamond markers | Resolved | + +Rendered inspection: no clipped labels, tick-label collision, legend overlap, +or panel overlap at 2,560-by-765 PNG resolution. SVG text remains editable and +the PDF uses embedded TrueType fonts. |
