]> gitweb.michael.orlitzky.com - numerical-analysis.git/blob - src/Integration/Trapezoid.hs
Fix compiler warnings and doctests.
[numerical-analysis.git] / src / Integration / Trapezoid.hs
1 {-# LANGUAGE RebindableSyntax #-}
2
3 module Integration.Trapezoid
4 where
5
6 import Misc (partition)
7
8 import NumericPrelude hiding (abs)
9 import qualified Algebra.Field as Field
10 import qualified Algebra.RealField as RealField
11 import qualified Algebra.ToInteger as ToInteger
12 import qualified Algebra.ToRational as ToRational
13
14 -- | Use the trapezoid rule to numerically integrate @f@ over the
15 -- interval [@a@, @b@].
16 --
17 -- Examples:
18 --
19 -- >>> let f x = x
20 -- >>> trapezoid_1 f (-1) 1
21 -- 0.0
22 --
23 -- >>> let f x = x^3
24 -- >>> trapezoid_1 f (-1) 1
25 -- 0.0
26 --
27 -- >>> let f x = 1
28 -- >>> trapezoid_1 f (-1) 1
29 -- 2.0
30 --
31 -- >>> let f x = x^2
32 -- >>> trapezoid_1 f (-1) 1
33 -- 2.0
34 --
35 trapezoid_1 :: (Field.C a, ToRational.C a, Field.C b)
36 => (a -> b) -- ^ The function @f@
37 -> a -- ^ The \"left\" endpoint, @a@
38 -> a -- ^ The \"right\" endpoint, @b@
39 -> b
40 trapezoid_1 f a b =
41 (((f a) + (f b)) / 2) * (fromRational' $ toRational (b - a))
42
43
44 -- | Use the composite trapezoid rule to numerically integrate @f@
45 -- over @n@ subintervals of [@a@, @b@].
46 --
47 -- Examples:
48 --
49 -- >>> import Algebra.Absolute (abs)
50 -- >>> let f x = x^2
51 -- >>> let area = trapezoid 1000 f (-1) 1
52 -- >>> abs (area - (2/3)) < 0.00001
53 -- True
54 --
55 -- >>> import Algebra.Absolute (abs)
56 -- >>> let area = trapezoid 1000 sin 0 pi
57 -- >>> abs (area - 2) < 0.0001
58 -- True
59 --
60 trapezoid :: (RealField.C a,
61 ToRational.C a,
62 RealField.C b,
63 ToInteger.C c,
64 Enum c)
65 => c -- ^ The number of subintervals to use, @n@
66 -> (a -> b) -- ^ The function @f@
67 -> a -- ^ The \"left\" endpoint, @a@
68 -> a -- ^ The \"right\" endpoint, @b@
69 -> b
70 trapezoid n f a b =
71 sum $ map trapezoid_pairs pieces
72 where
73 pieces = partition n a b
74 -- Convert the trapezoid_1 function into one that takes pairs
75 -- (a,b) instead of individual arguments 'a' and 'b'.
76 trapezoid_pairs = uncurry (trapezoid_1 f)