summaryrefslogtreecommitdiff
path: root/lib/Numeric/GSL/Root.hs
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2009-06-04 09:01:56 +0000
committerAlberto Ruiz <aruiz@um.es>2009-06-04 09:01:56 +0000
commit6e0dd472ef8c570ec1924ac641e5872db30ac142 (patch)
tree64963c6af75cdbc02336de82b51136964f36dc73 /lib/Numeric/GSL/Root.hs
parentf49ac4def26b38d3d084375007715156be347412 (diff)
added some root finding algorithms
Diffstat (limited to 'lib/Numeric/GSL/Root.hs')
-rw-r--r--lib/Numeric/GSL/Root.hs117
1 files changed, 117 insertions, 0 deletions
diff --git a/lib/Numeric/GSL/Root.hs b/lib/Numeric/GSL/Root.hs
new file mode 100644
index 0000000..ad1b72c
--- /dev/null
+++ b/lib/Numeric/GSL/Root.hs
@@ -0,0 +1,117 @@
1{- |
2Module : Numeric.GSL.Root
3Copyright : (c) Alberto Ruiz 2009
4License : GPL
5
6Maintainer : Alberto Ruiz (aruiz at um dot es)
7Stability : provisional
8Portability : uses ffi
9
10Multidimensional root finding.
11
12<http://www.gnu.org/software/gsl/manual/html_node/Multidimensional-Root_002dFinding.html>
13
14The example in the GSL manual:
15
16@import Numeric.GSL
17import Numeric.LinearAlgebra(format)
18import Text.Printf(printf)
19
20rosenbrock a b [x,y] = [ a*(1-x), b*(y-x^2) ]
21
22disp = putStrLn . format \" \" (printf \"%.3f\")
23
24main = do
25 let (sol,path) = root Hybrids 1E-7 30 (rosenbrock 1 10) [-10,-5]
26 print sol
27 disp path
28
29\> main
30[1.0,1.0]
31 0.000 -10.000 -5.000 11.000 -1050.000
32 1.000 -3.976 24.827 4.976 90.203
33 2.000 -3.976 24.827 4.976 90.203
34 3.000 -3.976 24.827 4.976 90.203
35 4.000 -1.274 -5.680 2.274 -73.018
36 5.000 -1.274 -5.680 2.274 -73.018
37 6.000 0.249 0.298 0.751 2.359
38 7.000 0.249 0.298 0.751 2.359
39 8.000 1.000 0.878 -0.000 -1.218
40 9.000 1.000 0.989 -0.000 -0.108
4110.000 1.000 1.000 0.000 0.000
42@
43
44-}
45-----------------------------------------------------------------------------
46
47module Numeric.GSL.Root (
48 root, RootMethod(..)
49) where
50
51import Data.Packed.Internal
52import Data.Packed.Matrix
53import Foreign
54import Foreign.C.Types(CInt)
55
56-------------------------------------------------------------------------
57
58data RootMethod = Hybrids
59 | Hybrid
60 | DNewton
61 | Broyden
62 deriving (Enum,Eq,Show)
63
64-- | Nonlinear multidimensional root finding using algorithms that do not require
65-- any derivative information to be supplied by the user.
66-- Any derivatives needed are approximated by finite differences.
67root :: RootMethod
68 -> Double -- ^ maximum residual
69 -> Int -- ^ maximum number of iterations allowed
70 -> ([Double] -> [Double]) -- ^ function to minimize
71 -> [Double] -- ^ starting point
72 -> ([Double], Matrix Double) -- ^ solution vector and optimization path
73
74root method epsabs maxit fun xinit = rootGen (fi (fromEnum method)) fun xinit epsabs maxit
75
76rootGen m f xi epsabs maxit = unsafePerformIO $ do
77 let xiv = fromList xi
78 n = dim xiv
79 fp <- mkVecVecfun (aux_vTov (fromList.f.toList))
80 rawpath <- withVector xiv $ \xiv' ->
81 createMIO maxit (2*n+1)
82 (c_root m fp epsabs (fi maxit) // xiv')
83 "root"
84 let it = round (rawpath @@> (maxit-1,0))
85 path = takeRows it rawpath
86 [sol] = toLists $ dropRows (it-1) path
87 freeHaskellFunPtr fp
88 return (take n $ drop 1 sol, path)
89
90
91foreign import ccall "root"
92 c_root:: CInt -> FunPtr (CInt -> Ptr Double -> Ptr Double -> IO ()) -> Double -> CInt -> TVM
93
94---------------------------------------------------------------------
95
96foreign import ccall "wrapper"
97 mkVecVecfun :: (CInt -> Ptr Double -> Ptr Double -> IO ())
98 -> IO (FunPtr (CInt -> Ptr Double -> Ptr Double->IO()))
99
100aux_vTov :: (Vector Double -> Vector Double) -> (CInt -> Ptr Double -> Ptr Double -> IO())
101aux_vTov f n p r = g where
102 V {fptr = pr} = f x
103 x = createV (fromIntegral n) copy "aux_vTov"
104 copy n' q = do
105 copyArray q p (fromIntegral n')
106 return 0
107 g = withForeignPtr pr $ \p' -> copyArray r p' (fromIntegral n)
108
109createV n fun msg = unsafePerformIO $ do
110 r <- createVector n
111 app1 fun vec r msg
112 return r
113
114createMIO r c fun msg = do
115 res <- createMatrix RowMajor r c
116 app1 fun mat res msg
117 return res