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)