@@ -43,8 +43,7 @@ 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} ; reltol = 1.e-5 , abstol = 1.e-8 )
47
-
46
+ function ode23 (F, tspan, y0; reltol = 1.e-5 , abstol = 1.e-8 )
48
47
if reltol == 0
49
48
warn (" setting reltol = 0 gives a step size of zero" )
50
49
end
@@ -58,7 +57,8 @@ function ode23{T}(F::Function, tspan::AbstractVector, y0::AbstractVector{T}; rel
58
57
y = y0
59
58
60
59
tout = t
61
- yout = y.'
60
+ yout = Array (typeof (y0),1 )
61
+ yout[1 ] = y
62
62
63
63
tlen = length (t)
64
64
@@ -101,7 +101,7 @@ function ode23{T}(F::Function, tspan::AbstractVector, y0::AbstractVector{T}; rel
101
101
t = tnew
102
102
y = ynew
103
103
tout = [tout; t]
104
- yout = [yout; y .' ]
104
+ push! ( yout, y)
105
105
s1 = s4 # Reuse final function value to start new step
106
106
end
107
107
@@ -118,7 +118,7 @@ function ode23{T}(F::Function, tspan::AbstractVector, y0::AbstractVector{T}; rel
118
118
119
119
end # while (t != tfinal)
120
120
121
- return ( tout, yout)
121
+ return tout, yout
122
122
123
123
end # ode23
124
124
@@ -180,9 +180,7 @@ end # ode23
180
180
181
181
# created : 06 October 1999
182
182
# modified: 17 January 2001
183
-
184
- function oderkf {T} (F:: Function , tspan:: AbstractVector , x0:: AbstractVector{T} , a, b4, b5; reltol = 1.0e-5 , abstol = 1.0e-8 )
185
-
183
+ function oderkf (F, tspan, x0, a, b4, b5; reltol = 1.0e-5 , abstol = 1.0e-8 )
186
184
# see p.91 in the Ascher & Petzold reference for more infomation.
187
185
pow = 1 / 5
188
186
@@ -196,25 +194,26 @@ function oderkf{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, a,
196
194
h = (tfinal - t)/ 100 # initial guess at a step size
197
195
x = x0
198
196
tout = t # first output time
199
- xout = x.' # first output solution
197
+ xout = Array (typeof (x0), 1 )
198
+ xout[1 ] = x # first output solution
200
199
201
- k = zeros ( eltype (x ), length (c), length (x ))
202
- k[1 ,: ] = F (t,x) # first stage
200
+ k = Array ( typeof (x0 ), length (c))
201
+ k[1 ] = F (t,x) # first stage
203
202
204
203
while t < tfinal && h >= hmin
205
204
if t + h > tfinal
206
205
h = tfinal - t
207
206
end
208
207
209
208
for j = 2 : length (c)
210
- k[j,: ] = F (t + h.* c[j], x + h.* (a[j,1 : j- 1 ]* k[1 : j- 1 ,:]) .' )
209
+ k[j] = F (t + h.* c[j], x + h.* (a[j,1 : j- 1 ]* k[1 : j- 1 ])[ 1 ] )
211
210
end
212
211
213
212
# compute the 4th order estimate
214
- x4 = x + h.* (b4* k).'
213
+ x4 = x + h.* (b4* k)[ 1 ]
215
214
216
215
# compute the 5th order estimate
217
- x5 = x + h.* (b5* k).'
216
+ x5 = x + h.* (b5* k)[ 1 ]
218
217
219
218
# estimate the local truncation error
220
219
gamma1 = x5 - x4
@@ -228,7 +227,7 @@ function oderkf{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, a,
228
227
t = t + h
229
228
x = x5 # <-- using the higher order estimate is called 'local extrapolation'
230
229
tout = [tout; t]
231
- xout = [xout; x .' ]
230
+ push! ( xout, x)
232
231
233
232
# Compute the slopes by computing the k[:,j+1]'th column based on the previous k[:,1:j] columns
234
233
# notes: k needs to end up as an Nxs, a is 7x6, which is s by (s-1),
@@ -238,9 +237,9 @@ function oderkf{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, a,
238
237
# This is part of the Dormand-Prince pair caveat.
239
238
# k[:,7] has already been computed, so use it instead of recomputing it
240
239
# again as k[:,1] during the next step.
241
- k[1 ,: ] = k[end ,: ]
240
+ k[1 ] = k[end ]
242
241
else
243
- k[1 ,: ] = F (t,x) # first stage
242
+ k[1 ] = F (t,x) # first stage
244
243
end
245
244
end
246
245
@@ -252,7 +251,7 @@ function oderkf{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, a,
252
251
println (" Step size grew too small. t=" , t, " , h=" , h, " , x=" , x)
253
252
end
254
253
255
- return ( tout, xout)
254
+ return tout, xout
256
255
end
257
256
258
257
# Both the Dormand-Prince and Fehlberg 4(5) coefficients are from a tableau in
@@ -316,59 +315,65 @@ const ode45 = ode45_dp
316
315
# ODEFUN(T,X) must return a column vector corresponding to f(t,x). Each
317
316
# row in the solution array X corresponds to a time returned in the
318
317
# column vector T.
319
- function ode4 {T} (F :: Function , tspan:: AbstractVector , x0:: AbstractVector{T} )
318
+ function ode4 (F , tspan, x0)
320
319
h = diff (tspan)
321
- x = Array (T, length (tspan ), length (x0 ))
322
- x[1 ,: ] = x0
320
+ x = Array (typeof (x0 ), length (tspan ))
321
+ x[1 ] = x0
323
322
324
- midxdot = Array (T, 4 , length (x0))
323
+ midxdot = Array (typeof (x0), 4 )
325
324
for i = 1 : length (tspan)- 1
326
325
# Compute midstep derivatives
327
- midxdot[1 ,: ] = F (tspan[i], x[i,:] ' )
328
- midxdot[2 ,: ] = F (tspan[i]+ h[i]. / 2 , x[i,:] ' + midxdot[1 ,:] ' .* h[i]. / 2 )
329
- midxdot[3 ,: ] = F (tspan[i]+ h[i]. / 2 , x[i,:] ' + midxdot[2 ,:] ' .* h[i]. / 2 )
330
- midxdot[4 ,: ] = F (tspan[i]+ h[i], x[i,:] ' + midxdot[3 ,:] ' .* h[i])
326
+ midxdot[1 ] = F (tspan[i], x[i] )
327
+ midxdot[2 ] = F (tspan[i]+ h[i]. / 2 , x[i] + midxdot[1 ] . * h[i]. / 2 )
328
+ midxdot[3 ] = F (tspan[i]+ h[i]. / 2 , x[i] + midxdot[2 ] . * h[i]. / 2 )
329
+ midxdot[4 ] = F (tspan[i]+ h[i], x[i] + midxdot[3 ] . * h[i])
331
330
332
331
# Integrate
333
- x[i+ 1 ,: ] = x[i,: ] + 1. / 6. * h[i]. * [1 2 2 1 ]* midxdot
332
+ x[i+ 1 ] = x[i] + 1. / 6. * ( h[i]. * [1 2 2 1 ]* midxdot)[ 1 ]
334
333
end
335
- return ( tspan, x)
334
+ return tspan, x
336
335
end
337
336
338
337
# ODEROSENBROCK Solve stiff differential equations, Rosenbrock method
339
338
# with provided coefficients.
340
- function oderosenbrock {T} (F :: Function , G:: Function , tspan:: AbstractVector , x0:: AbstractVector{T} , gamma, a, b, c)
339
+ function oderosenbrock (F , G, tspan, x0, gamma, a, b, c)
341
340
h = diff (tspan)
342
- x = Array (T, length (tspan ), length (x0 ))
343
- x[1 ,: ] = x0
341
+ x = Array (typeof (x0 ), length (tspan ))
342
+ x[1 ] = x0
344
343
345
344
solstep = 1
346
345
while tspan[solstep] < maximum (tspan)
347
346
ts = tspan[solstep]
348
347
hs = h[solstep]
349
- xs = reshape ( x[solstep,:], size (x0))
348
+ xs = x[solstep]
350
349
dFdx = G (ts, xs)
351
- jac = eye (size (dFdx,1 ))./ gamma./ hs- dFdx
350
+ # FIXME
351
+ if size (dFdx,1 ) == 1
352
+ jac = 1 / gamma/ hs - dFdx[1 ]
353
+ else
354
+ jac = eye (dFdx)./ gamma./ hs - dFdx
355
+ end
352
356
353
- g = zeros ( size (a, 1 ), length (x0 ))
354
- g[1 ,: ] = jac \ F (ts + b[1 ]. * hs, xs)
357
+ g = Array ( typeof (x0 ), size (a, 1 ))
358
+ g[1 ] = ( jac \ F (ts + b[1 ]. * hs, xs) )
355
359
for i = 2 : size (a,1 )
356
- g[i,: ] = jac \ (F (ts + b[i]. * hs, xs + (a[i,1 : i- 1 ]* g[1 : i- 1 ,:]) .' ) + (c[i,1 : i- 1 ]* g[1 : i- 1 ,:]) .' . / hs)
360
+ g[i] = ( jac \ (F (ts + b[i]. * hs, xs + (a[i,1 : i- 1 ]* g[1 : i- 1 ])[ 1 ] ) + (c[i,1 : i- 1 ]* g[1 : i- 1 ])[ 1 ] . / hs) )
357
361
end
358
-
359
- x[solstep+ 1 ,:] = x[solstep,:] + b* g
362
+ x[solstep+ 1 ] = x[solstep] + (b* g)[1 ]
360
363
solstep += 1
361
364
end
362
- return ( tspan, x)
365
+ return tspan, x
363
366
end
364
367
365
- function oderosenbrock {T} (F :: Function , tspan:: AbstractVector , x0:: AbstractVector{T} , gamma, a, b, c)
368
+ function oderosenbrock (F , tspan, x0, gamma, a, b, c)
366
369
# Crude forward finite differences estimator as fallback
367
- function jacobian (F:: Function , t:: Number , x:: AbstractVector )
370
+ # FIXME : This doesn't really work if x is anything but a Vector or a scalar
371
+ function jacobian (F, t, x)
368
372
ftx = F (t, x)
369
- dFdx = zeros (length (x), length (x))
370
- for j = 1 : length (x)
371
- dx = zeros (size (x))
373
+ lx = max (length (x),1 )
374
+ dFdx = zeros (eltype (x), lx, lx)
375
+ for j = 1 : lx
376
+ dx = zeros (eltype (x), lx)
372
377
# The 100 below is heuristic
373
378
dx[j] = (x[j]+ (x[j]== 0 )). / 100
374
379
dFdx[:,j] = (F (t,x+ dx)- ftx). / dx[j]
@@ -412,10 +417,10 @@ ode4s_s(F, G, tspan, x0) = oderosenbrock(F, G, tspan, x0, s4_coefficients...)
412
417
const ode4s = ode4s_s
413
418
414
419
# ODE_MS Fixed-step, fixed-order multi-step numerical method with Adams-Bashforth-Moulton coefficients
415
- function ode_ms {T} (F :: Function , tspan:: AbstractVector , x0:: AbstractVector{T} , order:: Integer )
420
+ function ode_ms (F , tspan, x0, order:: Integer )
416
421
h = diff (tspan)
417
- x = zeros (T, length (tspan ), length (x0 ))
418
- x[1 ,: ] = x0
422
+ x = Array ( typeof (x0 ), length (tspan ))
423
+ x[1 ] = x0
419
424
420
425
if 1 <= order <= 4
421
426
b = [ 1 0 0 0
@@ -438,10 +443,10 @@ function ode_ms{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, or
438
443
for i = 1 : length (tspan)- 1
439
444
# Need to run the first several steps at reduced order
440
445
steporder = min (i, order)
441
- xdot[i,: ] = F (tspan[i], x[i,:] ' )
442
- x[i+ 1 ,: ] = x[i,: ] + b[steporder,1 : steporder]* xdot[i- (steporder- 1 ): i,: ]. * h[i]
446
+ xdot[i] = F (tspan[i], x[i] )
447
+ x[i+ 1 ] = x[i] + ( b[steporder,1 : steporder]* xdot[i- (steporder- 1 ): i])[ 1 ]. * h[i]
443
448
end
444
- return ( tspan, x)
449
+ return tspan, x
445
450
end
446
451
447
452
# Use order 4 by default
0 commit comments