Solvers
CurveFit provides built-in solvers for linear curve fitting problems. Nonlinear problems are delegated to NonlinearSolve.jl. In addition, CurveFit includes specialized algorithms for selected nonstandard models.
Linear fitting
Linear curve fitting in CurveFit solves problems of the general form $f_y(y) = a \cdot f_x(x) + b$ where x and y are the data points being fitted and a and b are the fit parameters.
Linear fits do not require an initial guess. The user must explicitly select a linear algorithm, as no default is assumed.
Linear fitting algorithms are represented by the LinearCurveFitAlgorithm type, which encapsulates transformations applied to the input and output data. The fields xfun and yfun define transformations applied to x and y, respectively, while yfun_inverse maps fitted parameters back to the original data space.
The default constructor corresponds to the standard linear model $ y = a \cdot x + b $ where both transformations are identity functions. Users may supply custom transformations to define alternative linear relationships. The inverse transformation is computed using InverseFunctions.jl.
These are the convenience constructors exported by CurveFit used for defining some linear curve fitting algorithms:
CurveFit.LinearCurveFitAlgorithm — Type
LinearCurveFitAlgorithm(;
xfun = identity, yfun = identity, yfun_inverse = inverse(yfun)
)Represents a linear curve fitting algorithm where x and y are the data points to fit. If the CurveFitProblem being solved has a sigma then it will be used as weights. We want to solve for a and b such that:
\[f_y(y) = a f_x(x) + b\]
where $f_x$ corresponds to xfun and $f_y$ corresponds to yfun. Note that this is a general problem specification of a curve fitting problem which can be converted to a linear fit in a specific function space by choosing appropriate xfun and yfun. The yfun_inverse is used to convert the fitted values back to the original space (can be specified by defining InverseFunctions.inverse).
CurveFit.LogCurveFitAlgorithm — Function
LogCurveFitAlgorithm()Represents a log curve fitting algorithm where x and y are the data points to fit. If the CurveFitProblem being solved has a sigma then it will be used as weights. We want to solve for a and b such that:
\[y = a \log(x) + b\]
CurveFit.PowerCurveFitAlgorithm — Function
PowerCurveFitAlgorithm()Represents a power curve fitting algorithm where x and y are the data points to fit. This algorithm does not support passing weights through sigma in CurveFitProblem. We want to solve for a and b such that:
\[y = b x^a\]
This is equivalent to a linear fit in log-log space, i.e.,
\[\log(y) = a \log(x) + \log(b)\]
CurveFit.ExpCurveFitAlgorithm — Function
ExpCurveFitAlgorithm()Represents an exponential curve fitting algorithm where x and y are the data points to fit. This algorithm does not support passing weights through sigma in CurveFitProblem. We want to solve for a and b such that:
\[y = b \exp(a x)\]
This is equivalent to a linear fit in log-linear space, i.e.,
\[\log(y) = a x + \log(b)\]
CurveFit.KingCurveFitAlgorithm — Function
KingCurveFitAlgorithm()Represents a king curve fitting problem where x and y are the data points to fit. This algorithm does not support passing weights through sigma in CurveFitProblem. We want to solve for a and b according to original King's law (1910) that represents the relationship between voltage (E) and velocity (U) in a hotwire anemometer:
\[E^2 = A + B U^{1/2}\]
or
\[x^2 = A + B y^{1/2}\]
Nonlinear fitting
Nonlinear curve fitting problems are solved through NonlinearSolve.jl. The user defines a nonlinear problem using NonlinearCurveFitProblem, supplying a model function and an initial guess for the parameters.
During initialization, CurveFit detects nonlinear problems by checking if a model function is provided and internally constructs a NonlinearLeastSquaresProblem, which is then passed to NonlinearSolve.jl for solution. For details, see the documentation for NonlinearLeastSquaresProblem.
By default, NonlinearSolve.jl automatically selects an appropriate nonlinear least-squares algorithm. Advanced users may explicitly specify a solver, such as LevenbergMarquardt or GaussNewton. Documentation for available solvers can be found here.
For more details, see Advanced usage.
Special functions
CurveFit provides specialized algorithms for fitting selected classes of nonlinear models with known structure. These algorithms exploit problem-specific properties to improve robustness and performance compared to fully generic nonlinear least-squares approaches.
Modified King fitting
The Modified King fit algorithm is designed for the model function of the form:
\[x^2 = a + b \cdot y^n\]
Unlike the linear King fit where the exponent is a constant (1/2), n in the exponent is a coefficient and thus the problem becomes nonlinear. Since it is nonlinear solving it is done via NonlinearSolve.jl. This Modified King fit has a defined model and if the user tries to solve a problem with a specified model function using this algorithm an error will be thrown. However, the user can pass an initial guess for the coefficients a, b and n. In case an initial guess is not provided CurveFit will obtain it internally by using the related linear King fit.
CurveFit.ModifiedKingCurveFitAlgorithm — Type
ModifiedKingCurveFitAlgorithm(alg::Union{Nothing, AbstractNonlinearAlgorithm} = nothing)Similar to KingCurveFitAlgorithm, but uses the modified King's law:
\[E^2 = A + B U^n\]
where n is also a parameter.
Sum of exponentials fitting
The sum of exponentials fitting algorithm is defined for models of the form:
\[y = k + \sum_{i=1}^{n} p_i \exp(\lambda_i x)\]
The number of exponential terms is specified by the user. This method exploits the algebraic structure of exponential sums to avoid solving a nonlinear problem. By computing discrete cumulative integrals of the data, the problem is transformed into a linear recurrence whose coefficients can be estimated using linear least squares. The exponential rates (\lambda_i) are then recovered as eigenvalues of a matrix derived from this recurrence.
Once the rates are known, the amplitudes (p_i) and the optional constant term (k) are obtained by solving a linear least squares problem with fixed exponential basis functions.
For more details see here.
CurveFit.ExpSumFitAlgorithm — Type
ExpSumFitAlgorithm(; n::Int, m::Int = 1, withconst::Bool = true)Fits the sum of n exponentials and a constant. This algorithm does not support passing weights through sigma in CurveFitProblem.
\[y = k + p_1 e^{λ_1 t} + p_2 e^{λ_2 t} + ⋯ + p_n e^{λ_n t}\]
If the keyword withconst is set to false, the constant is not fitted but set k=0.
Uses numerical integration with m strips, where the default m=1 uses linear interpolation. m=2 and higher require uniform interval and usually lead to better accuracy.
This algorithm is from Matlab code of Juan Gonzales Burgos.
Polynomial fitting
Standard
Polynomial fitting solves problems of the form
\[y = \sum_{k=0}^{n} a_k x^k\]
The polynomial degree is specified by the user. The problem is formulated as a LinearProblem using a Vandermonde matrix constructed from the input data The polynomial coefficients are obtained by solving this linear system with a user-selectable linear solver.
Polynomial fitting is only applicable to linear curve fitting problems and does not support user-provided initial guesses. It is recommended to use numerically stable solvers such as QR-based factorizations. CurveFit allows the linear solver to be customized via the linsolve_algorithm field of PolynomialFitAlgorithm.
CurveFit.PolynomialFitAlgorithm — Type
PolynomialFitAlgorithm(degree::Int)
PolynomialFitAlgorithm(;
degree::Int,
linsolve_algorithm::Union{Nothing, AbstractLinearAlgorithm} = nothing
)Represents a polynomial fitting algorithm of degree degree. Only applicable to LinearCurveFitAlgorithms. This algorithm does not support passing weights through sigma in CurveFitProblem.
Rational
Rational polynomial fitting solves problems of the form
\[y = \frac{p(x)}{q(x)}\]
(p(x)) and (q(x)) are polynomials of user-specified degrees. The constant term of the denominator is assumed to be 1. Rational polynomial fitting implements both linear and nonlinear methods. RationalPolynomialFitAlgorithm has three fields, the first two are degrees of the numerator and denominator and third is the alg field which contains the algorithm used for solving the problem.
In case the user chooses a linear fit algorithm initial guesses are not supported. The problem is transformed into $y \cdot q(x) = p(x)$. This linearized problem is then solved by creating linear fit cache with LinearProblem which is then handled by the internal solver for linear rational fit of CurveFit. For more detail on Linear problemsee.
If the user chooses a nonlinear algorithm, then the problem is solved via NonlinearSolve.jl. In this case the user can provide an initial guess. If it is not provided, then CurveFit will obtain one from the linear rational fit.
CurveFit.RationalPolynomialFitAlgorithm — Type
RationalPolynomialFitAlgorithm(num_degree::Int, den_degree::Int)
RationalPolynomialFitAlgorithm(;
num_degree::Int, den_degree::Int, alg = nothing
)Represents a rational polynomial fitting algorithm with numerator degree num_degree and denominator degree den_degree. The internal polynomial fitting algorithm is determined by the alg keyword argument. If alg is nothing or a AbstractNonlinearAlgorithm (like solvers from NonlinearSolve.jl), it will use a nonlinear curve fitting approach. If alg is a AbstractLinearAlgorithm, it will use linear least squares fitting. This algorithm does not support passing weights through sigma in CurveFitProblem.
Linear Rational Polynomial Fitting
In this case the following curve fit is done:
\[y = \frac{p(x)}{q(x)}\]
where p(x) is a polynomial of degree num_degree and q(x) is a polynomial of degree den_degree. The linear case is solved by doing a least squares fit on:
\[y q(x) = p(x)\]
where the zero order term of q(x) is assumed to be 1.
Nonlinear Rational Polynomial Fitting
If an u0 is not provided to the problem, then we will use linear least squares for an initial guess.