Numerical integration: Difference between revisions

Content added Content deleted
(Completed Haskell version)
Line 1,599: Line 1,599:
*Main> intSimpson (\x -> x*x) 0 1 10
*Main> intSimpson (\x -> x*x) 0 1 10
0.3333333333333334
0.3333333333333334

The whole program:

<lang haskell>approx f xs ws = sum [w * f x | (x,w) <- zip xs ws]

integrateOpen :: Fractional a => a -> [a] -> (a -> a) -> a -> a -> Int -> a
integrateOpen v vs f a b n = approx f xs ws * h / v where
m = fromIntegral (length vs) * n
h = (b-a) / fromIntegral m
ws = concat $ replicate n vs
c = a + h/2
xs = [c + h * fromIntegral i | i <- [0..m-1]]

integrateClosed :: Fractional a => a -> [a] -> (a -> a) -> a -> a -> Int -> a
integrateClosed v vs f a b n = approx f xs ws * h / v where
m = fromIntegral (length vs - 1) * n
h = (b-a) / fromIntegral m
ws = overlap n vs
xs = [a + h * fromIntegral i | i <- [0..m]]

overlap :: Num a => Int -> [a] -> [a]
overlap n [] = []
overlap n (x:xs) = x : inter n xs where
inter 1 ys = ys
inter n [] = x : inter (n-1) xs
inter n [y] = (x+y) : inter (n-1) xs
inter n (y:ys) = y : inter n ys

intLeftRect = integrateClosed 1 [1,0]
intMidRect = integrateOpen 1 [1]
intRightRect = integrateClosed 1 [0,1]
intTrapezium = integrateClosed 2 [1,1]
intSimpson = integrateClosed 3 [1,4,1]

uncurry4 f ~(a, b, c, d) = f a b c d

main = do
let m1 = "rectangular left: "
let m2 = "rectangular middle: "
let m3 = "rectangular right: "
let m4 = "trapezium: "
let m5 = "simpson: "

let arg1 = ((\x -> x ^ 3), 0, 1, 100)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg1)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg1)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg1)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg1)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg1)
putStrLn ""

let arg2 = ((\x -> 1 / x), 1, 100, 1000)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg2)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg2)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg2)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg2)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg2)
putStrLn ""

let arg3 = ((\x -> x), 0, 5000, 5000000)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg3)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg3)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg3)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg3)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg3)
putStrLn ""

let arg4 = ((\x -> x), 0, 6000, 6000000)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg4)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg4)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg4)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg4)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg4)</lang>

Output:
<pre>rectangular left: 0.24502500000000005
rectangular middle: 0.24998750000000006
rectangular right: 0.25502500000000006
trapezium: 0.25002500000000005
simpson: 0.25000000000000006

rectangular left: 4.65499105751468
rectangular middle: 4.604762548678376
rectangular right: 4.55698105751468
trapezium: 4.605986057514681
simpson: 4.605170384957134

rectangular left: 1.24999975e7
rectangular middle: 1.25e7
rectangular right: 1.25000025e7
trapezium: 1.25e7
simpson: 1.2499999999999993e7

rectangular left: 1.7999997000000004e7
rectangular middle: 1.7999999999999993e7
rectangular right: 1.8000003000000004e7
trapezium: 1.8000000000000004e7
simpson: 1.7999999999999993e7</pre>
Runtime: about 7 seconds.


=={{header|J}}==
=={{header|J}}==