packages feed

l-bfgs-b 0.1 → 0.1.0.1

raw patch · 6 files changed

+46/−93 lines, 6 files

Files

− examples/Example1.hs
@@ -1,42 +0,0 @@-module Main where--import Numeric.LBFGSB-import Numeric.LBFGSB.Result-import qualified Data.Vector.Storable as V---- Example optimization problem taken from driver1.f in the tarball--- for version 3.0 of L-BFGS-B itself.--n :: Int-n = 25--f :: V.Vector Double -> Double-f x = 4* (V.foldl (\s i -> s + (x V.! i - (x V.! (i-1))^2)^2) (0.25* (x V.! 0 - 1)^2) (V.enumFromN 1 (n-1)))--g :: V.Vector Double -> V.Vector Double-g x = V.generate n (\i -> 8*(t (i-1)) - 1.6e1*(x V.! i)*(t i))-    where-      t i-        | i == -1  = 0.25*(x V.! 0 - 1)-        | i == n-1 = 0-        | otherwise =  x V.! (i+1) - (x V.! i)^2--bounds :: [(Maybe Double, Maybe Double)]-bounds = map (\i -> if odd i then (Just 1e0, Just 1e2) else (Just (-1e2), Just 1e2)) [1..n]--start :: V.Vector Double-start = V.replicate n 3.0--main :: IO ()-main = putStrLn "Testing with function and parameters from driver1.f from L-BFGS-B 3.0 distribution archive." >>-       let-           res = minimize 5 1e7 1e-5 Nothing bounds start f g-       in-         putStrLn "Full results:" >>-         print res >>-         putStrLn "Solution point:" >>-         print (solution res) >>-         putStrLn "Steps needed:" >>-         print (length (backtrace res)) >>-         putStrLn "Function value at solution:" >>-         print (f (solution res))
− examples/Example2.hs
@@ -1,26 +0,0 @@-module Main where--import Numeric.LBFGSB-import Numeric.LBFGSB.Convenience-import Numeric.LBFGSB.Result-import qualified Data.Vector.Storable as V---- 2D Rosenbrock function with approximate derivatives.--rosenbrock :: V.Vector Double -> Double-rosenbrock x = (1 - x0)^2 + 100*(x1-x0^2)^2-    where-      x0 = x V.! 0-      x1 = x V.! 1--main :: IO ()-main = putStrLn "Testing with Rosenbrock function, both unbounded and bounded with minimum outside bounds." >>-       let-           resUnbounded = minimize 5 1e0 1e-12 (Just 100) [] (V.fromList [100, 100]) rosenbrock (approximateGradient 1e-6 rosenbrock)-           resBounded = minimize 5 1e0 1e-12 (Just 100) [(Nothing, Nothing), (Nothing, Just 0.1)] (V.fromList [0, 0]) rosenbrock (approximateGradient 1e-6 rosenbrock)-       in-       putStrLn "Unbounded:" >>-       print resUnbounded >>-       putStrLn "-------------------" >>-       putStrLn "Bounded to (-infty, 0.1) in the second direction only:" >>-       print resBounded
− examples/build.sh
@@ -1,6 +0,0 @@-#!/bin/bash--ghc -threaded -i../src -O2 -fforce-recomp -o example1 --make Example1.hs -llbfgsb -ghc -threaded -i../src -O2 -fforce-recomp -o example2 --make Example2.hs -llbfgsb--
l-bfgs-b.cabal view
@@ -1,12 +1,12 @@ Name:                l-bfgs-b-Version:             0.1+Version:             0.1.0.1 Synopsis:            Bindings to L-BFGS-B, Fortran code for limited-memory quasi-Newton bound-constrained optimization Homepage:            http://nonempty.org/software/haskell-l-bfgs-b License:             BSD3 License-file:        LICENSE Author:              Gard Spreemann Maintainer:          Gard Spreemann <gspreemann@gmail.com>-Copyright:           2013 Gard Spreemann+Copyright:           2013-2014 Gard Spreemann Category:            Math Build-type:          Simple Cabal-version:       >=1.4@@ -26,18 +26,32 @@                      output as specified in the L-BFGS-B code. However, there are two places in said code where the flag is ignored                      and output still occurs. If it bothers you that code exposed as pure prints things, see                       <http://nonempty.org/software/haskell-l-bfgs-b> for information on a simple patch for L-BFGS-B. The SciPy project-                     has described the same behavior at <http://projects.scipy.org/scipy/ticket/1742>.+                     has described the same behavior in <https://github.com/scipy/scipy/issues/2261>.                      .+                     The code assumes that your Haskell compiler's Doubles are IEEE-754 doubles.+                     . 		     Example on usage can be found in the included @examples@ directiory.                      .                      The current version has only been lightly tested, and should not be trusted for serious work. Feedback is appreciated.                      .+                     Changes in version 0.1.0.1:+                     .+                     * Check some function arguments for sanity and cause a runtime error otherwise.+                     .+                     * Add note above on double representation.+                     .+                     * Added TODO below.+                     .                      Changes in version 0.1:                      . 		     * There has only been cursory testing, so do not trust these bindings yet. 		     .                      * Initial release.-		     . +		     .+                     TODO:+                     .+                     * Be more generic with regards to vector types?+                     .  		     . 		     \[1] R. H. Byrd, P. Lu and J. Nocedal. A Limited Memory Algorithm for Bound Constrained Optimization, (1995), SIAM Journal on Scientific and Statistical Computing , 16, 5, pp. 1190-1208. 
src/Numeric/LBFGSB.hs view
@@ -28,9 +28,9 @@   -- | Minimization using L-BFGS-B. If you only require the solution--- point, and not the full 'R.Result', see 'minimize''. If the--- arguments do not satisfy the given requirements, behavior is--- undefined and the program may even crash.+-- point, and not the full 'R.Result', see 'minimize''. Take care to+-- satisfy the requirements on the arguments. Failure to do so may result+-- in a runtime error, or, when noted, undefined behavior/crash. minimize :: Int                                  -- ^ @m@: The maximum number of variable metric corrections used                                                  -- to define the limited memory matrix. /Suggestion:/ @5@.          -> Double                               -- ^ @factr@: Iteration stops when the relative change in function value@@ -49,12 +49,20 @@                                                  -- as constraint.          -> V.Vector Double                      -- ^ @x0@: Starting point. The point /must/ be within the bounds.          -> (V.Vector Double -> Double)          -- ^ @f@: Function to minimize. /Must/ take 'V.Vector's of precisely the same-                                                 -- length as @x0@.+                                                 -- length as @x0@, or else behavior is undefined (the program may crash)!          -> (V.Vector Double -> V.Vector Double) -- ^ @g@: Gradient of @f@. /Must/ take and return 'V.Vector's of precisely the same-                                                 -- length as @x0@. "Numeric.LBFGSB.Convenience" provides a simple-                                                 -- approximation of the gradient if you do not have the real one.+                                                 -- length as @x0@, or else behavior is undefined (the program may crash)!+                                                 -- "Numeric.LBFGSB.Convenience" provides a simple approximation of the gradient if+                                                 -- you do not have the real one.          -> R.Result-minimize m factr tol steps bounds x0 f g = unsafeDupablePerformIO (runDriver m factr tol steps bounds x0 f g)+minimize m factr pgtol steps bounds x0 f g +    | not (factr >= 0) = error "factr must be >=0."+    | not (pgtol >= 0) = error "pgtol must be >=0."+    | not (maybe True (>0) steps) = error "steps must be >0."+    | not (inBounds bounds' x0) = error "x0 must be within bounds."+    | otherwise = unsafeDupablePerformIO (runDriver m factr pgtol steps bounds' x0 f g)+    where+      bounds' = take (V.length x0) (bounds ++ repeat (Nothing, Nothing))  -- | If L-BFGS-B converges within the specified number of steps, the -- solution point is returned as @'Just' solution@. Otherwise@@ -69,12 +77,20 @@           -> (V.Vector Double -> Double)            -> (V.Vector Double -> V.Vector Double)            -> Maybe (V.Vector Double)-minimize' m factr tol steps bounds x0 f g +minimize' m factr pgtol steps bounds x0 f g      | R.stopReason result == R.Converged = Just $ R.solution result     | otherwise                          = Nothing     where-      result = minimize m factr tol steps bounds x0 f g+      result = minimize m factr pgtol steps bounds x0 f g +inBounds :: [(Maybe Double, Maybe Double)] -> V.Vector Double -> Bool+inBounds bounds v = all ib (zip bounds (V.toList v))+    where+      ib ((Nothing, Nothing), _) = True+      ib ((Nothing, Just u),  x) = x <= u+      ib ((Just l , Nothing), x) = x >= l+      ib ((Just l , Just u),  x) = x >= l && x <= u+ data DriverContext = DriverContext { pn :: Ptr CInt                                    , pm :: Ptr CInt                                    , px :: Ptr Double@@ -134,7 +150,7 @@ runDriver m factr tol steps bounds x0 f g      = let          n = V.length x0-         (ls, us, bds) = unzipBounds (take n (bounds ++ repeat (Nothing, Nothing)))+         (ls, us, bds) = unzipBounds bounds       in          with (fromIntegral n) $ \pn ->       with (fromIntegral m) $ \pm ->@@ -201,9 +217,7 @@  makeCall :: DriverContext -> IO () makeCall context@(DriverContext pn pm px pl pu pnbd pf pg pfactr ppgtol pwa piwa ptask piprint pcsave plsave pisave pdsave)-    = fortran_setulb pn pm px pl pu pnbd pf pg pfactr ppgtol pwa piwa ptask piprint pcsave plsave pisave pdsave --(fromIntegral taskLength) (fromIntegral csaveLength)--+    = fortran_setulb pn pm px pl pu pnbd pf pg pfactr ppgtol pwa piwa ptask piprint pcsave plsave pisave pdsave   foreign import ccall "setulb_"         fortran_setulb     -- #   Comments below are from the L-BFGS-B Fortran source code:@@ -325,6 +339,5 @@                            --                                 the starting point of the line search;                            --         dsave(16) = the square of the 2-norm of the line search                            --                                                      direction vector.---            -> CInt -> CInt -- FORTRAN string lengths piled at the end. Fixme, is this right?             -> IO () 
src/Numeric/LBFGSB/Result.hs view
@@ -9,7 +9,7 @@       solution :: V.Vector Double    -- ^ Solution point /if the minimization completed successfully/. See 'stopReason'.     , backtrace :: [V.Vector Double] -- ^ The steps taken to reach the solution, in reverse order. Does not include the starting point.     , stopReason :: StopReason       -- ^ The reason L-BFGS-B terminated. Only if this is-                                     -- 'Converted' should you consider the solution correct!+                                     -- 'Converged' should you consider the solution correct!     }               deriving (Show)