Anonymous user
Euler method: Difference between revisions
→{{header|Haskell}}: Changed to modular solution
m (elided some whitespace after the PNG image (and before the 1st programming example).) |
(→{{header|Haskell}}: Changed to modular solution) |
||
Line 1,174:
=={{header|Haskell}}==
Modular solution which separates the solver and a method. Moreover it works on a given mesh which can be irregular.
<lang Haskell>
dsolveBy _ _ [] _ = error "empty solution interval"
dsolveBy method f mesh x0 = zip mesh results
where results = scanl (method f) x0 intervals
intervals = zip mesh (tail mesh)
-- methods
euler f
It is better to use strict <code>Data.List.scanl'</code> in the solver but avoiding highlighting problems we leave lazy <code>scanl</code> function.
newtonCooling _ t = -0.07 * (t - 20)▼
Another possible methods:
<lang haskell>-- 2-nd order Runge-Kutta
rk2 f x (t1,t2) = x + h * f (t1 + h/2) (x + h/2*f t1 x)
where h = t2 - t1
-- 4-th order Runge-Kutta
rk4 f x (t1,t2) = x + h/6 * (k1 + 2*k2 + 2*k3 + k4)
where k1 = f t1 x
k2 = f (t1 + h/2) (x + h/2*k1)
k3 = f (t1 + h/2) (x + h/2*k2)
k4 = f (t1 + h) (x + h*k3)
h = t2 - t1</lang>
Graphical output, using EasyPlot:
<lang haskell>import Graphics.EasyPlot
exactSolution t = 80*exp(-0.07*t)+20
test1 = plot (PNG "euler1.png")
[ Data2D [Title "Step 10", Style Lines] [] sol1
, Data2D [Title "Step 5", Style Lines] [] sol2
, Data2D [Title "Step 1", Style Lines] [] sol3
, Function2D [Title "exact solution"] [Range 0 100] exactSolution ]
where sol1 = dsolveBy euler newton [0,10..100] 100
sol2 = dsolveBy euler newton [0,5..100] 100
sol3 = dsolveBy euler newton [0,1..100] 100
test2 = plot (PNG "euler2.png")
[ Data2D [Title "Euler"] [] sol1
, Data2D [Title "RK2"] [] sol2
, Data2D [Title "RK4"] [] sol3
, Function2D [Title "exact solution"] [Range 0 100] exactSolution ]
where sol1 = dsolveBy euler newton [0,10..100] 100
sol2 = dsolveBy rk2 newton [0,10..100] 100
sol3 = dsolveBy rk4 newton [0,10..100] 100</lang>
=={{header|Icon}} and {{header|Unicon}}==
|