diff options
Diffstat (limited to 'lib/Numeric/GSL/Root.hs')
-rw-r--r-- | lib/Numeric/GSL/Root.hs | 83 |
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 | ||
47 | module Numeric.GSL.Root ( | 47 | module Numeric.GSL.Root ( |
48 | root, RootMethod(..) | 48 | root, RootMethod(..), |
49 | rootJ, RootMethodJ(..), | ||
49 | ) where | 50 | ) where |
50 | 51 | ||
51 | import Data.Packed.Internal | 52 | import Data.Packed.Internal |
@@ -76,7 +77,7 @@ root method epsabs maxit fun xinit = rootGen (fi (fromEnum method)) fun xinit ep | |||
76 | rootGen m f xi epsabs maxit = unsafePerformIO $ do | 77 | rootGen 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 | ||
91 | foreign import ccall "root" | 92 | foreign 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 | |||
97 | data 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. | ||
104 | rootJ :: 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 | |||
112 | rootJ method epsabs maxit fun jac xinit = rootJGen (fi (fromEnum method)) fun jac xinit epsabs maxit | ||
113 | |||
114 | rootJGen 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 | |||
130 | foreign import ccall "rootj" | ||
131 | c_rootj:: CInt -> FunPtr TVV -> FunPtr TVM -> Double -> CInt -> TVM | ||
132 | |||
93 | 133 | ||
94 | --------------------------------------------------------------------- | 134 | --------------------------------------------------------------------- |
95 | 135 | ||
96 | foreign import ccall "wrapper" | 136 | foreign 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 | ||
100 | aux_vTov :: (Vector Double -> Vector Double) -> (CInt -> Ptr Double -> Ptr Double -> IO()) | 139 | aux_vTov :: (Vector Double -> Vector Double) -> TVV |
101 | aux_vTov f n p r = g where | 140 | aux_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 | |||
149 | foreign import ccall "wrapper" | ||
150 | mkVecMatfun :: TVM -> IO (FunPtr TVM) | ||
151 | |||
152 | aux_vTom :: (Vector Double -> Matrix Double) -> TVM | ||
153 | aux_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 | ||
109 | createV n fun msg = unsafePerformIO $ do | 162 | createV 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 | ||
119 | checkdim n f x | 172 | checkdim1 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 | |
177 | checkdim2 n m | ||
178 | | rows m == n && cols m == n = m | ||
179 | | otherwise = error $ "Error: "++ show n ++ "x" ++ show n | ||
180 | ++ " Jacobian expected in root" | ||