How to resolve the algorithm Runge-Kutta method step by step in the Haskell programming language
Published on 7 June 2024 03:52 AM
How to resolve the algorithm Runge-Kutta method step by step in the Haskell programming language
Table of Contents
Problem Statement
Given the example Differential equation: With initial condition: This equation has an exact solution:
Demonstrate the commonly used explicit fourth-order Runge–Kutta method to solve the above differential equation.
Starting with a given
y
n
{\displaystyle y_{n}}
and
t
n
{\displaystyle t_{n}}
calculate: then:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Runge-Kutta method step by step in the Haskell programming language
Explanation of the First Code:
This code solves an initial value problem using the fourth-order Runge-Kutta method. It calculates the solution of the differential equation y' = sqrt(y)
with initial condition y(0) = 1
.
dv
: Computes the derivative of the functiony
, which issqrt(y)
.fy
: Defines the functionf(x) = 1/16 * (4 + x^2)^2
.rk4
: Implements the fourth-order Runge-Kutta method to numerically solve the initial value problem.task
: Runs therk4
method for various values ofx
in steps of0.1
, prints the results, and compares them to the actual solution.
Explanation of the Second Code:
This code also solves the same initial value problem, but it uses a more streamlined implementation.
rk4
: Implements the fourth-order Runge-Kutta method in a concise manner.actual
: Defines the exact solution of the differential equation.step
: Defines the step size for the numerical integration.ixs
: Generates a list ofx
values from 0 to 10 with the step size.xys
: Computes the numerical solutiony
for eachx
value.samples
: Extracts data points from the numerical solution at intervals of10 * step
.main
: Prints the numerical solution along with the error.
Key Concepts:
- Initial Value Problem: A mathematical problem where a differential equation is given along with an initial condition.
- Runge-Kutta Method: A family of numerical methods used to solve initial value problems.
- Numerical Integration: Approximating the solution of a continuous function by evaluating it at discrete intervals.
- Error Analysis: Comparing the numerical solution to the exact solution to assess the accuracy of the integration method.
Source code in the haskell programming language
dv
:: Floating a
=> a -> a -> a
dv = (. sqrt) . (*)
fy t = 1 / 16 * (4 + t ^ 2) ^ 2
rk4
:: (Enum a, Fractional a)
=> (a -> a -> a) -> a -> a -> a -> [(a, a)]
rk4 fd y0 a h = zip ts $ scanl (flip fc) y0 ts
where
ts = [a,h ..]
fc t y =
sum . (y :) . zipWith (*) [1 / 6, 1 / 3, 1 / 3, 1 / 6] $
scanl
(\k f -> h * fd (t + f * h) (y + f * k))
(h * fd t y)
[1 / 2, 1 / 2, 1]
task =
mapM_
(print . (\(x, y) -> (truncate x, y, fy x - y)))
(filter (\(x, _) -> 0 == mod (truncate $ 10 * x) 10) $
take 101 $ rk4 dv 1.0 0 0.1)
*Main> task
(0,1.0,0.0)
(1,1.5624998542781088,1.4572189122041834e-7)
(2,3.9999990805208006,9.194792029987298e-7)
(3,10.562497090437557,2.909562461184123e-6)
(4,24.999993765090654,6.234909399438493e-6)
(5,52.56248918030265,1.0819697635611192e-5)
(6,99.99998340540378,1.6594596999652822e-5)
(7,175.56247648227165,2.3517730085131916e-5)
(8,288.99996843479926,3.1565204153594095e-5)
(9,451.562459276841,4.0723166534917254e-5)
(10,675.9999490167125,5.098330132113915e-5)
rk4 :: Double -> Double -> Double -> Double
rk4 y x dx =
let f x y = x * sqrt y
k1 = dx * f x y
k2 = dx * f (x + dx / 2.0) (y + k1 / 2.0)
k3 = dx * f (x + dx / 2.0) (y + k2 / 2.0)
k4 = dx * f (x + dx) (y + k3)
in y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0
actual :: Double -> Double
actual x = (1 / 16) * (x * x + 4) * (x * x + 4)
step :: Double
step = 0.1
ixs :: [Int]
ixs = [0 .. 100]
xys :: [(Double, Double)]
xys =
scanl
(\(x, y) _ -> (((x * 10) + (step * 10)) / 10, rk4 y x step))
(0.0, 1.0)
ixs
samples :: [(Double, Double, Double)]
samples =
zip ixs xys >>=
(\(i, (x, y)) ->
[ (x, y, actual x - y)
| 0 == mod i 10 ])
main :: IO ()
main =
(putStrLn . unlines) $
(\(x, y, v) ->
unwords
[ "y" ++ justifyRight 3 ' ' ('(' : show (round x)) ++ ") = "
, justifyLeft 19 ' ' (show y)
, '±' : show v
]) <$>
samples
where
justifyLeft n c s = take n (s ++ replicate n c)
justifyRight n c s = drop (length s) (replicate n c ++ s)
You may also check:How to resolve the algorithm Discordian date step by step in the Julia programming language
You may also check:How to resolve the algorithm LZW compression step by step in the Seed7 programming language
You may also check:How to resolve the algorithm Wilson primes of order n step by step in the Java programming language
You may also check:How to resolve the algorithm Exponentiation operator step by step in the jq programming language
You may also check:How to resolve the algorithm Add a variable to a class instance at runtime step by step in the Smalltalk programming language