{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# LANGUAGE FlexibleContexts #-}
module Numeric.GSL.Minimization (
minimize, minimizeV, MinimizeMethod(..),
minimizeD, minimizeVD, MinimizeMethodD(..),
uniMinimize, UniMinimizeMethod(..),
minimizeNMSimplex,
minimizeConjugateGradient,
minimizeVectorBFGS2
) where
import Numeric.LinearAlgebra.HMatrix hiding(step)
import Numeric.GSL.Internal
import Foreign.Ptr(Ptr, FunPtr, freeHaskellFunPtr)
import Foreign.C.Types
import System.IO.Unsafe(unsafePerformIO)
{-# DEPRECATED minimizeNMSimplex "use minimize NMSimplex2 eps maxit sizes f xi" #-}
minimizeNMSimplex f xi szs eps maxit = minimize NMSimplex eps maxit szs f xi
{-# DEPRECATED minimizeConjugateGradient "use minimizeD ConjugateFR eps maxit step tol f g xi" #-}
minimizeConjugateGradient step tol eps maxit f g xi = minimizeD ConjugateFR eps maxit step tol f g xi
{-# DEPRECATED minimizeVectorBFGS2 "use minimizeD VectorBFGS2 eps maxit step tol f g xi" #-}
minimizeVectorBFGS2 step tol eps maxit f g xi = minimizeD VectorBFGS2 eps maxit step tol f g xi
data UniMinimizeMethod = GoldenSection
| BrentMini
| QuadGolden
deriving (Enum, Eq, Show, Bounded)
uniMinimize :: UniMinimizeMethod
-> Double
-> Int
-> (Double -> Double)
-> Double
-> Double
-> Double
-> (Double, Matrix Double)
uniMinimize method epsrel maxit fun xmin xl xu = uniMinimizeGen (fi (fromEnum method)) fun xmin xl xu epsrel maxit
uniMinimizeGen m f xmin xl xu epsrel maxit = unsafePerformIO $ do
fp <- mkDoublefun f
rawpath <- createMIO maxit 4
(c_uniMinize m fp epsrel (fi maxit) xmin xl xu)
"uniMinimize"
let it = round (rawpath `atIndex` (maxit-1,0))
path = takeRows it rawpath
[sol] = toLists $ dropRows (it-1) path
freeHaskellFunPtr fp
return (sol !! 1, path)
foreign import ccall safe "uniMinimize"
c_uniMinize:: CInt -> FunPtr (Double -> Double) -> Double -> CInt -> Double -> Double -> Double -> TM Res
data MinimizeMethod = NMSimplex
| NMSimplex2
deriving (Enum,Eq,Show,Bounded)
minimize :: MinimizeMethod
-> Double
-> Int
-> [Double]
-> ([Double] -> Double)
-> [Double]
-> ([Double], Matrix Double)
minimizeV :: MinimizeMethod
-> Double
-> Int
-> Vector Double
-> (Vector Double -> Double)
-> Vector Double
-> (Vector Double, Matrix Double)
minimize method eps maxit sz f xi = v2l $ minimizeV method eps maxit (fromList sz) (f.toList) (fromList xi)
where v2l (v,m) = (toList v, m)
minimizeV method eps maxit szv f xiv = unsafePerformIO $ do
let n = size xiv
fp <- mkVecfun (iv f)
rawpath <- ww2 vec xiv vec szv $ \xiv' szv' ->
createMIO maxit (n+3)
(c_minimize (fi (fromEnum method)) fp eps (fi maxit) // xiv' // szv')
"minimize"
let it = round (rawpath `atIndex` (maxit-1,0))
path = takeRows it rawpath
sol = flatten $ dropColumns 3 $ dropRows (it-1) path
freeHaskellFunPtr fp
return (sol, path)
foreign import ccall safe "gsl-aux.h minimize"
c_minimize:: CInt -> FunPtr (CInt -> Ptr Double -> Double) -> Double -> CInt -> TV(TV(TM Res))
data MinimizeMethodD = ConjugateFR
| ConjugatePR
| VectorBFGS
| VectorBFGS2
| SteepestDescent
deriving (Enum,Eq,Show,Bounded)
minimizeD :: MinimizeMethodD
-> Double
-> Int
-> Double
-> Double
-> ([Double] -> Double)
-> ([Double] -> [Double])
-> [Double]
-> ([Double], Matrix Double)
minimizeVD :: MinimizeMethodD
-> Double
-> Int
-> Double
-> Double
-> (Vector Double -> Double)
-> (Vector Double -> Vector Double)
-> Vector Double
-> (Vector Double, Matrix Double)
minimizeD method eps maxit istep tol f df xi = v2l $ minimizeVD
method eps maxit istep tol (f.toList) (fromList.df.toList) (fromList xi)
where v2l (v,m) = (toList v, m)
minimizeVD method eps maxit istep tol f df xiv = unsafePerformIO $ do
let n = size xiv
f' = f
df' = (checkdim1 n . df)
fp <- mkVecfun (iv f')
dfp <- mkVecVecfun (aux_vTov df')
rawpath <- vec xiv $ \xiv' ->
createMIO maxit (n+2)
(c_minimizeD (fi (fromEnum method)) fp dfp istep tol eps (fi maxit) // xiv')
"minimizeD"
let it = round (rawpath `atIndex` (maxit-1,0))
path = takeRows it rawpath
sol = flatten $ dropColumns 2 $ dropRows (it-1) path
freeHaskellFunPtr fp
freeHaskellFunPtr dfp
return (sol,path)
foreign import ccall safe "gsl-aux.h minimizeD"
c_minimizeD :: CInt
-> FunPtr (CInt -> Ptr Double -> Double)
-> FunPtr (TV (TV Res))
-> Double -> Double -> Double -> CInt
-> TV (TM Res)
checkdim1 n v
| size v == n = v
| otherwise = error $ "Error: "++ show n
++ " components expected in the result of the gradient supplied to minimizeD"