diff options
author | Alberto Ruiz <aruiz@um.es> | 2014-05-08 08:48:12 +0200 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2014-05-08 08:48:12 +0200 |
commit | 1925c123d7d8184a1d2ddc0a413e0fd2776e1083 (patch) | |
tree | fad79f909d9c3be53d68e6ebd67202650536d387 /lib/Numeric/GSL | |
parent | eb3f702d065a4a967bb754977233e6eec408fd1f (diff) |
empty hmatrix-base
Diffstat (limited to 'lib/Numeric/GSL')
-rw-r--r-- | lib/Numeric/GSL/Differentiation.hs | 87 | ||||
-rw-r--r-- | lib/Numeric/GSL/Fitting.hs | 179 | ||||
-rw-r--r-- | lib/Numeric/GSL/Fourier.hs | 47 | ||||
-rw-r--r-- | lib/Numeric/GSL/Integration.hs | 250 | ||||
-rw-r--r-- | lib/Numeric/GSL/Internal.hs | 76 | ||||
-rw-r--r-- | lib/Numeric/GSL/Minimization.hs | 227 | ||||
-rw-r--r-- | lib/Numeric/GSL/ODE.hs | 138 | ||||
-rw-r--r-- | lib/Numeric/GSL/Polynomials.hs | 58 | ||||
-rw-r--r-- | lib/Numeric/GSL/Root.hs | 199 | ||||
-rw-r--r-- | lib/Numeric/GSL/Vector.hs | 328 | ||||
-rw-r--r-- | lib/Numeric/GSL/gsl-aux.c | 1541 | ||||
-rw-r--r-- | lib/Numeric/GSL/gsl-ode.c | 182 |
12 files changed, 0 insertions, 3312 deletions
diff --git a/lib/Numeric/GSL/Differentiation.hs b/lib/Numeric/GSL/Differentiation.hs deleted file mode 100644 index 93c5007..0000000 --- a/lib/Numeric/GSL/Differentiation.hs +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | {-# OPTIONS #-} | ||
2 | ----------------------------------------------------------------------------- | ||
3 | {- | | ||
4 | Module : Numeric.GSL.Differentiation | ||
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 differentiation. | ||
13 | |||
14 | <http://www.gnu.org/software/gsl/manual/html_node/Numerical-Differentiation.html#Numerical-Differentiation> | ||
15 | |||
16 | From 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 | ----------------------------------------------------------------------------- | ||
19 | module Numeric.GSL.Differentiation ( | ||
20 | derivCentral, | ||
21 | derivForward, | ||
22 | derivBackward | ||
23 | ) where | ||
24 | |||
25 | import Foreign.C.Types | ||
26 | import Foreign.Marshal.Alloc(malloc, free) | ||
27 | import Foreign.Ptr(Ptr, FunPtr, freeHaskellFunPtr) | ||
28 | import Foreign.Storable(peek) | ||
29 | import Data.Packed.Internal(check,(//)) | ||
30 | import System.IO.Unsafe(unsafePerformIO) | ||
31 | |||
32 | derivGen :: | ||
33 | CInt -- ^ type: 0 central, 1 forward, 2 backward | ||
34 | -> Double -- ^ initial step size | ||
35 | -> (Double -> Double) -- ^ function | ||
36 | -> Double -- ^ point where the derivative is taken | ||
37 | -> (Double, Double) -- ^ result and error | ||
38 | derivGen c h f x = unsafePerformIO $ do | ||
39 | r <- malloc | ||
40 | e <- malloc | ||
41 | fp <- mkfun (\y _ -> f y) | ||
42 | c_deriv c fp x h r e // check "deriv" | ||
43 | vr <- peek r | ||
44 | ve <- peek e | ||
45 | let result = (vr,ve) | ||
46 | free r | ||
47 | free e | ||
48 | freeHaskellFunPtr fp | ||
49 | return result | ||
50 | |||
51 | foreign import ccall safe "gsl-aux.h deriv" | ||
52 | c_deriv :: CInt -> FunPtr (Double -> Ptr () -> Double) -> Double -> Double | ||
53 | -> Ptr Double -> Ptr Double -> IO CInt | ||
54 | |||
55 | |||
56 | {- | Adaptive central difference algorithm, /gsl_deriv_central/. For example: | ||
57 | |||
58 | >>> let deriv = derivCentral 0.01 | ||
59 | >>> deriv sin (pi/4) | ||
60 | (0.7071067812000676,1.0600063101654055e-10) | ||
61 | >>> cos (pi/4) | ||
62 | 0.7071067811865476 | ||
63 | |||
64 | -} | ||
65 | derivCentral :: Double -- ^ initial step size | ||
66 | -> (Double -> Double) -- ^ function | ||
67 | -> Double -- ^ point where the derivative is taken | ||
68 | -> (Double, Double) -- ^ result and absolute error | ||
69 | derivCentral = derivGen 0 | ||
70 | |||
71 | -- | 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. | ||
72 | derivForward :: Double -- ^ initial step size | ||
73 | -> (Double -> Double) -- ^ function | ||
74 | -> Double -- ^ point where the derivative is taken | ||
75 | -> (Double, Double) -- ^ result and absolute error | ||
76 | derivForward = derivGen 1 | ||
77 | |||
78 | -- | Adaptive backward difference algorithm, /gsl_deriv_backward/. | ||
79 | derivBackward ::Double -- ^ initial step size | ||
80 | -> (Double -> Double) -- ^ function | ||
81 | -> Double -- ^ point where the derivative is taken | ||
82 | -> (Double, Double) -- ^ result and absolute error | ||
83 | derivBackward = derivGen 2 | ||
84 | |||
85 | {- | conversion of Haskell functions into function pointers that can be used in the C side | ||
86 | -} | ||
87 | foreign import ccall safe "wrapper" mkfun:: (Double -> Ptr() -> Double) -> IO( FunPtr (Double -> Ptr() -> Double)) | ||
diff --git a/lib/Numeric/GSL/Fitting.hs b/lib/Numeric/GSL/Fitting.hs deleted file mode 100644 index c4f3a91..0000000 --- a/lib/Numeric/GSL/Fitting.hs +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
1 | {- | | ||
2 | Module : Numeric.GSL.Fitting | ||
3 | Copyright : (c) Alberto Ruiz 2010 | ||
4 | License : GPL | ||
5 | |||
6 | Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
7 | Stability : provisional | ||
8 | Portability : uses ffi | ||
9 | |||
10 | Nonlinear Least-Squares Fitting | ||
11 | |||
12 | <http://www.gnu.org/software/gsl/manual/html_node/Nonlinear-Least_002dSquares-Fitting.html> | ||
13 | |||
14 | The example program in the GSL manual (see examples/fitting.hs): | ||
15 | |||
16 | @ | ||
17 | dat = [ | ||
18 | ([0.0],([6.0133918608118675],0.1)), | ||
19 | ([1.0],([5.5153769909966535],0.1)), | ||
20 | ([2.0],([5.261094606015287],0.1)), | ||
21 | ... | ||
22 | ([39.0],([1.0619821710802808],0.1))] | ||
23 | |||
24 | expModel [a,lambda,b] [t] = [a * exp (-lambda * t) + b] | ||
25 | |||
26 | expModelDer [a,lambda,b] [t] = [[exp (-lambda * t), -t * a * exp(-lambda*t) , 1]] | ||
27 | |||
28 | (sol,path) = fitModelScaled 1E-4 1E-4 20 (expModel, expModelDer) dat [1,0,0] | ||
29 | @ | ||
30 | |||
31 | >>> path | ||
32 | (6><5) | ||
33 | [ 1.0, 76.45780563978782, 1.6465931240727802, 1.8147715267618197e-2, 0.6465931240727797 | ||
34 | , 2.0, 37.683816318260355, 2.858760367632973, 8.092094813253975e-2, 1.4479636296208662 | ||
35 | , 3.0, 9.5807893736187, 4.948995119561291, 0.11942927999921617, 1.0945766509238248 | ||
36 | , 4.0, 5.630494933603935, 5.021755718065913, 0.10287787128056883, 1.0338835440862608 | ||
37 | , 5.0, 5.443976278682909, 5.045204331329302, 0.10405523433131504, 1.019416067207375 | ||
38 | , 6.0, 5.4439736648994685, 5.045357818922331, 0.10404905846029407, 1.0192487112786812 ] | ||
39 | >>> sol | ||
40 | [(5.045357818922331,6.027976702418132e-2), | ||
41 | (0.10404905846029407,3.157045047172834e-3), | ||
42 | (1.0192487112786812,3.782067731353722e-2)] | ||
43 | |||
44 | -} | ||
45 | ----------------------------------------------------------------------------- | ||
46 | |||
47 | module Numeric.GSL.Fitting ( | ||
48 | -- * Levenberg-Marquardt | ||
49 | nlFitting, FittingMethod(..), | ||
50 | -- * Utilities | ||
51 | fitModelScaled, fitModel | ||
52 | ) where | ||
53 | |||
54 | import Data.Packed.Internal | ||
55 | import Numeric.LinearAlgebra | ||
56 | import Numeric.GSL.Internal | ||
57 | |||
58 | import Foreign.Ptr(FunPtr, freeHaskellFunPtr) | ||
59 | import Foreign.C.Types | ||
60 | import System.IO.Unsafe(unsafePerformIO) | ||
61 | |||
62 | ------------------------------------------------------------------------- | ||
63 | |||
64 | data FittingMethod = LevenbergMarquardtScaled -- ^ Interface to gsl_multifit_fdfsolver_lmsder. This is a robust and efficient version of the Levenberg-Marquardt algorithm as implemented in the scaled lmder routine in minpack. Minpack was written by Jorge J. More, Burton S. Garbow and Kenneth E. Hillstrom. | ||
65 | | LevenbergMarquardt -- ^ This is an unscaled version of the lmder algorithm. The elements of the diagonal scaling matrix D are set to 1. This algorithm may be useful in circumstances where the scaled version of lmder converges too slowly, or the function is already scaled appropriately. | ||
66 | deriving (Enum,Eq,Show,Bounded) | ||
67 | |||
68 | |||
69 | -- | Nonlinear multidimensional least-squares fitting. | ||
70 | nlFitting :: FittingMethod | ||
71 | -> Double -- ^ absolute tolerance | ||
72 | -> Double -- ^ relative tolerance | ||
73 | -> Int -- ^ maximum number of iterations allowed | ||
74 | -> (Vector Double -> Vector Double) -- ^ function to be minimized | ||
75 | -> (Vector Double -> Matrix Double) -- ^ Jacobian | ||
76 | -> Vector Double -- ^ starting point | ||
77 | -> (Vector Double, Matrix Double) -- ^ solution vector and optimization path | ||
78 | |||
79 | nlFitting method epsabs epsrel maxit fun jac xinit = nlFitGen (fi (fromEnum method)) fun jac xinit epsabs epsrel maxit | ||
80 | |||
81 | nlFitGen m f jac xiv epsabs epsrel maxit = unsafePerformIO $ do | ||
82 | let p = dim xiv | ||
83 | n = dim (f xiv) | ||
84 | fp <- mkVecVecfun (aux_vTov (checkdim1 n p . f)) | ||
85 | jp <- mkVecMatfun (aux_vTom (checkdim2 n p . jac)) | ||
86 | rawpath <- createMatrix RowMajor maxit (2+p) | ||
87 | app2 (c_nlfit m fp jp epsabs epsrel (fi maxit) (fi n)) vec xiv mat rawpath "c_nlfit" | ||
88 | let it = round (rawpath @@> (maxit-1,0)) | ||
89 | path = takeRows it rawpath | ||
90 | [sol] = toRows $ dropRows (it-1) path | ||
91 | freeHaskellFunPtr fp | ||
92 | freeHaskellFunPtr jp | ||
93 | return (subVector 2 p sol, path) | ||
94 | |||
95 | foreign import ccall safe "nlfit" | ||
96 | c_nlfit:: CInt -> FunPtr TVV -> FunPtr TVM -> Double -> Double -> CInt -> CInt -> TVM | ||
97 | |||
98 | ------------------------------------------------------- | ||
99 | |||
100 | checkdim1 n _p v | ||
101 | | dim v == n = v | ||
102 | | otherwise = error $ "Error: "++ show n | ||
103 | ++ " components expected in the result of the function supplied to nlFitting" | ||
104 | |||
105 | checkdim2 n p m | ||
106 | | rows m == n && cols m == p = m | ||
107 | | otherwise = error $ "Error: "++ show n ++ "x" ++ show p | ||
108 | ++ " Jacobian expected in nlFitting" | ||
109 | |||
110 | ------------------------------------------------------------ | ||
111 | |||
112 | err (model,deriv) dat vsol = zip sol errs where | ||
113 | sol = toList vsol | ||
114 | c = max 1 (chi/sqrt (fromIntegral dof)) | ||
115 | dof = length dat - (rows cov) | ||
116 | chi = norm2 (fromList $ cost (resMs model) dat sol) | ||
117 | js = fromLists $ jacobian (resDs deriv) dat sol | ||
118 | cov = inv $ trans js <> js | ||
119 | errs = toList $ scalar c * sqrt (takeDiag cov) | ||
120 | |||
121 | |||
122 | |||
123 | -- | Higher level interface to 'nlFitting' 'LevenbergMarquardtScaled'. The optimization function and | ||
124 | -- Jacobian are automatically built from a model f vs x = y and its derivatives, and a list of | ||
125 | -- instances (x, (y,sigma)) to be fitted. | ||
126 | |||
127 | fitModelScaled | ||
128 | :: Double -- ^ absolute tolerance | ||
129 | -> Double -- ^ relative tolerance | ||
130 | -> Int -- ^ maximum number of iterations allowed | ||
131 | -> ([Double] -> x -> [Double], [Double] -> x -> [[Double]]) -- ^ (model, derivatives) | ||
132 | -> [(x, ([Double], Double))] -- ^ instances | ||
133 | -> [Double] -- ^ starting point | ||
134 | -> ([(Double, Double)], Matrix Double) -- ^ (solution, error) and optimization path | ||
135 | fitModelScaled epsabs epsrel maxit (model,deriv) dt xin = (err (model,deriv) dt sol, path) where | ||
136 | (sol,path) = nlFitting LevenbergMarquardtScaled epsabs epsrel maxit | ||
137 | (fromList . cost (resMs model) dt . toList) | ||
138 | (fromLists . jacobian (resDs deriv) dt . toList) | ||
139 | (fromList xin) | ||
140 | |||
141 | |||
142 | |||
143 | -- | Higher level interface to 'nlFitting' 'LevenbergMarquardt'. The optimization function and | ||
144 | -- Jacobian are automatically built from a model f vs x = y and its derivatives, and a list of | ||
145 | -- instances (x,y) to be fitted. | ||
146 | |||
147 | fitModel :: Double -- ^ absolute tolerance | ||
148 | -> Double -- ^ relative tolerance | ||
149 | -> Int -- ^ maximum number of iterations allowed | ||
150 | -> ([Double] -> x -> [Double], [Double] -> x -> [[Double]]) -- ^ (model, derivatives) | ||
151 | -> [(x, [Double])] -- ^ instances | ||
152 | -> [Double] -- ^ starting point | ||
153 | -> ([Double], Matrix Double) -- ^ solution and optimization path | ||
154 | fitModel epsabs epsrel maxit (model,deriv) dt xin = (toList sol, path) where | ||
155 | (sol,path) = nlFitting LevenbergMarquardt epsabs epsrel maxit | ||
156 | (fromList . cost (resM model) dt . toList) | ||
157 | (fromLists . jacobian (resD deriv) dt . toList) | ||
158 | (fromList xin) | ||
159 | |||
160 | cost model ds vs = concatMap (model vs) ds | ||
161 | |||
162 | jacobian modelDer ds vs = concatMap (modelDer vs) ds | ||
163 | |||
164 | -- | Model-to-residual for association pairs with sigma, to be used with 'fitModel'. | ||
165 | resMs :: ([Double] -> x -> [Double]) -> [Double] -> (x, ([Double], Double)) -> [Double] | ||
166 | resMs m v = \(x,(ys,s)) -> zipWith (g s) (m v x) ys where g s a b = (a-b)/s | ||
167 | |||
168 | -- | Associated derivative for 'resMs'. | ||
169 | resDs :: ([Double] -> x -> [[Double]]) -> [Double] -> (x, ([Double], Double)) -> [[Double]] | ||
170 | resDs m v = \(x,(_,s)) -> map (map (/s)) (m v x) | ||
171 | |||
172 | -- | Model-to-residual for association pairs, to be used with 'fitModel'. It is equivalent | ||
173 | -- to 'resMs' with all sigmas = 1. | ||
174 | resM :: ([Double] -> x -> [Double]) -> [Double] -> (x, [Double]) -> [Double] | ||
175 | resM m v = \(x,ys) -> zipWith g (m v x) ys where g a b = a-b | ||
176 | |||
177 | -- | Associated derivative for 'resM'. | ||
178 | resD :: ([Double] -> x -> [[Double]]) -> [Double] -> (x, [Double]) -> [[Double]] | ||
179 | resD m v = \(x,_) -> m v x | ||
diff --git a/lib/Numeric/GSL/Fourier.hs b/lib/Numeric/GSL/Fourier.hs deleted file mode 100644 index 86aedd6..0000000 --- a/lib/Numeric/GSL/Fourier.hs +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | {-# LANGUAGE ForeignFunctionInterface #-} | ||
2 | ----------------------------------------------------------------------------- | ||
3 | {- | | ||
4 | Module : Numeric.GSL.Fourier | ||
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 | Fourier Transform. | ||
13 | |||
14 | <http://www.gnu.org/software/gsl/manual/html_node/Fast-Fourier-Transforms.html#Fast-Fourier-Transforms> | ||
15 | |||
16 | -} | ||
17 | ----------------------------------------------------------------------------- | ||
18 | module Numeric.GSL.Fourier ( | ||
19 | fft, | ||
20 | ifft | ||
21 | ) where | ||
22 | |||
23 | import Data.Packed.Internal | ||
24 | import Data.Complex | ||
25 | import Foreign.C.Types | ||
26 | import System.IO.Unsafe (unsafePerformIO) | ||
27 | |||
28 | genfft code v = unsafePerformIO $ do | ||
29 | r <- createVector (dim v) | ||
30 | app2 (c_fft code) vec v vec r "fft" | ||
31 | return r | ||
32 | |||
33 | foreign import ccall unsafe "gsl-aux.h fft" c_fft :: CInt -> TCVCV | ||
34 | |||
35 | |||
36 | {- | Fast 1D Fourier transform of a 'Vector' @(@'Complex' 'Double'@)@ using /gsl_fft_complex_forward/. It uses the same scaling conventions as GNU Octave. | ||
37 | |||
38 | >>> fft (fromList [1,2,3,4]) | ||
39 | fromList [10.0 :+ 0.0,(-2.0) :+ 2.0,(-2.0) :+ 0.0,(-2.0) :+ (-2.0)] | ||
40 | |||
41 | -} | ||
42 | fft :: Vector (Complex Double) -> Vector (Complex Double) | ||
43 | fft = genfft 0 | ||
44 | |||
45 | -- | The inverse of 'fft', using /gsl_fft_complex_inverse/. | ||
46 | ifft :: Vector (Complex Double) -> Vector (Complex Double) | ||
47 | ifft = genfft 1 | ||
diff --git a/lib/Numeric/GSL/Integration.hs b/lib/Numeric/GSL/Integration.hs deleted file mode 100644 index 5f0a415..0000000 --- a/lib/Numeric/GSL/Integration.hs +++ /dev/null | |||
@@ -1,250 +0,0 @@ | |||
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 | |||
diff --git a/lib/Numeric/GSL/Internal.hs b/lib/Numeric/GSL/Internal.hs deleted file mode 100644 index 69a9750..0000000 --- a/lib/Numeric/GSL/Internal.hs +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | -- Module : Numeric.GSL.Internal | ||
2 | -- Copyright : (c) Alberto Ruiz 2009 | ||
3 | -- License : GPL | ||
4 | -- | ||
5 | -- Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
6 | -- Stability : provisional | ||
7 | -- Portability : uses ffi | ||
8 | -- | ||
9 | -- Auxiliary functions. | ||
10 | -- | ||
11 | -- #hide | ||
12 | |||
13 | module Numeric.GSL.Internal where | ||
14 | |||
15 | import Data.Packed.Internal | ||
16 | |||
17 | import Foreign.Marshal.Array(copyArray) | ||
18 | import Foreign.Ptr(Ptr, FunPtr) | ||
19 | import Foreign.C.Types | ||
20 | import System.IO.Unsafe(unsafePerformIO) | ||
21 | |||
22 | iv :: (Vector Double -> Double) -> (CInt -> Ptr Double -> Double) | ||
23 | iv f n p = f (createV (fromIntegral n) copy "iv") where | ||
24 | copy n' q = do | ||
25 | copyArray q p (fromIntegral n') | ||
26 | return 0 | ||
27 | |||
28 | -- | conversion of Haskell functions into function pointers that can be used in the C side | ||
29 | foreign import ccall safe "wrapper" | ||
30 | mkVecfun :: (CInt -> Ptr Double -> Double) | ||
31 | -> IO( FunPtr (CInt -> Ptr Double -> Double)) | ||
32 | |||
33 | foreign import ccall safe "wrapper" | ||
34 | mkVecVecfun :: TVV -> IO (FunPtr TVV) | ||
35 | |||
36 | foreign import ccall safe "wrapper" | ||
37 | mkDoubleVecVecfun :: (Double -> TVV) -> IO (FunPtr (Double -> TVV)) | ||
38 | |||
39 | foreign import ccall safe "wrapper" | ||
40 | mkDoublefun :: (Double -> Double) -> IO (FunPtr (Double -> Double)) | ||
41 | |||
42 | aux_vTov :: (Vector Double -> Vector Double) -> TVV | ||
43 | aux_vTov f n p nr r = g where | ||
44 | v = f x | ||
45 | x = createV (fromIntegral n) copy "aux_vTov" | ||
46 | copy n' q = do | ||
47 | copyArray q p (fromIntegral n') | ||
48 | return 0 | ||
49 | g = do unsafeWith v $ \p' -> copyArray r p' (fromIntegral nr) | ||
50 | return 0 | ||
51 | |||
52 | foreign import ccall safe "wrapper" | ||
53 | mkVecMatfun :: TVM -> IO (FunPtr TVM) | ||
54 | |||
55 | foreign import ccall safe "wrapper" | ||
56 | mkDoubleVecMatfun :: (Double -> TVM) -> IO (FunPtr (Double -> TVM)) | ||
57 | |||
58 | aux_vTom :: (Vector Double -> Matrix Double) -> TVM | ||
59 | aux_vTom f n p rr cr r = g where | ||
60 | v = flatten $ f x | ||
61 | x = createV (fromIntegral n) copy "aux_vTov" | ||
62 | copy n' q = do | ||
63 | copyArray q p (fromIntegral n') | ||
64 | return 0 | ||
65 | g = do unsafeWith v $ \p' -> copyArray r p' (fromIntegral $ rr*cr) | ||
66 | return 0 | ||
67 | |||
68 | createV n fun msg = unsafePerformIO $ do | ||
69 | r <- createVector n | ||
70 | app1 fun vec r msg | ||
71 | return r | ||
72 | |||
73 | createMIO r c fun msg = do | ||
74 | res <- createMatrix RowMajor r c | ||
75 | app1 fun mat res msg | ||
76 | return res | ||
diff --git a/lib/Numeric/GSL/Minimization.hs b/lib/Numeric/GSL/Minimization.hs deleted file mode 100644 index 1879dab..0000000 --- a/lib/Numeric/GSL/Minimization.hs +++ /dev/null | |||
@@ -1,227 +0,0 @@ | |||
1 | {-# LANGUAGE ForeignFunctionInterface #-} | ||
2 | ----------------------------------------------------------------------------- | ||
3 | {- | | ||
4 | Module : Numeric.GSL.Minimization | ||
5 | Copyright : (c) Alberto Ruiz 2006-9 | ||
6 | License : GPL-style | ||
7 | |||
8 | Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
9 | Stability : provisional | ||
10 | Portability : uses ffi | ||
11 | |||
12 | Minimization of a multidimensional function using some of the algorithms described in: | ||
13 | |||
14 | <http://www.gnu.org/software/gsl/manual/html_node/Multidimensional-Minimization.html> | ||
15 | |||
16 | The example in the GSL manual: | ||
17 | |||
18 | @ | ||
19 | f [x,y] = 10*(x-1)^2 + 20*(y-2)^2 + 30 | ||
20 | |||
21 | main = do | ||
22 | let (s,p) = minimize NMSimplex2 1E-2 30 [1,1] f [5,7] | ||
23 | print s | ||
24 | print p | ||
25 | @ | ||
26 | |||
27 | >>> main | ||
28 | [0.9920430849306288,1.9969168063253182] | ||
29 | 0.000 512.500 1.130 6.500 5.000 | ||
30 | 1.000 290.625 1.409 5.250 4.000 | ||
31 | 2.000 290.625 1.409 5.250 4.000 | ||
32 | 3.000 252.500 1.409 5.500 1.000 | ||
33 | ... | ||
34 | 22.000 30.001 0.013 0.992 1.997 | ||
35 | 23.000 30.001 0.008 0.992 1.997 | ||
36 | |||
37 | The path to the solution can be graphically shown by means of: | ||
38 | |||
39 | @'Graphics.Plot.mplot' $ drop 3 ('toColumns' p)@ | ||
40 | |||
41 | Taken from the GSL manual: | ||
42 | |||
43 | The vector Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm is a quasi-Newton method which builds up an approximation to the second derivatives of the function f using the difference between successive gradient vectors. By combining the first and second derivatives the algorithm is able to take Newton-type steps towards the function minimum, assuming quadratic behavior in that region. | ||
44 | |||
45 | The bfgs2 version of this minimizer is the most efficient version available, and is a faithful implementation of the line minimization scheme described in Fletcher's Practical Methods of Optimization, Algorithms 2.6.2 and 2.6.4. It supercedes the original bfgs routine and requires substantially fewer function and gradient evaluations. The user-supplied tolerance tol corresponds to the parameter \sigma used by Fletcher. A value of 0.1 is recommended for typical use (larger values correspond to less accurate line searches). | ||
46 | |||
47 | The nmsimplex2 version is a new O(N) implementation of the earlier O(N^2) nmsimplex minimiser. It calculates the size of simplex as the rms distance of each vertex from the center rather than the mean distance, which has the advantage of allowing a linear update. | ||
48 | |||
49 | -} | ||
50 | |||
51 | ----------------------------------------------------------------------------- | ||
52 | module Numeric.GSL.Minimization ( | ||
53 | minimize, minimizeV, MinimizeMethod(..), | ||
54 | minimizeD, minimizeVD, MinimizeMethodD(..), | ||
55 | uniMinimize, UniMinimizeMethod(..), | ||
56 | |||
57 | minimizeNMSimplex, | ||
58 | minimizeConjugateGradient, | ||
59 | minimizeVectorBFGS2 | ||
60 | ) where | ||
61 | |||
62 | |||
63 | import Data.Packed.Internal | ||
64 | import Data.Packed.Matrix | ||
65 | import Numeric.GSL.Internal | ||
66 | |||
67 | import Foreign.Ptr(Ptr, FunPtr, freeHaskellFunPtr) | ||
68 | import Foreign.C.Types | ||
69 | import System.IO.Unsafe(unsafePerformIO) | ||
70 | |||
71 | ------------------------------------------------------------------------ | ||
72 | |||
73 | {-# DEPRECATED minimizeNMSimplex "use minimize NMSimplex2 eps maxit sizes f xi" #-} | ||
74 | minimizeNMSimplex f xi szs eps maxit = minimize NMSimplex eps maxit szs f xi | ||
75 | |||
76 | {-# DEPRECATED minimizeConjugateGradient "use minimizeD ConjugateFR eps maxit step tol f g xi" #-} | ||
77 | minimizeConjugateGradient step tol eps maxit f g xi = minimizeD ConjugateFR eps maxit step tol f g xi | ||
78 | |||
79 | {-# DEPRECATED minimizeVectorBFGS2 "use minimizeD VectorBFGS2 eps maxit step tol f g xi" #-} | ||
80 | minimizeVectorBFGS2 step tol eps maxit f g xi = minimizeD VectorBFGS2 eps maxit step tol f g xi | ||
81 | |||
82 | ------------------------------------------------------------------------- | ||
83 | |||
84 | data UniMinimizeMethod = GoldenSection | ||
85 | | BrentMini | ||
86 | | QuadGolden | ||
87 | deriving (Enum, Eq, Show, Bounded) | ||
88 | |||
89 | -- | Onedimensional minimization. | ||
90 | |||
91 | uniMinimize :: UniMinimizeMethod -- ^ The method used. | ||
92 | -> Double -- ^ desired precision of the solution | ||
93 | -> Int -- ^ maximum number of iterations allowed | ||
94 | -> (Double -> Double) -- ^ function to minimize | ||
95 | -> Double -- ^ guess for the location of the minimum | ||
96 | -> Double -- ^ lower bound of search interval | ||
97 | -> Double -- ^ upper bound of search interval | ||
98 | -> (Double, Matrix Double) -- ^ solution and optimization path | ||
99 | |||
100 | uniMinimize method epsrel maxit fun xmin xl xu = uniMinimizeGen (fi (fromEnum method)) fun xmin xl xu epsrel maxit | ||
101 | |||
102 | uniMinimizeGen m f xmin xl xu epsrel maxit = unsafePerformIO $ do | ||
103 | fp <- mkDoublefun f | ||
104 | rawpath <- createMIO maxit 4 | ||
105 | (c_uniMinize m fp epsrel (fi maxit) xmin xl xu) | ||
106 | "uniMinimize" | ||
107 | let it = round (rawpath @@> (maxit-1,0)) | ||
108 | path = takeRows it rawpath | ||
109 | [sol] = toLists $ dropRows (it-1) path | ||
110 | freeHaskellFunPtr fp | ||
111 | return (sol !! 1, path) | ||
112 | |||
113 | |||
114 | foreign import ccall safe "uniMinimize" | ||
115 | c_uniMinize:: CInt -> FunPtr (Double -> Double) -> Double -> CInt -> Double -> Double -> Double -> TM | ||
116 | |||
117 | data MinimizeMethod = NMSimplex | ||
118 | | NMSimplex2 | ||
119 | deriving (Enum,Eq,Show,Bounded) | ||
120 | |||
121 | -- | Minimization without derivatives | ||
122 | minimize :: MinimizeMethod | ||
123 | -> Double -- ^ desired precision of the solution (size test) | ||
124 | -> Int -- ^ maximum number of iterations allowed | ||
125 | -> [Double] -- ^ sizes of the initial search box | ||
126 | -> ([Double] -> Double) -- ^ function to minimize | ||
127 | -> [Double] -- ^ starting point | ||
128 | -> ([Double], Matrix Double) -- ^ solution vector and optimization path | ||
129 | |||
130 | -- | Minimization without derivatives (vector version) | ||
131 | minimizeV :: MinimizeMethod | ||
132 | -> Double -- ^ desired precision of the solution (size test) | ||
133 | -> Int -- ^ maximum number of iterations allowed | ||
134 | -> Vector Double -- ^ sizes of the initial search box | ||
135 | -> (Vector Double -> Double) -- ^ function to minimize | ||
136 | -> Vector Double -- ^ starting point | ||
137 | -> (Vector Double, Matrix Double) -- ^ solution vector and optimization path | ||
138 | |||
139 | minimize method eps maxit sz f xi = v2l $ minimizeV method eps maxit (fromList sz) (f.toList) (fromList xi) | ||
140 | where v2l (v,m) = (toList v, m) | ||
141 | |||
142 | ww2 w1 o1 w2 o2 f = w1 o1 $ \a1 -> w2 o2 $ \a2 -> f a1 a2 | ||
143 | |||
144 | minimizeV method eps maxit szv f xiv = unsafePerformIO $ do | ||
145 | let n = dim xiv | ||
146 | fp <- mkVecfun (iv f) | ||
147 | rawpath <- ww2 vec xiv vec szv $ \xiv' szv' -> | ||
148 | createMIO maxit (n+3) | ||
149 | (c_minimize (fi (fromEnum method)) fp eps (fi maxit) // xiv' // szv') | ||
150 | "minimize" | ||
151 | let it = round (rawpath @@> (maxit-1,0)) | ||
152 | path = takeRows it rawpath | ||
153 | sol = cdat $ dropColumns 3 $ dropRows (it-1) path | ||
154 | freeHaskellFunPtr fp | ||
155 | return (sol, path) | ||
156 | |||
157 | |||
158 | foreign import ccall safe "gsl-aux.h minimize" | ||
159 | c_minimize:: CInt -> FunPtr (CInt -> Ptr Double -> Double) -> Double -> CInt -> TVVM | ||
160 | |||
161 | ---------------------------------------------------------------------------------- | ||
162 | |||
163 | |||
164 | data MinimizeMethodD = ConjugateFR | ||
165 | | ConjugatePR | ||
166 | | VectorBFGS | ||
167 | | VectorBFGS2 | ||
168 | | SteepestDescent | ||
169 | deriving (Enum,Eq,Show,Bounded) | ||
170 | |||
171 | -- | Minimization with derivatives. | ||
172 | minimizeD :: MinimizeMethodD | ||
173 | -> Double -- ^ desired precision of the solution (gradient test) | ||
174 | -> Int -- ^ maximum number of iterations allowed | ||
175 | -> Double -- ^ size of the first trial step | ||
176 | -> Double -- ^ tol (precise meaning depends on method) | ||
177 | -> ([Double] -> Double) -- ^ function to minimize | ||
178 | -> ([Double] -> [Double]) -- ^ gradient | ||
179 | -> [Double] -- ^ starting point | ||
180 | -> ([Double], Matrix Double) -- ^ solution vector and optimization path | ||
181 | |||
182 | -- | Minimization with derivatives (vector version) | ||
183 | minimizeVD :: MinimizeMethodD | ||
184 | -> Double -- ^ desired precision of the solution (gradient test) | ||
185 | -> Int -- ^ maximum number of iterations allowed | ||
186 | -> Double -- ^ size of the first trial step | ||
187 | -> Double -- ^ tol (precise meaning depends on method) | ||
188 | -> (Vector Double -> Double) -- ^ function to minimize | ||
189 | -> (Vector Double -> Vector Double) -- ^ gradient | ||
190 | -> Vector Double -- ^ starting point | ||
191 | -> (Vector Double, Matrix Double) -- ^ solution vector and optimization path | ||
192 | |||
193 | minimizeD method eps maxit istep tol f df xi = v2l $ minimizeVD | ||
194 | method eps maxit istep tol (f.toList) (fromList.df.toList) (fromList xi) | ||
195 | where v2l (v,m) = (toList v, m) | ||
196 | |||
197 | |||
198 | minimizeVD method eps maxit istep tol f df xiv = unsafePerformIO $ do | ||
199 | let n = dim xiv | ||
200 | f' = f | ||
201 | df' = (checkdim1 n . df) | ||
202 | fp <- mkVecfun (iv f') | ||
203 | dfp <- mkVecVecfun (aux_vTov df') | ||
204 | rawpath <- vec xiv $ \xiv' -> | ||
205 | createMIO maxit (n+2) | ||
206 | (c_minimizeD (fi (fromEnum method)) fp dfp istep tol eps (fi maxit) // xiv') | ||
207 | "minimizeD" | ||
208 | let it = round (rawpath @@> (maxit-1,0)) | ||
209 | path = takeRows it rawpath | ||
210 | sol = cdat $ dropColumns 2 $ dropRows (it-1) path | ||
211 | freeHaskellFunPtr fp | ||
212 | freeHaskellFunPtr dfp | ||
213 | return (sol,path) | ||
214 | |||
215 | foreign import ccall safe "gsl-aux.h minimizeD" | ||
216 | c_minimizeD :: CInt | ||
217 | -> FunPtr (CInt -> Ptr Double -> Double) | ||
218 | -> FunPtr TVV | ||
219 | -> Double -> Double -> Double -> CInt | ||
220 | -> TVM | ||
221 | |||
222 | --------------------------------------------------------------------- | ||
223 | |||
224 | checkdim1 n v | ||
225 | | dim v == n = v | ||
226 | | otherwise = error $ "Error: "++ show n | ||
227 | ++ " components expected in the result of the gradient supplied to minimizeD" | ||
diff --git a/lib/Numeric/GSL/ODE.hs b/lib/Numeric/GSL/ODE.hs deleted file mode 100644 index 9a29085..0000000 --- a/lib/Numeric/GSL/ODE.hs +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | {- | | ||
2 | Module : Numeric.GSL.ODE | ||
3 | Copyright : (c) Alberto Ruiz 2010 | ||
4 | License : GPL | ||
5 | |||
6 | Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
7 | Stability : provisional | ||
8 | Portability : uses ffi | ||
9 | |||
10 | Solution of ordinary differential equation (ODE) initial value problems. | ||
11 | |||
12 | <http://www.gnu.org/software/gsl/manual/html_node/Ordinary-Differential-Equations.html> | ||
13 | |||
14 | A simple example: | ||
15 | |||
16 | @ | ||
17 | import Numeric.GSL.ODE | ||
18 | import Numeric.LinearAlgebra | ||
19 | import Numeric.LinearAlgebra.Util(mplot) | ||
20 | |||
21 | xdot t [x,v] = [v, -0.95*x - 0.1*v] | ||
22 | |||
23 | ts = linspace 100 (0,20 :: Double) | ||
24 | |||
25 | sol = odeSolve xdot [10,0] ts | ||
26 | |||
27 | main = mplot (ts : toColumns sol) | ||
28 | @ | ||
29 | |||
30 | -} | ||
31 | ----------------------------------------------------------------------------- | ||
32 | |||
33 | module Numeric.GSL.ODE ( | ||
34 | odeSolve, odeSolveV, ODEMethod(..), Jacobian | ||
35 | ) where | ||
36 | |||
37 | import Data.Packed.Internal | ||
38 | import Numeric.GSL.Internal | ||
39 | |||
40 | import Foreign.Ptr(FunPtr, nullFunPtr, freeHaskellFunPtr) | ||
41 | import Foreign.C.Types | ||
42 | import System.IO.Unsafe(unsafePerformIO) | ||
43 | |||
44 | ------------------------------------------------------------------------- | ||
45 | |||
46 | type Jacobian = Double -> Vector Double -> Matrix Double | ||
47 | |||
48 | -- | Stepping functions | ||
49 | data ODEMethod = RK2 -- ^ Embedded Runge-Kutta (2, 3) method. | ||
50 | | RK4 -- ^ 4th order (classical) Runge-Kutta. The error estimate is obtained by halving the step-size. For more efficient estimate of the error, use the embedded methods. | ||
51 | | RKf45 -- ^ Embedded Runge-Kutta-Fehlberg (4, 5) method. This method is a good general-purpose integrator. | ||
52 | | RKck -- ^ Embedded Runge-Kutta Cash-Karp (4, 5) method. | ||
53 | | RK8pd -- ^ Embedded Runge-Kutta Prince-Dormand (8,9) method. | ||
54 | | RK2imp Jacobian -- ^ Implicit 2nd order Runge-Kutta at Gaussian points. | ||
55 | | RK4imp Jacobian -- ^ Implicit 4th order Runge-Kutta at Gaussian points. | ||
56 | | BSimp Jacobian -- ^ Implicit Bulirsch-Stoer method of Bader and Deuflhard. The method is generally suitable for stiff problems. | ||
57 | | RK1imp Jacobian -- ^ Implicit Gaussian first order Runge-Kutta. Also known as implicit Euler or backward Euler method. Error estimation is carried out by the step doubling method. | ||
58 | | MSAdams -- ^ A variable-coefficient linear multistep Adams method in Nordsieck form. This stepper uses explicit Adams-Bashforth (predictor) and implicit Adams-Moulton (corrector) methods in P(EC)^m functional iteration mode. Method order varies dynamically between 1 and 12. | ||
59 | | MSBDF Jacobian -- ^ A variable-coefficient linear multistep backward differentiation formula (BDF) method in Nordsieck form. This stepper uses the explicit BDF formula as predictor and implicit BDF formula as corrector. A modified Newton iteration method is used to solve the system of non-linear equations. Method order varies dynamically between 1 and 5. The method is generally suitable for stiff problems. | ||
60 | |||
61 | |||
62 | -- | A version of 'odeSolveV' with reasonable default parameters and system of equations defined using lists. | ||
63 | odeSolve | ||
64 | :: (Double -> [Double] -> [Double]) -- ^ xdot(t,x) | ||
65 | -> [Double] -- ^ initial conditions | ||
66 | -> Vector Double -- ^ desired solution times | ||
67 | -> Matrix Double -- ^ solution | ||
68 | odeSolve xdot xi ts = odeSolveV RKf45 hi epsAbs epsRel (l2v xdot) (fromList xi) ts | ||
69 | where hi = (ts@>1 - ts@>0)/100 | ||
70 | epsAbs = 1.49012e-08 | ||
71 | epsRel = 1.49012e-08 | ||
72 | l2v f = \t -> fromList . f t . toList | ||
73 | |||
74 | -- | Evolution of the system with adaptive step-size control. | ||
75 | odeSolveV | ||
76 | :: ODEMethod | ||
77 | -> Double -- ^ initial step size | ||
78 | -> Double -- ^ absolute tolerance for the state vector | ||
79 | -> Double -- ^ relative tolerance for the state vector | ||
80 | -> (Double -> Vector Double -> Vector Double) -- ^ xdot(t,x) | ||
81 | -> Vector Double -- ^ initial conditions | ||
82 | -> Vector Double -- ^ desired solution times | ||
83 | -> Matrix Double -- ^ solution | ||
84 | odeSolveV RK2 = odeSolveV' 0 Nothing | ||
85 | odeSolveV RK4 = odeSolveV' 1 Nothing | ||
86 | odeSolveV RKf45 = odeSolveV' 2 Nothing | ||
87 | odeSolveV RKck = odeSolveV' 3 Nothing | ||
88 | odeSolveV RK8pd = odeSolveV' 4 Nothing | ||
89 | odeSolveV (RK2imp jac) = odeSolveV' 5 (Just jac) | ||
90 | odeSolveV (RK4imp jac) = odeSolveV' 6 (Just jac) | ||
91 | odeSolveV (BSimp jac) = odeSolveV' 7 (Just jac) | ||
92 | odeSolveV (RK1imp jac) = odeSolveV' 8 (Just jac) | ||
93 | odeSolveV MSAdams = odeSolveV' 9 Nothing | ||
94 | odeSolveV (MSBDF jac) = odeSolveV' 10 (Just jac) | ||
95 | |||
96 | |||
97 | odeSolveV' | ||
98 | :: CInt | ||
99 | -> Maybe (Double -> Vector Double -> Matrix Double) -- ^ optional jacobian | ||
100 | -> Double -- ^ initial step size | ||
101 | -> Double -- ^ absolute tolerance for the state vector | ||
102 | -> Double -- ^ relative tolerance for the state vector | ||
103 | -> (Double -> Vector Double -> Vector Double) -- ^ xdot(t,x) | ||
104 | -> Vector Double -- ^ initial conditions | ||
105 | -> Vector Double -- ^ desired solution times | ||
106 | -> Matrix Double -- ^ solution | ||
107 | odeSolveV' method mbjac h epsAbs epsRel f xiv ts = unsafePerformIO $ do | ||
108 | let n = dim xiv | ||
109 | fp <- mkDoubleVecVecfun (\t -> aux_vTov (checkdim1 n . f t)) | ||
110 | jp <- case mbjac of | ||
111 | Just jac -> mkDoubleVecMatfun (\t -> aux_vTom (checkdim2 n . jac t)) | ||
112 | Nothing -> return nullFunPtr | ||
113 | sol <- vec xiv $ \xiv' -> | ||
114 | vec (checkTimes ts) $ \ts' -> | ||
115 | createMIO (dim ts) n | ||
116 | (ode_c (method) h epsAbs epsRel fp jp // xiv' // ts' ) | ||
117 | "ode" | ||
118 | freeHaskellFunPtr fp | ||
119 | return sol | ||
120 | |||
121 | foreign import ccall safe "ode" | ||
122 | ode_c :: CInt -> Double -> Double -> Double -> FunPtr (Double -> TVV) -> FunPtr (Double -> TVM) -> TVVM | ||
123 | |||
124 | ------------------------------------------------------- | ||
125 | |||
126 | checkdim1 n v | ||
127 | | dim v == n = v | ||
128 | | otherwise = error $ "Error: "++ show n | ||
129 | ++ " components expected in the result of the function supplied to odeSolve" | ||
130 | |||
131 | checkdim2 n m | ||
132 | | rows m == n && cols m == n = m | ||
133 | | otherwise = error $ "Error: "++ show n ++ "x" ++ show n | ||
134 | ++ " Jacobian expected in odeSolve" | ||
135 | |||
136 | checkTimes ts | dim ts > 1 && all (>0) (zipWith subtract ts' (tail ts')) = ts | ||
137 | | otherwise = error "odeSolve requires increasing times" | ||
138 | where ts' = toList ts | ||
diff --git a/lib/Numeric/GSL/Polynomials.hs b/lib/Numeric/GSL/Polynomials.hs deleted file mode 100644 index 290c615..0000000 --- a/lib/Numeric/GSL/Polynomials.hs +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | {-# LANGUAGE CPP, ForeignFunctionInterface #-} | ||
2 | ----------------------------------------------------------------------------- | ||
3 | {- | | ||
4 | Module : Numeric.GSL.Polynomials | ||
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 | Polynomials. | ||
13 | |||
14 | <http://www.gnu.org/software/gsl/manual/html_node/General-Polynomial-Equations.html#General-Polynomial-Equations> | ||
15 | |||
16 | -} | ||
17 | ----------------------------------------------------------------------------- | ||
18 | module Numeric.GSL.Polynomials ( | ||
19 | polySolve | ||
20 | ) where | ||
21 | |||
22 | import Data.Packed.Internal | ||
23 | import Data.Complex | ||
24 | import System.IO.Unsafe (unsafePerformIO) | ||
25 | |||
26 | #if __GLASGOW_HASKELL__ >= 704 | ||
27 | import Foreign.C.Types (CInt(..)) | ||
28 | #endif | ||
29 | |||
30 | {- | Solution of general polynomial equations, using /gsl_poly_complex_solve/. | ||
31 | |||
32 | For example, the three solutions of x^3 + 8 = 0 | ||
33 | |||
34 | >>> polySolve [8,0,0,1] | ||
35 | [(-2.0) :+ 0.0,1.0 :+ 1.7320508075688776,1.0 :+ (-1.7320508075688776)] | ||
36 | |||
37 | |||
38 | The example in the GSL manual: To find the roots of x^5 -1 = 0: | ||
39 | |||
40 | >>> polySolve [-1, 0, 0, 0, 0, 1] | ||
41 | [(-0.8090169943749472) :+ 0.5877852522924731, | ||
42 | (-0.8090169943749472) :+ (-0.5877852522924731), | ||
43 | 0.30901699437494756 :+ 0.9510565162951535, | ||
44 | 0.30901699437494756 :+ (-0.9510565162951535), | ||
45 | 1.0000000000000002 :+ 0.0] | ||
46 | |||
47 | -} | ||
48 | polySolve :: [Double] -> [Complex Double] | ||
49 | polySolve = toList . polySolve' . fromList | ||
50 | |||
51 | polySolve' :: Vector Double -> Vector (Complex Double) | ||
52 | polySolve' v | dim v > 1 = unsafePerformIO $ do | ||
53 | r <- createVector (dim v-1) | ||
54 | app2 c_polySolve vec v vec r "polySolve" | ||
55 | return r | ||
56 | | otherwise = error "polySolve on a polynomial of degree zero" | ||
57 | |||
58 | foreign import ccall unsafe "gsl-aux.h polySolve" c_polySolve:: TVCV | ||
diff --git a/lib/Numeric/GSL/Root.hs b/lib/Numeric/GSL/Root.hs deleted file mode 100644 index 9d561c4..0000000 --- a/lib/Numeric/GSL/Root.hs +++ /dev/null | |||
@@ -1,199 +0,0 @@ | |||
1 | {- | | ||
2 | Module : Numeric.GSL.Root | ||
3 | Copyright : (c) Alberto Ruiz 2009 | ||
4 | License : GPL | ||
5 | |||
6 | Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
7 | Stability : provisional | ||
8 | Portability : uses ffi | ||
9 | |||
10 | Multidimensional root finding. | ||
11 | |||
12 | <http://www.gnu.org/software/gsl/manual/html_node/Multidimensional-Root_002dFinding.html> | ||
13 | |||
14 | The example in the GSL manual: | ||
15 | |||
16 | >>> let rosenbrock a b [x,y] = [ a*(1-x), b*(y-x^2) ] | ||
17 | >>> let (sol,path) = root Hybrids 1E-7 30 (rosenbrock 1 10) [-10,-5] | ||
18 | >>> sol | ||
19 | [1.0,1.0] | ||
20 | >>> disp 3 path | ||
21 | 11x5 | ||
22 | 1.000 -10.000 -5.000 11.000 -1050.000 | ||
23 | 2.000 -3.976 24.827 4.976 90.203 | ||
24 | 3.000 -3.976 24.827 4.976 90.203 | ||
25 | 4.000 -3.976 24.827 4.976 90.203 | ||
26 | 5.000 -1.274 -5.680 2.274 -73.018 | ||
27 | 6.000 -1.274 -5.680 2.274 -73.018 | ||
28 | 7.000 0.249 0.298 0.751 2.359 | ||
29 | 8.000 0.249 0.298 0.751 2.359 | ||
30 | 9.000 1.000 0.878 -0.000 -1.218 | ||
31 | 10.000 1.000 0.989 -0.000 -0.108 | ||
32 | 11.000 1.000 1.000 0.000 0.000 | ||
33 | |||
34 | -} | ||
35 | ----------------------------------------------------------------------------- | ||
36 | |||
37 | module Numeric.GSL.Root ( | ||
38 | uniRoot, UniRootMethod(..), | ||
39 | uniRootJ, UniRootMethodJ(..), | ||
40 | root, RootMethod(..), | ||
41 | rootJ, RootMethodJ(..), | ||
42 | ) where | ||
43 | |||
44 | import Data.Packed.Internal | ||
45 | import Data.Packed.Matrix | ||
46 | import Numeric.GSL.Internal | ||
47 | import Foreign.Ptr(FunPtr, freeHaskellFunPtr) | ||
48 | import Foreign.C.Types | ||
49 | import System.IO.Unsafe(unsafePerformIO) | ||
50 | |||
51 | ------------------------------------------------------------------------- | ||
52 | |||
53 | data UniRootMethod = Bisection | ||
54 | | FalsePos | ||
55 | | Brent | ||
56 | deriving (Enum, Eq, Show, Bounded) | ||
57 | |||
58 | uniRoot :: UniRootMethod | ||
59 | -> Double | ||
60 | -> Int | ||
61 | -> (Double -> Double) | ||
62 | -> Double | ||
63 | -> Double | ||
64 | -> (Double, Matrix Double) | ||
65 | uniRoot method epsrel maxit fun xl xu = uniRootGen (fi (fromEnum method)) fun xl xu epsrel maxit | ||
66 | |||
67 | uniRootGen m f xl xu epsrel maxit = unsafePerformIO $ do | ||
68 | fp <- mkDoublefun f | ||
69 | rawpath <- createMIO maxit 4 | ||
70 | (c_root m fp epsrel (fi maxit) xl xu) | ||
71 | "root" | ||
72 | let it = round (rawpath @@> (maxit-1,0)) | ||
73 | path = takeRows it rawpath | ||
74 | [sol] = toLists $ dropRows (it-1) path | ||
75 | freeHaskellFunPtr fp | ||
76 | return (sol !! 1, path) | ||
77 | |||
78 | foreign import ccall safe "root" | ||
79 | c_root:: CInt -> FunPtr (Double -> Double) -> Double -> CInt -> Double -> Double -> TM | ||
80 | |||
81 | ------------------------------------------------------------------------- | ||
82 | data UniRootMethodJ = UNewton | ||
83 | | Secant | ||
84 | | Steffenson | ||
85 | deriving (Enum, Eq, Show, Bounded) | ||
86 | |||
87 | uniRootJ :: UniRootMethodJ | ||
88 | -> Double | ||
89 | -> Int | ||
90 | -> (Double -> Double) | ||
91 | -> (Double -> Double) | ||
92 | -> Double | ||
93 | -> (Double, Matrix Double) | ||
94 | uniRootJ method epsrel maxit fun dfun x = uniRootJGen (fi (fromEnum method)) fun | ||
95 | dfun x epsrel maxit | ||
96 | |||
97 | uniRootJGen m f df x epsrel maxit = unsafePerformIO $ do | ||
98 | fp <- mkDoublefun f | ||
99 | dfp <- mkDoublefun df | ||
100 | rawpath <- createMIO maxit 2 | ||
101 | (c_rootj m fp dfp epsrel (fi maxit) x) | ||
102 | "rootj" | ||
103 | let it = round (rawpath @@> (maxit-1,0)) | ||
104 | path = takeRows it rawpath | ||
105 | [sol] = toLists $ dropRows (it-1) path | ||
106 | freeHaskellFunPtr fp | ||
107 | return (sol !! 1, path) | ||
108 | |||
109 | foreign import ccall safe "rootj" | ||
110 | c_rootj :: CInt -> FunPtr (Double -> Double) -> FunPtr (Double -> Double) | ||
111 | -> Double -> CInt -> Double -> TM | ||
112 | |||
113 | ------------------------------------------------------------------------- | ||
114 | |||
115 | data RootMethod = Hybrids | ||
116 | | Hybrid | ||
117 | | DNewton | ||
118 | | Broyden | ||
119 | deriving (Enum,Eq,Show,Bounded) | ||
120 | |||
121 | -- | Nonlinear multidimensional root finding using algorithms that do not require | ||
122 | -- any derivative information to be supplied by the user. | ||
123 | -- Any derivatives needed are approximated by finite differences. | ||
124 | root :: RootMethod | ||
125 | -> Double -- ^ maximum residual | ||
126 | -> Int -- ^ maximum number of iterations allowed | ||
127 | -> ([Double] -> [Double]) -- ^ function to minimize | ||
128 | -> [Double] -- ^ starting point | ||
129 | -> ([Double], Matrix Double) -- ^ solution vector and optimization path | ||
130 | |||
131 | root method epsabs maxit fun xinit = rootGen (fi (fromEnum method)) fun xinit epsabs maxit | ||
132 | |||
133 | rootGen m f xi epsabs maxit = unsafePerformIO $ do | ||
134 | let xiv = fromList xi | ||
135 | n = dim xiv | ||
136 | fp <- mkVecVecfun (aux_vTov (checkdim1 n . fromList . f . toList)) | ||
137 | rawpath <- vec xiv $ \xiv' -> | ||
138 | createMIO maxit (2*n+1) | ||
139 | (c_multiroot m fp epsabs (fi maxit) // xiv') | ||
140 | "multiroot" | ||
141 | let it = round (rawpath @@> (maxit-1,0)) | ||
142 | path = takeRows it rawpath | ||
143 | [sol] = toLists $ dropRows (it-1) path | ||
144 | freeHaskellFunPtr fp | ||
145 | return (take n $ drop 1 sol, path) | ||
146 | |||
147 | |||
148 | foreign import ccall safe "multiroot" | ||
149 | c_multiroot:: CInt -> FunPtr TVV -> Double -> CInt -> TVM | ||
150 | |||
151 | ------------------------------------------------------------------------- | ||
152 | |||
153 | data RootMethodJ = HybridsJ | ||
154 | | HybridJ | ||
155 | | Newton | ||
156 | | GNewton | ||
157 | deriving (Enum,Eq,Show,Bounded) | ||
158 | |||
159 | -- | Nonlinear multidimensional root finding using both the function and its derivatives. | ||
160 | rootJ :: RootMethodJ | ||
161 | -> Double -- ^ maximum residual | ||
162 | -> Int -- ^ maximum number of iterations allowed | ||
163 | -> ([Double] -> [Double]) -- ^ function to minimize | ||
164 | -> ([Double] -> [[Double]]) -- ^ Jacobian | ||
165 | -> [Double] -- ^ starting point | ||
166 | -> ([Double], Matrix Double) -- ^ solution vector and optimization path | ||
167 | |||
168 | rootJ method epsabs maxit fun jac xinit = rootJGen (fi (fromEnum method)) fun jac xinit epsabs maxit | ||
169 | |||
170 | rootJGen m f jac xi epsabs maxit = unsafePerformIO $ do | ||
171 | let xiv = fromList xi | ||
172 | n = dim xiv | ||
173 | fp <- mkVecVecfun (aux_vTov (checkdim1 n . fromList . f . toList)) | ||
174 | jp <- mkVecMatfun (aux_vTom (checkdim2 n . fromLists . jac . toList)) | ||
175 | rawpath <- vec xiv $ \xiv' -> | ||
176 | createMIO maxit (2*n+1) | ||
177 | (c_multirootj m fp jp epsabs (fi maxit) // xiv') | ||
178 | "multiroot" | ||
179 | let it = round (rawpath @@> (maxit-1,0)) | ||
180 | path = takeRows it rawpath | ||
181 | [sol] = toLists $ dropRows (it-1) path | ||
182 | freeHaskellFunPtr fp | ||
183 | freeHaskellFunPtr jp | ||
184 | return (take n $ drop 1 sol, path) | ||
185 | |||
186 | foreign import ccall safe "multirootj" | ||
187 | c_multirootj:: CInt -> FunPtr TVV -> FunPtr TVM -> Double -> CInt -> TVM | ||
188 | |||
189 | ------------------------------------------------------- | ||
190 | |||
191 | checkdim1 n v | ||
192 | | dim v == n = v | ||
193 | | otherwise = error $ "Error: "++ show n | ||
194 | ++ " components expected in the result of the function supplied to root" | ||
195 | |||
196 | checkdim2 n m | ||
197 | | rows m == n && cols m == n = m | ||
198 | | otherwise = error $ "Error: "++ show n ++ "x" ++ show n | ||
199 | ++ " Jacobian expected in rootJ" | ||
diff --git a/lib/Numeric/GSL/Vector.hs b/lib/Numeric/GSL/Vector.hs deleted file mode 100644 index 6204b8e..0000000 --- a/lib/Numeric/GSL/Vector.hs +++ /dev/null | |||
@@ -1,328 +0,0 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- | | ||
3 | -- Module : Numeric.GSL.Vector | ||
4 | -- Copyright : (c) Alberto Ruiz 2007 | ||
5 | -- License : GPL-style | ||
6 | -- | ||
7 | -- Maintainer : Alberto Ruiz <aruiz@um.es> | ||
8 | -- Stability : provisional | ||
9 | -- Portability : portable (uses FFI) | ||
10 | -- | ||
11 | -- Low level interface to vector operations. | ||
12 | -- | ||
13 | ----------------------------------------------------------------------------- | ||
14 | |||
15 | module Numeric.GSL.Vector ( | ||
16 | sumF, sumR, sumQ, sumC, | ||
17 | prodF, prodR, prodQ, prodC, | ||
18 | dotF, dotR, dotQ, dotC, | ||
19 | FunCodeS(..), toScalarR, toScalarF, toScalarC, toScalarQ, | ||
20 | FunCodeV(..), vectorMapR, vectorMapC, vectorMapF, vectorMapQ, | ||
21 | FunCodeSV(..), vectorMapValR, vectorMapValC, vectorMapValF, vectorMapValQ, | ||
22 | FunCodeVV(..), vectorZipR, vectorZipC, vectorZipF, vectorZipQ, | ||
23 | RandDist(..), randomVector | ||
24 | ) where | ||
25 | |||
26 | import Data.Packed.Internal.Common | ||
27 | import Data.Packed.Internal.Signatures | ||
28 | import Data.Packed.Internal.Vector | ||
29 | |||
30 | import Data.Complex | ||
31 | import Foreign.Marshal.Alloc(free) | ||
32 | import Foreign.Marshal.Array(newArray) | ||
33 | import Foreign.Ptr(Ptr) | ||
34 | import Foreign.C.Types | ||
35 | import System.IO.Unsafe(unsafePerformIO) | ||
36 | import Control.Monad(when) | ||
37 | |||
38 | fromei x = fromIntegral (fromEnum x) :: CInt | ||
39 | |||
40 | data FunCodeV = Sin | ||
41 | | Cos | ||
42 | | Tan | ||
43 | | Abs | ||
44 | | ASin | ||
45 | | ACos | ||
46 | | ATan | ||
47 | | Sinh | ||
48 | | Cosh | ||
49 | | Tanh | ||
50 | | ASinh | ||
51 | | ACosh | ||
52 | | ATanh | ||
53 | | Exp | ||
54 | | Log | ||
55 | | Sign | ||
56 | | Sqrt | ||
57 | deriving Enum | ||
58 | |||
59 | data FunCodeSV = Scale | ||
60 | | Recip | ||
61 | | AddConstant | ||
62 | | Negate | ||
63 | | PowSV | ||
64 | | PowVS | ||
65 | deriving Enum | ||
66 | |||
67 | data FunCodeVV = Add | ||
68 | | Sub | ||
69 | | Mul | ||
70 | | Div | ||
71 | | Pow | ||
72 | | ATan2 | ||
73 | deriving Enum | ||
74 | |||
75 | data FunCodeS = Norm2 | ||
76 | | AbsSum | ||
77 | | MaxIdx | ||
78 | | Max | ||
79 | | MinIdx | ||
80 | | Min | ||
81 | deriving Enum | ||
82 | |||
83 | ------------------------------------------------------------------ | ||
84 | |||
85 | -- | sum of elements | ||
86 | sumF :: Vector Float -> Float | ||
87 | sumF x = unsafePerformIO $ do | ||
88 | r <- createVector 1 | ||
89 | app2 c_sumF vec x vec r "sumF" | ||
90 | return $ r @> 0 | ||
91 | |||
92 | -- | sum of elements | ||
93 | sumR :: Vector Double -> Double | ||
94 | sumR x = unsafePerformIO $ do | ||
95 | r <- createVector 1 | ||
96 | app2 c_sumR vec x vec r "sumR" | ||
97 | return $ r @> 0 | ||
98 | |||
99 | -- | sum of elements | ||
100 | sumQ :: Vector (Complex Float) -> Complex Float | ||
101 | sumQ x = unsafePerformIO $ do | ||
102 | r <- createVector 1 | ||
103 | app2 c_sumQ vec x vec r "sumQ" | ||
104 | return $ r @> 0 | ||
105 | |||
106 | -- | sum of elements | ||
107 | sumC :: Vector (Complex Double) -> Complex Double | ||
108 | sumC x = unsafePerformIO $ do | ||
109 | r <- createVector 1 | ||
110 | app2 c_sumC vec x vec r "sumC" | ||
111 | return $ r @> 0 | ||
112 | |||
113 | foreign import ccall unsafe "gsl-aux.h sumF" c_sumF :: TFF | ||
114 | foreign import ccall unsafe "gsl-aux.h sumR" c_sumR :: TVV | ||
115 | foreign import ccall unsafe "gsl-aux.h sumQ" c_sumQ :: TQVQV | ||
116 | foreign import ccall unsafe "gsl-aux.h sumC" c_sumC :: TCVCV | ||
117 | |||
118 | -- | product of elements | ||
119 | prodF :: Vector Float -> Float | ||
120 | prodF x = unsafePerformIO $ do | ||
121 | r <- createVector 1 | ||
122 | app2 c_prodF vec x vec r "prodF" | ||
123 | return $ r @> 0 | ||
124 | |||
125 | -- | product of elements | ||
126 | prodR :: Vector Double -> Double | ||
127 | prodR x = unsafePerformIO $ do | ||
128 | r <- createVector 1 | ||
129 | app2 c_prodR vec x vec r "prodR" | ||
130 | return $ r @> 0 | ||
131 | |||
132 | -- | product of elements | ||
133 | prodQ :: Vector (Complex Float) -> Complex Float | ||
134 | prodQ x = unsafePerformIO $ do | ||
135 | r <- createVector 1 | ||
136 | app2 c_prodQ vec x vec r "prodQ" | ||
137 | return $ r @> 0 | ||
138 | |||
139 | -- | product of elements | ||
140 | prodC :: Vector (Complex Double) -> Complex Double | ||
141 | prodC x = unsafePerformIO $ do | ||
142 | r <- createVector 1 | ||
143 | app2 c_prodC vec x vec r "prodC" | ||
144 | return $ r @> 0 | ||
145 | |||
146 | foreign import ccall unsafe "gsl-aux.h prodF" c_prodF :: TFF | ||
147 | foreign import ccall unsafe "gsl-aux.h prodR" c_prodR :: TVV | ||
148 | foreign import ccall unsafe "gsl-aux.h prodQ" c_prodQ :: TQVQV | ||
149 | foreign import ccall unsafe "gsl-aux.h prodC" c_prodC :: TCVCV | ||
150 | |||
151 | -- | dot product | ||
152 | dotF :: Vector Float -> Vector Float -> Float | ||
153 | dotF x y = unsafePerformIO $ do | ||
154 | r <- createVector 1 | ||
155 | app3 c_dotF vec x vec y vec r "dotF" | ||
156 | return $ r @> 0 | ||
157 | |||
158 | -- | dot product | ||
159 | dotR :: Vector Double -> Vector Double -> Double | ||
160 | dotR x y = unsafePerformIO $ do | ||
161 | r <- createVector 1 | ||
162 | app3 c_dotR vec x vec y vec r "dotR" | ||
163 | return $ r @> 0 | ||
164 | |||
165 | -- | dot product | ||
166 | dotQ :: Vector (Complex Float) -> Vector (Complex Float) -> Complex Float | ||
167 | dotQ x y = unsafePerformIO $ do | ||
168 | r <- createVector 1 | ||
169 | app3 c_dotQ vec x vec y vec r "dotQ" | ||
170 | return $ r @> 0 | ||
171 | |||
172 | -- | dot product | ||
173 | dotC :: Vector (Complex Double) -> Vector (Complex Double) -> Complex Double | ||
174 | dotC x y = unsafePerformIO $ do | ||
175 | r <- createVector 1 | ||
176 | app3 c_dotC vec x vec y vec r "dotC" | ||
177 | return $ r @> 0 | ||
178 | |||
179 | foreign import ccall unsafe "gsl-aux.h dotF" c_dotF :: TFFF | ||
180 | foreign import ccall unsafe "gsl-aux.h dotR" c_dotR :: TVVV | ||
181 | foreign import ccall unsafe "gsl-aux.h dotQ" c_dotQ :: TQVQVQV | ||
182 | foreign import ccall unsafe "gsl-aux.h dotC" c_dotC :: TCVCVCV | ||
183 | |||
184 | ------------------------------------------------------------------ | ||
185 | |||
186 | toScalarAux fun code v = unsafePerformIO $ do | ||
187 | r <- createVector 1 | ||
188 | app2 (fun (fromei code)) vec v vec r "toScalarAux" | ||
189 | return (r `at` 0) | ||
190 | |||
191 | vectorMapAux fun code v = unsafePerformIO $ do | ||
192 | r <- createVector (dim v) | ||
193 | app2 (fun (fromei code)) vec v vec r "vectorMapAux" | ||
194 | return r | ||
195 | |||
196 | vectorMapValAux fun code val v = unsafePerformIO $ do | ||
197 | r <- createVector (dim v) | ||
198 | pval <- newArray [val] | ||
199 | app2 (fun (fromei code) pval) vec v vec r "vectorMapValAux" | ||
200 | free pval | ||
201 | return r | ||
202 | |||
203 | vectorZipAux fun code u v = unsafePerformIO $ do | ||
204 | r <- createVector (dim u) | ||
205 | when (dim u > 0) $ app3 (fun (fromei code)) vec u vec v vec r "vectorZipAux" | ||
206 | return r | ||
207 | |||
208 | --------------------------------------------------------------------- | ||
209 | |||
210 | -- | obtains different functions of a vector: norm1, norm2, max, min, posmax, posmin, etc. | ||
211 | toScalarR :: FunCodeS -> Vector Double -> Double | ||
212 | toScalarR oper = toScalarAux c_toScalarR (fromei oper) | ||
213 | |||
214 | foreign import ccall unsafe "gsl-aux.h toScalarR" c_toScalarR :: CInt -> TVV | ||
215 | |||
216 | -- | obtains different functions of a vector: norm1, norm2, max, min, posmax, posmin, etc. | ||
217 | toScalarF :: FunCodeS -> Vector Float -> Float | ||
218 | toScalarF oper = toScalarAux c_toScalarF (fromei oper) | ||
219 | |||
220 | foreign import ccall unsafe "gsl-aux.h toScalarF" c_toScalarF :: CInt -> TFF | ||
221 | |||
222 | -- | obtains different functions of a vector: only norm1, norm2 | ||
223 | toScalarC :: FunCodeS -> Vector (Complex Double) -> Double | ||
224 | toScalarC oper = toScalarAux c_toScalarC (fromei oper) | ||
225 | |||
226 | foreign import ccall unsafe "gsl-aux.h toScalarC" c_toScalarC :: CInt -> TCVV | ||
227 | |||
228 | -- | obtains different functions of a vector: only norm1, norm2 | ||
229 | toScalarQ :: FunCodeS -> Vector (Complex Float) -> Float | ||
230 | toScalarQ oper = toScalarAux c_toScalarQ (fromei oper) | ||
231 | |||
232 | foreign import ccall unsafe "gsl-aux.h toScalarQ" c_toScalarQ :: CInt -> TQVF | ||
233 | |||
234 | ------------------------------------------------------------------ | ||
235 | |||
236 | -- | map of real vectors with given function | ||
237 | vectorMapR :: FunCodeV -> Vector Double -> Vector Double | ||
238 | vectorMapR = vectorMapAux c_vectorMapR | ||
239 | |||
240 | foreign import ccall unsafe "gsl-aux.h mapR" c_vectorMapR :: CInt -> TVV | ||
241 | |||
242 | -- | map of complex vectors with given function | ||
243 | vectorMapC :: FunCodeV -> Vector (Complex Double) -> Vector (Complex Double) | ||
244 | vectorMapC oper = vectorMapAux c_vectorMapC (fromei oper) | ||
245 | |||
246 | foreign import ccall unsafe "gsl-aux.h mapC" c_vectorMapC :: CInt -> TCVCV | ||
247 | |||
248 | -- | map of real vectors with given function | ||
249 | vectorMapF :: FunCodeV -> Vector Float -> Vector Float | ||
250 | vectorMapF = vectorMapAux c_vectorMapF | ||
251 | |||
252 | foreign import ccall unsafe "gsl-aux.h mapF" c_vectorMapF :: CInt -> TFF | ||
253 | |||
254 | -- | map of real vectors with given function | ||
255 | vectorMapQ :: FunCodeV -> Vector (Complex Float) -> Vector (Complex Float) | ||
256 | vectorMapQ = vectorMapAux c_vectorMapQ | ||
257 | |||
258 | foreign import ccall unsafe "gsl-aux.h mapQ" c_vectorMapQ :: CInt -> TQVQV | ||
259 | |||
260 | ------------------------------------------------------------------- | ||
261 | |||
262 | -- | map of real vectors with given function | ||
263 | vectorMapValR :: FunCodeSV -> Double -> Vector Double -> Vector Double | ||
264 | vectorMapValR oper = vectorMapValAux c_vectorMapValR (fromei oper) | ||
265 | |||
266 | foreign import ccall unsafe "gsl-aux.h mapValR" c_vectorMapValR :: CInt -> Ptr Double -> TVV | ||
267 | |||
268 | -- | map of complex vectors with given function | ||
269 | vectorMapValC :: FunCodeSV -> Complex Double -> Vector (Complex Double) -> Vector (Complex Double) | ||
270 | vectorMapValC = vectorMapValAux c_vectorMapValC | ||
271 | |||
272 | foreign import ccall unsafe "gsl-aux.h mapValC" c_vectorMapValC :: CInt -> Ptr (Complex Double) -> TCVCV | ||
273 | |||
274 | -- | map of real vectors with given function | ||
275 | vectorMapValF :: FunCodeSV -> Float -> Vector Float -> Vector Float | ||
276 | vectorMapValF oper = vectorMapValAux c_vectorMapValF (fromei oper) | ||
277 | |||
278 | foreign import ccall unsafe "gsl-aux.h mapValF" c_vectorMapValF :: CInt -> Ptr Float -> TFF | ||
279 | |||
280 | -- | map of complex vectors with given function | ||
281 | vectorMapValQ :: FunCodeSV -> Complex Float -> Vector (Complex Float) -> Vector (Complex Float) | ||
282 | vectorMapValQ oper = vectorMapValAux c_vectorMapValQ (fromei oper) | ||
283 | |||
284 | foreign import ccall unsafe "gsl-aux.h mapValQ" c_vectorMapValQ :: CInt -> Ptr (Complex Float) -> TQVQV | ||
285 | |||
286 | ------------------------------------------------------------------- | ||
287 | |||
288 | -- | elementwise operation on real vectors | ||
289 | vectorZipR :: FunCodeVV -> Vector Double -> Vector Double -> Vector Double | ||
290 | vectorZipR = vectorZipAux c_vectorZipR | ||
291 | |||
292 | foreign import ccall unsafe "gsl-aux.h zipR" c_vectorZipR :: CInt -> TVVV | ||
293 | |||
294 | -- | elementwise operation on complex vectors | ||
295 | vectorZipC :: FunCodeVV -> Vector (Complex Double) -> Vector (Complex Double) -> Vector (Complex Double) | ||
296 | vectorZipC = vectorZipAux c_vectorZipC | ||
297 | |||
298 | foreign import ccall unsafe "gsl-aux.h zipC" c_vectorZipC :: CInt -> TCVCVCV | ||
299 | |||
300 | -- | elementwise operation on real vectors | ||
301 | vectorZipF :: FunCodeVV -> Vector Float -> Vector Float -> Vector Float | ||
302 | vectorZipF = vectorZipAux c_vectorZipF | ||
303 | |||
304 | foreign import ccall unsafe "gsl-aux.h zipF" c_vectorZipF :: CInt -> TFFF | ||
305 | |||
306 | -- | elementwise operation on complex vectors | ||
307 | vectorZipQ :: FunCodeVV -> Vector (Complex Float) -> Vector (Complex Float) -> Vector (Complex Float) | ||
308 | vectorZipQ = vectorZipAux c_vectorZipQ | ||
309 | |||
310 | foreign import ccall unsafe "gsl-aux.h zipQ" c_vectorZipQ :: CInt -> TQVQVQV | ||
311 | |||
312 | ----------------------------------------------------------------------- | ||
313 | |||
314 | data RandDist = Uniform -- ^ uniform distribution in [0,1) | ||
315 | | Gaussian -- ^ normal distribution with mean zero and standard deviation one | ||
316 | deriving Enum | ||
317 | |||
318 | -- | Obtains a vector of pseudorandom elements from the the mt19937 generator in GSL, with a given seed. Use randomIO to get a random seed. | ||
319 | randomVector :: Int -- ^ seed | ||
320 | -> RandDist -- ^ distribution | ||
321 | -> Int -- ^ vector size | ||
322 | -> Vector Double | ||
323 | randomVector seed dist n = unsafePerformIO $ do | ||
324 | r <- createVector n | ||
325 | app1 (c_random_vector (fi seed) ((fi.fromEnum) dist)) vec r "randomVector" | ||
326 | return r | ||
327 | |||
328 | foreign import ccall unsafe "random_vector" c_random_vector :: CInt -> CInt -> TV | ||
diff --git a/lib/Numeric/GSL/gsl-aux.c b/lib/Numeric/GSL/gsl-aux.c deleted file mode 100644 index 410d157..0000000 --- a/lib/Numeric/GSL/gsl-aux.c +++ /dev/null | |||
@@ -1,1541 +0,0 @@ | |||
1 | #include <gsl/gsl_complex.h> | ||
2 | |||
3 | #define RVEC(A) int A##n, double*A##p | ||
4 | #define RMAT(A) int A##r, int A##c, double* A##p | ||
5 | #define KRVEC(A) int A##n, const double*A##p | ||
6 | #define KRMAT(A) int A##r, int A##c, const double* A##p | ||
7 | |||
8 | #define CVEC(A) int A##n, gsl_complex*A##p | ||
9 | #define CMAT(A) int A##r, int A##c, gsl_complex* A##p | ||
10 | #define KCVEC(A) int A##n, const gsl_complex*A##p | ||
11 | #define KCMAT(A) int A##r, int A##c, const gsl_complex* A##p | ||
12 | |||
13 | #define FVEC(A) int A##n, float*A##p | ||
14 | #define FMAT(A) int A##r, int A##c, float* A##p | ||
15 | #define KFVEC(A) int A##n, const float*A##p | ||
16 | #define KFMAT(A) int A##r, int A##c, const float* A##p | ||
17 | |||
18 | #define QVEC(A) int A##n, gsl_complex_float*A##p | ||
19 | #define QMAT(A) int A##r, int A##c, gsl_complex_float* A##p | ||
20 | #define KQVEC(A) int A##n, const gsl_complex_float*A##p | ||
21 | #define KQMAT(A) int A##r, int A##c, const gsl_complex_float* A##p | ||
22 | |||
23 | #include <gsl/gsl_blas.h> | ||
24 | #include <gsl/gsl_math.h> | ||
25 | #include <gsl/gsl_errno.h> | ||
26 | #include <gsl/gsl_fft_complex.h> | ||
27 | #include <gsl/gsl_integration.h> | ||
28 | #include <gsl/gsl_deriv.h> | ||
29 | #include <gsl/gsl_poly.h> | ||
30 | #include <gsl/gsl_multimin.h> | ||
31 | #include <gsl/gsl_multiroots.h> | ||
32 | #include <gsl/gsl_min.h> | ||
33 | #include <gsl/gsl_complex_math.h> | ||
34 | #include <gsl/gsl_rng.h> | ||
35 | #include <gsl/gsl_randist.h> | ||
36 | #include <gsl/gsl_roots.h> | ||
37 | #include <gsl/gsl_multifit_nlin.h> | ||
38 | #include <string.h> | ||
39 | #include <stdio.h> | ||
40 | |||
41 | #define MACRO(B) do {B} while (0) | ||
42 | #define ERROR(CODE) MACRO(return CODE;) | ||
43 | #define REQUIRES(COND, CODE) MACRO(if(!(COND)) {ERROR(CODE);}) | ||
44 | #define OK return 0; | ||
45 | |||
46 | #define MIN(A,B) ((A)<(B)?(A):(B)) | ||
47 | #define MAX(A,B) ((A)>(B)?(A):(B)) | ||
48 | |||
49 | #ifdef DBG | ||
50 | #define DEBUGMSG(M) printf("*** calling aux C function: %s\n",M); | ||
51 | #else | ||
52 | #define DEBUGMSG(M) | ||
53 | #endif | ||
54 | |||
55 | #define CHECK(RES,CODE) MACRO(if(RES) return CODE;) | ||
56 | |||
57 | #ifdef DBG | ||
58 | #define DEBUGMAT(MSG,X) printf(MSG" = \n"); gsl_matrix_fprintf(stdout,X,"%f"); printf("\n"); | ||
59 | #else | ||
60 | #define DEBUGMAT(MSG,X) | ||
61 | #endif | ||
62 | |||
63 | #ifdef DBG | ||
64 | #define DEBUGVEC(MSG,X) printf(MSG" = \n"); gsl_vector_fprintf(stdout,X,"%f"); printf("\n"); | ||
65 | #else | ||
66 | #define DEBUGVEC(MSG,X) | ||
67 | #endif | ||
68 | |||
69 | #define DVVIEW(A) gsl_vector_view A = gsl_vector_view_array(A##p,A##n) | ||
70 | #define DMVIEW(A) gsl_matrix_view A = gsl_matrix_view_array(A##p,A##r,A##c) | ||
71 | #define CVVIEW(A) gsl_vector_complex_view A = gsl_vector_complex_view_array((double*)A##p,A##n) | ||
72 | #define CMVIEW(A) gsl_matrix_complex_view A = gsl_matrix_complex_view_array((double*)A##p,A##r,A##c) | ||
73 | #define KDVVIEW(A) gsl_vector_const_view A = gsl_vector_const_view_array(A##p,A##n) | ||
74 | #define KDMVIEW(A) gsl_matrix_const_view A = gsl_matrix_const_view_array(A##p,A##r,A##c) | ||
75 | #define KCVVIEW(A) gsl_vector_complex_const_view A = gsl_vector_complex_const_view_array((double*)A##p,A##n) | ||
76 | #define KCMVIEW(A) gsl_matrix_complex_const_view A = gsl_matrix_complex_const_view_array((double*)A##p,A##r,A##c) | ||
77 | |||
78 | #define FVVIEW(A) gsl_vector_float_view A = gsl_vector_float_view_array(A##p,A##n) | ||
79 | #define FMVIEW(A) gsl_matrix_float_view A = gsl_matrix_float_view_array(A##p,A##r,A##c) | ||
80 | #define QVVIEW(A) gsl_vector_complex_float_view A = gsl_vector_float_complex_view_array((float*)A##p,A##n) | ||
81 | #define QMVIEW(A) gsl_matrix_complex_float_view A = gsl_matrix_float_complex_view_array((float*)A##p,A##r,A##c) | ||
82 | #define KFVVIEW(A) gsl_vector_float_const_view A = gsl_vector_float_const_view_array(A##p,A##n) | ||
83 | #define KFMVIEW(A) gsl_matrix_float_const_view A = gsl_matrix_float_const_view_array(A##p,A##r,A##c) | ||
84 | #define KQVVIEW(A) gsl_vector_complex_float_const_view A = gsl_vector_complex_float_const_view_array((float*)A##p,A##n) | ||
85 | #define KQMVIEW(A) gsl_matrix_complex_float_const_view A = gsl_matrix_complex_float_const_view_array((float*)A##p,A##r,A##c) | ||
86 | |||
87 | #define V(a) (&a.vector) | ||
88 | #define M(a) (&a.matrix) | ||
89 | |||
90 | #define GCVEC(A) int A##n, gsl_complex*A##p | ||
91 | #define KGCVEC(A) int A##n, const gsl_complex*A##p | ||
92 | |||
93 | #define GQVEC(A) int A##n, gsl_complex_float*A##p | ||
94 | #define KGQVEC(A) int A##n, const gsl_complex_float*A##p | ||
95 | |||
96 | #define BAD_SIZE 2000 | ||
97 | #define BAD_CODE 2001 | ||
98 | #define MEM 2002 | ||
99 | #define BAD_FILE 2003 | ||
100 | |||
101 | |||
102 | void no_abort_on_error() { | ||
103 | gsl_set_error_handler_off(); | ||
104 | } | ||
105 | |||
106 | |||
107 | int sumF(KFVEC(x),FVEC(r)) { | ||
108 | DEBUGMSG("sumF"); | ||
109 | REQUIRES(rn==1,BAD_SIZE); | ||
110 | int i; | ||
111 | float res = 0; | ||
112 | for (i = 0; i < xn; i++) res += xp[i]; | ||
113 | rp[0] = res; | ||
114 | OK | ||
115 | } | ||
116 | |||
117 | int sumR(KRVEC(x),RVEC(r)) { | ||
118 | DEBUGMSG("sumR"); | ||
119 | REQUIRES(rn==1,BAD_SIZE); | ||
120 | int i; | ||
121 | double res = 0; | ||
122 | for (i = 0; i < xn; i++) res += xp[i]; | ||
123 | rp[0] = res; | ||
124 | OK | ||
125 | } | ||
126 | |||
127 | int sumQ(KQVEC(x),QVEC(r)) { | ||
128 | DEBUGMSG("sumQ"); | ||
129 | REQUIRES(rn==1,BAD_SIZE); | ||
130 | int i; | ||
131 | gsl_complex_float res; | ||
132 | res.dat[0] = 0; | ||
133 | res.dat[1] = 0; | ||
134 | for (i = 0; i < xn; i++) { | ||
135 | res.dat[0] += xp[i].dat[0]; | ||
136 | res.dat[1] += xp[i].dat[1]; | ||
137 | } | ||
138 | rp[0] = res; | ||
139 | OK | ||
140 | } | ||
141 | |||
142 | int sumC(KCVEC(x),CVEC(r)) { | ||
143 | DEBUGMSG("sumC"); | ||
144 | REQUIRES(rn==1,BAD_SIZE); | ||
145 | int i; | ||
146 | gsl_complex res; | ||
147 | res.dat[0] = 0; | ||
148 | res.dat[1] = 0; | ||
149 | for (i = 0; i < xn; i++) { | ||
150 | res.dat[0] += xp[i].dat[0]; | ||
151 | res.dat[1] += xp[i].dat[1]; | ||
152 | } | ||
153 | rp[0] = res; | ||
154 | OK | ||
155 | } | ||
156 | |||
157 | int prodF(KFVEC(x),FVEC(r)) { | ||
158 | DEBUGMSG("prodF"); | ||
159 | REQUIRES(rn==1,BAD_SIZE); | ||
160 | int i; | ||
161 | float res = 1; | ||
162 | for (i = 0; i < xn; i++) res *= xp[i]; | ||
163 | rp[0] = res; | ||
164 | OK | ||
165 | } | ||
166 | |||
167 | int prodR(KRVEC(x),RVEC(r)) { | ||
168 | DEBUGMSG("prodR"); | ||
169 | REQUIRES(rn==1,BAD_SIZE); | ||
170 | int i; | ||
171 | double res = 1; | ||
172 | for (i = 0; i < xn; i++) res *= xp[i]; | ||
173 | rp[0] = res; | ||
174 | OK | ||
175 | } | ||
176 | |||
177 | int prodQ(KQVEC(x),QVEC(r)) { | ||
178 | DEBUGMSG("prodQ"); | ||
179 | REQUIRES(rn==1,BAD_SIZE); | ||
180 | int i; | ||
181 | gsl_complex_float res; | ||
182 | float temp; | ||
183 | res.dat[0] = 1; | ||
184 | res.dat[1] = 0; | ||
185 | for (i = 0; i < xn; i++) { | ||
186 | temp = res.dat[0] * xp[i].dat[0] - res.dat[1] * xp[i].dat[1]; | ||
187 | res.dat[1] = res.dat[0] * xp[i].dat[1] + res.dat[1] * xp[i].dat[0]; | ||
188 | res.dat[0] = temp; | ||
189 | } | ||
190 | rp[0] = res; | ||
191 | OK | ||
192 | } | ||
193 | |||
194 | int prodC(KCVEC(x),CVEC(r)) { | ||
195 | DEBUGMSG("prodC"); | ||
196 | REQUIRES(rn==1,BAD_SIZE); | ||
197 | int i; | ||
198 | gsl_complex res; | ||
199 | double temp; | ||
200 | res.dat[0] = 1; | ||
201 | res.dat[1] = 0; | ||
202 | for (i = 0; i < xn; i++) { | ||
203 | temp = res.dat[0] * xp[i].dat[0] - res.dat[1] * xp[i].dat[1]; | ||
204 | res.dat[1] = res.dat[0] * xp[i].dat[1] + res.dat[1] * xp[i].dat[0]; | ||
205 | res.dat[0] = temp; | ||
206 | } | ||
207 | rp[0] = res; | ||
208 | OK | ||
209 | } | ||
210 | |||
211 | int dotF(KFVEC(x), KFVEC(y), FVEC(r)) { | ||
212 | DEBUGMSG("dotF"); | ||
213 | REQUIRES(xn==yn,BAD_SIZE); | ||
214 | REQUIRES(rn==1,BAD_SIZE); | ||
215 | DEBUGMSG("dotF"); | ||
216 | KFVVIEW(x); | ||
217 | KFVVIEW(y); | ||
218 | gsl_blas_sdot(V(x),V(y),rp); | ||
219 | OK | ||
220 | } | ||
221 | |||
222 | int dotR(KRVEC(x), KRVEC(y), RVEC(r)) { | ||
223 | DEBUGMSG("dotR"); | ||
224 | REQUIRES(xn==yn,BAD_SIZE); | ||
225 | REQUIRES(rn==1,BAD_SIZE); | ||
226 | DEBUGMSG("dotR"); | ||
227 | KDVVIEW(x); | ||
228 | KDVVIEW(y); | ||
229 | gsl_blas_ddot(V(x),V(y),rp); | ||
230 | OK | ||
231 | } | ||
232 | |||
233 | int dotQ(KQVEC(x), KQVEC(y), QVEC(r)) { | ||
234 | DEBUGMSG("dotQ"); | ||
235 | REQUIRES(xn==yn,BAD_SIZE); | ||
236 | REQUIRES(rn==1,BAD_SIZE); | ||
237 | DEBUGMSG("dotQ"); | ||
238 | KQVVIEW(x); | ||
239 | KQVVIEW(y); | ||
240 | gsl_blas_cdotu(V(x),V(y),rp); | ||
241 | OK | ||
242 | } | ||
243 | |||
244 | int dotC(KCVEC(x), KCVEC(y), CVEC(r)) { | ||
245 | DEBUGMSG("dotC"); | ||
246 | REQUIRES(xn==yn,BAD_SIZE); | ||
247 | REQUIRES(rn==1,BAD_SIZE); | ||
248 | DEBUGMSG("dotC"); | ||
249 | KCVVIEW(x); | ||
250 | KCVVIEW(y); | ||
251 | gsl_blas_zdotu(V(x),V(y),rp); | ||
252 | OK | ||
253 | } | ||
254 | |||
255 | int toScalarR(int code, KRVEC(x), RVEC(r)) { | ||
256 | REQUIRES(rn==1,BAD_SIZE); | ||
257 | DEBUGMSG("toScalarR"); | ||
258 | KDVVIEW(x); | ||
259 | double res; | ||
260 | switch(code) { | ||
261 | case 0: { res = gsl_blas_dnrm2(V(x)); break; } | ||
262 | case 1: { res = gsl_blas_dasum(V(x)); break; } | ||
263 | case 2: { res = gsl_vector_max_index(V(x)); break; } | ||
264 | case 3: { res = gsl_vector_max(V(x)); break; } | ||
265 | case 4: { res = gsl_vector_min_index(V(x)); break; } | ||
266 | case 5: { res = gsl_vector_min(V(x)); break; } | ||
267 | default: ERROR(BAD_CODE); | ||
268 | } | ||
269 | rp[0] = res; | ||
270 | OK | ||
271 | } | ||
272 | |||
273 | int toScalarF(int code, KFVEC(x), FVEC(r)) { | ||
274 | REQUIRES(rn==1,BAD_SIZE); | ||
275 | DEBUGMSG("toScalarF"); | ||
276 | KFVVIEW(x); | ||
277 | float res; | ||
278 | switch(code) { | ||
279 | case 0: { res = gsl_blas_snrm2(V(x)); break; } | ||
280 | case 1: { res = gsl_blas_sasum(V(x)); break; } | ||
281 | case 2: { res = gsl_vector_float_max_index(V(x)); break; } | ||
282 | case 3: { res = gsl_vector_float_max(V(x)); break; } | ||
283 | case 4: { res = gsl_vector_float_min_index(V(x)); break; } | ||
284 | case 5: { res = gsl_vector_float_min(V(x)); break; } | ||
285 | default: ERROR(BAD_CODE); | ||
286 | } | ||
287 | rp[0] = res; | ||
288 | OK | ||
289 | } | ||
290 | |||
291 | |||
292 | int toScalarC(int code, KCVEC(x), RVEC(r)) { | ||
293 | REQUIRES(rn==1,BAD_SIZE); | ||
294 | DEBUGMSG("toScalarC"); | ||
295 | KCVVIEW(x); | ||
296 | double res; | ||
297 | switch(code) { | ||
298 | case 0: { res = gsl_blas_dznrm2(V(x)); break; } | ||
299 | case 1: { res = gsl_blas_dzasum(V(x)); break; } | ||
300 | default: ERROR(BAD_CODE); | ||
301 | } | ||
302 | rp[0] = res; | ||
303 | OK | ||
304 | } | ||
305 | |||
306 | int toScalarQ(int code, KQVEC(x), FVEC(r)) { | ||
307 | REQUIRES(rn==1,BAD_SIZE); | ||
308 | DEBUGMSG("toScalarQ"); | ||
309 | KQVVIEW(x); | ||
310 | float res; | ||
311 | switch(code) { | ||
312 | case 0: { res = gsl_blas_scnrm2(V(x)); break; } | ||
313 | case 1: { res = gsl_blas_scasum(V(x)); break; } | ||
314 | default: ERROR(BAD_CODE); | ||
315 | } | ||
316 | rp[0] = res; | ||
317 | OK | ||
318 | } | ||
319 | |||
320 | |||
321 | inline double sign(double x) { | ||
322 | if(x>0) { | ||
323 | return +1.0; | ||
324 | } else if (x<0) { | ||
325 | return -1.0; | ||
326 | } else { | ||
327 | return 0.0; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | inline float float_sign(float x) { | ||
332 | if(x>0) { | ||
333 | return +1.0; | ||
334 | } else if (x<0) { | ||
335 | return -1.0; | ||
336 | } else { | ||
337 | return 0.0; | ||
338 | } | ||
339 | } | ||
340 | |||
341 | inline gsl_complex complex_abs(gsl_complex z) { | ||
342 | gsl_complex r; | ||
343 | r.dat[0] = gsl_complex_abs(z); | ||
344 | r.dat[1] = 0; | ||
345 | return r; | ||
346 | } | ||
347 | |||
348 | inline gsl_complex complex_signum(gsl_complex z) { | ||
349 | gsl_complex r; | ||
350 | double mag; | ||
351 | if (z.dat[0] == 0 && z.dat[1] == 0) { | ||
352 | r.dat[0] = 0; | ||
353 | r.dat[1] = 0; | ||
354 | } else { | ||
355 | mag = gsl_complex_abs(z); | ||
356 | r.dat[0] = z.dat[0]/mag; | ||
357 | r.dat[1] = z.dat[1]/mag; | ||
358 | } | ||
359 | return r; | ||
360 | } | ||
361 | |||
362 | #define OP(C,F) case C: { for(k=0;k<xn;k++) rp[k] = F(xp[k]); OK } | ||
363 | #define OPV(C,E) case C: { for(k=0;k<xn;k++) rp[k] = E; OK } | ||
364 | int mapR(int code, KRVEC(x), RVEC(r)) { | ||
365 | int k; | ||
366 | REQUIRES(xn == rn,BAD_SIZE); | ||
367 | DEBUGMSG("mapR"); | ||
368 | switch (code) { | ||
369 | OP(0,sin) | ||
370 | OP(1,cos) | ||
371 | OP(2,tan) | ||
372 | OP(3,fabs) | ||
373 | OP(4,asin) | ||
374 | OP(5,acos) | ||
375 | OP(6,atan) /* atan2 mediante vectorZip */ | ||
376 | OP(7,sinh) | ||
377 | OP(8,cosh) | ||
378 | OP(9,tanh) | ||
379 | OP(10,gsl_asinh) | ||
380 | OP(11,gsl_acosh) | ||
381 | OP(12,gsl_atanh) | ||
382 | OP(13,exp) | ||
383 | OP(14,log) | ||
384 | OP(15,sign) | ||
385 | OP(16,sqrt) | ||
386 | default: ERROR(BAD_CODE); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | int mapF(int code, KFVEC(x), FVEC(r)) { | ||
391 | int k; | ||
392 | REQUIRES(xn == rn,BAD_SIZE); | ||
393 | DEBUGMSG("mapF"); | ||
394 | switch (code) { | ||
395 | OP(0,sin) | ||
396 | OP(1,cos) | ||
397 | OP(2,tan) | ||
398 | OP(3,fabs) | ||
399 | OP(4,asin) | ||
400 | OP(5,acos) | ||
401 | OP(6,atan) /* atan2 mediante vectorZip */ | ||
402 | OP(7,sinh) | ||
403 | OP(8,cosh) | ||
404 | OP(9,tanh) | ||
405 | OP(10,gsl_asinh) | ||
406 | OP(11,gsl_acosh) | ||
407 | OP(12,gsl_atanh) | ||
408 | OP(13,exp) | ||
409 | OP(14,log) | ||
410 | OP(15,sign) | ||
411 | OP(16,sqrt) | ||
412 | default: ERROR(BAD_CODE); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | |||
417 | int mapCAux(int code, KGCVEC(x), GCVEC(r)) { | ||
418 | int k; | ||
419 | REQUIRES(xn == rn,BAD_SIZE); | ||
420 | DEBUGMSG("mapC"); | ||
421 | switch (code) { | ||
422 | OP(0,gsl_complex_sin) | ||
423 | OP(1,gsl_complex_cos) | ||
424 | OP(2,gsl_complex_tan) | ||
425 | OP(3,complex_abs) | ||
426 | OP(4,gsl_complex_arcsin) | ||
427 | OP(5,gsl_complex_arccos) | ||
428 | OP(6,gsl_complex_arctan) | ||
429 | OP(7,gsl_complex_sinh) | ||
430 | OP(8,gsl_complex_cosh) | ||
431 | OP(9,gsl_complex_tanh) | ||
432 | OP(10,gsl_complex_arcsinh) | ||
433 | OP(11,gsl_complex_arccosh) | ||
434 | OP(12,gsl_complex_arctanh) | ||
435 | OP(13,gsl_complex_exp) | ||
436 | OP(14,gsl_complex_log) | ||
437 | OP(15,complex_signum) | ||
438 | OP(16,gsl_complex_sqrt) | ||
439 | |||
440 | // gsl_complex_arg | ||
441 | // gsl_complex_abs | ||
442 | default: ERROR(BAD_CODE); | ||
443 | } | ||
444 | } | ||
445 | |||
446 | int mapC(int code, KCVEC(x), CVEC(r)) { | ||
447 | return mapCAux(code, xn, (gsl_complex*)xp, rn, (gsl_complex*)rp); | ||
448 | } | ||
449 | |||
450 | |||
451 | gsl_complex_float complex_float_math_fun(gsl_complex (*cf)(gsl_complex), gsl_complex_float a) | ||
452 | { | ||
453 | gsl_complex c; | ||
454 | gsl_complex r; | ||
455 | |||
456 | gsl_complex_float float_r; | ||
457 | |||
458 | c.dat[0] = a.dat[0]; | ||
459 | c.dat[1] = a.dat[1]; | ||
460 | |||
461 | r = (*cf)(c); | ||
462 | |||
463 | float_r.dat[0] = r.dat[0]; | ||
464 | float_r.dat[1] = r.dat[1]; | ||
465 | |||
466 | return float_r; | ||
467 | } | ||
468 | |||
469 | gsl_complex_float complex_float_math_op(gsl_complex (*cf)(gsl_complex,gsl_complex), | ||
470 | gsl_complex_float a,gsl_complex_float b) | ||
471 | { | ||
472 | gsl_complex c1; | ||
473 | gsl_complex c2; | ||
474 | gsl_complex r; | ||
475 | |||
476 | gsl_complex_float float_r; | ||
477 | |||
478 | c1.dat[0] = a.dat[0]; | ||
479 | c1.dat[1] = a.dat[1]; | ||
480 | |||
481 | c2.dat[0] = b.dat[0]; | ||
482 | c2.dat[1] = b.dat[1]; | ||
483 | |||
484 | r = (*cf)(c1,c2); | ||
485 | |||
486 | float_r.dat[0] = r.dat[0]; | ||
487 | float_r.dat[1] = r.dat[1]; | ||
488 | |||
489 | return float_r; | ||
490 | } | ||
491 | |||
492 | #define OPC(C,F) case C: { for(k=0;k<xn;k++) rp[k] = complex_float_math_fun(&F,xp[k]); OK } | ||
493 | #define OPCA(C,F,A,B) case C: { for(k=0;k<xn;k++) rp[k] = complex_float_math_op(&F,A,B); OK } | ||
494 | int mapQAux(int code, KGQVEC(x), GQVEC(r)) { | ||
495 | int k; | ||
496 | REQUIRES(xn == rn,BAD_SIZE); | ||
497 | DEBUGMSG("mapQ"); | ||
498 | switch (code) { | ||
499 | OPC(0,gsl_complex_sin) | ||
500 | OPC(1,gsl_complex_cos) | ||
501 | OPC(2,gsl_complex_tan) | ||
502 | OPC(3,complex_abs) | ||
503 | OPC(4,gsl_complex_arcsin) | ||
504 | OPC(5,gsl_complex_arccos) | ||
505 | OPC(6,gsl_complex_arctan) | ||
506 | OPC(7,gsl_complex_sinh) | ||
507 | OPC(8,gsl_complex_cosh) | ||
508 | OPC(9,gsl_complex_tanh) | ||
509 | OPC(10,gsl_complex_arcsinh) | ||
510 | OPC(11,gsl_complex_arccosh) | ||
511 | OPC(12,gsl_complex_arctanh) | ||
512 | OPC(13,gsl_complex_exp) | ||
513 | OPC(14,gsl_complex_log) | ||
514 | OPC(15,complex_signum) | ||
515 | OPC(16,gsl_complex_sqrt) | ||
516 | |||
517 | // gsl_complex_arg | ||
518 | // gsl_complex_abs | ||
519 | default: ERROR(BAD_CODE); | ||
520 | } | ||
521 | } | ||
522 | |||
523 | int mapQ(int code, KQVEC(x), QVEC(r)) { | ||
524 | return mapQAux(code, xn, (gsl_complex_float*)xp, rn, (gsl_complex_float*)rp); | ||
525 | } | ||
526 | |||
527 | |||
528 | int mapValR(int code, double* pval, KRVEC(x), RVEC(r)) { | ||
529 | int k; | ||
530 | double val = *pval; | ||
531 | REQUIRES(xn == rn,BAD_SIZE); | ||
532 | DEBUGMSG("mapValR"); | ||
533 | switch (code) { | ||
534 | OPV(0,val*xp[k]) | ||
535 | OPV(1,val/xp[k]) | ||
536 | OPV(2,val+xp[k]) | ||
537 | OPV(3,val-xp[k]) | ||
538 | OPV(4,pow(val,xp[k])) | ||
539 | OPV(5,pow(xp[k],val)) | ||
540 | default: ERROR(BAD_CODE); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | int mapValF(int code, float* pval, KFVEC(x), FVEC(r)) { | ||
545 | int k; | ||
546 | float val = *pval; | ||
547 | REQUIRES(xn == rn,BAD_SIZE); | ||
548 | DEBUGMSG("mapValF"); | ||
549 | switch (code) { | ||
550 | OPV(0,val*xp[k]) | ||
551 | OPV(1,val/xp[k]) | ||
552 | OPV(2,val+xp[k]) | ||
553 | OPV(3,val-xp[k]) | ||
554 | OPV(4,pow(val,xp[k])) | ||
555 | OPV(5,pow(xp[k],val)) | ||
556 | default: ERROR(BAD_CODE); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | int mapValCAux(int code, gsl_complex* pval, KGCVEC(x), GCVEC(r)) { | ||
561 | int k; | ||
562 | gsl_complex val = *pval; | ||
563 | REQUIRES(xn == rn,BAD_SIZE); | ||
564 | DEBUGMSG("mapValC"); | ||
565 | switch (code) { | ||
566 | OPV(0,gsl_complex_mul(val,xp[k])) | ||
567 | OPV(1,gsl_complex_div(val,xp[k])) | ||
568 | OPV(2,gsl_complex_add(val,xp[k])) | ||
569 | OPV(3,gsl_complex_sub(val,xp[k])) | ||
570 | OPV(4,gsl_complex_pow(val,xp[k])) | ||
571 | OPV(5,gsl_complex_pow(xp[k],val)) | ||
572 | default: ERROR(BAD_CODE); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | int mapValC(int code, gsl_complex* val, KCVEC(x), CVEC(r)) { | ||
577 | return mapValCAux(code, val, xn, (gsl_complex*)xp, rn, (gsl_complex*)rp); | ||
578 | } | ||
579 | |||
580 | |||
581 | int mapValQAux(int code, gsl_complex_float* pval, KQVEC(x), GQVEC(r)) { | ||
582 | int k; | ||
583 | gsl_complex_float val = *pval; | ||
584 | REQUIRES(xn == rn,BAD_SIZE); | ||
585 | DEBUGMSG("mapValQ"); | ||
586 | switch (code) { | ||
587 | OPCA(0,gsl_complex_mul,val,xp[k]) | ||
588 | OPCA(1,gsl_complex_div,val,xp[k]) | ||
589 | OPCA(2,gsl_complex_add,val,xp[k]) | ||
590 | OPCA(3,gsl_complex_sub,val,xp[k]) | ||
591 | OPCA(4,gsl_complex_pow,val,xp[k]) | ||
592 | OPCA(5,gsl_complex_pow,xp[k],val) | ||
593 | default: ERROR(BAD_CODE); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | int mapValQ(int code, gsl_complex_float* val, KQVEC(x), QVEC(r)) { | ||
598 | return mapValQAux(code, val, xn, (gsl_complex_float*)xp, rn, (gsl_complex_float*)rp); | ||
599 | } | ||
600 | |||
601 | |||
602 | #define OPZE(C,msg,E) case C: {DEBUGMSG(msg) for(k=0;k<an;k++) rp[k] = E(ap[k],bp[k]); OK } | ||
603 | #define OPZV(C,msg,E) case C: {DEBUGMSG(msg) res = E(V(r),V(b)); CHECK(res,res); OK } | ||
604 | int zipR(int code, KRVEC(a), KRVEC(b), RVEC(r)) { | ||
605 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
606 | int k; | ||
607 | switch(code) { | ||
608 | OPZE(4,"zipR Pow",pow) | ||
609 | OPZE(5,"zipR ATan2",atan2) | ||
610 | } | ||
611 | KDVVIEW(a); | ||
612 | KDVVIEW(b); | ||
613 | DVVIEW(r); | ||
614 | gsl_vector_memcpy(V(r),V(a)); | ||
615 | int res; | ||
616 | switch(code) { | ||
617 | OPZV(0,"zipR Add",gsl_vector_add) | ||
618 | OPZV(1,"zipR Sub",gsl_vector_sub) | ||
619 | OPZV(2,"zipR Mul",gsl_vector_mul) | ||
620 | OPZV(3,"zipR Div",gsl_vector_div) | ||
621 | default: ERROR(BAD_CODE); | ||
622 | } | ||
623 | } | ||
624 | |||
625 | |||
626 | int zipF(int code, KFVEC(a), KFVEC(b), FVEC(r)) { | ||
627 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
628 | int k; | ||
629 | switch(code) { | ||
630 | OPZE(4,"zipF Pow",pow) | ||
631 | OPZE(5,"zipF ATan2",atan2) | ||
632 | } | ||
633 | KFVVIEW(a); | ||
634 | KFVVIEW(b); | ||
635 | FVVIEW(r); | ||
636 | gsl_vector_float_memcpy(V(r),V(a)); | ||
637 | int res; | ||
638 | switch(code) { | ||
639 | OPZV(0,"zipF Add",gsl_vector_float_add) | ||
640 | OPZV(1,"zipF Sub",gsl_vector_float_sub) | ||
641 | OPZV(2,"zipF Mul",gsl_vector_float_mul) | ||
642 | OPZV(3,"zipF Div",gsl_vector_float_div) | ||
643 | default: ERROR(BAD_CODE); | ||
644 | } | ||
645 | } | ||
646 | |||
647 | |||
648 | int zipCAux(int code, KGCVEC(a), KGCVEC(b), GCVEC(r)) { | ||
649 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
650 | int k; | ||
651 | switch(code) { | ||
652 | OPZE(0,"zipC Add",gsl_complex_add) | ||
653 | OPZE(1,"zipC Sub",gsl_complex_sub) | ||
654 | OPZE(2,"zipC Mul",gsl_complex_mul) | ||
655 | OPZE(3,"zipC Div",gsl_complex_div) | ||
656 | OPZE(4,"zipC Pow",gsl_complex_pow) | ||
657 | //OPZE(5,"zipR ATan2",atan2) | ||
658 | } | ||
659 | //KCVVIEW(a); | ||
660 | //KCVVIEW(b); | ||
661 | //CVVIEW(r); | ||
662 | //gsl_vector_memcpy(V(r),V(a)); | ||
663 | //int res; | ||
664 | switch(code) { | ||
665 | default: ERROR(BAD_CODE); | ||
666 | } | ||
667 | } | ||
668 | |||
669 | |||
670 | int zipC(int code, KCVEC(a), KCVEC(b), CVEC(r)) { | ||
671 | return zipCAux(code, an, (gsl_complex*)ap, bn, (gsl_complex*)bp, rn, (gsl_complex*)rp); | ||
672 | } | ||
673 | |||
674 | |||
675 | #define OPCZE(C,msg,E) case C: {DEBUGMSG(msg) for(k=0;k<an;k++) rp[k] = complex_float_math_op(&E,ap[k],bp[k]); OK } | ||
676 | int zipQAux(int code, KGQVEC(a), KGQVEC(b), GQVEC(r)) { | ||
677 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
678 | int k; | ||
679 | switch(code) { | ||
680 | OPCZE(0,"zipQ Add",gsl_complex_add) | ||
681 | OPCZE(1,"zipQ Sub",gsl_complex_sub) | ||
682 | OPCZE(2,"zipQ Mul",gsl_complex_mul) | ||
683 | OPCZE(3,"zipQ Div",gsl_complex_div) | ||
684 | OPCZE(4,"zipQ Pow",gsl_complex_pow) | ||
685 | //OPZE(5,"zipR ATan2",atan2) | ||
686 | } | ||
687 | //KCVVIEW(a); | ||
688 | //KCVVIEW(b); | ||
689 | //CVVIEW(r); | ||
690 | //gsl_vector_memcpy(V(r),V(a)); | ||
691 | //int res; | ||
692 | switch(code) { | ||
693 | default: ERROR(BAD_CODE); | ||
694 | } | ||
695 | } | ||
696 | |||
697 | |||
698 | int zipQ(int code, KQVEC(a), KQVEC(b), QVEC(r)) { | ||
699 | return zipQAux(code, an, (gsl_complex_float*)ap, bn, (gsl_complex_float*)bp, rn, (gsl_complex_float*)rp); | ||
700 | } | ||
701 | |||
702 | |||
703 | |||
704 | int fft(int code, KCVEC(X), CVEC(R)) { | ||
705 | REQUIRES(Xn == Rn,BAD_SIZE); | ||
706 | DEBUGMSG("fft"); | ||
707 | int s = Xn; | ||
708 | gsl_fft_complex_wavetable * wavetable = gsl_fft_complex_wavetable_alloc (s); | ||
709 | gsl_fft_complex_workspace * workspace = gsl_fft_complex_workspace_alloc (s); | ||
710 | gsl_vector_const_view X = gsl_vector_const_view_array((double*)Xp, 2*Xn); | ||
711 | gsl_vector_view R = gsl_vector_view_array((double*)Rp, 2*Rn); | ||
712 | gsl_blas_dcopy(&X.vector,&R.vector); | ||
713 | if(code==0) { | ||
714 | gsl_fft_complex_forward ((double*)Rp, 1, s, wavetable, workspace); | ||
715 | } else { | ||
716 | gsl_fft_complex_inverse ((double*)Rp, 1, s, wavetable, workspace); | ||
717 | } | ||
718 | gsl_fft_complex_wavetable_free (wavetable); | ||
719 | gsl_fft_complex_workspace_free (workspace); | ||
720 | OK | ||
721 | } | ||
722 | |||
723 | |||
724 | int deriv(int code, double f(double, void*), double x, double h, double * result, double * abserr) | ||
725 | { | ||
726 | gsl_function F; | ||
727 | F.function = f; | ||
728 | F.params = 0; | ||
729 | |||
730 | if(code==0) return gsl_deriv_central (&F, x, h, result, abserr); | ||
731 | |||
732 | if(code==1) return gsl_deriv_forward (&F, x, h, result, abserr); | ||
733 | |||
734 | if(code==2) return gsl_deriv_backward (&F, x, h, result, abserr); | ||
735 | |||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | |||
740 | int integrate_qng(double f(double, void*), double a, double b, double aprec, double prec, | ||
741 | double *result, double*error) { | ||
742 | DEBUGMSG("integrate_qng"); | ||
743 | gsl_function F; | ||
744 | F.function = f; | ||
745 | F.params = NULL; | ||
746 | size_t neval; | ||
747 | int res = gsl_integration_qng (&F, a,b, aprec, prec, result, error, &neval); | ||
748 | CHECK(res,res); | ||
749 | OK | ||
750 | } | ||
751 | |||
752 | int integrate_qags(double f(double,void*), double a, double b, double aprec, double prec, int w, | ||
753 | double *result, double* error) { | ||
754 | DEBUGMSG("integrate_qags"); | ||
755 | gsl_integration_workspace * wk = gsl_integration_workspace_alloc (w); | ||
756 | gsl_function F; | ||
757 | F.function = f; | ||
758 | F.params = NULL; | ||
759 | int res = gsl_integration_qags (&F, a,b, aprec, prec, w,wk, result, error); | ||
760 | CHECK(res,res); | ||
761 | gsl_integration_workspace_free (wk); | ||
762 | OK | ||
763 | } | ||
764 | |||
765 | int integrate_qagi(double f(double,void*), double aprec, double prec, int w, | ||
766 | double *result, double* error) { | ||
767 | DEBUGMSG("integrate_qagi"); | ||
768 | gsl_integration_workspace * wk = gsl_integration_workspace_alloc (w); | ||
769 | gsl_function F; | ||
770 | F.function = f; | ||
771 | F.params = NULL; | ||
772 | int res = gsl_integration_qagi (&F, aprec, prec, w,wk, result, error); | ||
773 | CHECK(res,res); | ||
774 | gsl_integration_workspace_free (wk); | ||
775 | OK | ||
776 | } | ||
777 | |||
778 | |||
779 | int integrate_qagiu(double f(double,void*), double a, double aprec, double prec, int w, | ||
780 | double *result, double* error) { | ||
781 | DEBUGMSG("integrate_qagiu"); | ||
782 | gsl_integration_workspace * wk = gsl_integration_workspace_alloc (w); | ||
783 | gsl_function F; | ||
784 | F.function = f; | ||
785 | F.params = NULL; | ||
786 | int res = gsl_integration_qagiu (&F, a, aprec, prec, w,wk, result, error); | ||
787 | CHECK(res,res); | ||
788 | gsl_integration_workspace_free (wk); | ||
789 | OK | ||
790 | } | ||
791 | |||
792 | |||
793 | int integrate_qagil(double f(double,void*), double b, double aprec, double prec, int w, | ||
794 | double *result, double* error) { | ||
795 | DEBUGMSG("integrate_qagil"); | ||
796 | gsl_integration_workspace * wk = gsl_integration_workspace_alloc (w); | ||
797 | gsl_function F; | ||
798 | F.function = f; | ||
799 | F.params = NULL; | ||
800 | int res = gsl_integration_qagil (&F, b, aprec, prec, w,wk, result, error); | ||
801 | CHECK(res,res); | ||
802 | gsl_integration_workspace_free (wk); | ||
803 | OK | ||
804 | } | ||
805 | |||
806 | int integrate_cquad(double f(double,void*), double a, double b, double aprec, double prec, | ||
807 | int w, double *result, double* error, int *neval) { | ||
808 | DEBUGMSG("integrate_cquad"); | ||
809 | gsl_integration_cquad_workspace * wk = gsl_integration_cquad_workspace_alloc (w); | ||
810 | gsl_function F; | ||
811 | F.function = f; | ||
812 | F.params = NULL; | ||
813 | size_t * sneval = NULL; | ||
814 | int res = gsl_integration_cquad (&F, a, b, aprec, prec, wk, result, error, sneval); | ||
815 | *neval = *sneval; | ||
816 | CHECK(res,res); | ||
817 | gsl_integration_cquad_workspace_free (wk); | ||
818 | OK | ||
819 | } | ||
820 | |||
821 | |||
822 | int polySolve(KRVEC(a), CVEC(z)) { | ||
823 | DEBUGMSG("polySolve"); | ||
824 | REQUIRES(an>1,BAD_SIZE); | ||
825 | gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc (an); | ||
826 | int res = gsl_poly_complex_solve ((double*)ap, an, w, (double*)zp); | ||
827 | CHECK(res,res); | ||
828 | gsl_poly_complex_workspace_free (w); | ||
829 | OK; | ||
830 | } | ||
831 | |||
832 | int vector_fscanf(char*filename, RVEC(a)) { | ||
833 | DEBUGMSG("gsl_vector_fscanf"); | ||
834 | DVVIEW(a); | ||
835 | FILE * f = fopen(filename,"r"); | ||
836 | CHECK(!f,BAD_FILE); | ||
837 | int res = gsl_vector_fscanf(f,V(a)); | ||
838 | CHECK(res,res); | ||
839 | fclose (f); | ||
840 | OK | ||
841 | } | ||
842 | |||
843 | int vector_fprintf(char*filename, char*fmt, RVEC(a)) { | ||
844 | DEBUGMSG("gsl_vector_fprintf"); | ||
845 | DVVIEW(a); | ||
846 | FILE * f = fopen(filename,"w"); | ||
847 | CHECK(!f,BAD_FILE); | ||
848 | int res = gsl_vector_fprintf(f,V(a),fmt); | ||
849 | CHECK(res,res); | ||
850 | fclose (f); | ||
851 | OK | ||
852 | } | ||
853 | |||
854 | int vector_fread(char*filename, RVEC(a)) { | ||
855 | DEBUGMSG("gsl_vector_fread"); | ||
856 | DVVIEW(a); | ||
857 | FILE * f = fopen(filename,"r"); | ||
858 | CHECK(!f,BAD_FILE); | ||
859 | int res = gsl_vector_fread(f,V(a)); | ||
860 | CHECK(res,res); | ||
861 | fclose (f); | ||
862 | OK | ||
863 | } | ||
864 | |||
865 | int vector_fwrite(char*filename, RVEC(a)) { | ||
866 | DEBUGMSG("gsl_vector_fwrite"); | ||
867 | DVVIEW(a); | ||
868 | FILE * f = fopen(filename,"w"); | ||
869 | CHECK(!f,BAD_FILE); | ||
870 | int res = gsl_vector_fwrite(f,V(a)); | ||
871 | CHECK(res,res); | ||
872 | fclose (f); | ||
873 | OK | ||
874 | } | ||
875 | |||
876 | int matrix_fprintf(char*filename, char*fmt, int ro, RMAT(m)) { | ||
877 | DEBUGMSG("matrix_fprintf"); | ||
878 | FILE * f = fopen(filename,"w"); | ||
879 | CHECK(!f,BAD_FILE); | ||
880 | int i,j,sr,sc; | ||
881 | if (ro==1) { sr = mc; sc = 1;} else { sr = 1; sc = mr;} | ||
882 | #define AT(M,r,c) (M##p[(r)*sr+(c)*sc]) | ||
883 | for (i=0; i<mr; i++) { | ||
884 | for (j=0; j<mc-1; j++) { | ||
885 | fprintf(f,fmt,AT(m,i,j)); | ||
886 | fprintf(f," "); | ||
887 | } | ||
888 | fprintf(f,fmt,AT(m,i,j)); | ||
889 | fprintf(f,"\n"); | ||
890 | } | ||
891 | fclose (f); | ||
892 | OK | ||
893 | } | ||
894 | |||
895 | //--------------------------------------------------------------- | ||
896 | |||
897 | typedef double Trawfun(int, double*); | ||
898 | |||
899 | double only_f_aux_min(const gsl_vector*x, void *pars) { | ||
900 | Trawfun * f = (Trawfun*) pars; | ||
901 | double* p = (double*)calloc(x->size,sizeof(double)); | ||
902 | int k; | ||
903 | for(k=0;k<x->size;k++) { | ||
904 | p[k] = gsl_vector_get(x,k); | ||
905 | } | ||
906 | double res = f(x->size,p); | ||
907 | free(p); | ||
908 | return res; | ||
909 | } | ||
910 | |||
911 | double only_f_aux_root(double x, void *pars); | ||
912 | int uniMinimize(int method, double f(double), | ||
913 | double epsrel, int maxit, double min, | ||
914 | double xl, double xu, RMAT(sol)) { | ||
915 | REQUIRES(solr == maxit && solc == 4,BAD_SIZE); | ||
916 | DEBUGMSG("minimize_only_f"); | ||
917 | gsl_function my_func; | ||
918 | my_func.function = only_f_aux_root; | ||
919 | my_func.params = f; | ||
920 | size_t iter = 0; | ||
921 | int status; | ||
922 | const gsl_min_fminimizer_type *T; | ||
923 | gsl_min_fminimizer *s; | ||
924 | // Starting point | ||
925 | switch(method) { | ||
926 | case 0 : {T = gsl_min_fminimizer_goldensection; break; } | ||
927 | case 1 : {T = gsl_min_fminimizer_brent; break; } | ||
928 | case 2 : {T = gsl_min_fminimizer_quad_golden; break; } | ||
929 | default: ERROR(BAD_CODE); | ||
930 | } | ||
931 | s = gsl_min_fminimizer_alloc (T); | ||
932 | gsl_min_fminimizer_set (s, &my_func, min, xl, xu); | ||
933 | do { | ||
934 | double current_min, current_lo, current_hi; | ||
935 | status = gsl_min_fminimizer_iterate (s); | ||
936 | current_min = gsl_min_fminimizer_x_minimum (s); | ||
937 | current_lo = gsl_min_fminimizer_x_lower (s); | ||
938 | current_hi = gsl_min_fminimizer_x_upper (s); | ||
939 | solp[iter*solc] = iter + 1; | ||
940 | solp[iter*solc+1] = current_min; | ||
941 | solp[iter*solc+2] = current_lo; | ||
942 | solp[iter*solc+3] = current_hi; | ||
943 | iter++; | ||
944 | if (status) /* check if solver is stuck */ | ||
945 | break; | ||
946 | |||
947 | status = | ||
948 | gsl_min_test_interval (current_lo, current_hi, 0, epsrel); | ||
949 | } | ||
950 | while (status == GSL_CONTINUE && iter < maxit); | ||
951 | int i; | ||
952 | for (i=iter; i<solr; i++) { | ||
953 | solp[i*solc+0] = iter; | ||
954 | solp[i*solc+1]=0.; | ||
955 | solp[i*solc+2]=0.; | ||
956 | solp[i*solc+3]=0.; | ||
957 | } | ||
958 | gsl_min_fminimizer_free(s); | ||
959 | OK | ||
960 | } | ||
961 | |||
962 | |||
963 | |||
964 | // this version returns info about intermediate steps | ||
965 | int minimize(int method, double f(int, double*), double tolsize, int maxit, | ||
966 | KRVEC(xi), KRVEC(sz), RMAT(sol)) { | ||
967 | REQUIRES(xin==szn && solr == maxit && solc == 3+xin,BAD_SIZE); | ||
968 | DEBUGMSG("minimizeList (nmsimplex)"); | ||
969 | gsl_multimin_function my_func; | ||
970 | // extract function from pars | ||
971 | my_func.f = only_f_aux_min; | ||
972 | my_func.n = xin; | ||
973 | my_func.params = f; | ||
974 | size_t iter = 0; | ||
975 | int status; | ||
976 | double size; | ||
977 | const gsl_multimin_fminimizer_type *T; | ||
978 | gsl_multimin_fminimizer *s = NULL; | ||
979 | // Initial vertex size vector | ||
980 | KDVVIEW(sz); | ||
981 | // Starting point | ||
982 | KDVVIEW(xi); | ||
983 | // Minimizer nmsimplex, without derivatives | ||
984 | switch(method) { | ||
985 | case 0 : {T = gsl_multimin_fminimizer_nmsimplex; break; } | ||
986 | #ifdef GSL110 | ||
987 | case 1 : {T = gsl_multimin_fminimizer_nmsimplex; break; } | ||
988 | #else | ||
989 | case 1 : {T = gsl_multimin_fminimizer_nmsimplex2; break; } | ||
990 | #endif | ||
991 | default: ERROR(BAD_CODE); | ||
992 | } | ||
993 | s = gsl_multimin_fminimizer_alloc (T, my_func.n); | ||
994 | gsl_multimin_fminimizer_set (s, &my_func, V(xi), V(sz)); | ||
995 | do { | ||
996 | status = gsl_multimin_fminimizer_iterate (s); | ||
997 | size = gsl_multimin_fminimizer_size (s); | ||
998 | |||
999 | solp[iter*solc+0] = iter+1; | ||
1000 | solp[iter*solc+1] = s->fval; | ||
1001 | solp[iter*solc+2] = size; | ||
1002 | |||
1003 | int k; | ||
1004 | for(k=0;k<xin;k++) { | ||
1005 | solp[iter*solc+k+3] = gsl_vector_get(s->x,k); | ||
1006 | } | ||
1007 | iter++; | ||
1008 | if (status) break; | ||
1009 | status = gsl_multimin_test_size (size, tolsize); | ||
1010 | } while (status == GSL_CONTINUE && iter < maxit); | ||
1011 | int i,j; | ||
1012 | for (i=iter; i<solr; i++) { | ||
1013 | solp[i*solc+0] = iter; | ||
1014 | for(j=1;j<solc;j++) { | ||
1015 | solp[i*solc+j]=0.; | ||
1016 | } | ||
1017 | } | ||
1018 | gsl_multimin_fminimizer_free(s); | ||
1019 | OK | ||
1020 | } | ||
1021 | |||
1022 | // working with the gradient | ||
1023 | |||
1024 | typedef struct {double (*f)(int, double*); int (*df)(int, double*, int, double*);} Tfdf; | ||
1025 | |||
1026 | double f_aux_min(const gsl_vector*x, void *pars) { | ||
1027 | Tfdf * fdf = ((Tfdf*) pars); | ||
1028 | double* p = (double*)calloc(x->size,sizeof(double)); | ||
1029 | int k; | ||
1030 | for(k=0;k<x->size;k++) { | ||
1031 | p[k] = gsl_vector_get(x,k); | ||
1032 | } | ||
1033 | double res = fdf->f(x->size,p); | ||
1034 | free(p); | ||
1035 | return res; | ||
1036 | } | ||
1037 | |||
1038 | |||
1039 | void df_aux_min(const gsl_vector * x, void * pars, gsl_vector * g) { | ||
1040 | Tfdf * fdf = ((Tfdf*) pars); | ||
1041 | double* p = (double*)calloc(x->size,sizeof(double)); | ||
1042 | double* q = (double*)calloc(g->size,sizeof(double)); | ||
1043 | int k; | ||
1044 | for(k=0;k<x->size;k++) { | ||
1045 | p[k] = gsl_vector_get(x,k); | ||
1046 | } | ||
1047 | |||
1048 | fdf->df(x->size,p,g->size,q); | ||
1049 | |||
1050 | for(k=0;k<x->size;k++) { | ||
1051 | gsl_vector_set(g,k,q[k]); | ||
1052 | } | ||
1053 | free(p); | ||
1054 | free(q); | ||
1055 | } | ||
1056 | |||
1057 | void fdf_aux_min(const gsl_vector * x, void * pars, double * f, gsl_vector * g) { | ||
1058 | *f = f_aux_min(x,pars); | ||
1059 | df_aux_min(x,pars,g); | ||
1060 | } | ||
1061 | |||
1062 | |||
1063 | int minimizeD(int method, double f(int, double*), int df(int, double*, int, double*), | ||
1064 | double initstep, double minimpar, double tolgrad, int maxit, | ||
1065 | KRVEC(xi), RMAT(sol)) { | ||
1066 | REQUIRES(solr == maxit && solc == 2+xin,BAD_SIZE); | ||
1067 | DEBUGMSG("minimizeWithDeriv (conjugate_fr)"); | ||
1068 | gsl_multimin_function_fdf my_func; | ||
1069 | // extract function from pars | ||
1070 | my_func.f = f_aux_min; | ||
1071 | my_func.df = df_aux_min; | ||
1072 | my_func.fdf = fdf_aux_min; | ||
1073 | my_func.n = xin; | ||
1074 | Tfdf stfdf; | ||
1075 | stfdf.f = f; | ||
1076 | stfdf.df = df; | ||
1077 | my_func.params = &stfdf; | ||
1078 | size_t iter = 0; | ||
1079 | int status; | ||
1080 | const gsl_multimin_fdfminimizer_type *T; | ||
1081 | gsl_multimin_fdfminimizer *s = NULL; | ||
1082 | // Starting point | ||
1083 | KDVVIEW(xi); | ||
1084 | // conjugate gradient fr | ||
1085 | switch(method) { | ||
1086 | case 0 : {T = gsl_multimin_fdfminimizer_conjugate_fr; break; } | ||
1087 | case 1 : {T = gsl_multimin_fdfminimizer_conjugate_pr; break; } | ||
1088 | case 2 : {T = gsl_multimin_fdfminimizer_vector_bfgs; break; } | ||
1089 | case 3 : {T = gsl_multimin_fdfminimizer_vector_bfgs2; break; } | ||
1090 | case 4 : {T = gsl_multimin_fdfminimizer_steepest_descent; break; } | ||
1091 | default: ERROR(BAD_CODE); | ||
1092 | } | ||
1093 | s = gsl_multimin_fdfminimizer_alloc (T, my_func.n); | ||
1094 | gsl_multimin_fdfminimizer_set (s, &my_func, V(xi), initstep, minimpar); | ||
1095 | do { | ||
1096 | status = gsl_multimin_fdfminimizer_iterate (s); | ||
1097 | solp[iter*solc+0] = iter+1; | ||
1098 | solp[iter*solc+1] = s->f; | ||
1099 | int k; | ||
1100 | for(k=0;k<xin;k++) { | ||
1101 | solp[iter*solc+k+2] = gsl_vector_get(s->x,k); | ||
1102 | } | ||
1103 | iter++; | ||
1104 | if (status) break; | ||
1105 | status = gsl_multimin_test_gradient (s->gradient, tolgrad); | ||
1106 | } while (status == GSL_CONTINUE && iter < maxit); | ||
1107 | int i,j; | ||
1108 | for (i=iter; i<solr; i++) { | ||
1109 | solp[i*solc+0] = iter; | ||
1110 | for(j=1;j<solc;j++) { | ||
1111 | solp[i*solc+j]=0.; | ||
1112 | } | ||
1113 | } | ||
1114 | gsl_multimin_fdfminimizer_free(s); | ||
1115 | OK | ||
1116 | } | ||
1117 | |||
1118 | //--------------------------------------------------------------- | ||
1119 | |||
1120 | double only_f_aux_root(double x, void *pars) { | ||
1121 | double (*f)(double) = (double (*)(double)) pars; | ||
1122 | return f(x); | ||
1123 | } | ||
1124 | |||
1125 | int root(int method, double f(double), | ||
1126 | double epsrel, int maxit, | ||
1127 | double xl, double xu, RMAT(sol)) { | ||
1128 | REQUIRES(solr == maxit && solc == 4,BAD_SIZE); | ||
1129 | DEBUGMSG("root_only_f"); | ||
1130 | gsl_function my_func; | ||
1131 | // extract function from pars | ||
1132 | my_func.function = only_f_aux_root; | ||
1133 | my_func.params = f; | ||
1134 | size_t iter = 0; | ||
1135 | int status; | ||
1136 | const gsl_root_fsolver_type *T; | ||
1137 | gsl_root_fsolver *s; | ||
1138 | // Starting point | ||
1139 | switch(method) { | ||
1140 | case 0 : {T = gsl_root_fsolver_bisection; printf("7\n"); break; } | ||
1141 | case 1 : {T = gsl_root_fsolver_falsepos; break; } | ||
1142 | case 2 : {T = gsl_root_fsolver_brent; break; } | ||
1143 | default: ERROR(BAD_CODE); | ||
1144 | } | ||
1145 | s = gsl_root_fsolver_alloc (T); | ||
1146 | gsl_root_fsolver_set (s, &my_func, xl, xu); | ||
1147 | do { | ||
1148 | double best, current_lo, current_hi; | ||
1149 | status = gsl_root_fsolver_iterate (s); | ||
1150 | best = gsl_root_fsolver_root (s); | ||
1151 | current_lo = gsl_root_fsolver_x_lower (s); | ||
1152 | current_hi = gsl_root_fsolver_x_upper (s); | ||
1153 | solp[iter*solc] = iter + 1; | ||
1154 | solp[iter*solc+1] = best; | ||
1155 | solp[iter*solc+2] = current_lo; | ||
1156 | solp[iter*solc+3] = current_hi; | ||
1157 | iter++; | ||
1158 | if (status) /* check if solver is stuck */ | ||
1159 | break; | ||
1160 | |||
1161 | status = | ||
1162 | gsl_root_test_interval (current_lo, current_hi, 0, epsrel); | ||
1163 | } | ||
1164 | while (status == GSL_CONTINUE && iter < maxit); | ||
1165 | int i; | ||
1166 | for (i=iter; i<solr; i++) { | ||
1167 | solp[i*solc+0] = iter; | ||
1168 | solp[i*solc+1]=0.; | ||
1169 | solp[i*solc+2]=0.; | ||
1170 | solp[i*solc+3]=0.; | ||
1171 | } | ||
1172 | gsl_root_fsolver_free(s); | ||
1173 | OK | ||
1174 | } | ||
1175 | |||
1176 | typedef struct { | ||
1177 | double (*f)(double); | ||
1178 | double (*jf)(double); | ||
1179 | } uniTfjf; | ||
1180 | |||
1181 | double f_aux_uni(double x, void *pars) { | ||
1182 | uniTfjf * fjf = ((uniTfjf*) pars); | ||
1183 | return (fjf->f)(x); | ||
1184 | } | ||
1185 | |||
1186 | double jf_aux_uni(double x, void * pars) { | ||
1187 | uniTfjf * fjf = ((uniTfjf*) pars); | ||
1188 | return (fjf->jf)(x); | ||
1189 | } | ||
1190 | |||
1191 | void fjf_aux_uni(double x, void * pars, double * f, double * g) { | ||
1192 | *f = f_aux_uni(x,pars); | ||
1193 | *g = jf_aux_uni(x,pars); | ||
1194 | } | ||
1195 | |||
1196 | int rootj(int method, double f(double), | ||
1197 | double df(double), | ||
1198 | double epsrel, int maxit, | ||
1199 | double x, RMAT(sol)) { | ||
1200 | REQUIRES(solr == maxit && solc == 2,BAD_SIZE); | ||
1201 | DEBUGMSG("root_fjf"); | ||
1202 | gsl_function_fdf my_func; | ||
1203 | // extract function from pars | ||
1204 | my_func.f = f_aux_uni; | ||
1205 | my_func.df = jf_aux_uni; | ||
1206 | my_func.fdf = fjf_aux_uni; | ||
1207 | uniTfjf stfjf; | ||
1208 | stfjf.f = f; | ||
1209 | stfjf.jf = df; | ||
1210 | my_func.params = &stfjf; | ||
1211 | size_t iter = 0; | ||
1212 | int status; | ||
1213 | const gsl_root_fdfsolver_type *T; | ||
1214 | gsl_root_fdfsolver *s; | ||
1215 | // Starting point | ||
1216 | switch(method) { | ||
1217 | case 0 : {T = gsl_root_fdfsolver_newton;; break; } | ||
1218 | case 1 : {T = gsl_root_fdfsolver_secant; break; } | ||
1219 | case 2 : {T = gsl_root_fdfsolver_steffenson; break; } | ||
1220 | default: ERROR(BAD_CODE); | ||
1221 | } | ||
1222 | s = gsl_root_fdfsolver_alloc (T); | ||
1223 | |||
1224 | gsl_root_fdfsolver_set (s, &my_func, x); | ||
1225 | |||
1226 | do { | ||
1227 | double x0; | ||
1228 | status = gsl_root_fdfsolver_iterate (s); | ||
1229 | x0 = x; | ||
1230 | x = gsl_root_fdfsolver_root(s); | ||
1231 | solp[iter*solc+0] = iter+1; | ||
1232 | solp[iter*solc+1] = x; | ||
1233 | |||
1234 | iter++; | ||
1235 | if (status) /* check if solver is stuck */ | ||
1236 | break; | ||
1237 | |||
1238 | status = | ||
1239 | gsl_root_test_delta (x, x0, 0, epsrel); | ||
1240 | } | ||
1241 | while (status == GSL_CONTINUE && iter < maxit); | ||
1242 | |||
1243 | int i; | ||
1244 | for (i=iter; i<solr; i++) { | ||
1245 | solp[i*solc+0] = iter; | ||
1246 | solp[i*solc+1]=0.; | ||
1247 | } | ||
1248 | gsl_root_fdfsolver_free(s); | ||
1249 | OK | ||
1250 | } | ||
1251 | |||
1252 | |||
1253 | //--------------------------------------------------------------- | ||
1254 | |||
1255 | typedef void TrawfunV(int, double*, int, double*); | ||
1256 | |||
1257 | int only_f_aux_multiroot(const gsl_vector*x, void *pars, gsl_vector*y) { | ||
1258 | TrawfunV * f = (TrawfunV*) pars; | ||
1259 | double* p = (double*)calloc(x->size,sizeof(double)); | ||
1260 | double* q = (double*)calloc(y->size,sizeof(double)); | ||
1261 | int k; | ||
1262 | for(k=0;k<x->size;k++) { | ||
1263 | p[k] = gsl_vector_get(x,k); | ||
1264 | } | ||
1265 | f(x->size,p,y->size,q); | ||
1266 | for(k=0;k<y->size;k++) { | ||
1267 | gsl_vector_set(y,k,q[k]); | ||
1268 | } | ||
1269 | free(p); | ||
1270 | free(q); | ||
1271 | return 0; //hmmm | ||
1272 | } | ||
1273 | |||
1274 | int multiroot(int method, void f(int, double*, int, double*), | ||
1275 | double epsabs, int maxit, | ||
1276 | KRVEC(xi), RMAT(sol)) { | ||
1277 | REQUIRES(solr == maxit && solc == 1+2*xin,BAD_SIZE); | ||
1278 | DEBUGMSG("root_only_f"); | ||
1279 | gsl_multiroot_function my_func; | ||
1280 | // extract function from pars | ||
1281 | my_func.f = only_f_aux_multiroot; | ||
1282 | my_func.n = xin; | ||
1283 | my_func.params = f; | ||
1284 | size_t iter = 0; | ||
1285 | int status; | ||
1286 | const gsl_multiroot_fsolver_type *T; | ||
1287 | gsl_multiroot_fsolver *s; | ||
1288 | // Starting point | ||
1289 | KDVVIEW(xi); | ||
1290 | switch(method) { | ||
1291 | case 0 : {T = gsl_multiroot_fsolver_hybrids;; break; } | ||
1292 | case 1 : {T = gsl_multiroot_fsolver_hybrid; break; } | ||
1293 | case 2 : {T = gsl_multiroot_fsolver_dnewton; break; } | ||
1294 | case 3 : {T = gsl_multiroot_fsolver_broyden; break; } | ||
1295 | default: ERROR(BAD_CODE); | ||
1296 | } | ||
1297 | s = gsl_multiroot_fsolver_alloc (T, my_func.n); | ||
1298 | gsl_multiroot_fsolver_set (s, &my_func, V(xi)); | ||
1299 | |||
1300 | do { | ||
1301 | status = gsl_multiroot_fsolver_iterate (s); | ||
1302 | |||
1303 | solp[iter*solc+0] = iter+1; | ||
1304 | |||
1305 | int k; | ||
1306 | for(k=0;k<xin;k++) { | ||
1307 | solp[iter*solc+k+1] = gsl_vector_get(s->x,k); | ||
1308 | } | ||
1309 | for(k=xin;k<2*xin;k++) { | ||
1310 | solp[iter*solc+k+1] = gsl_vector_get(s->f,k-xin); | ||
1311 | } | ||
1312 | |||
1313 | iter++; | ||
1314 | if (status) /* check if solver is stuck */ | ||
1315 | break; | ||
1316 | |||
1317 | status = | ||
1318 | gsl_multiroot_test_residual (s->f, epsabs); | ||
1319 | } | ||
1320 | while (status == GSL_CONTINUE && iter < maxit); | ||
1321 | |||
1322 | int i,j; | ||
1323 | for (i=iter; i<solr; i++) { | ||
1324 | solp[i*solc+0] = iter; | ||
1325 | for(j=1;j<solc;j++) { | ||
1326 | solp[i*solc+j]=0.; | ||
1327 | } | ||
1328 | } | ||
1329 | gsl_multiroot_fsolver_free(s); | ||
1330 | OK | ||
1331 | } | ||
1332 | |||
1333 | // working with the jacobian | ||
1334 | |||
1335 | typedef struct {int (*f)(int, double*, int, double *); | ||
1336 | int (*jf)(int, double*, int, int, double*);} Tfjf; | ||
1337 | |||
1338 | int f_aux(const gsl_vector*x, void *pars, gsl_vector*y) { | ||
1339 | Tfjf * fjf = ((Tfjf*) pars); | ||
1340 | double* p = (double*)calloc(x->size,sizeof(double)); | ||
1341 | double* q = (double*)calloc(y->size,sizeof(double)); | ||
1342 | int k; | ||
1343 | for(k=0;k<x->size;k++) { | ||
1344 | p[k] = gsl_vector_get(x,k); | ||
1345 | } | ||
1346 | (fjf->f)(x->size,p,y->size,q); | ||
1347 | for(k=0;k<y->size;k++) { | ||
1348 | gsl_vector_set(y,k,q[k]); | ||
1349 | } | ||
1350 | free(p); | ||
1351 | free(q); | ||
1352 | return 0; | ||
1353 | } | ||
1354 | |||
1355 | int jf_aux(const gsl_vector * x, void * pars, gsl_matrix * jac) { | ||
1356 | Tfjf * fjf = ((Tfjf*) pars); | ||
1357 | double* p = (double*)calloc(x->size,sizeof(double)); | ||
1358 | double* q = (double*)calloc((jac->size1)*(jac->size2),sizeof(double)); | ||
1359 | int i,j,k; | ||
1360 | for(k=0;k<x->size;k++) { | ||
1361 | p[k] = gsl_vector_get(x,k); | ||
1362 | } | ||
1363 | |||
1364 | (fjf->jf)(x->size,p,jac->size1,jac->size2,q); | ||
1365 | |||
1366 | k=0; | ||
1367 | for(i=0;i<jac->size1;i++) { | ||
1368 | for(j=0;j<jac->size2;j++){ | ||
1369 | gsl_matrix_set(jac,i,j,q[k++]); | ||
1370 | } | ||
1371 | } | ||
1372 | free(p); | ||
1373 | free(q); | ||
1374 | return 0; | ||
1375 | } | ||
1376 | |||
1377 | int fjf_aux(const gsl_vector * x, void * pars, gsl_vector * f, gsl_matrix * g) { | ||
1378 | f_aux(x,pars,f); | ||
1379 | jf_aux(x,pars,g); | ||
1380 | return 0; | ||
1381 | } | ||
1382 | |||
1383 | int multirootj(int method, int f(int, double*, int, double*), | ||
1384 | int jac(int, double*, int, int, double*), | ||
1385 | double epsabs, int maxit, | ||
1386 | KRVEC(xi), RMAT(sol)) { | ||
1387 | REQUIRES(solr == maxit && solc == 1+2*xin,BAD_SIZE); | ||
1388 | DEBUGMSG("root_fjf"); | ||
1389 | gsl_multiroot_function_fdf my_func; | ||
1390 | // extract function from pars | ||
1391 | my_func.f = f_aux; | ||
1392 | my_func.df = jf_aux; | ||
1393 | my_func.fdf = fjf_aux; | ||
1394 | my_func.n = xin; | ||
1395 | Tfjf stfjf; | ||
1396 | stfjf.f = f; | ||
1397 | stfjf.jf = jac; | ||
1398 | my_func.params = &stfjf; | ||
1399 | size_t iter = 0; | ||
1400 | int status; | ||
1401 | const gsl_multiroot_fdfsolver_type *T; | ||
1402 | gsl_multiroot_fdfsolver *s; | ||
1403 | // Starting point | ||
1404 | KDVVIEW(xi); | ||
1405 | switch(method) { | ||
1406 | case 0 : {T = gsl_multiroot_fdfsolver_hybridsj;; break; } | ||
1407 | case 1 : {T = gsl_multiroot_fdfsolver_hybridj; break; } | ||
1408 | case 2 : {T = gsl_multiroot_fdfsolver_newton; break; } | ||
1409 | case 3 : {T = gsl_multiroot_fdfsolver_gnewton; break; } | ||
1410 | default: ERROR(BAD_CODE); | ||
1411 | } | ||
1412 | s = gsl_multiroot_fdfsolver_alloc (T, my_func.n); | ||
1413 | |||
1414 | gsl_multiroot_fdfsolver_set (s, &my_func, V(xi)); | ||
1415 | |||
1416 | do { | ||
1417 | status = gsl_multiroot_fdfsolver_iterate (s); | ||
1418 | |||
1419 | solp[iter*solc+0] = iter+1; | ||
1420 | |||
1421 | int k; | ||
1422 | for(k=0;k<xin;k++) { | ||
1423 | solp[iter*solc+k+1] = gsl_vector_get(s->x,k); | ||
1424 | } | ||
1425 | for(k=xin;k<2*xin;k++) { | ||
1426 | solp[iter*solc+k+1] = gsl_vector_get(s->f,k-xin); | ||
1427 | } | ||
1428 | |||
1429 | iter++; | ||
1430 | if (status) /* check if solver is stuck */ | ||
1431 | break; | ||
1432 | |||
1433 | status = | ||
1434 | gsl_multiroot_test_residual (s->f, epsabs); | ||
1435 | } | ||
1436 | while (status == GSL_CONTINUE && iter < maxit); | ||
1437 | |||
1438 | int i,j; | ||
1439 | for (i=iter; i<solr; i++) { | ||
1440 | solp[i*solc+0] = iter; | ||
1441 | for(j=1;j<solc;j++) { | ||
1442 | solp[i*solc+j]=0.; | ||
1443 | } | ||
1444 | } | ||
1445 | gsl_multiroot_fdfsolver_free(s); | ||
1446 | OK | ||
1447 | } | ||
1448 | |||
1449 | //-------------- non linear least squares fitting ------------------- | ||
1450 | |||
1451 | int nlfit(int method, int f(int, double*, int, double*), | ||
1452 | int jac(int, double*, int, int, double*), | ||
1453 | double epsabs, double epsrel, int maxit, int p, | ||
1454 | KRVEC(xi), RMAT(sol)) { | ||
1455 | REQUIRES(solr == maxit && solc == 2+xin,BAD_SIZE); | ||
1456 | DEBUGMSG("nlfit"); | ||
1457 | const gsl_multifit_fdfsolver_type *T; | ||
1458 | gsl_multifit_fdfsolver *s; | ||
1459 | gsl_multifit_function_fdf my_f; | ||
1460 | // extract function from pars | ||
1461 | my_f.f = f_aux; | ||
1462 | my_f.df = jf_aux; | ||
1463 | my_f.fdf = fjf_aux; | ||
1464 | my_f.n = p; | ||
1465 | my_f.p = xin; // !!!! | ||
1466 | Tfjf stfjf; | ||
1467 | stfjf.f = f; | ||
1468 | stfjf.jf = jac; | ||
1469 | my_f.params = &stfjf; | ||
1470 | size_t iter = 0; | ||
1471 | int status; | ||
1472 | |||
1473 | KDVVIEW(xi); | ||
1474 | //DMVIEW(cov); | ||
1475 | |||
1476 | switch(method) { | ||
1477 | case 0 : { T = gsl_multifit_fdfsolver_lmsder; break; } | ||
1478 | case 1 : { T = gsl_multifit_fdfsolver_lmder; break; } | ||
1479 | default: ERROR(BAD_CODE); | ||
1480 | } | ||
1481 | |||
1482 | s = gsl_multifit_fdfsolver_alloc (T, my_f.n, my_f.p); | ||
1483 | gsl_multifit_fdfsolver_set (s, &my_f, V(xi)); | ||
1484 | |||
1485 | do { status = gsl_multifit_fdfsolver_iterate (s); | ||
1486 | |||
1487 | solp[iter*solc+0] = iter+1; | ||
1488 | solp[iter*solc+1] = gsl_blas_dnrm2 (s->f); | ||
1489 | |||
1490 | int k; | ||
1491 | for(k=0;k<xin;k++) { | ||
1492 | solp[iter*solc+k+2] = gsl_vector_get(s->x,k); | ||
1493 | } | ||
1494 | |||
1495 | iter++; | ||
1496 | if (status) /* check if solver is stuck */ | ||
1497 | break; | ||
1498 | |||
1499 | status = gsl_multifit_test_delta (s->dx, s->x, epsabs, epsrel); | ||
1500 | } | ||
1501 | while (status == GSL_CONTINUE && iter < maxit); | ||
1502 | |||
1503 | int i,j; | ||
1504 | for (i=iter; i<solr; i++) { | ||
1505 | solp[i*solc+0] = iter; | ||
1506 | for(j=1;j<solc;j++) { | ||
1507 | solp[i*solc+j]=0.; | ||
1508 | } | ||
1509 | } | ||
1510 | |||
1511 | //gsl_multifit_covar (s->J, 0.0, M(cov)); | ||
1512 | |||
1513 | gsl_multifit_fdfsolver_free (s); | ||
1514 | OK | ||
1515 | } | ||
1516 | |||
1517 | |||
1518 | ////////////////////////////////////////////////////// | ||
1519 | |||
1520 | |||
1521 | #define RAN(C,F) case C: { for(k=0;k<rn;k++) { rp[k]= F(gen); }; OK } | ||
1522 | |||
1523 | int random_vector(int seed, int code, RVEC(r)) { | ||
1524 | DEBUGMSG("random_vector") | ||
1525 | static gsl_rng * gen = NULL; | ||
1526 | if (!gen) { gen = gsl_rng_alloc (gsl_rng_mt19937);} | ||
1527 | gsl_rng_set (gen, seed); | ||
1528 | int k; | ||
1529 | switch (code) { | ||
1530 | RAN(0,gsl_rng_uniform) | ||
1531 | RAN(1,gsl_ran_ugaussian) | ||
1532 | default: ERROR(BAD_CODE); | ||
1533 | } | ||
1534 | } | ||
1535 | #undef RAN | ||
1536 | |||
1537 | ////////////////////////////////////////////////////// | ||
1538 | |||
1539 | #include "gsl-ode.c" | ||
1540 | |||
1541 | ////////////////////////////////////////////////////// | ||
diff --git a/lib/Numeric/GSL/gsl-ode.c b/lib/Numeric/GSL/gsl-ode.c deleted file mode 100644 index 3f2771b..0000000 --- a/lib/Numeric/GSL/gsl-ode.c +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | |||
2 | #ifdef GSLODE1 | ||
3 | |||
4 | ////////////////////////////// ODE V1 ////////////////////////////////////////// | ||
5 | |||
6 | #include <gsl/gsl_odeiv.h> | ||
7 | |||
8 | typedef struct {int n; int (*f)(double,int, const double*, int, double *); int (*j)(double,int, const double*, int, int, double*);} Tode; | ||
9 | |||
10 | int odefunc (double t, const double y[], double f[], void *params) { | ||
11 | Tode * P = (Tode*) params; | ||
12 | (P->f)(t,P->n,y,P->n,f); | ||
13 | return GSL_SUCCESS; | ||
14 | } | ||
15 | |||
16 | int odejac (double t, const double y[], double *dfdy, double dfdt[], void *params) { | ||
17 | Tode * P = ((Tode*) params); | ||
18 | (P->j)(t,P->n,y,P->n,P->n,dfdy); | ||
19 | int j; | ||
20 | for (j=0; j< P->n; j++) | ||
21 | dfdt[j] = 0.0; | ||
22 | return GSL_SUCCESS; | ||
23 | } | ||
24 | |||
25 | |||
26 | int ode(int method, double h, double eps_abs, double eps_rel, | ||
27 | int f(double, int, const double*, int, double*), | ||
28 | int jac(double, int, const double*, int, int, double*), | ||
29 | KRVEC(xi), KRVEC(ts), RMAT(sol)) { | ||
30 | |||
31 | const gsl_odeiv_step_type * T; | ||
32 | |||
33 | switch(method) { | ||
34 | case 0 : {T = gsl_odeiv_step_rk2; break; } | ||
35 | case 1 : {T = gsl_odeiv_step_rk4; break; } | ||
36 | case 2 : {T = gsl_odeiv_step_rkf45; break; } | ||
37 | case 3 : {T = gsl_odeiv_step_rkck; break; } | ||
38 | case 4 : {T = gsl_odeiv_step_rk8pd; break; } | ||
39 | case 5 : {T = gsl_odeiv_step_rk2imp; break; } | ||
40 | case 6 : {T = gsl_odeiv_step_rk4imp; break; } | ||
41 | case 7 : {T = gsl_odeiv_step_bsimp; break; } | ||
42 | case 8 : { printf("Sorry: ODE rk1imp not available in this GSL version\n"); exit(0); } | ||
43 | case 9 : { printf("Sorry: ODE msadams not available in this GSL version\n"); exit(0); } | ||
44 | case 10: { printf("Sorry: ODE msbdf not available in this GSL version\n"); exit(0); } | ||
45 | default: ERROR(BAD_CODE); | ||
46 | } | ||
47 | |||
48 | gsl_odeiv_step * s = gsl_odeiv_step_alloc (T, xin); | ||
49 | gsl_odeiv_control * c = gsl_odeiv_control_y_new (eps_abs, eps_rel); | ||
50 | gsl_odeiv_evolve * e = gsl_odeiv_evolve_alloc (xin); | ||
51 | |||
52 | Tode P; | ||
53 | P.f = f; | ||
54 | P.j = jac; | ||
55 | P.n = xin; | ||
56 | |||
57 | gsl_odeiv_system sys = {odefunc, odejac, xin, &P}; | ||
58 | |||
59 | double t = tsp[0]; | ||
60 | |||
61 | double* y = (double*)calloc(xin,sizeof(double)); | ||
62 | int i,j; | ||
63 | for(i=0; i< xin; i++) { | ||
64 | y[i] = xip[i]; | ||
65 | solp[i] = xip[i]; | ||
66 | } | ||
67 | |||
68 | for (i = 1; i < tsn ; i++) | ||
69 | { | ||
70 | double ti = tsp[i]; | ||
71 | while (t < ti) | ||
72 | { | ||
73 | gsl_odeiv_evolve_apply (e, c, s, | ||
74 | &sys, | ||
75 | &t, ti, &h, | ||
76 | y); | ||
77 | // if (h < hmin) h = hmin; | ||
78 | } | ||
79 | for(j=0; j<xin; j++) { | ||
80 | solp[i*xin + j] = y[j]; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | free(y); | ||
85 | gsl_odeiv_evolve_free (e); | ||
86 | gsl_odeiv_control_free (c); | ||
87 | gsl_odeiv_step_free (s); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | #else | ||
92 | |||
93 | ///////////////////// ODE V2 /////////////////////////////////////////////////// | ||
94 | |||
95 | #include <gsl/gsl_odeiv2.h> | ||
96 | |||
97 | typedef struct {int n; int (*f)(double,int, const double*, int, double *); int (*j)(double,int, const double*, int, int, double*);} Tode; | ||
98 | |||
99 | int odefunc (double t, const double y[], double f[], void *params) { | ||
100 | Tode * P = (Tode*) params; | ||
101 | (P->f)(t,P->n,y,P->n,f); | ||
102 | return GSL_SUCCESS; | ||
103 | } | ||
104 | |||
105 | int odejac (double t, const double y[], double *dfdy, double dfdt[], void *params) { | ||
106 | Tode * P = ((Tode*) params); | ||
107 | (P->j)(t,P->n,y,P->n,P->n,dfdy); | ||
108 | int j; | ||
109 | for (j=0; j< P->n; j++) | ||
110 | dfdt[j] = 0.0; | ||
111 | return GSL_SUCCESS; | ||
112 | } | ||
113 | |||
114 | |||
115 | int ode(int method, double h, double eps_abs, double eps_rel, | ||
116 | int f(double, int, const double*, int, double*), | ||
117 | int jac(double, int, const double*, int, int, double*), | ||
118 | KRVEC(xi), KRVEC(ts), RMAT(sol)) { | ||
119 | |||
120 | const gsl_odeiv2_step_type * T; | ||
121 | |||
122 | switch(method) { | ||
123 | case 0 : {T = gsl_odeiv2_step_rk2; break; } | ||
124 | case 1 : {T = gsl_odeiv2_step_rk4; break; } | ||
125 | case 2 : {T = gsl_odeiv2_step_rkf45; break; } | ||
126 | case 3 : {T = gsl_odeiv2_step_rkck; break; } | ||
127 | case 4 : {T = gsl_odeiv2_step_rk8pd; break; } | ||
128 | case 5 : {T = gsl_odeiv2_step_rk2imp; break; } | ||
129 | case 6 : {T = gsl_odeiv2_step_rk4imp; break; } | ||
130 | case 7 : {T = gsl_odeiv2_step_bsimp; break; } | ||
131 | case 8 : {T = gsl_odeiv2_step_rk1imp; break; } | ||
132 | case 9 : {T = gsl_odeiv2_step_msadams; break; } | ||
133 | case 10: {T = gsl_odeiv2_step_msbdf; break; } | ||
134 | default: ERROR(BAD_CODE); | ||
135 | } | ||
136 | |||
137 | Tode P; | ||
138 | P.f = f; | ||
139 | P.j = jac; | ||
140 | P.n = xin; | ||
141 | |||
142 | gsl_odeiv2_system sys = {odefunc, odejac, xin, &P}; | ||
143 | |||
144 | gsl_odeiv2_driver * d = | ||
145 | gsl_odeiv2_driver_alloc_y_new (&sys, T, h, eps_abs, eps_rel); | ||
146 | |||
147 | double t = tsp[0]; | ||
148 | |||
149 | double* y = (double*)calloc(xin,sizeof(double)); | ||
150 | int i,j; | ||
151 | int status=0; | ||
152 | for(i=0; i< xin; i++) { | ||
153 | y[i] = xip[i]; | ||
154 | solp[i] = xip[i]; | ||
155 | } | ||
156 | |||
157 | for (i = 1; i < tsn ; i++) | ||
158 | { | ||
159 | double ti = tsp[i]; | ||
160 | |||
161 | status = gsl_odeiv2_driver_apply (d, &t, ti, y); | ||
162 | |||
163 | if (status != GSL_SUCCESS) { | ||
164 | printf ("error in ode, return value=%d\n", status); | ||
165 | break; | ||
166 | } | ||
167 | |||
168 | // printf ("%.5e %.5e %.5e\n", t, y[0], y[1]); | ||
169 | |||
170 | for(j=0; j<xin; j++) { | ||
171 | solp[i*xin + j] = y[j]; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | free(y); | ||
176 | gsl_odeiv2_driver_free (d); | ||
177 | |||
178 | return status; | ||
179 | } | ||
180 | |||
181 | #endif | ||
182 | |||