Skip to content

Commit 038f21e

Browse files
committed
Modified Muller to be an IntervalNonlinearProblem
1 parent 69ba15c commit 038f21e

File tree

5 files changed

+68
-66
lines changed

5 files changed

+68
-66
lines changed

lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ include("bisection.jl")
1717
include("brent.jl")
1818
include("falsi.jl")
1919
include("itp.jl")
20+
include("muller.jl")
2021
include("ridder.jl")
2122

2223
# Default Algorithm
@@ -44,6 +45,6 @@ end
4445

4546
@reexport using SciMLBase, NonlinearSolveBase
4647

47-
export Alefeld, Bisection, Brent, Falsi, ITP, Ridder
48+
export Alefeld, Bisection, Brent, Falsi, Muller, ITP, Ridder
4849

4950
end

lib/SimpleNonlinearSolve/src/muller.jl lib/BracketingNonlinearSolve/src/muller.jl

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
"""
2-
SimpleMuller()
2+
Muller()
33
44
Muller's method for determining a root of a univariate, scalar function. The
55
algorithm, described in Sec. 9.5.2 of
66
[Press et al. (2007)](https://numerical.recipes/book.html), requires three
77
initial guesses `(xᵢ₋₂, xᵢ₋₁, xᵢ)` for the root.
88
"""
9-
struct SimpleMuller <: AbstractSimpleNonlinearSolveAlgorithm end
9+
struct Muller <: AbstractBracketingAlgorithm end
1010

11-
function SciMLBase.solve(prob::NonlinearProblem, alg::SimpleMuller, args...;
12-
abstol = 1e-3, maxiters = 1000, kwargs...)
13-
@assert !isinplace(prob) "`SimpleMuller` only supports OOP problems."
14-
@assert length(prob.u0) == 3 "`SimpleMuller` requires three initial guesses."
15-
xᵢ₋₂, xᵢ₋₁, xᵢ = prob.u0
11+
function CommonSolve.solve(prob::IntervalNonlinearProblem, alg::Muller, args...;
12+
abstol = nothing, maxiters = 1000, kwargs...)
13+
@assert !SciMLBase.isinplace(prob) "`Muller` only supports out-of-place problems."
14+
xᵢ₋₂, xᵢ = prob.tspan
15+
xᵢ₋= (xᵢ₋+ xᵢ) / 2 # Use midpoint for middle guess
1616
xᵢ₋₂, xᵢ₋₁, xᵢ = promote(xᵢ₋₂, xᵢ₋₁, xᵢ)
1717
@assert xᵢ₋₂ xᵢ₋₁ xᵢ xᵢ₋₂
1818
f = Base.Fix2(prob.f, prob.p)
1919
fxᵢ₋₂, fxᵢ₋₁, fxᵢ = f(xᵢ₋₂), f(xᵢ₋₁), f(xᵢ)
2020

2121
xᵢ₊₁, fxᵢ₊₁ = xᵢ₋₂, fxᵢ₋₂
2222

23+
abstol = NonlinearSolveBase.get_tolerance(
24+
xᵢ₋₂, abstol, promote_type(eltype(xᵢ₋₂), eltype(xᵢ)))
25+
2326
for _ 1:maxiters
2427
q = (xᵢ - xᵢ₋₁)/(xᵢ₋₁ - xᵢ₋₂)
2528
A = q*fxᵢ - q*(1 + q)*fxᵢ₋₁ + q^2*fxᵢ₋₂
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
@testitem "Muller" begin
2+
@testset "Quadratic function" begin
3+
f(u, p) = u^2 - p
4+
5+
tspan = (10.0, 30.0)
6+
p = 612.0
7+
prob = IntervalNonlinearProblem{false}(f, tspan, p)
8+
sol = solve(prob, Muller())
9+
10+
@test sol.u 612
11+
12+
tspan = (-10.0, -30.0)
13+
prob = IntervalNonlinearProblem{false}(f, tspan, p)
14+
sol = solve(prob, Muller())
15+
16+
@test sol.u -√612
17+
end
18+
19+
@testset "Sine function" begin
20+
f(u, p) = sin(u)
21+
22+
tspan = (1.0, 3.0)
23+
prob = IntervalNonlinearProblem{false}(f, tspan)
24+
sol = solve(prob, Muller())
25+
26+
@test sol.u π
27+
28+
tspan = (2.0, 6.0)
29+
prob = IntervalNonlinearProblem{false}(f, tspan)
30+
sol = solve(prob, Muller())
31+
32+
@test sol.u 2*π
33+
end
34+
35+
@testset "Exponential-sine function" begin
36+
f(u, p) = exp(-u)*sin(u)
37+
38+
tspan = (-2.0, -4.0)
39+
prob = IntervalNonlinearProblem{false}(f, tspan)
40+
sol = solve(prob, Muller())
41+
42+
@test sol.u -π
43+
44+
tspan = (-3.0, 1.0)
45+
prob = IntervalNonlinearProblem{false}(f, tspan)
46+
sol = solve(prob, Muller())
47+
48+
@test sol.u 0 atol = 1e-15
49+
50+
tspan = (-1.0, 1.0)
51+
prob = IntervalNonlinearProblem{false}(f, tspan)
52+
sol = solve(prob, Muller())
53+
54+
@test sol.u π
55+
end
56+
end

lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl

-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ include("klement.jl")
5454
include("lbroyden.jl")
5555
include("raphson.jl")
5656
include("trust_region.jl")
57-
include("muller.jl")
5857

5958
# By Pass the highlevel checks for NonlinearProblem for Simple Algorithms
6059
function CommonSolve.solve(
@@ -167,7 +166,6 @@ export SimpleBroyden, SimpleKlement, SimpleLimitedMemoryBroyden
167166
export SimpleDFSane
168167
export SimpleGaussNewton, SimpleNewtonRaphson, SimpleTrustRegion
169168
export SimpleHalley
170-
export SimpleMuller
171169

172170
export solve
173171

lib/SimpleNonlinearSolve/test/core/muller_tests.jl

-56
This file was deleted.

0 commit comments

Comments
 (0)