# Porting from Python optimize.broyden2

**URL:** <https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874>\
**Category:** General Usage\
**Tags:** question, optimization\
**Created:** [May 29, 2022, 5:09pm UTC](https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874 "2022-05-29T17:09:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 29, 2022, 5:09pm UTC](https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874/1 "2022-05-29T17:09:56Z")

</div>

Still porting code from Python… What is a good alternative to the `optimize.broyden2` solver from SciPy?

[https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.broyden2.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.broyden2.html)

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 29, 2022, 5:53pm UTC](https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874/2 "2022-05-29T17:53:21Z")

</div>

FastDEQ.jl has a nice Broyden implementation. @avikpal we really should move it to NonlinearSolve.jl soon 😅 .

[https://fastdeq.sciml.ai/dev/api/nlsolve/](https://fastdeq.sciml.ai/dev/api/nlsolve/)

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 29, 2022, 7:32pm UTC](https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874/3 "2022-05-29T19:32:03Z")

</div>

For now I just use NLsove:

```julia
# from scipy import optimize

# def fun(x):
# return [x[0] + 0.5 * (x[0] - x[1])**3 - 1.0, 0.5 * (x[1] - x[0])**3 + x[1]]
    
# def test_broyden2():
# sol = optimize.broyden2(fun, [0, 0])
# print(sol)
    
# test_broyden2()
# Output: [0.84116365 0.15883529], needs 10 iterations
# time for executing test_broyden2() loop in µs: 1276

using NLsolve

function fun!(F, x)
    F[1] = x[1] + 0.5 * (x[1] - x[2])^3 - 1.0
    F[2] = 0.5 * (x[2] - x[1])^3 + x[2]
end

function test_broyden2()
    sol = nlsolve(fun!, [0.0; 0.0])
    sol.zero
end
# execution time: 5 µs, 255 times faster than Python

```

In this example it needs 5 iteration where Python needs 10…

And 255 times faster than Python…

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 29, 2022, 9:56pm UTC](https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874/4 "2022-05-29T21:56:55Z")

</div>

And here you go, I made it 50x faster (100 ns)

```julia
using NonlinearSolve, StaticArrays, BenchmarkTools

function fun(x, p)
    SA[x[1] + 0.5 * (x[1] - x[2])^3 - 1.0,
     0.5 * (x[2] - x[1])^3 + x[2]]
end

function test_nr()
    prob = NonlinearProblem{false}(fun,SA[0.0; 0.0])
    sol = solve(prob, NewtonRaphson())
    sol.u
end

@btime test_nr() # 106.760 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 30, 2022, 4:10am UTC](https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874/5 "2022-05-30T04:10:24Z")

</div>

I already wanted to ask if there is a non-allocating way of doing this. You have been faster than me!

But what about stability? I mean, my real problems are more complex.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 30, 2022, 4:35am UTC](https://discourse.julialang.org/t/porting-from-python-optimize-broyden2/81874/6 "2022-05-30T04:35:23Z")

</div>

> [@ufechner7](#):
>
> But what about stability? I mean, my real problems are more complex.

It’s a Newton-Rhapson, no trust region or line searches in that implementation. But NonlinearSolve is a uniform interface over all of the algorithms we could find, so

[https://nonlinearsolve.sciml.ai/dev/solvers/NonlinearSystemSolvers/#SciMLNLSolve.jl](https://nonlinearsolve.sciml.ai/dev/solvers/NonlinearSystemSolvers/#SciMLNLSolve.jl)

there’s MINPACK and NLsolve in the interface, which could be used until other implementations are added. The optimal algorithm will likely depend on the problem and we still need to do more benchmarking before really knowing the lay of the land here.
