summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYurenHao0426 <Blackhao0426@gmail.com>2026-08-06 16:17:50 -0500
committerYurenHao0426 <Blackhao0426@gmail.com>2026-08-06 16:17:50 -0500
commit907b5e25af32dc938bb04f4cb06a99cd55a20f46 (patch)
treea251a3cacf7b5acf9444fbd40ff78b9e9c70a5be
parenta6d9cc53f77906305dcefa454d77151c1996405f (diff)
results: identify state-dependent physical drift
-rw-r--r--TWO_STATE_BIAS_PROGRAM.md7
-rw-r--r--experiments/analyze_physical_drift_state_dependence.py493
-rw-r--r--results/figs/physical_bias_state_dependence.pngbin0 -> 231580 bytes
-rw-r--r--results/figs/physical_bias_state_dependence_caption.md15
-rw-r--r--results/physical_bias/p0_state_dependence.json901
5 files changed, 1416 insertions, 0 deletions
diff --git a/TWO_STATE_BIAS_PROGRAM.md b/TWO_STATE_BIAS_PROGRAM.md
index b0df1b2..1020b11 100644
--- a/TWO_STATE_BIAS_PROGRAM.md
+++ b/TWO_STATE_BIAS_PROGRAM.md
@@ -290,6 +290,13 @@ Stop this paper direction if:
`1.8374/1.7360/1.9468`; see `results/physical_bias/p0_summary.json`. This
reproduces a nonzero rapid-switching error floor and an approximately
constant low-period drift speed from real hardware. It is not an SDIL result.
+- Physical state-dependence diagnostic: complete. On held-out later portions of
+ the four released `DriftTests` traces, a per-edge affine field reduces
+ tangential-velocity RMSE to `0.21/0.54` of a constant-bias model for the two
+ task pairs. The direction is unchanged when excluding the final
+ `30/50/80/100 mV` before the observed gate plateaus; see
+ `results/physical_bias/p0_state_dependence.json`. This establishes a measured
+ locally predictable component suitable for P1, not an SDIL learning result.
- Dual Prop same-path confirmation: active/supporting, not a passed result.
- EP/CpL adapters: not implemented under this bias model.
- Current score for this new paper framing: 5/10 until P1 passes.
diff --git a/experiments/analyze_physical_drift_state_dependence.py b/experiments/analyze_physical_drift_state_dependence.py
new file mode 100644
index 0000000..42ca420
--- /dev/null
+++ b/experiments/analyze_physical_drift_state_dependence.py
@@ -0,0 +1,493 @@
+#!/usr/bin/env python3
+"""Test whether released physical drift is state dependent.
+
+Dillavou et al. approximate the two-edge physical network with a constant
+bias vector. Their appendix also notes that the experimental drift rate is
+not constant. This script tests that statement directly from the four
+released DriftTests traces.
+
+Once a trace is close to a one-task solution line, the clean learning force is
+normal to that line. Its measured tangential velocity therefore estimates
+the tangential projection of the physical bias. We compare:
+
+ constant: B(G) = b
+ local affine: B_i(G_i) = b_i + k_i (G_i - G_ref_i)
+
+The second model uses exactly the per-edge local information available to an
+affine SDIL predictor. It is a measured-data identifiability diagnostic, not
+yet evidence that SDIL improves task learning.
+"""
+
+from __future__ import annotations
+
+import argparse
+from dataclasses import dataclass
+import hashlib
+import json
+from pathlib import Path
+from typing import Dict, List, Sequence
+
+import matplotlib
+
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import numpy as np
+from scipy.io import loadmat
+
+
+ZENODO_RECORD = "15692914"
+ZENODO_DOI = "10.5281/zenodo.15692914"
+RELEASE = "v1.0.1"
+SOURCE_TREE = "maguzj-imperfect-learning-physical-systems-71b8d72"
+
+
+@dataclass(frozen=True)
+class TraceSpec:
+ filename: str
+ task: str
+ solution_slope: float
+ solution_intercept: float
+
+
+@dataclass(frozen=True)
+class PairSpec:
+ name: str
+ reference_gate: tuple[float, float]
+ published_bias_at_reference: tuple[float, float]
+ traces: tuple[TraceSpec, TraceSpec]
+
+
+PAIR_SPECS = (
+ PairSpec(
+ name="experiment_1",
+ reference_gate=(3.0, 3.5),
+ published_bias_at_reference=(2.9, 4.7),
+ traces=(
+ TraceSpec("exp1DriftTest_1.mat", "beta", 0.43914, 1.6061),
+ TraceSpec("exp1DriftTest_2.mat", "alpha", 2.7257, -3.3003),
+ ),
+ ),
+ PairSpec(
+ name="experiment_2",
+ reference_gate=(3.1, 4.3),
+ published_bias_at_reference=(-0.3, 2.0),
+ traces=(
+ TraceSpec("exp2DriftTest_1.mat", "beta", 0.74821, 1.9224),
+ TraceSpec("exp2DriftTest_2.mat", "alpha", 2.5678, -2.901),
+ ),
+ ),
+)
+
+
+def sha256(path: Path) -> str:
+ digest = hashlib.sha256()
+ with path.open("rb") as handle:
+ for block in iter(lambda: handle.read(1024 * 1024), b""):
+ digest.update(block)
+ return digest.hexdigest()
+
+
+def rmse(observed: np.ndarray, predicted: np.ndarray) -> float:
+ return float(np.sqrt(np.mean((observed - predicted) ** 2)))
+
+
+def r_squared(observed: np.ndarray, predicted: np.ndarray) -> float:
+ denominator = float(np.sum((observed - np.mean(observed)) ** 2))
+ if denominator == 0.0:
+ return float("nan")
+ return float(1.0 - np.sum((observed - predicted) ** 2) / denominator)
+
+
+def load_trace(
+ drift_dir: Path,
+ spec: TraceSpec,
+ reference_gate: Sequence[float],
+ *,
+ minimum_time: float,
+ terminal_headroom: float,
+ maximum_line_distance: float,
+ trim_selected_ends: int,
+) -> dict:
+ path = drift_dir / spec.filename
+ raw = loadmat(path, squeeze_me=True)
+ time = np.asarray(raw["time"], dtype=float)
+ gate_minus = np.asarray(raw["GMINUS"], dtype=float)
+ gate_plus = np.asarray(raw["GPLUS"], dtype=float)
+ if time.ndim != 1 or len(time) != 300:
+ raise ValueError(f"unexpected time array in {path}: {time.shape}")
+ if not (time.shape == gate_minus.shape == gate_plus.shape):
+ raise ValueError(f"array shape disagreement in {path}")
+ if not np.all(np.isfinite(np.column_stack((time, gate_minus, gate_plus)))):
+ raise ValueError(f"nonfinite source value in {path}")
+
+ # The first two entries straddle the experiment initialization and a
+ # roughly 0.9 s gap. The remaining samples have a stable ~30 ms cadence.
+ time = time[2:]
+ gate_minus = gate_minus[2:]
+ gate_plus = gate_plus[2:]
+ sample_period = float(np.median(np.diff(time)))
+ velocity_minus = np.gradient(gate_minus, time)
+ velocity_plus = np.gradient(gate_plus, time)
+
+ slope = spec.solution_slope
+ intercept = spec.solution_intercept
+ tangent = np.asarray((1.0, slope), dtype=float)
+ tangent /= np.linalg.norm(tangent)
+ signed_distance = (
+ gate_plus - slope * gate_minus - intercept
+ ) / np.sqrt(1.0 + slope * slope)
+ # Every released trace terminates on a clear gate-voltage plateau. Exclude
+ # the final headroom before either observed plateau so a hardware rail is
+ # not mislabeled as a state-dependent bias. Trimming the selected ends
+ # then ensures that centered differences use only pre-plateau samples.
+ selected = (
+ (time >= minimum_time)
+ & (gate_minus < np.max(gate_minus) - terminal_headroom)
+ & (gate_plus < np.max(gate_plus) - terminal_headroom)
+ & (np.abs(signed_distance) < maximum_line_distance)
+ )
+ indices = np.flatnonzero(selected)
+ if len(indices) <= 2 * trim_selected_ends:
+ raise ValueError(f"too few usable solution-line samples in {path}")
+ if np.any(np.diff(indices) != 1):
+ raise ValueError(f"selected solution-line window is not contiguous in {path}")
+ indices = indices[trim_selected_ends:-trim_selected_ends]
+
+ gates = np.column_stack((gate_minus[indices], gate_plus[indices]))
+ velocities = np.column_stack(
+ (velocity_minus[indices], velocity_plus[indices]))
+ reference = np.asarray(reference_gate, dtype=float)
+ design = np.column_stack((
+ np.full(len(indices), tangent[0]),
+ np.full(len(indices), tangent[1]),
+ tangent[0] * (gates[:, 0] - reference[0]),
+ tangent[1] * (gates[:, 1] - reference[1]),
+ ))
+ projected_velocity = velocities @ tangent
+ path_coordinate = gates @ tangent
+ if len(indices) < 6:
+ raise ValueError(f"need at least six retained samples in {path}")
+
+ return {
+ "spec": spec,
+ "source_file": {"path": str(path), "sha256": sha256(path)},
+ "sample_period_seconds": sample_period,
+ "raw_gate_minus": gate_minus,
+ "raw_gate_plus": gate_plus,
+ "time": time,
+ "selected_indices": indices,
+ "selected_time": time[indices],
+ "selected_gates": gates,
+ "selected_line_distance": signed_distance[indices],
+ "tangent": tangent,
+ "path_coordinate": path_coordinate,
+ "projected_velocity": projected_velocity,
+ "design": design,
+ }
+
+
+def fit_columns(design: np.ndarray, target: np.ndarray, columns: List[int]) -> dict:
+ selected = design[:, columns]
+ parameters, _, _, _ = np.linalg.lstsq(selected, target, rcond=None)
+ predicted = selected @ parameters
+ return {
+ "columns": columns,
+ "parameters": parameters,
+ "predicted": predicted,
+ "rank": int(np.linalg.matrix_rank(selected)),
+ "condition_number": float(np.linalg.cond(selected)),
+ "rmse": rmse(target, predicted),
+ "r_squared": r_squared(target, predicted),
+ }
+
+
+def forward_block_test(traces: Sequence[dict], columns: List[int]) -> dict:
+ train_design = []
+ train_target = []
+ test_design = []
+ test_target = []
+ split_records = []
+ for trace in traces:
+ count = len(trace["projected_velocity"])
+ train_count = max(2, int(np.floor(0.6 * count)))
+ if count - train_count < 2:
+ raise ValueError("forward block test needs at least two held-out samples")
+ train_design.append(trace["design"][:train_count, columns])
+ train_target.append(trace["projected_velocity"][:train_count])
+ test_design.append(trace["design"][train_count:, columns])
+ test_target.append(trace["projected_velocity"][train_count:])
+ split_records.append({
+ "source": trace["spec"].filename,
+ "train_samples": train_count,
+ "test_samples": count - train_count,
+ })
+ train_design_array = np.vstack(train_design)
+ train_target_array = np.concatenate(train_target)
+ test_design_array = np.vstack(test_design)
+ test_target_array = np.concatenate(test_target)
+ parameters, _, _, _ = np.linalg.lstsq(
+ train_design_array, train_target_array, rcond=None)
+ train_prediction = train_design_array @ parameters
+ test_prediction = test_design_array @ parameters
+ return {
+ "split": "first 60% of each retained trace trains; final 40% tests",
+ "trace_splits": split_records,
+ "parameters": parameters.tolist(),
+ "train_rank": int(np.linalg.matrix_rank(train_design_array)),
+ "train_condition_number": float(np.linalg.cond(train_design_array)),
+ "train_rmse": rmse(train_target_array, train_prediction),
+ "test_rmse": rmse(test_target_array, test_prediction),
+ "test_r_squared": r_squared(test_target_array, test_prediction),
+ }
+
+
+def serializable_trace(trace: dict) -> dict:
+ spec = trace["spec"]
+ return {
+ "source_file": trace["source_file"],
+ "task": spec.task,
+ "solution_line": {
+ "gate_plus_slope": spec.solution_slope,
+ "gate_plus_intercept": spec.solution_intercept,
+ },
+ "sample_period_seconds": trace["sample_period_seconds"],
+ "retained_samples": int(len(trace["projected_velocity"])),
+ "retained_time_seconds": trace["selected_time"].tolist(),
+ "retained_gate_minus": trace["selected_gates"][:, 0].tolist(),
+ "retained_gate_plus": trace["selected_gates"][:, 1].tolist(),
+ "retained_line_distance": trace["selected_line_distance"].tolist(),
+ "path_coordinate": trace["path_coordinate"].tolist(),
+ "projected_drift_velocity_v_per_s": trace["projected_velocity"].tolist(),
+ }
+
+
+def analyze_pair(drift_dir: Path, spec: PairSpec, settings: dict) -> dict:
+ traces = [
+ load_trace(
+ drift_dir,
+ trace_spec,
+ spec.reference_gate,
+ **settings,
+ )
+ for trace_spec in spec.traces
+ ]
+ design = np.vstack([trace["design"] for trace in traces])
+ target = np.concatenate([trace["projected_velocity"] for trace in traces])
+ constant = fit_columns(design, target, [0, 1])
+ local_affine = fit_columns(design, target, [0, 1, 2, 3])
+ constant_forward = forward_block_test(traces, [0, 1])
+ affine_forward = forward_block_test(traces, [0, 1, 2, 3])
+ affine_parameters = local_affine["parameters"]
+ published = np.asarray(spec.published_bias_at_reference)
+ intercept = affine_parameters[:2]
+ return {
+ "reference_gate": list(spec.reference_gate),
+ "published_constant_bias_at_reference_v_per_s": published.tolist(),
+ "traces": [serializable_trace(trace) for trace in traces],
+ "constant_model": {
+ "definition": "B(G) = b",
+ "bias_v_per_s": constant["parameters"].tolist(),
+ "rank": constant["rank"],
+ "condition_number": constant["condition_number"],
+ "in_sample_rmse_v_per_s": constant["rmse"],
+ "in_sample_r_squared": constant["r_squared"],
+ "forward_block": constant_forward,
+ },
+ "local_affine_model": {
+ "definition": "B_i(G_i) = b_i + k_i (G_i - G_ref_i)",
+ "bias_at_reference_v_per_s": intercept.tolist(),
+ "local_slopes_per_s": affine_parameters[2:].tolist(),
+ "rank": local_affine["rank"],
+ "condition_number": local_affine["condition_number"],
+ "in_sample_rmse_v_per_s": local_affine["rmse"],
+ "in_sample_r_squared": local_affine["r_squared"],
+ "forward_block": affine_forward,
+ "reference_bias_error_v_per_s": (intercept - published).tolist(),
+ },
+ "diagnostic": {
+ "in_sample_rmse_ratio_affine_over_constant": (
+ local_affine["rmse"] / constant["rmse"]),
+ "forward_test_rmse_ratio_affine_over_constant": (
+ affine_forward["test_rmse"] / constant_forward["test_rmse"]),
+ "affine_improves_forward_test": bool(
+ affine_forward["test_rmse"] < constant_forward["test_rmse"]),
+ },
+ "_plot": {
+ "traces": traces,
+ "constant_parameters": constant["parameters"],
+ "affine_parameters": affine_parameters,
+ },
+ }
+
+
+def headroom_sensitivity(drift_dir: Path, base_settings: dict) -> List[dict]:
+ records = []
+ for headroom in (0.03, 0.05, 0.08, 0.10):
+ settings = dict(base_settings)
+ settings["terminal_headroom"] = headroom
+ pair_ratios = {}
+ for spec in PAIR_SPECS:
+ pair = analyze_pair(drift_dir, spec, settings)
+ pair_ratios[spec.name] = pair["diagnostic"][
+ "forward_test_rmse_ratio_affine_over_constant"]
+ records.append({
+ "terminal_headroom_v": headroom,
+ "forward_test_rmse_ratios_affine_over_constant": pair_ratios,
+ "affine_improves_both": bool(all(
+ ratio < 1.0 for ratio in pair_ratios.values())),
+ })
+ return records
+
+
+def plot_report(report: dict, output: Path) -> None:
+ colors = {"alpha": "#4477AA", "beta": "#EE6677"}
+ fig, axes = plt.subplots(2, 2, figsize=(9.2, 7.0))
+ for column, pair_name in enumerate(("experiment_1", "experiment_2")):
+ pair = report["pairs"][pair_name]
+ plot_data = pair["_plot"]
+ path_axis = axes[0, column]
+ velocity_axis = axes[1, column]
+ for trace in plot_data["traces"]:
+ spec = trace["spec"]
+ color = colors[spec.task]
+ path_axis.plot(
+ trace["raw_gate_minus"], trace["raw_gate_plus"],
+ color=color, alpha=0.24, linewidth=1.0)
+ gates = trace["selected_gates"]
+ path_axis.plot(
+ gates[:, 0], gates[:, 1], "o-", color=color,
+ markersize=3.0, linewidth=1.2, label=f"task {spec.task}")
+ x_line = np.linspace(gates[:, 0].min(), gates[:, 0].max(), 100)
+ path_axis.plot(
+ x_line, spec.solution_slope * x_line + spec.solution_intercept,
+ "--", color=color, linewidth=1.0)
+
+ order = np.argsort(trace["path_coordinate"])
+ coordinate = trace["path_coordinate"][order]
+ observed = trace["projected_velocity"][order]
+ design = trace["design"][order]
+ constant_prediction = design[:, :2] @ plot_data["constant_parameters"]
+ affine_prediction = design @ plot_data["affine_parameters"]
+ velocity_axis.plot(
+ coordinate, observed, "o", color=color, markersize=3.5,
+ label=f"task {spec.task} measured")
+ velocity_axis.plot(
+ coordinate, constant_prediction, ":", color=color,
+ linewidth=1.3)
+ velocity_axis.plot(
+ coordinate, affine_prediction, "-", color=color,
+ linewidth=1.5)
+
+ path_axis.set_title(
+ f"{chr(ord('A') + column)} Published drift: {pair_name.replace('_', ' ')}")
+ path_axis.set_xlabel("gate voltage minus (V)")
+ path_axis.set_ylabel("gate voltage plus (V)")
+ path_axis.legend(frameon=False, fontsize=8)
+ path_axis.grid(alpha=0.18)
+
+ ratio = pair["diagnostic"]["forward_test_rmse_ratio_affine_over_constant"]
+ velocity_axis.set_title(
+ f"{chr(ord('C') + column)} Held-out RMSE ratio affine/constant = {ratio:.2f}")
+ velocity_axis.set_xlabel("position along solution line (V)")
+ velocity_axis.set_ylabel("tangential drift (V/s)")
+ velocity_axis.legend(frameon=False, fontsize=7)
+ velocity_axis.grid(alpha=0.18)
+
+ fig.suptitle(
+ "Released physical drift varies with local gate state\n"
+ "dots: measured projection; dotted: constant bias; solid: per-edge affine bias",
+ fontsize=11)
+ fig.tight_layout()
+ output.parent.mkdir(parents=True, exist_ok=True)
+ fig.savefig(output, dpi=180)
+ plt.close(fig)
+
+
+def strip_plot_data(report: dict) -> dict:
+ clean = dict(report)
+ clean["pairs"] = {}
+ for name, pair in report["pairs"].items():
+ clean["pairs"][name] = {key: value for key, value in pair.items() if key != "_plot"}
+ return clean
+
+
+def parse_args() -> argparse.Namespace:
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--artifact-root", type=Path, required=True,
+ help="Root of the extracted Zenodo source tree")
+ parser.add_argument(
+ "--json", type=Path,
+ default=Path("results/physical_bias/p0_state_dependence.json"))
+ parser.add_argument(
+ "--figure", type=Path,
+ default=Path("results/figs/physical_bias_state_dependence.png"))
+ return parser.parse_args()
+
+
+def main() -> None:
+ args = parse_args()
+ root = args.artifact_root.resolve()
+ if root.name != SOURCE_TREE:
+ raise ValueError(f"expected source root {SOURCE_TREE}, received {root.name}")
+ drift_dir = root / "small network" / "DriftTests"
+ settings = {
+ "minimum_time": 1.05,
+ "terminal_headroom": 0.05,
+ "maximum_line_distance": 0.03,
+ "trim_selected_ends": 1,
+ }
+ report = {
+ "analysis": "published_physical_drift_state_dependence_diagnostic",
+ "confirmatory": False,
+ "supports_task_learning_improvement": False,
+ "provenance": {
+ "zenodo_record": ZENODO_RECORD,
+ "doi": ZENODO_DOI,
+ "release": RELEASE,
+ "source_tree": SOURCE_TREE,
+ },
+ "identification": {
+ "observable": "tangential gate velocity after reaching a one-task solution line",
+ "assumption": (
+ "the clean force has zero tangential projection on the published solution line"
+ ),
+ "model_restriction": "each edge bias is affine in its own local gate voltage",
+ "limitation": (
+ "the traces identify a local affine surrogate over their visited states, not the "
+ "complete physical vector field"
+ ),
+ },
+ "preprocessing": settings,
+ "pairs": {},
+ }
+ for spec in PAIR_SPECS:
+ report["pairs"][spec.name] = analyze_pair(drift_dir, spec, settings)
+ report["headroom_sensitivity"] = headroom_sensitivity(drift_dir, settings)
+ report["summary"] = {
+ "forward_test_rmse_ratios_affine_over_constant": [
+ report["pairs"][spec.name]["diagnostic"][
+ "forward_test_rmse_ratio_affine_over_constant"]
+ for spec in PAIR_SPECS
+ ],
+ "affine_improves_both_forward_tests": bool(all(
+ report["pairs"][spec.name]["diagnostic"][
+ "affine_improves_forward_test"]
+ for spec in PAIR_SPECS
+ )),
+ "affine_improves_both_for_all_headroom_thresholds": bool(all(
+ record["affine_improves_both"]
+ for record in report["headroom_sensitivity"]
+ )),
+ }
+ plot_report(report, args.figure)
+ serializable = strip_plot_data(report)
+ args.json.parent.mkdir(parents=True, exist_ok=True)
+ args.json.write_text(json.dumps(serializable, indent=2) + "\n")
+ print(json.dumps(serializable["summary"], indent=2))
+ print(f"wrote {args.json}")
+ print(f"wrote {args.figure}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/figs/physical_bias_state_dependence.png b/results/figs/physical_bias_state_dependence.png
new file mode 100644
index 0000000..6e15af6
--- /dev/null
+++ b/results/figs/physical_bias_state_dependence.png
Binary files differ
diff --git a/results/figs/physical_bias_state_dependence_caption.md b/results/figs/physical_bias_state_dependence_caption.md
new file mode 100644
index 0000000..51d63dc
--- /dev/null
+++ b/results/figs/physical_bias_state_dependence_caption.md
@@ -0,0 +1,15 @@
+**Released physical drift contains a locally predictable state-dependent
+component.** A--B, gate-voltage trajectories from the four small-network
+`DriftTests` files released with Dillavou et al. (Zenodo 15692914). Colored
+points are the retained pre-saturation samples within 30 mV of the published
+single-task solution lines; faint curves show the complete post-initialization
+traces. C--D, tangential drift velocity along each solution line. A constant
+bias model (dotted) is compared with a per-edge local affine model
+`B_i(G_i)=b_i+k_i(G_i-G_ref_i)` (solid). With the pre-saturation threshold
+fixed at 50 mV before each trace's observed terminal gate plateau, the affine
+model reduces forward time-block test RMSE to 0.21 and 0.54 of the constant
+model in the two task pairs. The direction holds for terminal headrooms of 30,
+50, 80 and 100 mV using unsmoothed centered-difference velocities. This
+descriptive reanalysis establishes a measured state-dependent component
+representable by the proposed local predictor. It does not demonstrate that
+SDIL improves physical task learning; that is the prospective P1 test.
diff --git a/results/physical_bias/p0_state_dependence.json b/results/physical_bias/p0_state_dependence.json
new file mode 100644
index 0000000..ef641c2
--- /dev/null
+++ b/results/physical_bias/p0_state_dependence.json
@@ -0,0 +1,901 @@
+{
+ "analysis": "published_physical_drift_state_dependence_diagnostic",
+ "confirmatory": false,
+ "supports_task_learning_improvement": false,
+ "provenance": {
+ "zenodo_record": "15692914",
+ "doi": "10.5281/zenodo.15692914",
+ "release": "v1.0.1",
+ "source_tree": "maguzj-imperfect-learning-physical-systems-71b8d72"
+ },
+ "identification": {
+ "observable": "tangential gate velocity after reaching a one-task solution line",
+ "assumption": "the clean force has zero tangential projection on the published solution line",
+ "model_restriction": "each edge bias is affine in its own local gate voltage",
+ "limitation": "the traces identify a local affine surrogate over their visited states, not the complete physical vector field"
+ },
+ "preprocessing": {
+ "minimum_time": 1.05,
+ "terminal_headroom": 0.05,
+ "maximum_line_distance": 0.03,
+ "trim_selected_ends": 1
+ },
+ "pairs": {
+ "experiment_1": {
+ "reference_gate": [
+ 3.0,
+ 3.5
+ ],
+ "published_constant_bias_at_reference_v_per_s": [
+ 2.9,
+ 4.7
+ ],
+ "traces": [
+ {
+ "source_file": {
+ "path": "/scratch/yurenh2/imperfect-learning-physical-systems-v1.0.1/maguzj-imperfect-learning-physical-systems-71b8d72/small network/DriftTests/exp1DriftTest_1.mat",
+ "sha256": "06dc0a494d255304e40b372bcf85a30df928248b46b8c9884008e52beabcb79f"
+ },
+ "task": "beta",
+ "solution_line": {
+ "gate_plus_slope": 0.43914,
+ "gate_plus_intercept": 1.6061
+ },
+ "sample_period_seconds": 0.030553000000000274,
+ "retained_samples": 13,
+ "retained_time_seconds": [
+ 1.095956,
+ 1.126507,
+ 1.157059,
+ 1.187613,
+ 1.218165,
+ 1.248715,
+ 1.279265,
+ 1.309815,
+ 1.340367,
+ 1.370923,
+ 1.401476,
+ 1.432031,
+ 1.462575
+ ],
+ "retained_gate_minus": [
+ 3.086655100456178,
+ 3.2045506972079334,
+ 3.325833171568152,
+ 3.4500186838784823,
+ 3.577671713740335,
+ 3.707743941893947,
+ 3.841203047656023,
+ 3.9774845514251513,
+ 4.1206204503542665,
+ 4.266014267689023,
+ 4.417133520980944,
+ 4.5722041314827395,
+ 4.731709938852762
+ ],
+ "retained_gate_plus": [
+ 2.9615825487722023,
+ 3.0177079491410272,
+ 3.073107590022324,
+ 3.1284265909605615,
+ 3.184874551101621,
+ 3.241806350901032,
+ 3.299221990358795,
+ 3.3585729884499664,
+ 3.419052945743958,
+ 3.4806618622407712,
+ 3.543964217541817,
+ 3.610008330906856,
+ 3.67516540489825
+ ],
+ "retained_line_distance": [
+ 8.08292293261819e-06,
+ 0.003993462730446216,
+ 0.005952541765860968,
+ 0.00667053642362007,
+ 0.00702799652153725,
+ 0.006855754296051377,
+ 0.005764726401341312,
+ 0.005310896245919922,
+ 0.0031347398202806855,
+ 0.0010844030170761051,
+ -0.0017174891048780722,
+ -0.003597770655753531,
+ -0.00807352861708409
+ ],
+ "path_coordinate": [
+ 4.016946619401107,
+ 4.147459258818917,
+ 4.28078112801541,
+ 4.4167286098466505,
+ 4.556304898876256,
+ 4.698290759784522,
+ 4.843572204653746,
+ 4.992216018121322,
+ 5.147589681075312,
+ 5.305484636124792,
+ 5.4693027251830655,
+ 5.6378410997238895,
+ 5.810083703241586
+ ],
+ "projected_drift_velocity_v_per_s": [
+ 4.236218003994951,
+ 4.31786355506276,
+ 4.40659149235734,
+ 4.508951804944697,
+ 4.608070247817559,
+ 4.701592565916367,
+ 4.810560692910009,
+ 4.975566045433641,
+ 5.126469375714378,
+ 5.264586676637202,
+ 5.438832155057525,
+ 5.57754355941491,
+ 5.619030794759777
+ ]
+ },
+ {
+ "source_file": {
+ "path": "/scratch/yurenh2/imperfect-learning-physical-systems-v1.0.1/maguzj-imperfect-learning-physical-systems-71b8d72/small network/DriftTests/exp1DriftTest_2.mat",
+ "sha256": "a3969a1ab6ccf616a6b63be13e633301cd276ebf9cebe4f83a5ab95d1673d151"
+ },
+ "task": "alpha",
+ "solution_line": {
+ "gate_plus_slope": 2.7257,
+ "gate_plus_intercept": -3.3003
+ },
+ "sample_period_seconds": 0.03055399999999997,
+ "retained_samples": 9,
+ "retained_time_seconds": [
+ 1.095956,
+ 1.126512,
+ 1.157067,
+ 1.187627,
+ 1.218176,
+ 1.248734,
+ 1.279291,
+ 1.309842,
+ 1.340396
+ ],
+ "retained_gate_minus": [
+ 2.5433031641269532,
+ 2.598460885179074,
+ 2.6534573263450776,
+ 2.71030848620143,
+ 2.7676434857161345,
+ 2.82731704357954,
+ 2.8861035620693003,
+ 2.947147998964703,
+ 3.009805234721279
+ ],
+ "retained_gate_plus": [
+ 3.628797437639523,
+ 3.775723413892394,
+ 3.9262781875829047,
+ 4.081510077970818,
+ 4.238354767219904,
+ 4.399876573166392,
+ 4.566720615354751,
+ 4.738967533728041,
+ 4.913875570222266
+ ],
+ "retained_line_distance": [
+ -0.0010966631510683081,
+ -0.002273725567717279,
+ -0.0020495107701148916,
+ -0.0019555903060644014,
+ -0.0017604085000549497,
+ -0.0021497555546336586,
+ 0.00012679705803813525,
+ 0.0021444997056754675,
+ 0.0035646554470346575
+ ],
+ "path_coordinate": [
+ 4.282748163383154,
+ 4.439682006812766,
+ 4.59996705960825,
+ 4.765281866414429,
+ 4.932277437071425,
+ 5.1044694104998145,
+ 5.281352440997655,
+ 5.464085451263993,
+ 5.649872247298023
+ ],
+ "projected_drift_velocity_v_per_s": [
+ 5.073957642099754,
+ 5.190865900919979,
+ 5.327645274680347,
+ 5.4380042889637465,
+ 5.5506902338683854,
+ 5.711775466397501,
+ 5.884944630487621,
+ 6.030922317661434,
+ 5.78602799059672
+ ]
+ }
+ ],
+ "constant_model": {
+ "definition": "B(G) = b",
+ "bias_v_per_s": [
+ 3.2711869099585456,
+ 4.716905017637164
+ ],
+ "rank": 2,
+ "condition_number": 2.4047328345335246,
+ "in_sample_rmse_v_per_s": 0.40489007770456675,
+ "in_sample_r_squared": 0.39348382809096927,
+ "forward_block": {
+ "split": "first 60% of each retained trace trains; final 40% tests",
+ "trace_splits": [
+ {
+ "source": "exp1DriftTest_1.mat",
+ "train_samples": 7,
+ "test_samples": 6
+ },
+ {
+ "source": "exp1DriftTest_2.mat",
+ "train_samples": 5,
+ "test_samples": 4
+ }
+ ],
+ "parameters": [
+ 2.911080025813414,
+ 4.594710870787166
+ ],
+ "train_rank": 2,
+ "train_condition_number": 2.395452097552033,
+ "train_rmse": 0.18337490926920424,
+ "test_rmse": 0.7471220478750839,
+ "test_r_squared": -4.401819369148549
+ }
+ },
+ "local_affine_model": {
+ "definition": "B_i(G_i) = b_i + k_i (G_i - G_ref_i)",
+ "bias_at_reference_v_per_s": [
+ 2.6533247829167026,
+ 4.543278430598633
+ ],
+ "local_slopes_per_s": [
+ 0.8613144228168172,
+ 0.6281431773240994
+ ],
+ "rank": 4,
+ "condition_number": 8.410487632494219,
+ "in_sample_rmse_v_per_s": 0.06983797734487046,
+ "in_sample_r_squared": 0.9819552270127793,
+ "forward_block": {
+ "split": "first 60% of each retained trace trains; final 40% tests",
+ "trace_splits": [
+ {
+ "source": "exp1DriftTest_1.mat",
+ "train_samples": 7,
+ "test_samples": 6
+ },
+ {
+ "source": "exp1DriftTest_2.mat",
+ "train_samples": 5,
+ "test_samples": 4
+ }
+ ],
+ "parameters": [
+ 2.8030215562644067,
+ 4.40110352313821,
+ 0.6889298797902501,
+ 0.7452208221872205
+ ],
+ "train_rank": 4,
+ "train_condition_number": 11.121808766273288,
+ "train_rmse": 0.006170014713261239,
+ "test_rmse": 0.15556417672311493,
+ "test_r_squared": 0.7658057963184172
+ },
+ "reference_bias_error_v_per_s": [
+ -0.24667521708329732,
+ -0.15672156940136706
+ ]
+ },
+ "diagnostic": {
+ "in_sample_rmse_ratio_affine_over_constant": 0.17248626526192287,
+ "forward_test_rmse_ratio_affine_over_constant": 0.20821789045787162,
+ "affine_improves_forward_test": true
+ }
+ },
+ "experiment_2": {
+ "reference_gate": [
+ 3.1,
+ 4.3
+ ],
+ "published_constant_bias_at_reference_v_per_s": [
+ -0.3,
+ 2.0
+ ],
+ "traces": [
+ {
+ "source_file": {
+ "path": "/scratch/yurenh2/imperfect-learning-physical-systems-v1.0.1/maguzj-imperfect-learning-physical-systems-71b8d72/small network/DriftTests/exp2DriftTest_1.mat",
+ "sha256": "5d29c3e4e0d88f21d32e046b55519579f68e100ca44aa101c3336d589e628b77"
+ },
+ "task": "beta",
+ "solution_line": {
+ "gate_plus_slope": 0.74821,
+ "gate_plus_intercept": 1.9224
+ },
+ "sample_period_seconds": 0.0306280000000001,
+ "retained_samples": 49,
+ "retained_time_seconds": [
+ 1.099045,
+ 1.129673,
+ 1.160302,
+ 1.190932,
+ 1.221559,
+ 1.252181,
+ 1.282806,
+ 1.313436,
+ 1.34406,
+ 1.374678,
+ 1.405304,
+ 1.435927,
+ 1.466557,
+ 1.497188,
+ 1.527917,
+ 1.558541,
+ 1.589169,
+ 1.619801,
+ 1.650432,
+ 1.681061,
+ 1.711685,
+ 1.742315,
+ 1.772945,
+ 1.803576,
+ 1.834198,
+ 1.864831,
+ 1.895455,
+ 1.926073,
+ 1.956699,
+ 1.987322,
+ 2.017955,
+ 2.048582,
+ 2.079215,
+ 2.109842,
+ 2.140472,
+ 2.171099,
+ 2.201721,
+ 2.232343,
+ 2.262973,
+ 2.293597,
+ 2.324216,
+ 2.354845,
+ 2.385478,
+ 2.416105,
+ 2.446727,
+ 2.477349,
+ 2.507979,
+ 2.538703,
+ 2.569333
+ ],
+ "retained_gate_minus": [
+ 2.7862713125626843,
+ 2.805060419295351,
+ 2.8267525639781295,
+ 2.847396389401146,
+ 2.868604694425572,
+ 2.8874744411012974,
+ 2.9101342651007798,
+ 2.9318264097835587,
+ 2.9552119932705687,
+ 2.9779524572131097,
+ 3.000692921155651,
+ 3.023755944870426,
+ 3.048028567731082,
+ 3.06972071241386,
+ 3.0964125335662755,
+ 3.120362596654696,
+ 3.1474576175224045,
+ 3.173746238959527,
+ 3.1997929405674728,
+ 3.22575900223236,
+ 3.254144262189006,
+ 3.2797071241386004,
+ 3.3099471027855967,
+ 3.338574282571419,
+ 3.3686529813322985,
+ 3.39857040020706,
+ 3.428649098967938,
+ 3.4602599566469316,
+ 3.4917095344398072,
+ 3.522917192403507,
+ 3.558076207577081,
+ 3.5923481833770103,
+ 3.6275071985505845,
+ 3.662666213724158,
+ 3.7004057070756096,
+ 3.7387096800284705,
+ 3.77475573457569,
+ 3.814672506389725,
+ 3.8546699181468185,
+ 3.89539308939144,
+ 3.937083939952765,
+ 3.9790167103432657,
+ 4.020626920961533,
+ 4.063849930440972,
+ 4.106992299977353,
+ 4.1499733896276165,
+ 4.192228719790353,
+ 4.233677650522502,
+ 4.2742395418810055
+ ],
+ "retained_gate_plus": [
+ 4.002402293830277,
+ 4.017723883011421,
+ 4.034335711281504,
+ 4.05078625966547,
+ 4.066107848846615,
+ 4.081751997799993,
+ 4.0992508654437225,
+ 4.11618525348604,
+ 4.132474521983888,
+ 4.15037658934291,
+ 4.168520576531107,
+ 4.185696884402601,
+ 4.203518311818565,
+ 4.220855899576176,
+ 4.240773965511663,
+ 4.260450111617976,
+ 4.27996497783817,
+ 4.298834724513896,
+ 4.319155990164678,
+ 4.339315975929341,
+ 4.360040441295416,
+ 4.37955530751561,
+ 4.402215131515093,
+ 4.4246330356854,
+ 4.445760700766767,
+ 4.468178604937074,
+ 4.49116098870879,
+ 4.514546572195801,
+ 4.537690235853636,
+ 4.561720938885115,
+ 4.587525720663884,
+ 4.612040263353716,
+ 4.637603125303309,
+ 4.664940066000194,
+ 4.693164046070724,
+ 4.721065466369019,
+ 4.7474347277492,
+ 4.775900627648905,
+ 4.806624445954253,
+ 4.835896745284545,
+ 4.865814164159307,
+ 4.896376702578538,
+ 4.925568361965771,
+ 4.956130900385001,
+ 4.985,
+ 5.014998058817821,
+ 5.044270358148112,
+ 5.0725749781617,
+ 5.097492720566826
+ ],
+ "retained_line_distance": [
+ -0.003774252312594643,
+ -0.002762670519732154,
+ -0.002457169276120157,
+ -0.0016527732559892293,
+ -0.002090490432055128,
+ -0.0008689490514576152,
+ -0.0004329261236608246,
+ 0.00013084467331587446,
+ -0.0008364329146888713,
+ -0.00012588301081632548,
+ 0.0007783690580801915,
+ 0.0007145726043557115,
+ 0.00044266577289839764,
+ 0.0013292735115833746,
+ 0.0012868198080744596,
+ 0.0026932027709954294,
+ 0.002086362297624157,
+ 0.0014460823738319949,
+ 0.002112945337078738,
+ 0.0026989834892726305,
+ 0.0022876943909292975,
+ 0.0025987432645467982,
+ 0.002625942276885615,
+ 0.003425638436819979,
+ 0.0023226770019321723,
+ 0.002349413711770708,
+ 0.002731502208737495,
+ 0.002518538300423075,
+ 0.0022084921583465293,
+ 0.0027536171849184376,
+ 0.00235203643908527,
+ 0.0014487871017293524,
+ 0.0008535041908711466,
+ 0.0016787038235268033,
+ 0.001668225827745958,
+ 0.0010613085191844862,
+ 0.0005802898698007323,
+ -0.0005408550329912286,
+ 9.75769721471591e-05,
+ -0.0008609937035399608,
+ -0.001882744860066258,
+ -0.002532886806753963,
+ -0.004087434492723206,
+ -0.005510535889506739,
+ -0.008241242475830168,
+ -0.00997138569411014,
+ -0.011847845716786744,
+ -0.014016014743249651,
+ -0.01836460445811316
+ ],
+ "path_coordinate": [
+ 4.628700926136281,
+ 4.652924021089726,
+ 4.6802445014735605,
+ 4.706628985877694,
+ 4.732789102481384,
+ 4.757270004685695,
+ 4.785896703351568,
+ 4.813410423597927,
+ 4.841893579274408,
+ 4.870826395156777,
+ 4.899904140936038,
+ 4.928660436681094,
+ 4.958771722976321,
+ 4.986526993050834,
+ 5.0198313601027085,
+ 5.050795506054081,
+ 5.084181160219508,
+ 5.116534660776474,
+ 5.149564038549772,
+ 5.182432229003467,
+ 5.217575610866822,
+ 5.249734484653762,
+ 5.287522355624115,
+ 5.3238739489307445,
+ 5.360614795777427,
+ 5.39799946729752,
+ 5.435851443353713,
+ 5.475171749616551,
+ 5.514217991205811,
+ 5.553601940251987,
+ 5.5972125105707775,
+ 5.639339880167716,
+ 5.682805520589612,
+ 5.727333980255391,
+ 5.774460005970037,
+ 5.8218447635405495,
+ 5.866503744890513,
+ 5.915518019987271,
+ 5.965949541510039,
+ 6.016092590146521,
+ 6.067396927168149,
+ 6.1192814460798495,
+ 6.170086426022458,
+ 6.223004023147621,
+ 6.274842543606193,
+ 6.327228268806916,
+ 6.378598097821887,
+ 6.428742533365871,
+ 6.476147709081599
+ ],
+ "projected_drift_velocity_v_per_s": [
+ 0.7508246006659008,
+ 0.8414299465725285,
+ 0.8766874316465273,
+ 0.8577726510194819,
+ 0.82680117750534,
+ 0.8670987148152298,
+ 0.9165064297815321,
+ 0.914178125758254,
+ 0.9375275263588382,
+ 0.9472034122255371,
+ 0.9442441560240576,
+ 0.9610512771772265,
+ 0.9445917193305037,
+ 0.9948211100106393,
+ 1.0473958781155777,
+ 1.0505695225846392,
+ 1.0731193286458487,
+ 1.0672494071443286,
+ 1.0757028704320981,
+ 1.1103447123411982,
+ 1.0987501489464184,
+ 1.1418012529757333,
+ 1.2102236530082084,
+ 1.1932894339307194,
+ 1.2101100630989776,
+ 1.2282153572495578,
+ 1.2601249389462414,
+ 1.279580401767342,
+ 1.2805143609502787,
+ 1.354857382175512,
+ 1.3995698828247278,
+ 1.397204530067973,
+ 1.4364072799172218,
+ 1.4962246174920166,
+ 1.542857291097899,
+ 1.5027722104082968,
+ 1.5295091183907252,
+ 1.6235458402160727,
+ 1.6419256795601518,
+ 1.6564762769665926,
+ 1.6847680247757024,
+ 1.6762371568553536,
+ 1.6931601843080926,
+ 1.710329030699083,
+ 1.7017870429641289,
+ 1.6939173108439396,
+ 1.6546353289335909,
+ 1.5898177070821977,
+ 1.542909605414097
+ ]
+ },
+ {
+ "source_file": {
+ "path": "/scratch/yurenh2/imperfect-learning-physical-systems-v1.0.1/maguzj-imperfect-learning-physical-systems-71b8d72/small network/DriftTests/exp2DriftTest_2.mat",
+ "sha256": "808a0d0ed8824b1717597f63e38ec4412034d9171f0d58edb15d098862ddb1ed"
+ },
+ "task": "alpha",
+ "solution_line": {
+ "gate_plus_slope": 2.5678,
+ "gate_plus_intercept": -2.901
+ },
+ "sample_period_seconds": 0.03062599999999982,
+ "retained_samples": 19,
+ "retained_time_seconds": [
+ 1.099048,
+ 1.129669,
+ 1.16029,
+ 1.190925,
+ 1.22154,
+ 1.252169,
+ 1.282799,
+ 1.313423,
+ 1.344047,
+ 1.374672,
+ 1.405303,
+ 1.43593,
+ 1.466554,
+ 1.497174,
+ 1.527901,
+ 1.558528,
+ 1.589145,
+ 1.619774,
+ 1.650404
+ ],
+ "retained_gate_minus": [
+ 2.7462739008055905,
+ 2.7657081270827266,
+ 2.7834489145556316,
+ 2.801592901743829,
+ 2.820220728590378,
+ 2.840783914070336,
+ 2.8594117409168853,
+ 2.88013620628296,
+ 2.899973632275389,
+ 2.920859377527581,
+ 2.9411000032353036,
+ 2.9613406289430264,
+ 2.9832746934549808,
+ 3.005289397909994,
+ 3.0258525833899514,
+ 3.0464157688699083,
+ 3.066414474748455,
+ 3.085042301595005,
+ 3.1010090103206185
+ ],
+ "retained_gate_plus": [
+ 4.179245688957909,
+ 4.224645976899932,
+ 4.271336503930894,
+ 4.319075350221619,
+ 4.364233718334466,
+ 4.416085201721182,
+ 4.464953007214727,
+ 4.517530250088971,
+ 4.569139813646511,
+ 4.622765375780517,
+ 4.678810136206283,
+ 4.7325969782264075,
+ 4.787754699278528,
+ 4.842670500501472,
+ 4.897425021838299,
+ 4.950647384257013,
+ 4.999676469636675,
+ 5.04378651848976,
+ 5.084106490019089
+ ],
+ "retained_line_distance": [
+ 0.0102928838202821,
+ 0.008658815167945599,
+ 0.00907096246968139,
+ 0.00948782119683568,
+ 0.008517390467588221,
+ 0.00817240292568413,
+ 0.008548093744283286,
+ 0.008316192117803585,
+ 0.00855969965310696,
+ 0.008557937989690165,
+ 0.010035224450619176,
+ 0.010693132578076012,
+ 0.01027052064448047,
+ 0.009684975329273742,
+ 0.010393474216119818,
+ 0.010545966376681908,
+ 0.009702755839110155,
+ 0.008351899455035996,
+ 0.008105371925304106
+ ],
+ "path_coordinate": [
+ 4.890951292266569,
+ 4.9403092208682535,
+ 4.990254901253943,
+ 5.041323756195643,
+ 5.0901636211405865,
+ 5.14594266657955,
+ 5.198239102435053,
+ 5.254752960510771,
+ 5.310043205804902,
+ 5.367592447900904,
+ 5.42716186727808,
+ 5.484627286970569,
+ 5.54398466879315,
+ 5.603145885589996,
+ 5.661630073480702,
+ 5.718686547299655,
+ 5.771630748549389,
+ 5.819493756497868,
+ 5.862859354796883
+ ],
+ "projected_drift_velocity_v_per_s": [
+ 1.6087724632953608,
+ 1.6214951991668174,
+ 1.64904715422736,
+ 1.6311393555026201,
+ 1.7081795573430563,
+ 1.7642402757671922,
+ 1.7763921088543277,
+ 1.8254327222088798,
+ 1.84230622027992,
+ 1.9119476944202922,
+ 1.9105188758276812,
+ 1.9072829408108736,
+ 1.9351866959457025,
+ 1.9177544493326175,
+ 1.883114736635644,
+ 1.79608350237785,
+ 1.6459721135468859,
+ 1.4892302050103952,
+ 1.2620512042404304
+ ]
+ }
+ ],
+ "constant_model": {
+ "definition": "B(G) = b",
+ "bias_v_per_s": [
+ 0.23663724932160932,
+ 1.7766114352081004
+ ],
+ "rank": 2,
+ "condition_number": 3.9628889816190975,
+ "in_sample_rmse_v_per_s": 0.26995705909308504,
+ "in_sample_r_squared": 0.3964148715513893,
+ "forward_block": {
+ "split": "first 60% of each retained trace trains; final 40% tests",
+ "trace_splits": [
+ {
+ "source": "exp2DriftTest_1.mat",
+ "train_samples": 29,
+ "test_samples": 20
+ },
+ {
+ "source": "exp2DriftTest_2.mat",
+ "train_samples": 11,
+ "test_samples": 8
+ }
+ ],
+ "parameters": [
+ -0.16524636483433422,
+ 1.9423235060216164
+ ],
+ "train_rank": 2,
+ "train_condition_number": 3.9850204349776597,
+ "train_rmse": 0.13829635115886643,
+ "test_rmse": 0.48616449768925685,
+ "test_r_squared": -7.221033907983498
+ }
+ },
+ "local_affine_model": {
+ "definition": "B_i(G_i) = b_i + k_i (G_i - G_ref_i)",
+ "bias_at_reference_v_per_s": [
+ -0.2839863287520495,
+ 2.099298282479029
+ ],
+ "local_slopes_per_s": [
+ 0.9254562644135597,
+ -0.17006402648360702
+ ],
+ "rank": 4,
+ "condition_number": 11.267646483964826,
+ "in_sample_rmse_v_per_s": 0.1071040687889852,
+ "in_sample_r_squared": 0.9049917992864138,
+ "forward_block": {
+ "split": "first 60% of each retained trace trains; final 40% tests",
+ "trace_splits": [
+ {
+ "source": "exp2DriftTest_1.mat",
+ "train_samples": 29,
+ "test_samples": 20
+ },
+ {
+ "source": "exp2DriftTest_2.mat",
+ "train_samples": 11,
+ "test_samples": 8
+ }
+ ],
+ "parameters": [
+ -0.11013912378906168,
+ 1.892594891638608,
+ 0.5000251775829843,
+ 0.6507436117634928
+ ],
+ "train_rank": 4,
+ "train_condition_number": 17.497835518797263,
+ "train_rmse": 0.021606899405393228,
+ "test_rmse": 0.2641280985833621,
+ "test_r_squared": -1.426549566890654
+ },
+ "reference_bias_error_v_per_s": [
+ 0.0160136712479505,
+ 0.09929828247902917
+ ]
+ },
+ "diagnostic": {
+ "in_sample_rmse_ratio_affine_over_constant": 0.3967448347111167,
+ "forward_test_rmse_ratio_affine_over_constant": 0.5432895652372083,
+ "affine_improves_forward_test": true
+ }
+ }
+ },
+ "headroom_sensitivity": [
+ {
+ "terminal_headroom_v": 0.03,
+ "forward_test_rmse_ratios_affine_over_constant": {
+ "experiment_1": 0.4819119278880803,
+ "experiment_2": 0.5769371754474453
+ },
+ "affine_improves_both": true
+ },
+ {
+ "terminal_headroom_v": 0.05,
+ "forward_test_rmse_ratios_affine_over_constant": {
+ "experiment_1": 0.20821789045787162,
+ "experiment_2": 0.5432895652372083
+ },
+ "affine_improves_both": true
+ },
+ {
+ "terminal_headroom_v": 0.08,
+ "forward_test_rmse_ratios_affine_over_constant": {
+ "experiment_1": 0.20821789045787162,
+ "experiment_2": 0.40322524115717306
+ },
+ "affine_improves_both": true
+ },
+ {
+ "terminal_headroom_v": 0.1,
+ "forward_test_rmse_ratios_affine_over_constant": {
+ "experiment_1": 0.22615952365875847,
+ "experiment_2": 0.2908505511376861
+ },
+ "affine_improves_both": true
+ }
+ ],
+ "summary": {
+ "forward_test_rmse_ratios_affine_over_constant": [
+ 0.20821789045787162,
+ 0.5432895652372083
+ ],
+ "affine_improves_both_forward_tests": true,
+ "affine_improves_both_for_all_headroom_thresholds": true
+ }
+}