Commit 9059292
mp_fdjac2: guard non-finite numerical derivatives
The only protection against a non-finite finite-difference derivative
here was assert(isfinite(fjac[ij])), which a release build (-DNDEBUG)
strips out entirely, and the two-sided derivative path had no check at
all. If the user function returns a degenerate residual for some
parameter value, wa[i]/fvec[i] can be non-finite, writing NaN/Inf
straight into fjac.
That NaN then poisons fnorm/ratio in mpfit()'s outer Levenberg-Marquardt
loop. Since any comparison against NaN is false, the iteration counter
(which only advances inside the ratio>=p0001 success branch) never
increments, so the maxiter check that's supposed to bound the loop never
fires. The result is an unbounded CPU spin instead of a clean failure
return -- in our case, confirmed via gdb on a real reproduction: ~465k
spin iterations/sec with zero progress, instead of returning MP_MAXITER.
Fix: sanitize fjac to 0 on a non-finite derivative in all three
non-debug/debug, one-sided/two-sided paths, so the column is treated as
having no measurable gradient -- the same fallback mp_qrfac already uses
for a zero-norm column.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent d230bf7 commit 9059292
1 file changed
Lines changed: 6 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1228 | 1228 | | |
1229 | 1229 | | |
1230 | 1230 | | |
1231 | | - | |
| 1231 | + | |
| 1232 | + | |
1232 | 1233 | | |
1233 | 1234 | | |
1234 | 1235 | | |
1235 | 1236 | | |
1236 | 1237 | | |
1237 | 1238 | | |
1238 | | - | |
| 1239 | + | |
| 1240 | + | |
1239 | 1241 | | |
1240 | 1242 | | |
1241 | 1243 | | |
| |||
1264 | 1266 | | |
1265 | 1267 | | |
1266 | 1268 | | |
| 1269 | + | |
| 1270 | + | |
1267 | 1271 | | |
1268 | 1272 | | |
1269 | 1273 | | |
| |||
0 commit comments