# lsqcurvefit

Find the equation parameters that produce the least squares best fit to a data set.

## Syntax

x = lsqcurvefit(@func,x0,xdata,ydata)

x = lsqcurvefit(@func,x0,xdata,ydata,lb,ub)

x = lsqcurvefit(@func,x0,xdata,ydata,lb,ub,options)

[x,resnorm,residual,exitflag,output] = lsqcurvefit(...)

## Inputs

`func`- The function of system residuals. See the optimset option Jacobian for details.
`x0`- An estimate of the best fit parameters.
`xdata`- The domain values for which the best fit is performed. If the domain is multivariate
then each variable is stored in
`xdata`by column. `ydata`- The range values for which the best fit is performed.
`lb`- The fitting parameter lower bounds.
`ub`- The fitting parameter upper bounds.
`options`- A struct containing option settings.

## Outputs

- x
- The best fit parameters.
- resnorm
- The squared length of the residuals vector.
- residual
- The residuals vector.
- info
- The convergence status flag.
- info = 4
- Relative step size converged to within tolX.
- info = 3
- Relative function value converged to within tolFun.
- info = 2
- Step size converged to within tolX.
- info = 1
- Function value converged to within tolFun.
- info = 0
- Reached maximum number of iterations or function calls, or the algorithm aborted because it was not converging.
- info = -3
- Trust region became too small to continue.

- output
- A struct containing iteration details. The members are as follows:
- iterations
- The number of iterations.
- nfev
- The number of function evaluations.
- xiter
- The candidate solution at each iteration.
- resnormiter
- The objective function value at each iteration.

## Examples

```
function y = FittingFunc(p, x)
y = p(1) * exp(-p(2)*x);
end
x = [1; 2; 3; 4];
y = [8.025, 3.975, 2.025, 0.975];
p0 = [15; 1];
[p,res] = lsqcurvefit(@FittingFunc,p0,x,y)
```

```
p = [Matrix] 2 x 1
16.09850
0.69669
res = 0.00190995097
```

```
function y = FittingFunc(p, x, offset)
y = p(1) * exp(-p(2)*x) + offset;
end
handle = @(x, p) FittingFunc(x, p, 2);
[p,res] = lsqcurvefit(handle,p0,x,y+2)
```

```
p = [Matrix] 2 x 1
16.09850
0.69669
res = 0.00190995097
```

`[p,res] = lsqcurvefit(@FittingFunc,p0,x,y,[10,0.7],[16.2,2])`

```
p = [Matrix] 2 x 1
16.16859
0.70000
resnorm = 0.00226086103
```

## Comments

lsqcurvefit uses a modified Gauss-Netwon algorithm with a trust region method. Bounds are supported with the addition of an affine scaling method drawn from the following sources.

- Francisco, J.B., N. Krejic, M. Martínez. 2005. "An interior-point method for solving
box-constrained underdetermined nonlinear systems."
*Journal of Computational and Applied Mathematics*177, no. 1: 67-88. https://doi.org/10.1016/j.cam.2004.08.013 - Bellavia, Stefania, Maria Macconi, Sandra Pieraccini. 2012. "Constrained Dogleg Methods
for nonlinear systems with simple bounds."
*Computational Optimization and Applications*53, 771-794 https://doi.org/10.1007/s10589-012-9469-8 - Klug, Andreas. 2006. "Affine-Scaling Methods for Nonlinear Minimization Problems and Nonlinear Systems of Equations with Bound Constraints" PhD Dissertation, Bavarian Julius Maximilians University, Wurzburg https://opus.bibliothek.uni-wuerzburg.de/opus4-wuerzburg/frontdoor/deliver/index/docId/1628/file/thesis.pdf

Options for convergence tolerance controls and analytical derivatives are specified with optimset.

To pass additional parameters to a function argument, use an anonymous function.

When using `lb` or `ub` with unbounded variables, use or +/-inf rather than
arbitrarily large +/- numeric values. Large numeric bound ranges will degrade the performance of the function.

- MaxIter: 400
- MaxFunEvals: 1,000,000
- TolFun: 1.0e-7
- TolX: 1.0e-7
- Jacobian: 'off'
- Display: 'off'