## Generate Code for `lsqcurvefit` or `lsqnonlin`

This example shows how to generate C code for nonlinear least squares.

### Data and Model for Least Squares

In this example, the vector `xdata` represents 100 data points, and the vector `ydata` represents the associated measurements. The modeled relationship between `xdata` and `ydata` is

`${\text{ydata}}_{i}={a}_{1}+{a}_{2}\mathrm{exp}\left(-{a}_{3}{\text{xdata}}_{i}\right)+{\epsilon }_{i}.$`

Generate the data for the problem.

```rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata);```

The code generates `xdata` from 100 independent samples of an exponential distribution with mean 2. The code generates `ydata` from its defining equation using `a = [1;3;2]`, perturbed by adding normal deviates with standard deviations `[0.1;0.5;0.5]`.

### Solve Generating Code for `lsqcurvefit`

#### Solver Approach

The goal is to find parameters for the model ${\stackrel{^}{a}}_{i}$, i = 1, 2, 3 that best fit the data.

To fit the parameters to the data using `lsqcurvefit`, you need to define a fitting function. For `lsqcurvefit`, the fitting function takes a parameter vector `a` and the data `xdata` and returns a prediction of the response, which should be equal to `ydata` with no noise and a perfect model. Define the fitting function `predicted` as an anonymous function.

`predicted = @(a,xdata) a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata);`

To fit the model to the data, `lsqcurvefit` needs an initial estimate `a0` of the parameters.

`a0 = [2;2;2];`

Call `lsqcurvefit` to find the best-fitting parameters ${\stackrel{^}{a}}_{i}$.

```[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =... lsqcurvefit(predicted,a0,xdata,ydata);```

#### Code Generation Approach

To solve the same problem using code generation, complete the following steps.

1. Write a function that incorporates all of the previous steps: generate data, create a fitting function, create an initial point, and call `lsqcurvefit`.

```function [x,res] = solvelsqcurve rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata); predicted = @(a,xdata) a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata); options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt','Display','off'); a0 = [2;2;2]; lb = []; ub = []; [x,res] = lsqcurvefit(predicted,a0,xdata,ydata,lb,ub,options); end```
2. Create a configuration for code generation. In this case, use `'mex'`.

`cfg = coder.config('mex');`
3. Generate code for the `solvelsqcurve` function.

`codegen -config cfg solvelsqcurve`
4. Test the generated code by running the generated file, which is named `solvelsqcurve_mex.mexw64` or similar.

`[x,res] = solvelsqcurve_mex`
```x = 1.0169 3.1444 2.1596 res = 7.4101```

### Solve Generating Code for `lsqnonlin`

#### Solver Approach

The goal is to find parameters for the model ${\stackrel{^}{a}}_{i}$, i = 1, 2, 3 that best fit the data.

To fit the parameters to the data using `lsqnonlin`, you need to define a fitting function. For `lsqnonlin`, the fitting function takes a parameter vector `a`, the data `xdata`, and the data `ydata`. The fitting function returns the difference between the prediction of a response and the data `ydata`, which should equal 0 with no noise and a perfect model. Define the fitting function `predicted` as an anonymous function.

`predicted = @(a)(a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata) - ydata)`

To fit the model to the data, `lsqnonlin` needs an initial estimate `a0` of the parameters.

`a0 = [2;2;2];`

Call `lsqnonlin` to find the best-fitting parameters ${\stackrel{^}{a}}_{i}$.

```[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =... lsqnonlin(predicted,a0);```

#### Code Generation Approach

To solve the same problem using code generation, complete the following steps.

1. Write a function that incorporates all of the previous steps: generate data, create a fitting function, create an initial point, and call `lsqnonlin`.

```function [x,res] = solvelsqnon rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata); predicted = @(a) (a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata) - ydata); options = optimoptions('lsqnonlin','Algorithm','levenberg-marquardt','Display','off'); a0 = [2;2;2]; lb = []; ub = []; [x,res] = lsqnonlin(predicted,a0,lb,ub,options); end```
2. Create a configuration for code generation. In this case, use `'mex'`.

`cfg = coder.config('mex');`
3. Generate code for the `solvelsqnon` function.

`codegen -config cfg solvelsqnon`
4. Test the generated code by running the generated file, which is named `solvelsqnon_mex.mexw64` or similar.

`[x,res] = solvelsqnon_mex`
```x = 1.0169 3.1444 2.1596 res = 7.4101```

The solution is identical to the one generated by `solvelsqcurve_mex` because the solvers have identical underlying algorithms. So, you can use the solver you find most convenient.