diff options
Diffstat (limited to 'packages/hmatrix/src/Numeric/GSL/Integration.hs')
-rw-r--r-- | packages/hmatrix/src/Numeric/GSL/Integration.hs | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/packages/hmatrix/src/Numeric/GSL/Integration.hs b/packages/hmatrix/src/Numeric/GSL/Integration.hs new file mode 100644 index 0000000..5f0a415 --- /dev/null +++ b/packages/hmatrix/src/Numeric/GSL/Integration.hs | |||
@@ -0,0 +1,250 @@ | |||
1 | {-# OPTIONS #-} | ||
2 | ----------------------------------------------------------------------------- | ||
3 | {- | | ||
4 | Module : Numeric.GSL.Integration | ||
5 | Copyright : (c) Alberto Ruiz 2006 | ||
6 | License : GPL-style | ||
7 | |||
8 | Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
9 | Stability : provisional | ||
10 | Portability : uses ffi | ||
11 | |||
12 | Numerical integration routines. | ||
13 | |||
14 | <http://www.gnu.org/software/gsl/manual/html_node/Numerical-Integration.html#Numerical-Integration> | ||
15 | -} | ||
16 | ----------------------------------------------------------------------------- | ||
17 | |||
18 | module Numeric.GSL.Integration ( | ||
19 | integrateQNG, | ||
20 | integrateQAGS, | ||
21 | integrateQAGI, | ||
22 | integrateQAGIU, | ||
23 | integrateQAGIL, | ||
24 | integrateCQUAD | ||
25 | ) where | ||
26 | |||
27 | import Foreign.C.Types | ||
28 | import Foreign.Marshal.Alloc(malloc, free) | ||
29 | import Foreign.Ptr(Ptr, FunPtr, freeHaskellFunPtr) | ||
30 | import Foreign.Storable(peek) | ||
31 | import Data.Packed.Internal(check,(//)) | ||
32 | import System.IO.Unsafe(unsafePerformIO) | ||
33 | |||
34 | eps = 1e-12 | ||
35 | |||
36 | {- | conversion of Haskell functions into function pointers that can be used in the C side | ||
37 | -} | ||
38 | foreign import ccall safe "wrapper" mkfun:: (Double -> Ptr() -> Double) -> IO( FunPtr (Double -> Ptr() -> Double)) | ||
39 | |||
40 | -------------------------------------------------------------------- | ||
41 | {- | Numerical integration using /gsl_integration_qags/ (adaptive integration with singularities). For example: | ||
42 | |||
43 | >>> let quad = integrateQAGS 1E-9 1000 | ||
44 | >>> let f a x = x**(-0.5) * log (a*x) | ||
45 | >>> quad (f 1) 0 1 | ||
46 | (-3.999999999999974,4.871658632055187e-13) | ||
47 | |||
48 | -} | ||
49 | |||
50 | integrateQAGS :: Double -- ^ precision (e.g. 1E-9) | ||
51 | -> Int -- ^ size of auxiliary workspace (e.g. 1000) | ||
52 | -> (Double -> Double) -- ^ function to be integrated on the interval (a,b) | ||
53 | -> Double -- ^ a | ||
54 | -> Double -- ^ b | ||
55 | -> (Double, Double) -- ^ result of the integration and error | ||
56 | integrateQAGS prec n f a b = unsafePerformIO $ do | ||
57 | r <- malloc | ||
58 | e <- malloc | ||
59 | fp <- mkfun (\x _ -> f x) | ||
60 | c_integrate_qags fp a b eps prec (fromIntegral n) r e // check "integrate_qags" | ||
61 | vr <- peek r | ||
62 | ve <- peek e | ||
63 | let result = (vr,ve) | ||
64 | free r | ||
65 | free e | ||
66 | freeHaskellFunPtr fp | ||
67 | return result | ||
68 | |||
69 | foreign import ccall safe "integrate_qags" c_integrate_qags | ||
70 | :: FunPtr (Double-> Ptr() -> Double) -> Double -> Double | ||
71 | -> Double -> Double -> CInt -> Ptr Double -> Ptr Double -> IO CInt | ||
72 | |||
73 | ----------------------------------------------------------------- | ||
74 | {- | Numerical integration using /gsl_integration_qng/ (useful for fast integration of smooth functions). For example: | ||
75 | |||
76 | >>> let quad = integrateQNG 1E-6 | ||
77 | >>> quad (\x -> 4/(1+x*x)) 0 1 | ||
78 | (3.141592653589793,3.487868498008632e-14) | ||
79 | |||
80 | -} | ||
81 | |||
82 | integrateQNG :: Double -- ^ precision (e.g. 1E-9) | ||
83 | -> (Double -> Double) -- ^ function to be integrated on the interval (a,b) | ||
84 | -> Double -- ^ a | ||
85 | -> Double -- ^ b | ||
86 | -> (Double, Double) -- ^ result of the integration and error | ||
87 | integrateQNG prec f a b = unsafePerformIO $ do | ||
88 | r <- malloc | ||
89 | e <- malloc | ||
90 | fp <- mkfun (\x _ -> f x) | ||
91 | c_integrate_qng fp a b eps prec r e // check "integrate_qng" | ||
92 | vr <- peek r | ||
93 | ve <- peek e | ||
94 | let result = (vr,ve) | ||
95 | free r | ||
96 | free e | ||
97 | freeHaskellFunPtr fp | ||
98 | return result | ||
99 | |||
100 | foreign import ccall safe "integrate_qng" c_integrate_qng | ||
101 | :: FunPtr (Double-> Ptr() -> Double) -> Double -> Double | ||
102 | -> Double -> Double -> Ptr Double -> Ptr Double -> IO CInt | ||
103 | |||
104 | -------------------------------------------------------------------- | ||
105 | {- | Numerical integration using /gsl_integration_qagi/ (integration over the infinite integral -Inf..Inf using QAGS). | ||
106 | For example: | ||
107 | |||
108 | >>> let quad = integrateQAGI 1E-9 1000 | ||
109 | >>> let f a x = exp(-a * x^2) | ||
110 | >>> quad (f 0.5) | ||
111 | (2.5066282746310002,6.229215880648858e-11) | ||
112 | |||
113 | -} | ||
114 | |||
115 | integrateQAGI :: Double -- ^ precision (e.g. 1E-9) | ||
116 | -> Int -- ^ size of auxiliary workspace (e.g. 1000) | ||
117 | -> (Double -> Double) -- ^ function to be integrated on the interval (-Inf,Inf) | ||
118 | -> (Double, Double) -- ^ result of the integration and error | ||
119 | integrateQAGI prec n f = unsafePerformIO $ do | ||
120 | r <- malloc | ||
121 | e <- malloc | ||
122 | fp <- mkfun (\x _ -> f x) | ||
123 | c_integrate_qagi fp eps prec (fromIntegral n) r e // check "integrate_qagi" | ||
124 | vr <- peek r | ||
125 | ve <- peek e | ||
126 | let result = (vr,ve) | ||
127 | free r | ||
128 | free e | ||
129 | freeHaskellFunPtr fp | ||
130 | return result | ||
131 | |||
132 | foreign import ccall safe "integrate_qagi" c_integrate_qagi | ||
133 | :: FunPtr (Double-> Ptr() -> Double) -> Double -> Double | ||
134 | -> CInt -> Ptr Double -> Ptr Double -> IO CInt | ||
135 | |||
136 | -------------------------------------------------------------------- | ||
137 | {- | Numerical integration using /gsl_integration_qagiu/ (integration over the semi-infinite integral a..Inf). | ||
138 | For example: | ||
139 | |||
140 | >>> let quad = integrateQAGIU 1E-9 1000 | ||
141 | >>> let f a x = exp(-a * x^2) | ||
142 | >>> quad (f 0.5) 0 | ||
143 | (1.2533141373155001,3.114607940324429e-11) | ||
144 | |||
145 | -} | ||
146 | |||
147 | integrateQAGIU :: Double -- ^ precision (e.g. 1E-9) | ||
148 | -> Int -- ^ size of auxiliary workspace (e.g. 1000) | ||
149 | -> (Double -> Double) -- ^ function to be integrated on the interval (a,Inf) | ||
150 | -> Double -- ^ a | ||
151 | -> (Double, Double) -- ^ result of the integration and error | ||
152 | integrateQAGIU prec n f a = unsafePerformIO $ do | ||
153 | r <- malloc | ||
154 | e <- malloc | ||
155 | fp <- mkfun (\x _ -> f x) | ||
156 | c_integrate_qagiu fp a eps prec (fromIntegral n) r e // check "integrate_qagiu" | ||
157 | vr <- peek r | ||
158 | ve <- peek e | ||
159 | let result = (vr,ve) | ||
160 | free r | ||
161 | free e | ||
162 | freeHaskellFunPtr fp | ||
163 | return result | ||
164 | |||
165 | foreign import ccall safe "integrate_qagiu" c_integrate_qagiu | ||
166 | :: FunPtr (Double-> Ptr() -> Double) -> Double -> Double | ||
167 | -> Double -> CInt -> Ptr Double -> Ptr Double -> IO CInt | ||
168 | |||
169 | -------------------------------------------------------------------- | ||
170 | {- | Numerical integration using /gsl_integration_qagil/ (integration over the semi-infinite integral -Inf..b). | ||
171 | For example: | ||
172 | |||
173 | >>> let quad = integrateQAGIL 1E-9 1000 | ||
174 | >>> let f a x = exp(-a * x^2) | ||
175 | >>> quad (f 0.5) 0 | ||
176 | (1.2533141373155001,3.114607940324429e-11) | ||
177 | |||
178 | -} | ||
179 | |||
180 | integrateQAGIL :: Double -- ^ precision (e.g. 1E-9) | ||
181 | -> Int -- ^ size of auxiliary workspace (e.g. 1000) | ||
182 | -> (Double -> Double) -- ^ function to be integrated on the interval (a,Inf) | ||
183 | -> Double -- ^ b | ||
184 | -> (Double, Double) -- ^ result of the integration and error | ||
185 | integrateQAGIL prec n f b = unsafePerformIO $ do | ||
186 | r <- malloc | ||
187 | e <- malloc | ||
188 | fp <- mkfun (\x _ -> f x) | ||
189 | c_integrate_qagil fp b eps prec (fromIntegral n) r e // check "integrate_qagil" | ||
190 | vr <- peek r | ||
191 | ve <- peek e | ||
192 | let result = (vr,ve) | ||
193 | free r | ||
194 | free e | ||
195 | freeHaskellFunPtr fp | ||
196 | return result | ||
197 | |||
198 | foreign import ccall safe "gsl-aux.h integrate_qagil" c_integrate_qagil | ||
199 | :: FunPtr (Double-> Ptr() -> Double) -> Double -> Double | ||
200 | -> Double -> CInt -> Ptr Double -> Ptr Double -> IO CInt | ||
201 | |||
202 | |||
203 | -------------------------------------------------------------------- | ||
204 | {- | Numerical integration using /gsl_integration_cquad/ (quadrature | ||
205 | for general integrands). From the GSL manual: | ||
206 | |||
207 | @CQUAD is a new doubly-adaptive general-purpose quadrature routine | ||
208 | which can handle most types of singularities, non-numerical function | ||
209 | values such as Inf or NaN, as well as some divergent integrals. It | ||
210 | generally requires more function evaluations than the integration | ||
211 | routines in QUADPACK, yet fails less often for difficult integrands.@ | ||
212 | |||
213 | For example: | ||
214 | |||
215 | >>> let quad = integrateCQUAD 1E-12 1000 | ||
216 | >>> let f a x = exp(-a * x^2) | ||
217 | >>> quad (f 0.5) 2 5 | ||
218 | (5.7025405463957006e-2,9.678874441303705e-16,95) | ||
219 | |||
220 | Unlike other quadrature methods, integrateCQUAD also returns the | ||
221 | number of function evaluations required. | ||
222 | |||
223 | -} | ||
224 | |||
225 | integrateCQUAD :: Double -- ^ precision (e.g. 1E-9) | ||
226 | -> Int -- ^ size of auxiliary workspace (e.g. 1000) | ||
227 | -> (Double -> Double) -- ^ function to be integrated on the interval (a, b) | ||
228 | -> Double -- ^ a | ||
229 | -> Double -- ^ b | ||
230 | -> (Double, Double, Int) -- ^ result of the integration, error and number of function evaluations performed | ||
231 | integrateCQUAD prec n f a b = unsafePerformIO $ do | ||
232 | r <- malloc | ||
233 | e <- malloc | ||
234 | neval <- malloc | ||
235 | fp <- mkfun (\x _ -> f x) | ||
236 | c_integrate_cquad fp a b eps prec (fromIntegral n) r e neval // check "integrate_cquad" | ||
237 | vr <- peek r | ||
238 | ve <- peek e | ||
239 | vneval <- peek neval | ||
240 | let result = (vr,ve,vneval) | ||
241 | free r | ||
242 | free e | ||
243 | free neval | ||
244 | freeHaskellFunPtr fp | ||
245 | return result | ||
246 | |||
247 | foreign import ccall safe "integrate_cquad" c_integrate_cquad | ||
248 | :: FunPtr (Double-> Ptr() -> Double) -> Double -> Double | ||
249 | -> Double -> Double -> CInt -> Ptr Double -> Ptr Double -> Ptr Int -> IO CInt | ||
250 | |||