Solvers

The GModelFit.jl main purpose is to act as an high-level interface between the user and the underlying solver. Currently supported solvers are:

Additional solvers may be implemented in future releases.

To choose a specific solver add a third argument to the fit() or fit!() functions, e.g.

fit(model, data)                                # use default solver (lsqfit)
fit(model, data, GModelFit.Solvers.lsqfit())    # use LsqFit solver
fit(model, data, GModelFit.Solvers.cmpfit())    # use CMPFit solver
fit(model, data, GModelFit.Solvers.curvefit())  # use CurveFit solver

Examples

using GModelFit
model = Model(:main => @fd (x, T=3.14) -> sin.(x ./ T) ./ (x ./ T))
data = GModelFit.mock(Measures, model, Domain(1:0.1:50), seed=1)
bestfit, fsumm = fit(model, data, GModelFit.Solvers.lsqfit())
(Components:
╭───────────┬───────┬───────┬─────────────┬───────────┬───────────┬───────────┬─────────╮
│ Component │ Type  │ #Free │ Eval. count │    Min    │    Max    │   Mean    │ NaN/Inf │
├───────────┼───────┼───────┼─────────────┼───────────┼───────────┼───────────┼─────────┤
│ main      │ FComp │ 1     │ 23          │   -0.2172 │    0.9832 │   0.08517 │ 0       │
╰───────────┴───────┴───────┴─────────────┴───────────┴───────────┴───────────┴─────────╯

Parameters:
╭───────────┬───────┬────────┬──────────┬───────────┬───────────┬────────┬───────╮
│ Component │ Type  │ Param. │  Range   │   Value   │  Uncert.  │ Actual │ Patch │
├───────────┼───────┼────────┼──────────┼───────────┼───────────┼────────┼───────┤
│ main      │ FComp │ T      │ -Inf:Inf │     3.141 │   0.01238 │        │       │
╰───────────┴───────┴────────┴──────────┴───────────┴───────────┴────────┴───────╯
, Fit summary: #data: 491, #free pars: 1, red. fit stat.: 1.0596, status: OK      
)

or

bestfit, fsumm = fit(model, data, GModelFit.Solvers.cmpfit())
(Components:
╭───────────┬───────┬───────┬─────────────┬───────────┬───────────┬───────────┬─────────╮
│ Component │ Type  │ #Free │ Eval. count │    Min    │    Max    │   Mean    │ NaN/Inf │
├───────────┼───────┼───────┼─────────────┼───────────┼───────────┼───────────┼─────────┤
│ main      │ FComp │ 1     │ 7           │   -0.2172 │    0.9832 │   0.08517 │ 0       │
╰───────────┴───────┴───────┴─────────────┴───────────┴───────────┴───────────┴─────────╯

Parameters:
╭───────────┬───────┬────────┬──────────┬───────────┬───────────┬────────┬───────╮
│ Component │ Type  │ Param. │  Range   │   Value   │  Uncert.  │ Actual │ Patch │
├───────────┼───────┼────────┼──────────┼───────────┼───────────┼────────┼───────┤
│ main      │ FComp │ T      │ -Inf:Inf │     3.141 │   0.01203 │        │       │
╰───────────┴───────┴────────┴──────────┴───────────┴───────────┴────────┴───────╯
, Fit summary: #data: 491, #free pars: 1, red. fit stat.: 1.0596, status: OK      
)

or

using NonlinearSolve
bestfit, fsumm = fit(model, data, GModelFit.Solvers.curvefit())
(Components:
╭───────────┬───────┬───────┬─────────────┬───────────┬───────────┬───────────┬─────────╮
│ Component │ Type  │ #Free │ Eval. count │    Min    │    Max    │   Mean    │ NaN/Inf │
├───────────┼───────┼───────┼─────────────┼───────────┼───────────┼───────────┼─────────┤
│ main      │ FComp │ 1     │ 90          │   -0.2172 │    0.9832 │   0.08517 │ 0       │
╰───────────┴───────┴───────┴─────────────┴───────────┴───────────┴───────────┴─────────╯

Parameters:
╭───────────┬───────┬────────┬──────────┬───────────┬───────────┬────────┬───────╮
│ Component │ Type  │ Param. │  Range   │   Value   │  Uncert.  │ Actual │ Patch │
├───────────┼───────┼────────┼──────────┼───────────┼───────────┼────────┼───────┤
│ main      │ FComp │ T      │ -Inf:Inf │     3.141 │   0.01238 │        │       │
╰───────────┴───────┴────────┴──────────┴───────────┴───────────┴────────┴───────╯
, Fit summary: #data: 491, #free pars: 1, red. fit stat.: 1.0596, status: ERROR
Not converged
)

The above solvers typically provide the same results, although in some complex case the results may differ.

The cmpfit() solver

The cmpfit() solver allows to specify several options to fine-tune the solver behaviour. Specifically:

  • the CMPFit.Config structure allows to specify the convergence criteria, the maximum number of iterations, etc. (see the "CONFIGURING MPFIT()" section here);

  • the ftol_after_maxiter allows to specify a threshold on the relative difference in fit statistics before and after the mpfit() execution. If the latter terminates because the maximum number of iterations has been reached, and the relative difference in fit statistics is still greater than ftol_after_maxiter the minimization process will continue. E.g.:

    using GModelFit
    dom = Domain(1:0.1:50)
    model = Model(:main => @fd (x, T=3.14) -> sin.(x ./ T) ./ (x ./ T))
    data = GModelFit.mock(Measures, model, dom, seed=1)
    
    # Set solver options
    solver = GModelFit.Solvers.cmpfit()
    solver.config.maxiter = 1
    solver.ftol_after_maxiter = 1e-8
    
    # Run the fit
    model[:main].T.val = 10  # guess value, purposely far from true one
    bestfit, fsumm = fit(model, data, solver)