Using levenberg

To solve a nonlinear system, we need to code only the function defining the system (residual vector), and not its Jacobian.

using FundamentalsNumericalComputation
function nlsystem(x)
    return [ 
        exp(x[2]-x[1]) - 2,
        x[1]*x[2] + x[3],
        x[2]*x[3] + x[1]^2 - x[2]
        ]
end
nlsystem (generic function with 1 method)

In all other respects usage is the same as for the newtonsys function.

x1 = [0,0,0]   
x = FNC.levenberg(nlsystem,x1)
12-element Array{Array{Float64,1},1}:
 [0.0, 0.0, 0.0]
 [-0.08396946555420857, 0.07633587776621241, 0.0]
 [-0.4220507601545548, 0.21991260524972361, 0.012997569767382334]
 [-0.48610710902101084, 0.21389682964709655, 0.0977187252071678]
 [-0.45628390779216876, 0.2421104774129355, 0.10100440266654645]
 [-0.45563883362225116, 0.23470443539126568, 0.108546657255663]
 [-0.4583961451217119, 0.23530956863847285, 0.10739828072313906]
 [-0.4580434038157383, 0.23512124061139036, 0.10768079583181711]
 [-0.4580333258441392, 0.23511390840122376, 0.1076899804953973]
 [-0.45803327880719313, 0.23511389867393445, 0.10768999250671268]
 [-0.45803328056019965, 0.23511389986307896, 0.107689990975689]
 [-0.458033280641234, 0.2351138999186528, 0.10768999090414473]

It’s always a good idea to check the accuracy of the root, by measuring the residual (backward error).

r = x[end]
@show backward_err = norm(nlsystem(r));
backward_err = norm(nlsystem(r)) = 1.2708308198538738e-13

Looking at the convergence of the first component, we find a subquadratic convergence rate, just as with the secant method.

[ log(norm(x[k]-r)) for k in 1:length(x)-1 ]
11-element Array{Float64,1}:
  -0.642464608920046
  -0.8665622983300257
  -2.278548436446176
  -3.3083905468408217
  -4.621899500113314
  -5.961582353290289
  -7.590899766347262
 -11.073290988317947
 -16.86982474417951
 -19.71706564311687
 -22.830722547915087