summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/minimize.hs18
-rw-r--r--lib/Numeric/GSL/Minimization.hs34
-rw-r--r--lib/Numeric/GSL/gsl-aux.c8
-rw-r--r--lib/Numeric/GSL/gsl-aux.h2
-rw-r--r--lib/Numeric/LinearAlgebra/Tests.hs15
5 files changed, 61 insertions, 16 deletions
diff --git a/examples/minimize.hs b/examples/minimize.hs
index 5beba3b..8962006 100644
--- a/examples/minimize.hs
+++ b/examples/minimize.hs
@@ -13,6 +13,9 @@ df [x,y] = [20*(x-1), 40*(y-2)]
13-- the conjugate gradient method 13-- the conjugate gradient method
14minimizeCG = minimizeConjugateGradient 1E-2 1E-4 1E-3 30 14minimizeCG = minimizeConjugateGradient 1E-2 1E-4 1E-3 30
15 15
16-- the BFGS2 method
17minimizeBFGS2 = minimizeVectorBFGS2 1E-2 1E-2 1E-3 30
18
16-- a minimization algorithm which does not require the gradient 19-- a minimization algorithm which does not require the gradient
17minimizeS f xi = minimizeNMSimplex f xi (replicate (length xi) 1) 1E-2 100 20minimizeS f xi = minimizeNMSimplex f xi (replicate (length xi) 1) 1E-2 100
18 21
@@ -24,20 +27,27 @@ partialDerivative n f v = fst (derivCentral 0.01 g (v!!n)) where
24 (a,_:b) = splitAt n v 27 (a,_:b) = splitAt n v
25 28
26main = do 29main = do
27 -- conjugate gradient with true gradient 30 putStrLn "BFGS2 with true gradient"
28 let (s,p) = minimizeCG f df [5,7] 31 let (s,p) = minimizeBFGS2 f df [5,7]
29 print s -- solution 32 print s -- solution
30 disp p -- evolution of the algorithm 33 disp p -- evolution of the algorithm
31 let [x,y] = drop 2 (toColumns p) 34 let [x,y] = drop 2 (toColumns p)
32 mplot [x,y] -- path from the starting point to the solution 35 mplot [x,y] -- path from the starting point to the solution
33 36
34 -- conjugate gradient with estimated gradient 37 putStrLn "conjugate gradient with true gradient"
38 let (s,p) = minimizeCG f df [5,7]
39 print s
40 disp p
41 let [x,y] = drop 2 (toColumns p)
42 mplot [x,y]
43
44 putStrLn "conjugate gradient with estimated gradient"
35 let (s,p) = minimizeCG f (gradient f) [5,7] 45 let (s,p) = minimizeCG f (gradient f) [5,7]
36 print s 46 print s
37 disp p 47 disp p
38 mplot $ drop 2 (toColumns p) 48 mplot $ drop 2 (toColumns p)
39 49
40 -- without gradient, using the NM Simplex method 50 putStrLn "without gradient, using the NM Simplex method"
41 let (s,p) = minimizeS f [5,7] 51 let (s,p) = minimizeS f [5,7]
42 print s 52 print s
43 disp p 53 disp p
diff --git a/lib/Numeric/GSL/Minimization.hs b/lib/Numeric/GSL/Minimization.hs
index a1d009b..b95765f 100644
--- a/lib/Numeric/GSL/Minimization.hs
+++ b/lib/Numeric/GSL/Minimization.hs
@@ -2,14 +2,14 @@
2----------------------------------------------------------------------------- 2-----------------------------------------------------------------------------
3{- | 3{- |
4Module : Numeric.GSL.Minimization 4Module : Numeric.GSL.Minimization
5Copyright : (c) Alberto Ruiz 2006 5Copyright : (c) Alberto Ruiz 2006-9
6License : GPL-style 6License : GPL-style
7 7
8Maintainer : Alberto Ruiz (aruiz at um dot es) 8Maintainer : Alberto Ruiz (aruiz at um dot es)
9Stability : provisional 9Stability : provisional
10Portability : uses ffi 10Portability : uses ffi
11 11
12Minimization of a multidimensional function Minimization of a multidimensional function using some of the algorithms described in: 12Minimization of a multidimensional function using some of the algorithms described in:
13 13
14<http://www.gnu.org/software/gsl/manual/html_node/Multidimensional-Minimization.html> 14<http://www.gnu.org/software/gsl/manual/html_node/Multidimensional-Minimization.html>
15 15
@@ -17,6 +17,7 @@ Minimization of a multidimensional function Minimization of a multidimensional f
17----------------------------------------------------------------------------- 17-----------------------------------------------------------------------------
18module Numeric.GSL.Minimization ( 18module Numeric.GSL.Minimization (
19 minimizeConjugateGradient, 19 minimizeConjugateGradient,
20 minimizeVectorBFGS2,
20 minimizeNMSimplex 21 minimizeNMSimplex
21) where 22) where
22 23
@@ -132,7 +133,7 @@ The path to the solution can be graphically shown by means of:
132 133
133@'Graphics.Plot.mplot' $ drop 2 ('toColumns' p)@ 134@'Graphics.Plot.mplot' $ drop 2 ('toColumns' p)@
134 135
135-} 136-}
136minimizeConjugateGradient :: 137minimizeConjugateGradient ::
137 Double -- ^ initial step size 138 Double -- ^ initial step size
138 -> Double -- ^ minimization parameter 139 -> Double -- ^ minimization parameter
@@ -142,7 +143,27 @@ minimizeConjugateGradient ::
142 -> ([Double] -> [Double]) -- ^ gradient 143 -> ([Double] -> [Double]) -- ^ gradient
143 -> [Double] -- ^ starting point 144 -> [Double] -- ^ starting point
144 -> ([Double], Matrix Double) -- ^ solution vector, and the optimization trajectory followed by the algorithm 145 -> ([Double], Matrix Double) -- ^ solution vector, and the optimization trajectory followed by the algorithm
145minimizeConjugateGradient istep minimpar tol maxit f df xi = unsafePerformIO $ do 146minimizeConjugateGradient = minimizeWithDeriv 0
147
148{- | Taken from the GSL manual:
149
150The vector Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm. This 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.
151
152The 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).
153-}
154minimizeVectorBFGS2 ::
155 Double -- ^ initial step size
156 -> Double -- ^ minimization parameter tol
157 -> Double -- ^ desired precision of the solution (gradient test)
158 -> Int -- ^ maximum number of iterations allowed
159 -> ([Double] -> Double) -- ^ function to minimize
160 -> ([Double] -> [Double]) -- ^ gradient
161 -> [Double] -- ^ starting point
162 -> ([Double], Matrix Double) -- ^ solution vector, and the optimization trajectory followed by the algorithm
163minimizeVectorBFGS2 = minimizeWithDeriv 1
164
165
166minimizeWithDeriv method istep minimpar tol maxit f df xi = unsafePerformIO $ do
146 let xiv = fromList xi 167 let xiv = fromList xi
147 n = dim xiv 168 n = dim xiv
148 f' = f . toList 169 f' = f . toList
@@ -151,7 +172,7 @@ minimizeConjugateGradient istep minimpar tol maxit f df xi = unsafePerformIO $ d
151 dfp <- mkVecVecfun (aux_vTov df') 172 dfp <- mkVecVecfun (aux_vTov df')
152 rawpath <- withVector xiv $ \xiv' -> 173 rawpath <- withVector xiv $ \xiv' ->
153 createMIO maxit (n+2) 174 createMIO maxit (n+2)
154 (c_minimizeConjugateGradient fp dfp istep minimpar tol (fi maxit) // xiv') 175 (c_minimizeWithDeriv method fp dfp istep minimpar tol (fi maxit) // xiv')
155 "minimizeDerivV" 176 "minimizeDerivV"
156 let it = round (rawpath @@> (maxit-1,0)) 177 let it = round (rawpath @@> (maxit-1,0))
157 path = takeRows it rawpath 178 path = takeRows it rawpath
@@ -160,9 +181,8 @@ minimizeConjugateGradient istep minimpar tol maxit f df xi = unsafePerformIO $ d
160 freeHaskellFunPtr dfp 181 freeHaskellFunPtr dfp
161 return (sol,path) 182 return (sol,path)
162 183
163
164foreign import ccall "gsl-aux.h minimizeWithDeriv" 184foreign import ccall "gsl-aux.h minimizeWithDeriv"
165 c_minimizeConjugateGradient :: FunPtr (CInt -> Ptr Double -> Double) 185 c_minimizeWithDeriv :: CInt -> FunPtr (CInt -> Ptr Double -> Double)
166 -> FunPtr (CInt -> Ptr Double -> Ptr Double -> IO ()) 186 -> FunPtr (CInt -> Ptr Double -> Ptr Double -> IO ())
167 -> Double -> Double -> Double -> CInt 187 -> Double -> Double -> Double -> CInt
168 -> TVM 188 -> TVM
diff --git a/lib/Numeric/GSL/gsl-aux.c b/lib/Numeric/GSL/gsl-aux.c
index 77e793e..3802574 100644
--- a/lib/Numeric/GSL/gsl-aux.c
+++ b/lib/Numeric/GSL/gsl-aux.c
@@ -441,7 +441,7 @@ void fdf_aux_min(const gsl_vector * x, void * pars, double * f, gsl_vector * g)
441} 441}
442 442
443// conjugate gradient 443// conjugate gradient
444int minimizeWithDeriv(double f(int, double*), void df(int, double*, double*), 444int minimizeWithDeriv(int method, double f(int, double*), void df(int, double*, double*),
445 double initstep, double minimpar, double tolgrad, int maxit, 445 double initstep, double minimpar, double tolgrad, int maxit,
446 KRVEC(xi), RMAT(sol)) { 446 KRVEC(xi), RMAT(sol)) {
447 REQUIRES(solr == maxit && solc == 2+xin,BAD_SIZE); 447 REQUIRES(solr == maxit && solc == 2+xin,BAD_SIZE);
@@ -463,7 +463,11 @@ int minimizeWithDeriv(double f(int, double*), void df(int, double*, double*),
463 // Starting point 463 // Starting point
464 KDVVIEW(xi); 464 KDVVIEW(xi);
465 // conjugate gradient fr 465 // conjugate gradient fr
466 T = gsl_multimin_fdfminimizer_conjugate_fr; 466 switch(method) {
467 case 0 : {T = gsl_multimin_fdfminimizer_conjugate_fr; break; }
468 case 1 : {T = gsl_multimin_fdfminimizer_vector_bfgs2; break; }
469 default: ERROR(BAD_CODE);
470 }
467 s = gsl_multimin_fdfminimizer_alloc (T, my_func.n); 471 s = gsl_multimin_fdfminimizer_alloc (T, my_func.n);
468 gsl_multimin_fdfminimizer_set (s, &my_func, V(xi), initstep, minimpar); 472 gsl_multimin_fdfminimizer_set (s, &my_func, V(xi), initstep, minimpar);
469 do { 473 do {
diff --git a/lib/Numeric/GSL/gsl-aux.h b/lib/Numeric/GSL/gsl-aux.h
index cd17ef0..e88322c 100644
--- a/lib/Numeric/GSL/gsl-aux.h
+++ b/lib/Numeric/GSL/gsl-aux.h
@@ -39,7 +39,7 @@ int polySolve(KRVEC(a), CVEC(z));
39int minimize(double f(int, double*), double tolsize, int maxit, 39int minimize(double f(int, double*), double tolsize, int maxit,
40 KRVEC(xi), KRVEC(sz), RMAT(sol)); 40 KRVEC(xi), KRVEC(sz), RMAT(sol));
41 41
42int minimizeWithDeriv(double f(int, double*), void df(int, double*, double*), 42int minimizeWithDeriv(int method, double f(int, double*), void df(int, double*, double*),
43 double initstep, double minimpar, double tolgrad, int maxit, 43 double initstep, double minimpar, double tolgrad, int maxit,
44 KRVEC(xi), RMAT(sol)); 44 KRVEC(xi), RMAT(sol));
45 45
diff --git a/lib/Numeric/LinearAlgebra/Tests.hs b/lib/Numeric/LinearAlgebra/Tests.hs
index 7758268..278df78 100644
--- a/lib/Numeric/LinearAlgebra/Tests.hs
+++ b/lib/Numeric/LinearAlgebra/Tests.hs
@@ -1,9 +1,9 @@
1{-# LANGUAGE CPP #-} 1{-# LANGUAGE CPP #-}
2{-# OPTIONS_GHC -fno-warn-unused-imports #-} 2{-# OPTIONS_GHC -fno-warn-unused-imports -fno-warn-incomplete-patterns #-}
3----------------------------------------------------------------------------- 3-----------------------------------------------------------------------------
4{- | 4{- |
5Module : Numeric.LinearAlgebra.Tests 5Module : Numeric.LinearAlgebra.Tests
6Copyright : (c) Alberto Ruiz 2007 6Copyright : (c) Alberto Ruiz 2007-9
7License : GPL-style 7License : GPL-style
8 8
9Maintainer : Alberto Ruiz (aruiz at um dot es) 9Maintainer : Alberto Ruiz (aruiz at um dot es)
@@ -105,6 +105,16 @@ expmTest2 = expm nd2 :~15~: (2><2)
105 , 2.718281828459045 105 , 2.718281828459045
106 , 2.718281828459045 ] 106 , 2.718281828459045 ]
107 107
108---------------------------------------------------------------------
109
110minimizationTest = TestList [ utest "minimization conj grad" (minim1 f df [5,7] ~~ [1,2])
111 , utest "minimization bg2" (minim2 f df [5,7] ~~ [1,2])
112 ]
113 where f [x,y] = 10*(x-1)^2 + 20*(y-2)^2 + 30
114 df [x,y] = [20*(x-1), 40*(y-2)]
115 a ~~ b = fromList a |~| fromList b
116 minim1 g dg ini = fst $ minimizeConjugateGradient 1E-2 1E-4 1E-3 30 g dg ini
117 minim2 g dg ini = fst $ minimizeVectorBFGS2 1E-2 1E-2 1E-3 30 g dg ini
108 118
109--------------------------------------------------------------------- 119---------------------------------------------------------------------
110 120
@@ -206,6 +216,7 @@ runTests n = do
206 , exponentialTest 216 , exponentialTest
207 , utest "integrate" (abs (volSphere 2.5 - 4/3*pi*2.5^3) < 1E-8) 217 , utest "integrate" (abs (volSphere 2.5 - 4/3*pi*2.5^3) < 1E-8)
208 , utest "polySolve" (polySolveProp [1,2,3,4]) 218 , utest "polySolve" (polySolveProp [1,2,3,4])
219 , minimizationTest
209 ] 220 ]
210 return () 221 return ()
211 222