@@ -43,11 +43,13 @@ export ode23, ode4, ode45, ode4s, ode4ms
43
43
# Initialize variables.
44
44
# Adapted from Cleve Moler's textbook
45
45
# http://www.mathworks.com/moler/ncm/ode23tx.m
46
- function ode23 {T} (F:: Function , tspan:: AbstractVector , y0:: AbstractVector{T} )
46
+ function ode23 {T} (F:: Function , tspan:: AbstractVector , y0:: AbstractVector{T} ; reltol = 1.e-5 , abstol = 1.e-8 )
47
47
48
- rtol = 1.e-5
49
- atol = 1.e-8
50
- threshold = atol / rtol
48
+ if reltol == 0
49
+ warn (" setting reltol = 0 gives a step size of zero" )
50
+ end
51
+
52
+ threshold = abstol / reltol
51
53
52
54
t = tspan[1 ]
53
55
tfinal = tspan[end ]
@@ -64,7 +66,7 @@ function ode23{T}(F::Function, tspan::AbstractVector, y0::AbstractVector{T})
64
66
65
67
s1 = F (t, y)
66
68
r = norm (s1./ max (abs (y), threshold), Inf ) + realmin () # TODO : fix type bug in max()
67
- h = tdir* 0.8 * rtol ^ (1 / 3 )/ r
69
+ h = tdir* 0.8 * reltol ^ (1 / 3 )/ r
68
70
69
71
# The main loop.
70
72
@@ -95,7 +97,7 @@ function ode23{T}(F::Function, tspan::AbstractVector, y0::AbstractVector{T})
95
97
96
98
# Accept the solution if the estimated error is less than the tolerance.
97
99
98
- if err <= rtol
100
+ if err <= reltol
99
101
t = tnew
100
102
y = ynew
101
103
tout = [tout; t]
@@ -105,7 +107,7 @@ function ode23{T}(F::Function, tspan::AbstractVector, y0::AbstractVector{T})
105
107
106
108
# Compute a new step size.
107
109
108
- h = h* min (5 , 0.8 * (rtol / err)^ (1 / 3 ))
110
+ h = h* min (5 , 0.8 * (reltol / err)^ (1 / 3 ))
109
111
110
112
# Exit early if step size is too small.
111
113
@@ -178,8 +180,8 @@ end # ode23
178
180
179
181
# created : 06 October 1999
180
182
# modified: 17 January 2001
181
- function oderkf {T} (F :: Function , tspan :: AbstractVector , x0 :: AbstractVector{T} , a, b4, b5)
182
- tol = 1.0e-5
183
+
184
+ function oderkf {T} (F :: Function , tspan :: AbstractVector , x0 :: AbstractVector{T} , a, b4, b5; reltol = 1.0e-5 , abstol = 1.0e-8 )
183
185
184
186
# see p.91 in the Ascher & Petzold reference for more infomation.
185
187
pow = 1 / 5
@@ -218,8 +220,8 @@ function oderkf{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, a,
218
220
gamma1 = x5 - x4
219
221
220
222
# Estimate the error and the acceptable error
221
- delta = norm (gamma1, Inf ) # actual error
222
- tau = tol * max (norm (x,Inf ), 1.0 ) # allowable error
223
+ delta = norm (gamma1, Inf ) # actual error
224
+ tau = max (reltol * norm (x,Inf ),abstol ) # allowable error
223
225
224
226
# Update the solution only if the error is acceptable
225
227
if delta <= tau
@@ -271,7 +273,7 @@ const dp_coefficients = ([ 0 0 0 0 0
271
273
# 5th order b-coefficients
272
274
[35 / 384 0 500 / 1113 125 / 192 - 2187 / 6784 11 / 84 0 ],
273
275
)
274
- ode45_dp (F, tspan, x0) = oderkf (F, tspan, x0, dp_coefficients... )
276
+ ode45_dp (F, tspan, x0; kwargs ... ) = oderkf (F, tspan, x0, dp_coefficients... ; kwargs ... )
275
277
276
278
# Fehlberg coefficients
277
279
const fb_coefficients = ([ 0 0 0 0 0
@@ -285,7 +287,7 @@ const fb_coefficients = ([ 0 0 0 0 0
285
287
# 5th order b-coefficients
286
288
[16 / 135 0 6656 / 12825 28561 / 56430 - 9 / 50 2 / 55 ],
287
289
)
288
- ode45_fb (F, tspan, x0) = oderkf (F, tspan, x0, fb_coefficients... )
290
+ ode45_fb (F, tspan, x0; kwargs ... ) = oderkf (F, tspan, x0, fb_coefficients... ; kwargs ... )
289
291
290
292
# Cash-Karp coefficients
291
293
# Numerical Recipes in Fortran 77
@@ -300,7 +302,7 @@ const ck_coefficients = ([ 0 0 0 0 0
300
302
# 5th order b-coefficients
301
303
[2825 / 27648 0 18575 / 48384 13525 / 55296 277 / 14336 1 / 4 ],
302
304
)
303
- ode45_ck (F, tspan, x0) = oderkf (F, tspan, x0, ck_coefficients... )
305
+ ode45_ck (F, tspan, x0; kwargs ... ) = oderkf (F, tspan, x0, ck_coefficients... ; kwargs ... )
304
306
305
307
# Use Dormand Prince version of ode45 by default
306
308
const ode45 = ode45_dp
0 commit comments