Repository navigation
Description
Description
When a tied expression refers to another tied parameter,
fitter_to_model_params_array (used by all the non-linear fitters) evaluates it
with the value of that parameter from the previous call, rather than the value
that was just computed.
In the tied-parameter loop each new value is written into the local
parameters array and then model._array_to_parameters() is called:
_array_to_parameters() re-reads model._parameters, which is not the local
array (the model.parameters setter copies into it), so the new tied value
never reaches the model before the next tied expression is evaluated. The
comment there ("To handle multiple tied constraints, model parameters need to
be updated after each iteration") suggests this was meant to work.
As a result, during fitting the objective function evaluated at a given set of
free parameters depends on the previous evaluation. Fits generally still end up
satisfying the tie, since the lag disappears once the free parameters stop
changing, but the function seen by the optimizer, and its finite-difference or
analytic Jacobian, are not consistent with each other.
Expected behavior
Tied values should be applied in order, so that a tied expression sees the
updated values of tied parameters that precede it in model.param_names.
A single call of fitter_to_model_params should give the same result as two.
How to Reproduce
from astropy.modeling import fitting, models
model = models.Gaussian1D(3, 1.0, 0.5) + models.Gaussian1D(1, 2.0, 0.5)
model.amplitude_1.tied = lambda m: 2 * m.amplitude_0
# mean_1 depends on amplitude_1, which is itself tied
model.mean_1.tied = lambda m: m.mean_0 + 0.1 * m.amplitude_1
free, _, _ = fitting.model_to_fit_params(model)
fitting.fitter_to_model_params(model, free)
print(model.amplitude_1.value, model.mean_1.value) # expected 6.0 1.6
fitting.fitter_to_model_params(model, free)
print(model.amplitude_1.value, model.mean_1.value)Output:
6.0 1.1
6.0 1.6
A likely fix is to assign the updated array back to the model
(model.parameters = parameters) instead of calling
model._array_to_parameters(), but since that changes what the fitters see I
thought it best to report it separately. Found while working on #20664 (the fix
there is consistent with the current behavior and does not depend on this).
Versions
platform.platform() = 'Linux-7.3.0-5-cachyos-x86_64-with-glibc2.44'
platform.python_version() = '3.13.16'
astropy main @ dbbf2acd6d
numpy 2.5.4
scipy 1.18.1
pyerfa 2.0.1.5
AI disclosure: this report was drafted with the help of Claude Code (Claude Opus 5.5), which also found the bug while working on #20664; I have checked the reproduction and the analysis.
Activity
Onkar-Raskar commentedon Oct 26, 2026
@tepickering , I would like to work on issue, i have reproduced it locally.
Onkar-Raskar commentedon Oct 27, 2026
@tepickering , can you review my pr and let me know if any changes required.
Add regression test and changelog for astropy#20710