This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,15 @@
def eulerStep = { xn, yn, h, dydx ->
(yn + h * dydx(xn, yn)) as BigDecimal
}
Map eulerMapping = { x0, y0, h, dydx, stopCond = { xx, yy, hh, xx0 -> abs(xx - xx0) > (hh * 100) }.rcurry(h, x0) ->
Map yMap = [:]
yMap[x0] = y0 as BigDecimal
def x = x0
while (!stopCond(x, yMap[x])) {
yMap[x + h] = eulerStep(x, yMap[x], h, dydx)
x += h
}
yMap
}
assert eulerMapping.maximumNumberOfParameters == 5

View file

@ -0,0 +1,8 @@
def dtdsNewton = { s, t, tR, k -> k * (tR - t) }
assert dtdsNewton.maximumNumberOfParameters == 4
def dtds = dtdsNewton.rcurry(20, 0.07)
assert dtds.maximumNumberOfParameters == 2
def tEulerH = eulerMapping.rcurry(dtds) { s, t -> s >= 100 }
assert tEulerH.maximumNumberOfParameters == 3

View file

@ -0,0 +1,7 @@
def tNewton = { s, s0, t0, tR, k ->
tR + (t0 - tR) * Math.exp(k * (s0 - s))
}
assert tNewton.maximumNumberOfParameters == 5
def tAnalytic = tNewton.rcurry(0, 100, 20, 0.07)
assert tAnalytic.maximumNumberOfParameters == 1

View file

@ -0,0 +1,14 @@
[10, 5, 2].each { h ->
def tEuler = tEulerH.rcurry(h)
assert tEuler.maximumNumberOfParameters == 2
println """
STEP SIZE == ${h}
time analytic euler relative
(seconds) (°C) (°C) error
-------- -------- -------- ---------"""
tEuler(0, 100).each { BigDecimal s, tE ->
def tA = tAnalytic(s)
def relError = ((tE - tA)/(tA - 20)).abs()
printf('%5.0f %8.4f %8.4f %9.6f\n', s, tA, tE, relError)
}
}

View file

@ -0,0 +1,22 @@
invocable "newton_cooling" # needed to use the 'proc' procedure
procedure euler (f, y0, a, b, h)
t := a
y := y0
until (t >= b) do {
write (right(t, 4) || " " || left(y, 7))
t +:= h
y +:= h * (proc(f) (t, y)) # 'proc' applies procedure named in f to (t, y)
}
write ("DONE")
end
procedure newton_cooling (time, T)
return -0.07 * (T - 20)
end
procedure main ()
# generate data for all three step sizes [2, 5, 10]
every (step_size := ![2,5,10]) do
euler ("newton_cooling", 100, 0, 100, step_size)
end

View file

@ -0,0 +1,9 @@
NB.*euler a Approximates Y(t) in Y'(t)=f(t,Y) with Y(a)=Y0 and t=a..b and step size h.
euler=: adverb define
'Y0 a b h'=. 4{. y
t=. i.@>:&.(%&h) b - a
Y=. (+ h * u)^:(<#t) Y0
t,.Y
)
ncl=: _0.07 * -&20 NB. Newton's Cooling Law

View file

@ -0,0 +1,16 @@
ncl euler 100 0 100 2
... NB. output redacted for brevity
ncl euler 100 0 100 5
... NB. output redacted for brevity
ncl euler 100 0 100 10
0 100
10 44
20 27.2
30 22.16
40 20.648
50 20.1944
60 20.0583
70 20.0175
80 20.0052
90 20.0016
100 20.0005

View file

@ -0,0 +1 @@
euler[step_, val_] := NDSolve[{T'[t] == -0.07 (T[t] - 20), T[0] == 100}, T, {t, 0, 100}, Method -> "ExplicitEuler", StartingStepSize -> step][[1, 1, 2]][val]