MATLAB · chapter 11 of 13

Accuracy and validation

"Accurate generator" is a claim that should be backed by numbers. GRNLab is checked at three levels.

1. Unit tests

tests/ holds 60 matlab.unittest tests (buildtool runs them, and buildtool package refuses to package if any fail). They cover analytic steady states of one- and two-stage models, finite-difference checks of every Jacobian, the textbook behaviour of the motifs (bistable toggle, oscillating repressilator and Goodwin loop, pulsing incoherent feed-forward loop, monotone coherent one), seeding, every noise model, perturbations, stimuli, steady states, screens, export round trips, and figure rendering.

2. The accuracy audit

audit/runAudit.m exercises the public API end to end against closed-form results and writes audit/AUDIT.md. It is independent of the unit tests and meant to be rerun after any change to the kinetics or integrators.

CheckAnalytic resultTolerance
Unregulated gene trajectoryx(t) = x* + (x0 - x*) e^{-gamma t}1e-6
Hill function at thresholdh(K) = 1/2, h'(K) = n / (4K)1e-14
Activation-edge steady stateclosed form from x1* = vmax/gamma1e-8 relative
Repressilator Hopf threshold (Hill 4)alpha_c = 2 (loop slope n x*^n / (1 + x*^n) = 2 at x* = 1)1e-6
Below/above thresholddecays / sustained oscillation
Toggle switch bistability threshold (Hill 2)alpha_c = 21e-6
Jacobian vs central differences01e-6
Euler–Maruyama convergenceerror ratio 2 when Dt halves0.3
Additive noise, linear genestationary variance sigma^2 / (2 gamma), mean vmax/gamma10 %
Chemical Langevin, linear geneFano factor sigma^2 (linear-noise approximation)8 %
Two-stage protein levelq* = beta m* / gammaP1e-8
Fast-protein limittwo-stage steady state equals one-stage1e-5
Step stimulusexact exponential after the switch, exactly zero before1e-6
Knockout screenevery knockout with a resolvable effect (above 1e-3 log2 units) moves its target in the sign predicted by Sexact
Seedstwo runs are bit-identicalexact

The last run passed 19 of 19 checks; the measured values are in audit/AUDIT.md. To rerun:

cd audit; report = runAudit();
Output
                                <strong>check</strong>                                 <strong>expected</strong>     <strong>measured</strong>       <strong>error</strong>       <strong>tolerance</strong>    <strong>pass</strong> 
    <strong>______________________________________________________________</strong>    <strong>________</strong>    <strong>__________</strong>    <strong>__________</strong>    <strong>_________</strong>    <strong>_____</strong>

    "Unregulated gene x(t): max |ODE - analytic|"                           0     1.1862e-07    1.1862e-07        1e-06    true 
    "Hill h(K) = 1/2"                                                     0.5            0.5             0        1e-15    true 
    "Hill dh/dx at K = n/(4K)"                                        0.44118        0.44118    5.5511e-17        1e-14    true 
    "Activation edge x2* (additive)"                                    2.297          2.297             0    2.297e-08    true 
    "Repressilator Hopf alpha_c (hill 4)"                                   2              2    4.4409e-16        1e-06    true 
    "Repressilator amplitude at alpha = 1.8 (below threshold)"              0     2.2272e-07    2.2272e-07        1e-06    true 
    "Repressilator oscillates at alpha = 2.4 (above threshold)"             1              1             0            0    true 
    "Toggle switch bistability alpha_c (hill 2)"                            2              2             0        1e-06    true 
    "Jacobian vs central differences (max abs)"                             0     2.7891e-10    2.7891e-10        1e-06    true 
    "Euler error ratio for dt halved (expect 2)"                            2         2.0012     0.0012015          0.3    true 
    "OU stationary variance sigma^2/(2 gamma)"                          0.125        0.13381     0.0088071        0.012    true 
    "OU stationary mean vmax/gamma"                                        20          20.01      0.009728         0.02    true 
    "Langevin Fano factor var/mean = sigma^2"                            0.16        0.15901    0.00099419        0.012    true 
    "Two-stage protein q* = beta m*/gammaP"                            6.4843         6.4843    8.8818e-16        1e-08    true 
    "Fast-protein limit: max |two-stage - one-stage| steady state"          0     4.4409e-16    4.4409e-16        1e-05    true 
    "Step stimulus x(t): max |ODE - analytic|"                              0     1.7995e-08    1.7995e-08        1e-06    true 
    "KO effect sign agreement with S (fraction)"                            1              1             0            0    true 
    "KO screen convergence (fraction)"                                      1              1             0            0    true 
    "Seed reproducibility: max |run A - run B|"                             0              0             0            0    true
Two of the audited thresholds. Left: repressilator amplitude against alpha; oscillation starts at the analytic Hopf point alpha = 2. Right: toggle-switch steady states against alpha; the symmetric state (blue) loses stability at alpha = 2 and two branches (teal) appear.
Two of the audited thresholds. Left: repressilator amplitude against alpha; oscillation starts at the analytic Hopf point alpha = 2. Right: toggle-switch steady states against alpha; the symmetric state (blue) loses stability at alpha = 2 and two branches (teal) appear.
Euler–Maruyama with zero noise against ode45: the error falls linearly with the step, as expected for a first-order scheme.
Euler–Maruyama with zero noise against ode45: the error falls linearly with the step, as expected for a first-order scheme.

3. Numerical methods and their limits

Known limitations