Skip to content

modeling: analytic Jacobian drops tied parameters' columns instead of chaining them into the free parameter, so LM/TRF fits with tied params stop off the minimum #20664

Open

Description

@scttfrdmn

Where. astropy/modeling/fitting.py, _wrap_deriv (main, ~L1221-1251). When model.has_tied, the full analytic derivative model.fit_deriv(...) is computed for every parameter, then the columns of fixed and tied parameters are deleted:

tied = list(np.where([par.tied is not False for par in pars], True, tied))
fix_and_tie = np.logical_or(fixed, tied)
ind = np.logical_not(fix_and_tie)
residues = full_deriv[np.nonzero(ind)]

Deleting the column is correct for a fixed parameter. For a tied parameter (p_t = f(p_free)), it drops the term ∂y/∂p_t · ∂f/∂p_free from the derivative with respect to the free parameter. So the Jacobian the optimiser sees is wrong whenever a tie depends on a free parameter, and LM/TRF converge to a point that is not the least-squares minimum. Using the numerical Jacobian (estimate_jacobian=True) avoids it, because the tie is then applied before differencing.

Measured impact (specutils fit_lines, whose default is TRFLSQFitter). The model is [O III] λ4960 + λ5007 as two Gaussian1D with the 4960 amplitude, mean and stddev tied to 5007, plus a fixed Const1D continuum. It was refit on 6,812 DESI DR1 spectra against DESI's own scipy.optimize.curve_fit fit of the same pixels, model, start and bounds:

  • default fitter: off the true χ² minimum in 6,608 of 6,812 fits, line flux off by a median 1.9% (p90 9.6%);
  • TRFLSQFitter() with estimate_jacobian=True: on DESI's minimum.

Untied lines (Hα, Hβ and so on) agreed with DESI on the same spectra.

Minimal reproduction to try: two Gaussian1D with the second's amplitude tied as lambda m: m.amplitude_0 / 2.98 (and mean/stddev tied similarly), plus a fixed Const1D, on synthetic noisy data. Compare TRFLSQFitter()(...) with TRFLSQFitter()(..., estimate_jacobian=True) and with curve_fit on the equivalent function.

Fix direction: for tied parameters, either fall back to the numerical Jacobian, or apply the chain rule through the tie (numerically differencing the tie function if it is a lambda).

(Found while building https://github.com/scttfrdmn/scientific-codes-cookbook/tree/main/measurements/specutils-real)

Activity

  1. pllim commented on Oct 21, 2026

    @pllim
    Member

    Since this mentions DESI and specutils... @weaverba137 @tepickering @rosteen 🙏

  2. weaverba137 commented on Oct 21, 2026

    @weaverba137
    Member

    The technical details of the model fitting described above are outside my area of expertise, but I know that @moustakas does similar work with the fastspecfit package.

  3. moustakas commented on Oct 23, 2026

    @moustakas

    Just clarifying the location of the repo:
    https://github.com/desihub/fastspecfit

    The paper describing FastSpecFit is currently in (DESI) internal review, but should hit the archive soon, but in the meantime this technote describes the emission-line fitting algorithm, which I'm sharing in case it's useful:
    https://github.com/desihub/fastspecfit/blob/main/doc/technote/emline-model.tex

  4. tepickering commented on Oct 24, 2026

    @tepickering
    Contributor

    I set up a PR to fix this, #20711. See that PR's description for details. It follows the same factorization as fastspecfit, but does not re-use that implementation since it is fairly specialized. In the process of working on that, I found another bug in handling tied parameters and filed issue #20710 to cover that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions