summaryrefslogtreecommitdiff
path: root/lib/Numeric/GSL/Differentiation.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Numeric/GSL/Differentiation.hs')
-rw-r--r--lib/Numeric/GSL/Differentiation.hs79
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/Numeric/GSL/Differentiation.hs b/lib/Numeric/GSL/Differentiation.hs
new file mode 100644
index 0000000..e7fea92
--- /dev/null
+++ b/lib/Numeric/GSL/Differentiation.hs
@@ -0,0 +1,79 @@
1{-# OPTIONS #-}
2-----------------------------------------------------------------------------
3{- |
4Module : Numeric.GSL.Differentiation
5Copyright : (c) Alberto Ruiz 2006
6License : GPL-style
7
8Maintainer : Alberto Ruiz (aruiz at um dot es)
9Stability : provisional
10Portability : uses ffi
11
12Numerical differentiation.
13
14<http://www.gnu.org/software/gsl/manual/html_node/Numerical-Differentiation.html#Numerical-Differentiation>
15
16From the GSL manual: \"The functions described in this chapter compute numerical derivatives by finite differencing. An adaptive algorithm is used to find the best choice of finite difference and to estimate the error in the derivative.\"
17-}
18-----------------------------------------------------------------------------
19module Numeric.GSL.Differentiation (
20 derivCentral,
21 derivForward,
22 derivBackward
23) where
24
25import Foreign
26import Data.Packed.Internal(mkfun,check,(//))
27
28derivGen ::
29 Int -- ^ type: 0 central, 1 forward, 2 backward
30 -> Double -- ^ initial step size
31 -> (Double -> Double) -- ^ function
32 -> Double -- ^ point where the derivative is taken
33 -> (Double, Double) -- ^ result and error
34derivGen c h f x = unsafePerformIO $ do
35 r <- malloc
36 e <- malloc
37 fp <- mkfun (\x _ -> f x)
38 c_deriv c fp x h r e // check "deriv" []
39 vr <- peek r
40 ve <- peek e
41 let result = (vr,ve)
42 free r
43 free e
44 freeHaskellFunPtr fp
45 return result
46
47foreign import ccall "gsl-aux.h deriv"
48 c_deriv :: Int -> FunPtr (Double -> Ptr () -> Double) -> Double -> Double
49 -> Ptr Double -> Ptr Double -> IO Int
50
51
52{- | Adaptive central difference algorithm, /gsl_deriv_central/. For example:
53
54> > let deriv = derivCentral 0.01
55> > deriv sin (pi/4)
56>(0.7071067812000676,1.0600063101654055e-10)
57> > cos (pi/4)
58>0.7071067811865476
59
60-}
61derivCentral :: Double -- ^ initial step size
62 -> (Double -> Double) -- ^ function
63 -> Double -- ^ point where the derivative is taken
64 -> (Double, Double) -- ^ result and absolute error
65derivCentral = derivGen 0
66
67-- | Adaptive forward difference algorithm, /gsl_deriv_forward/. The function is evaluated only at points greater than x, and never at x itself. The derivative is returned in result and an estimate of its absolute error is returned in abserr. This function should be used if f(x) has a discontinuity at x, or is undefined for values less than x. A backward derivative can be obtained using a negative step.
68derivForward :: Double -- ^ initial step size
69 -> (Double -> Double) -- ^ function
70 -> Double -- ^ point where the derivative is taken
71 -> (Double, Double) -- ^ result and absolute error
72derivForward = derivGen 1
73
74-- | Adaptive backward difference algorithm, /gsl_deriv_backward/.
75derivBackward ::Double -- ^ initial step size
76 -> (Double -> Double) -- ^ function
77 -> Double -- ^ point where the derivative is taken
78 -> (Double, Double) -- ^ result and absolute error
79derivBackward = derivGen 2