DiffEqBase.jl
DiffEqBase.jl copied to clipboard
RFC: Add nlsolve default
This is breaking. How should we go about this? @ChrisRackauckas
A bit unfortunate that Setfield does not support updating multiple fields at a time (https://github.com/jw3126/Setfield.jl/issues/62 mentions Kaleido.jl but it seems it only provides batch lenses but no equivalent to @set!). Maybe it doesn't have any impact on performance and e.g. the compiler is smart enough and removes intermediate constructions of NLFunctional etc. instances?
Let's do it, but not today. Let's get the controller downstream fixes all green first, then make the next move.
Also, let's make sure that any changes here make sense considering what will happen to linear solvers.
If we are gonna make a breaking change, maybe we should change max_iter to maxiters to be consistant?
Maybe it doesn't have any impact on performance and e.g. the compiler is smart enough and removes intermediate constructions of NLFunctional etc. instances?
Yes, Julia is smart enough to not construct and destruct the struct multiple times.
julia> @code_typed debuginfo=:none DiffEqBase.handle_defaults(1, NLNewton())
CodeInfo(
1 ── %1 = invoke Base.divgcd(1::Int64, 100::Int64)::Tuple{Int64, Int64}
│ %2 = Base.getfield(%1, 1)::Int64
│ %3 = Base.getfield(%1, 2)::Int64
│ %4 = Base.slt_int(%3, 0)::Bool
└─── goto #5 if not %4
2 ── %6 = Base.neg_int(%3)::Int64
│ %7 = Base.slt_int(%6, 0)::Bool
└─── goto #4 if not %7
3 ── invoke Base.__throw_rational_argerror_typemin(Int64::Type)::Union{}
└─── unreachable
4 ── %11 = Base.neg_int(%2)::Int64
5 ┄─ %12 = φ (#4 => %11, #1 => %2)::Int64
│ %13 = φ (#4 => %6, #1 => %3)::Int64
│ %14 = %new(Rational{Int64}, %12, %13)::Rational{Int64}
└─── goto #6
6 ── goto #7
7 ── goto #8
8 ── goto #9
9 ── goto #10
10 ─ %20 = invoke Base.divgcd(1::Int64, 5::Int64)::Tuple{Int64, Int64}
│ %21 = Base.getfield(%20, 1)::Int64
│ %22 = Base.getfield(%20, 2)::Int64
│ %23 = Base.slt_int(%22, 0)::Bool
└─── goto #14 if not %23
11 ─ %25 = Base.neg_int(%22)::Int64
│ %26 = Base.slt_int(%25, 0)::Bool
└─── goto #13 if not %26
12 ─ invoke Base.__throw_rational_argerror_typemin(Int64::Type)::Union{}
└─── unreachable
13 ─ %30 = Base.neg_int(%21)::Int64
14 ┄ %31 = φ (#13 => %30, #10 => %21)::Int64
│ %32 = φ (#13 => %25, #10 => %22)::Int64
│ %33 = %new(Rational{Int64}, %31, %32)::Rational{Int64}
└─── goto #15
15 ─ goto #16
16 ─ goto #17
17 ─ goto #18
18 ─ goto #19
19 ─ %39 = invoke Base.divgcd(1::Int64, 5::Int64)::Tuple{Int64, Int64}
│ %40 = Base.getfield(%39, 1)::Int64
│ %41 = Base.getfield(%39, 2)::Int64
│ %42 = Base.slt_int(%41, 0)::Bool
└─── goto #23 if not %42
20 ─ %44 = Base.neg_int(%41)::Int64
│ %45 = Base.slt_int(%44, 0)::Bool
└─── goto #22 if not %45
21 ─ invoke Base.__throw_rational_argerror_typemin(Int64::Type)::Union{}
└─── unreachable
22 ─ %49 = Base.neg_int(%40)::Int64
23 ┄ %50 = φ (#22 => %49, #19 => %40)::Int64
│ %51 = φ (#22 => %44, #19 => %41)::Int64
│ %52 = %new(Rational{Int64}, %50, %51)::Rational{Int64}
└─── goto #24
24 ─ goto #25
25 ─ goto #26
26 ─ goto #27
27 ─ goto #28
28 ─ %58 = %new(NLNewton{Rational{Int64}, Int64, Rational{Int64}, Rational{Int64}}, %14, 10, %33, %52)::NLNewton{Rational{Int64}, Int64, Rational{Int64}, Rational{Int64}}
└─── return %58
) => NLNewton{Rational{Int64}, Int64, Rational{Int64}, Rational{Int64}}
Note that there's only one NLNewton constructor call.
If we are gonna make a breaking change, maybe we should change max_iter to maxiters to be consistant?
Yes