Jump to content

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>import-- Text.Printfthe solver
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 :: (Num a, Ord a) => (a -> a -> a) -> a -> a -> a -> a -> [(a,a)]
euler f y0x a(t1,t2) b= hx =+ (t2 - t1) * f t1 x</lang>
(a, y0) :
if a < b
then euler f (y0 + (f a y0) * h) (a + h) b h
else []
 
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 :: Double -> Double -> Double
newtonCooling _ t = -0.07 * (t - 20)
 
Another possible methods:
main = do
<lang haskell>-- 2-nd order Runge-Kutta
mapM_ (uncurry $ printf "%6.3f %6.3f\n") $ euler newtonCooling 100 0 100 10
rk2 f x (t1,t2) = x + h * f (t1 + h/2) (x + h/2*f t1 x)
putStrLn "DONE"</lang>
where h = t2 - t1
Output:
 
<pre>
-- 4-th order Runge-Kutta
0.000 100.000
rk4 f x (t1,t2) = x + h/6 * (k1 + 2*k2 + 2*k3 + k4)
10.000 44.000
where k1 = f t1 x
20.000 27.200
k2 = f (t1 + h/2) (x + h/2*k1)
30.000 22.160
k3 = f (t1 + h/2) (x + h/2*k2)
40.000 20.648
k4 = f (t1 + h) (x + h*k3)
50.000 20.194
h = t2 - t1</lang>
60.000 20.058
 
70.000 20.017
Graphical output, using EasyPlot:
80.000 20.005
 
90.000 20.002
<lang haskell>import Graphics.EasyPlot
100.000 20.000
 
DONE
newtonCooling _newton t temp = -0.07 * (ttemp - 20)
</pre>
 
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}}==
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.