You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A job_type = ms run whose first augmented model is non-finite reports no fit at all,
even when the start point itself certifies perfectly well. The run ends with:
Start 1 of 1: homotopy over 1 stage(s), inner_failed: best certified objective none, 2 evaluations
stage trace: m=4: inf
No simulation completed, so there is no best fit to report.
job_type = gntr from the identical start point, same config, reports the fit normally:
Stop criterion satisfied with objective function value of -150.70078270720597
The two disagree about whether there is a result, and ms is the one that is wrong: the
point does score, and ms can prove it — see below.
Why
Reproduced on Borghans_BiophysChem1997 at a start drawn from the prior box. Rebuilding the m=4 stage at that exact point:
1. unsegmented simulation: OK, 112 rows
2. seeded knots (log10):
experiment1@1/4 [ 0.766 -2.836 4.133]
experiment1@1/2 [ 0.766 -2.836 4.133] <- all three identical
experiment1@3/4 [ 0.766 -2.836 4.133]
3. objective at the seeded start: value=inf finite=False
equality finite=False defect_norm=inf
4. per-segment simulation at the seeded start:
segment 0: OK end_state=[5.8307e+00 1.4589e-03 1.3584e+04] finite=False
segment 1: OK end_state=[5.8322e+00 1.4595e-03 1.3586e+04] finite=False
segment 2: OK end_state=[5.8322e+00 1.4595e-03 1.3586e+04] finite=False
segment 3: OK end_state=[5.8322e+00 1.4595e-03 1.3586e+04] finite=False
5. certificate: accepted=True objective=-150.70078278843627 detail='single-shoot reconstruction'
Three things are going on, and only the third is a bug:
The trajectories integrate; the forward sensitivities overflow. Every segment returns OK (so backend.simulate's own finiteness check passed on the trajectory) but SegmentTrace.is_finite() is False, which tests d_end_param / d_end_ic. Z_state
reaches 1.4e4 here. Refusing the point is correct — an assembly over non-finite
sensitivities would produce a garbage local model.
Seeding fell back to nominals, which is why all three knots carry the identical vector: _seed_knots returns [nominal.copy() for _ in knots] when the seeding trajectory is not
finite. That is the documented fallback and is also fine.
The run then reports nothing, although it has a certified score available. In AugmentedLagrangian.run:
model=subproblem.at(u)
outer_evals+=1ifnotmodel.is_finite():
stop_reason='inner_failed'break# <-- returns before _certify is ever called
...
record=self._certify(iteration, u, model, multipliers.penalty, optimality)
The break precedes _certify, so no CertifiedIterate is produced, nothing is offered
to CertifiedBest, on_iterate never fires, and nothing reaches MultipleShootingAlgorithm._record_iterate — hence an empty trajectory and
"No simulation completed". Yet step 5 above shows problem.certify() at that very point
returns accepted=True, objective=-150.70078, agreeing with gntr to 7 significant
digits. Certification does not need the augmented model at all: it discards the auxiliary
states and re-simulates unsegmented.
Why it matters beyond one start
On a single-start run this is the whole result. refine_method = ms (Add sensitivity-aware multiple shooting for ODE parameter estimation #563 arm 4) is
single-start by construction — _resolve_n_starts returns 1 for an injected start — so a
refine that lands here silently contributes nothing, and the run reports the search's
fit with no indication the refine produced nothing usable.
On a multi-start run other starts paper over it, so it is easy to miss.
It is not rare on a stiff oscillator: 1 of 8 oscillating box draws hit it in a small paired
experiment.
Suggested fix
Certify before bailing. The reported parameters at u are certifiable whether or not the augmented model at u is finite, and the certificate is the run's honest answer for that
point. Roughly: on the non-finite branch, build the CertifiedIterate from self.problem.certify(layout.reported_of(u)) with defect_norm = inf, offer it to best / shared_best / on_iterate as usual, and then break with stop_reason = 'inner_failed'.
That would have this run report -150.70078 — the same number gntr reports — instead of
nothing.
A test at the layer level can pin it without a simulator: an offline TranscriptionProblem
whose objective_at returns a non-finite model while certify succeeds should still produce OuterResult.best is not None.
Reproducing
Found while running the #563 acceptance work. The start is a prior-box draw on Borghans_BiophysChem1997; the distinguishing property is a point whose whole-horizon
trajectory integrates but whose forward sensitivities are non-finite. Happy to attach the
exact parameter vector and the two confs if useful.
What happens
A
job_type = msrun whose first augmented model is non-finite reports no fit at all,even when the start point itself certifies perfectly well. The run ends with:
job_type = gntrfrom the identical start point, same config, reports the fit normally:The two disagree about whether there is a result, and
msis the one that is wrong: thepoint does score, and
mscan prove it — see below.Why
Reproduced on
Borghans_BiophysChem1997at a start drawn from the prior box. Rebuilding them=4stage at that exact point:Three things are going on, and only the third is a bug:
The trajectories integrate; the forward sensitivities overflow. Every segment returns
OK(sobackend.simulate's own finiteness check passed on the trajectory) butSegmentTrace.is_finite()isFalse, which testsd_end_param/d_end_ic.Z_statereaches
1.4e4here. Refusing the point is correct — an assembly over non-finitesensitivities would produce a garbage local model.
Seeding fell back to nominals, which is why all three knots carry the identical vector:
_seed_knotsreturns[nominal.copy() for _ in knots]when the seeding trajectory is notfinite. That is the documented fallback and is also fine.
The run then reports nothing, although it has a certified score available. In
AugmentedLagrangian.run:The
breakprecedes_certify, so noCertifiedIterateis produced, nothing is offeredto
CertifiedBest,on_iteratenever fires, and nothing reachesMultipleShootingAlgorithm._record_iterate— hence an empty trajectory and"No simulation completed". Yet step 5 above shows
problem.certify()at that very pointreturns
accepted=True, objective=-150.70078, agreeing withgntrto 7 significantdigits. Certification does not need the augmented model at all: it discards the auxiliary
states and re-simulates unsegmented.
Why it matters beyond one start
refine_method = ms(Add sensitivity-aware multiple shooting for ODE parameter estimation #563 arm 4) issingle-start by construction —
_resolve_n_startsreturns 1 for an injected start — so arefine that lands here silently contributes nothing, and the run reports the search's
fit with no indication the refine produced nothing usable.
experiment.
Suggested fix
Certify before bailing. The reported parameters at
uare certifiable whether or not theaugmented model at
uis finite, and the certificate is the run's honest answer for thatpoint. Roughly: on the non-finite branch, build the
CertifiedIteratefromself.problem.certify(layout.reported_of(u))withdefect_norm = inf, offer it tobest/shared_best/on_iterateas usual, and then break withstop_reason = 'inner_failed'.That would have this run report
-150.70078— the same numbergntrreports — instead ofnothing.
A test at the layer level can pin it without a simulator: an offline
TranscriptionProblemwhose
objective_atreturns a non-finite model whilecertifysucceeds should still produceOuterResult.best is not None.Reproducing
Found while running the #563 acceptance work. The start is a prior-box draw on
Borghans_BiophysChem1997; the distinguishing property is a point whose whole-horizontrajectory integrates but whose forward sensitivities are non-finite. Happy to attach the
exact parameter vector and the two confs if useful.