Generate Code for fsolve

This example shows how to generate C code for solving systems of nonlinear equations with fsolve.

Equation to Solve

The system of nonlinear equations to solve is

$\begin{array}{c}{e}^{-{e}^{-\left({x}_{1}+{x}_{2}\right)}}={x}_{2}\left(1+{x}_{1}^{2}\right)\\ {x}_{1}\mathrm{cos}\left({x}_{2}\right)+{x}_{2}\mathrm{sin}\left({x}_{1}\right)=\frac{1}{2}.\end{array}$

Convert the equations to the form F(x) = 0.

$\begin{array}{c}{e}^{-{e}^{-\left({x}_{1}+{x}_{2}\right)}}-{x}_{2}\left(1+{x}_{1}^{2}\right)=0\\ {x}_{1}\mathrm{cos}\left({x}_{2}\right)+{x}_{2}\mathrm{sin}\left({x}_{1}\right)-\frac{1}{2}=0.\end{array}$

Code Generation Steps

1. Write a function that computes the left side of the two equations. For code generation, your program must allocate all arrays when they are created, and must not change their sizes after creation.

function F = root2d(x)
F = zeros(2,1); % Allocate return array
F(1) = exp(-exp(-(x(1)+x(2)))) - x(2)*(1+x(1)^2);
F(2) = x(1)*cos(x(2)) + x(2)*sin(x(1)) - 0.5;
end
2. Write a function that sets up the problem and calls fsolve. The function must refer to root2d as a function handle, not as a name.

function [x,fval] = solveroot
options = optimoptions('fsolve','Algorithm','levenberg-marquardt','Display','off');
fun = @root2d;
rng default
x0 = rand(2,1);
[x,fval] = fsolve(fun,x0,options);
end
3. Create a configuration for code generation. In this case, use 'mex'.

cfg = coder.config('mex');
4. Generate code for the solveroot function.

codegen -config cfg solveroot
5. Test the generated code by running the generated file, which is named solveroot_mex.mexw64 or similar.

[x,fval] = solveroot_mex
x =

0.3532
0.6061

fval =

1.0e-14 *

-0.1998
-0.1887