summaryrefslogtreecommitdiff
path: root/lib/Numeric/GSL/Root.hs
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2009-06-07 13:01:03 +0000
committerAlberto Ruiz <aruiz@um.es>2009-06-07 13:01:03 +0000
commit7697c6dc27fd0d9601728af576e8d7b9d1c800ee (patch)
treec4b2c0f52f3884fbbd93bd6c0739e0fc73b921a2 /lib/Numeric/GSL/Root.hs
parent49a3d719221cd9484a64688ffcdbeb13cb8e55a0 (diff)
root finding with jacobian
Diffstat (limited to 'lib/Numeric/GSL/Root.hs')
-rw-r--r--lib/Numeric/GSL/Root.hs83
1 files changed, 70 insertions, 13 deletions
diff --git a/lib/Numeric/GSL/Root.hs b/lib/Numeric/GSL/Root.hs
index d674fad..6ce2c4c 100644
--- a/lib/Numeric/GSL/Root.hs
+++ b/lib/Numeric/GSL/Root.hs
@@ -45,7 +45,8 @@ main = do
45----------------------------------------------------------------------------- 45-----------------------------------------------------------------------------
46 46
47module Numeric.GSL.Root ( 47module Numeric.GSL.Root (
48 root, RootMethod(..) 48 root, RootMethod(..),
49 rootJ, RootMethodJ(..),
49) where 50) where
50 51
51import Data.Packed.Internal 52import Data.Packed.Internal
@@ -76,7 +77,7 @@ root method epsabs maxit fun xinit = rootGen (fi (fromEnum method)) fun xinit ep
76rootGen m f xi epsabs maxit = unsafePerformIO $ do 77rootGen m f xi epsabs maxit = unsafePerformIO $ do
77 let xiv = fromList xi 78 let xiv = fromList xi
78 n = dim xiv 79 n = dim xiv
79 fp <- mkVecVecfun (aux_vTov (fromList . checkdim n f . toList)) 80 fp <- mkVecVecfun (aux_vTov (checkdim1 n . fromList . f . toList))
80 rawpath <- withVector xiv $ \xiv' -> 81 rawpath <- withVector xiv $ \xiv' ->
81 createMIO maxit (2*n+1) 82 createMIO maxit (2*n+1)
82 (c_root m fp epsabs (fi maxit) // xiv') 83 (c_root m fp epsabs (fi maxit) // xiv')
@@ -89,22 +90,74 @@ rootGen m f xi epsabs maxit = unsafePerformIO $ do
89 90
90 91
91foreign import ccall "root" 92foreign import ccall "root"
92 c_root:: CInt -> FunPtr (CInt -> Ptr Double -> Ptr Double -> IO ()) -> Double -> CInt -> TVM 93 c_root:: CInt -> FunPtr TVV -> Double -> CInt -> TVM
94
95-------------------------------------------------------------------------
96
97data RootMethodJ = HybridsJ
98 | HybridJ
99 | Newton
100 | GNewton
101 deriving (Enum,Eq,Show)
102
103-- | Nonlinear multidimensional root finding using both the function and its derivatives.
104rootJ :: RootMethodJ
105 -> Double -- ^ maximum residual
106 -> Int -- ^ maximum number of iterations allowed
107 -> ([Double] -> [Double]) -- ^ function to minimize
108 -> ([Double] -> [[Double]]) -- ^ Jacobian
109 -> [Double] -- ^ starting point
110 -> ([Double], Matrix Double) -- ^ solution vector and optimization path
111
112rootJ method epsabs maxit fun jac xinit = rootJGen (fi (fromEnum method)) fun jac xinit epsabs maxit
113
114rootJGen m f jac xi epsabs maxit = unsafePerformIO $ do
115 let xiv = fromList xi
116 n = dim xiv
117 fp <- mkVecVecfun (aux_vTov (checkdim1 n . fromList . f . toList))
118 jp <- mkVecMatfun (aux_vTom (checkdim2 n . fromLists . jac . toList))
119 rawpath <- withVector xiv $ \xiv' ->
120 createMIO maxit (2*n+1)
121 (c_rootj m fp jp epsabs (fi maxit) // xiv')
122 "root"
123 let it = round (rawpath @@> (maxit-1,0))
124 path = takeRows it rawpath
125 [sol] = toLists $ dropRows (it-1) path
126 freeHaskellFunPtr fp
127 return (take n $ drop 1 sol, path)
128
129
130foreign import ccall "rootj"
131 c_rootj:: CInt -> FunPtr TVV -> FunPtr TVM -> Double -> CInt -> TVM
132
93 133
94--------------------------------------------------------------------- 134---------------------------------------------------------------------
95 135
96foreign import ccall "wrapper" 136foreign import ccall "wrapper"
97 mkVecVecfun :: (CInt -> Ptr Double -> Ptr Double -> IO ()) 137 mkVecVecfun :: TVV -> IO (FunPtr TVV)
98 -> IO (FunPtr (CInt -> Ptr Double -> Ptr Double->IO()))
99 138
100aux_vTov :: (Vector Double -> Vector Double) -> (CInt -> Ptr Double -> Ptr Double -> IO()) 139aux_vTov :: (Vector Double -> Vector Double) -> TVV
101aux_vTov f n p r = g where 140aux_vTov f n p nr r = g where
102 V {fptr = pr} = f x 141 V {fptr = pr} = f x
103 x = createV (fromIntegral n) copy "aux_vTov" 142 x = createV (fromIntegral n) copy "aux_vTov"
104 copy n' q = do 143 copy n' q = do
105 copyArray q p (fromIntegral n') 144 copyArray q p (fromIntegral n')
106 return 0 145 return 0
107 g = withForeignPtr pr $ \p' -> copyArray r p' (fromIntegral n) 146 g = do withForeignPtr pr $ \p' -> copyArray r p' (fromIntegral nr)
147 return 0
148
149foreign import ccall "wrapper"
150 mkVecMatfun :: TVM -> IO (FunPtr TVM)
151
152aux_vTom :: (Vector Double -> Matrix Double) -> TVM
153aux_vTom f n p rr cr r = g where
154 V {fptr = pr} = flatten $ f x
155 x = createV (fromIntegral n) copy "aux_vTov"
156 copy n' q = do
157 copyArray q p (fromIntegral n')
158 return 0
159 g = do withForeignPtr pr $ \p' -> copyArray r p' (fromIntegral $ rr*cr)
160 return 0
108 161
109createV n fun msg = unsafePerformIO $ do 162createV n fun msg = unsafePerformIO $ do
110 r <- createVector n 163 r <- createVector n
@@ -116,8 +169,12 @@ createMIO r c fun msg = do
116 app1 fun mat res msg 169 app1 fun mat res msg
117 return res 170 return res
118 171
119checkdim n f x 172checkdim1 n v
120 | length y /= n = error $ "Error: "++ show n 173 | dim v == n = v
121 ++ " results expected in the function supplied to root" 174 | otherwise = error $ "Error: "++ show n
122 | otherwise = y 175 ++ " results expected in the function supplied to root"
123 where y = f x 176
177checkdim2 n m
178 | rows m == n && cols m == n = m
179 | otherwise = error $ "Error: "++ show n ++ "x" ++ show n
180 ++ " Jacobian expected in root"