CourseSynthesis assessment · CPU & changed-condition verification

Science synthesis: defend an inferred physical parameter

Scope: fixed-step differentiable cooling, numerical discretization error, inverse parameter estimation, and runtime measurement building on the scientific computing lessons and scientific inverse project.

Prepare an independent assessment

Retain your project implementation and create a separate assessment script and report. Record Python, JAX, NumPy, backend, device count and dtype. Keep predictions, observed values and conclusions separate. Run the project checker first, then transfer the methods to the fixtures below without changing its checks.

Worked verification scaffold

Run the baseline verification suite with python3 assessments/check_assessments.py, and use the starter scaffold below to verify your numerical contracts:

# Worked starter scaffold: two-compartment RK4 conservation & sensitivity check
import jax
import jax.numpy as jnp

def rhs(u: jnp.ndarray, k: float) -> jnp.ndarray:
    # Compute compartment exchange derivatives da/dt = -k(a - b), db/dt = k(a - b).
    diff = u[0] - u[1]
    return jnp.array([-k * diff, k * diff], dtype=jnp.float32)

def rk4_step(u: jnp.ndarray, dt: float, k: float) -> jnp.ndarray:
    # Advance state u by one fourth-order Runge-Kutta step of size dt.
    k1 = rhs(u, k)
    k2 = rhs(u + 0.5 * dt * k1, k)
    k3 = rhs(u + 0.5 * dt * k2, k)
    k4 = rhs(u + dt * k3, k)
    return u + (dt / 6.0) * (k1 + 2.0 * k2 + 2.0 * k3 + k4)

u0 = jnp.array([3.0, 1.0], dtype=jnp.float32)
sens_a = jax.grad(lambda rate: rk4_step(u0, 0.05, rate)[0])(0.4)
sens_total = jax.grad(lambda rate: jnp.sum(rk4_step(u0, 0.05, rate)))(0.4)
print("da/dk:", float(sens_a), "d(a+b)/dk:", float(sens_total))

Task 1: demonstrate conservation in a different physical system

Two compartments exchange a conserved substance. Their state is u=(a,b)u=(a,b), with

dadt=−k(a−b),dbdt=k(a−b).\frac{da}{dt}=-k(a-b),\qquad \frac{db}{dt}=k(a-b).

Use k=0.4k=0.4, initial state (3,1)(3,1), and a horizon of three seconds. Derive the conserved total a+ba+b and an independent solution by introducing the difference d=a−bd=a-b. Implement a vector-state RK4 solver and verify both compartments at every saved time with forty and eighty updates. State tolerances and show the initial point. Compare conservation error and trajectory error separately: a method can conserve a quantity while approximating its trajectory poorly.

Keep: derivation, state/axis diagram, independent reference, refinement table and an explanation of why conservation alone is insufficient.

Task 2: check both useful and uninformative sensitivities

Differentiate the final first-compartment value with respect to kk. Compare with an analytic expression and central differences at two perturbations. Then differentiate the final total a+ba+b: explain why its sensitivity is zero for every rate.

Demonstrate that fitting only total-substance measurements cannot identify the rate, even with many observation times. Propose a measurement that can distinguish rates and show its nonzero sensitivity. A zero derivative here is a physical property, not automatically a software defect.

Keep: derivative derivation, measured comparisons, an unidentifiable objective, and a repaired observation design.

Task 3: infer from one compartment and test a new initial condition

Generate independent analytic first-compartment observations at twenty-one evenly spaced times over three seconds. Use true rate 0.40.4, initial state (3,1)(3,1), and NumPy generator seed 71 with additive Gaussian noise of standard deviation 0.0050.005. Freeze this dataset before fitting.

Fit a positive rate from initial guesses 0.20.2 and 0.90.9. Compare each estimate with an independent analytic grid search over [0.25,0.55][0.25,0.55], with at least three thousand intervals. Report actual fit quality; do not select a new noise seed when a result looks inconvenient. Inspect the objective profile around the minimum rather than inferring uncertainty from one point estimate.

Before fitting, reserve a noiseless test trajectory with initial state (4,0.5)(4,0.5) and the same true rate. Evaluate both compartments without further updates. Refit on a finer numerical grid and report parameter movement. Compare fixed-parameter refined predictions separately from refitting; they answer different questions.

Keep: immutable data-generation rules, two complete histories, independent search, held-out errors, numerical-refinement evidence, and the limits of a single synthetic dataset.

Task 4: explain a figure and defend timing boundaries

Create a two-panel figure: observed first-compartment data with fitted trajectories, then residual versus time. Label units, initial conditions and the known synthetic truth separately from estimates. Describe at least two actual visible values or patterns, and explain which out-of-sample properties require separate experiments.

Measure batches of one, thirty-two and two hundred fifty-six initial states on the available CPU. Compile/warm up each shape, use already-placed inputs, synchronize outputs, and collect at least seven samples. Report median latency and time per trajectory with the batch, grid, precision and saved-output policy. Do not assert a speedup unless the measurements show it. A CPU batch curve provides no TPU or multi-host throughput evidence.

Keep: plotting code and data, figure interpretation, timing samples and an explicit inclusion/exclusion boundary.

Reviewer decision

Submit the implementation, executable assessment, report, source data and figure assets. An unresolved discrepancy is evidence to investigate, not a reason to remove the comparison.

Complete each task with changed inputs, independent numerical checks, and saved terminal outputs in your portfolio.