Newton + LineSearch in Hot Loop: Reduce allocations

I really like the NLsolve.jl package in conjunction with LineSearches.jl - great stuff!

I have a scalar, relatively simple nonlinear equation that I can solve using

res = nlsolve(gamma -> f(gamma[1], bla, bla, bla),
              gamma -> j(gamma[1], bla, bla, bla),
              [gamma], method = :newton,  ftol = 2 * eps(RealT), iterations = 20,
              linesearch = LineSearches.BackTracking(order=3))
gamma = res.zero[1]

which works really well.
The issue is, however, that I get a couple allocations whenever I call this. Is there any way to reduce these by e.g. initalizing the problem once and then updating it later?

The functions f and g stay constant over time, although their arguments bla change over time.

Xref: Newton + LineSearch in Hot Loop: Reduce allocations · Issue #290 · JuliaNLSolvers/NLsolve.jl · GitHub

If you use NonlinearSolve.jl there are a couple of options:

  1. Use SimpleNonlinearSolve Code Optimization for Small Nonlinear Systems in Julia · NonlinearSolve.jl that will pretty much outperform most solvers for scalar/static arrays problems
  2. Use the caching interface of cache = init(....) and inside the loop first do reinit!(cache; p = <bla, bla, bla>) and then solve!(cache)
3 Likes

Thanks for your swift response! Does NonlinearSolve.jl also support LineSearches? These are quite vital to speed up the Newton procedure.

Yes. You can use any LineSearches algorithm via LineSearches.jl · LineSearch.jl. There’s also Native Functionalities · LineSearch.jl

Okay, one more thing: It seems to be not as trivial to set the Jacobian by hand (I cannot resort to AD). I found this post but unfortunately NonlinearSolve.jl still tries to compute the Jacobian using AD.

NonlinearFunction(f; jac = ...)

1 Like

Xref: NonlinearSolve uses AD Jacobian even when I specify it analytically - #3 by DanDoe