    {-# OPTIONS_GHC -fno-warn-missing-signatures #-}

    {-# LANGUAGE FlexibleContexts #-}

    {- |
    Module      :  Numeric.GSL.Minimization
    Copyright   :  (c) Alberto Ruiz 2006-9
    License     :  GPL
    Maintainer  :  Alberto Ruiz
    Stability   :  provisional

    Minimization of a multidimensional function using some of the algorithms described in:

    <http://www.gnu.org/software/gsl/manual/html_node/Multidimensional-Minimization.html>

    The example in the GSL manual:

    @
    f [x,y] = 10*(x-1)^2 + 20*(y-2)^2 + 30

    main = do
        let (s,p) = minimize NMSimplex2 1E-2 30 [1,1] f [5,7]
        print s
        print p
    @

    >>> main
    [0.9920430849306288,1.9969168063253182]
     0.000  512.500  1.130  6.500  5.000
     1.000  290.625  1.409  5.250  4.000
     2.000  290.625  1.409  5.250  4.000
     3.000  252.500  1.409  5.500  1.000
     ...
    22.000   30.001  0.013  0.992  1.997
    23.000   30.001  0.008  0.992  1.997

    The path to the solution can be graphically shown by means of:

    @'Graphics.Plot.mplot' $ drop 3 ('toColumns' p)@

    Taken from the GSL manual:

    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.

    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).

    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.

    -}

    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 :: ([Double] -> Double)
    -> [Double]
    -> [Double]
    -> Double
    -> Int
    -> ([Double], Matrix Double)
    minimizeNMSimplex [Double] -> Double
    f [Double]
    xi [Double]
    szs Double
    eps Int
    maxit = MinimizeMethod
    -> Double
    -> Int
    -> [Double]
    -> ([Double] -> Double)
    -> [Double]
    -> ([Double], Matrix Double)
    minimize MinimizeMethod
    NMSimplex Double
    eps Int
    maxit [Double]
    szs [Double] -> Double
    f [Double]
    xi

    {-# DEPRECATED minimizeConjugateGradient "use minimizeD ConjugateFR eps maxit step tol f g xi" #-}
    minimizeConjugateGradient :: Double
    -> Double
    -> Double
    -> Int
    -> ([Double] -> Double)
    -> ([Double] -> [Double])
    -> [Double]
    -> ([Double], Matrix Double)
    minimizeConjugateGradient Double
    step Double
    tol Double
    eps Int
    maxit [Double] -> Double
    f [Double] -> [Double]
    g [Double]
    xi = MinimizeMethodD
    -> Double
    -> Int
    -> Double
    -> Double
    -> ([Double] -> Double)
    -> ([Double] -> [Double])
    -> [Double]
    -> ([Double], Matrix Double)
    minimizeD MinimizeMethodD
    ConjugateFR Double
    eps Int
    maxit Double
    step Double
    tol [Double] -> Double
    f [Double] -> [Double]
    g [Double]
    xi

    {-# DEPRECATED minimizeVectorBFGS2 "use minimizeD VectorBFGS2 eps maxit step tol f g xi" #-}
    minimizeVectorBFGS2 :: Double
    -> Double
    -> Double
    -> Int
    -> ([Double] -> Double)
    -> ([Double] -> [Double])
    -> [Double]
    -> ([Double], Matrix Double)
    minimizeVectorBFGS2 Double
    step Double
    tol Double
    eps Int
    maxit [Double] -> Double
    f [Double] -> [Double]
    g [Double]
    xi = MinimizeMethodD
    -> Double
    -> Int
    -> Double
    -> Double
    -> ([Double] -> Double)
    -> ([Double] -> [Double])
    -> [Double]
    -> ([Double], Matrix Double)
    minimizeD MinimizeMethodD
    VectorBFGS2 Double
    eps Int
    maxit Double
    step Double
    tol [Double] -> Double
    f [Double] -> [Double]
    g [Double]
    xi

    -------------------------------------------------------------------------

    data UniMinimizeMethod = GoldenSection
                           | BrentMini
                           | QuadGolden
                           deriving (Int -> UniMinimizeMethod
    UniMinimizeMethod -> Int
    UniMinimizeMethod -> [UniMinimizeMethod]
    UniMinimizeMethod -> UniMinimizeMethod
    UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    UniMinimizeMethod
    -> UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    (UniMinimizeMethod -> UniMinimizeMethod)
    -> (UniMinimizeMethod -> UniMinimizeMethod)
    -> (Int -> UniMinimizeMethod)
    -> (UniMinimizeMethod -> Int)
    -> (UniMinimizeMethod -> [UniMinimizeMethod])
    -> (UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod])
    -> (UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod])
    -> (UniMinimizeMethod
        -> UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod])
    -> Enum UniMinimizeMethod
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: UniMinimizeMethod -> UniMinimizeMethod
    succ :: UniMinimizeMethod -> UniMinimizeMethod
    $cpred :: UniMinimizeMethod -> UniMinimizeMethod
    pred :: UniMinimizeMethod -> UniMinimizeMethod
    $ctoEnum :: Int -> UniMinimizeMethod
    toEnum :: Int -> UniMinimizeMethod
    $cfromEnum :: UniMinimizeMethod -> Int
    fromEnum :: UniMinimizeMethod -> Int
    $cenumFrom :: UniMinimizeMethod -> [UniMinimizeMethod]
    enumFrom :: UniMinimizeMethod -> [UniMinimizeMethod]
    $cenumFromThen :: UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    enumFromThen :: UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    $cenumFromTo :: UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    enumFromTo :: UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    $cenumFromThenTo :: UniMinimizeMethod
    -> UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    enumFromThenTo :: UniMinimizeMethod
    -> UniMinimizeMethod -> UniMinimizeMethod -> [UniMinimizeMethod]
    Enum, UniMinimizeMethod -> UniMinimizeMethod -> Bool
    (UniMinimizeMethod -> UniMinimizeMethod -> Bool)
    -> (UniMinimizeMethod -> UniMinimizeMethod -> Bool)
    -> Eq UniMinimizeMethod
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: UniMinimizeMethod -> UniMinimizeMethod -> Bool
    == :: UniMinimizeMethod -> UniMinimizeMethod -> Bool
    $c/= :: UniMinimizeMethod -> UniMinimizeMethod -> Bool
    /= :: UniMinimizeMethod -> UniMinimizeMethod -> Bool
    Eq, Int -> UniMinimizeMethod -> ShowS
    [UniMinimizeMethod] -> ShowS
    UniMinimizeMethod -> String
    (Int -> UniMinimizeMethod -> ShowS)
    -> (UniMinimizeMethod -> String)
    -> ([UniMinimizeMethod] -> ShowS)
    -> Show UniMinimizeMethod
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> UniMinimizeMethod -> ShowS
    showsPrec :: Int -> UniMinimizeMethod -> ShowS
    $cshow :: UniMinimizeMethod -> String
    show :: UniMinimizeMethod -> String
    $cshowList :: [UniMinimizeMethod] -> ShowS
    showList :: [UniMinimizeMethod] -> ShowS
    Show, UniMinimizeMethod
    UniMinimizeMethod -> UniMinimizeMethod -> Bounded UniMinimizeMethod
    forall a. a -> a -> Bounded a
    $cminBound :: UniMinimizeMethod
    minBound :: UniMinimizeMethod
    $cmaxBound :: UniMinimizeMethod
    maxBound :: UniMinimizeMethod
    Bounded)

    -- | Onedimensional minimization.

    uniMinimize :: UniMinimizeMethod -- ^ The method used.
            -> Double               -- ^ desired precision of the solution
            -> Int                  -- ^ maximum number of iterations allowed
            -> (Double -> Double)   -- ^ function to minimize
            -> Double               -- ^ guess for the location of the minimum
            -> Double               -- ^ lower bound of search interval
            -> Double               -- ^ upper bound of search interval
            -> (Double, Matrix Double) -- ^ solution and optimization path

    uniMinimize :: UniMinimizeMethod
    -> Double
    -> Int
    -> (Double -> Double)
    -> Double
    -> Double
    -> Double
    -> (Double, Matrix Double)
    uniMinimize UniMinimizeMethod
    method Double
    epsrel Int
    maxit Double -> Double
    fun Double
    xmin Double
    xl Double
    xu = CInt
    -> (Double -> Double)
    -> Double
    -> Double
    -> Double
    -> Double
    -> Int
    -> (Double, Matrix Double)
    uniMinimizeGen (Int -> CInt
    fi (UniMinimizeMethod -> Int
    forall a. Enum a => a -> Int
    fromEnum UniMinimizeMethod
    method)) Double -> Double
    fun Double
    xmin Double
    xl Double
    xu Double
    epsrel Int
    maxit

    uniMinimizeGen :: CInt
    -> (Double -> Double)
    -> Double
    -> Double
    -> Double
    -> Double
    -> Int
    -> (Double, Matrix Double)
    uniMinimizeGen CInt
    m Double -> Double
    f Double
    xmin Double
    xl Double
    xu Double
    epsrel Int
    maxit = IO (Double, Matrix Double) -> (Double, Matrix Double)
    forall a. IO a -> a
    unsafePerformIO (IO (Double, Matrix Double) -> (Double, Matrix Double))
    -> IO (Double, Matrix Double) -> (Double, Matrix Double)
    forall a b. (a -> b) -> a -> b
    $ do
        fp <- (Double -> Double) -> IO (FunPtr (Double -> Double))
    mkDoublefun Double -> Double
    f
        rawpath <- createMIO maxit 4
                             (c_uniMinize m fp epsrel (fi maxit) xmin xl xu)
                             "uniMinimize"
        let it = Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Matrix Double
    rawpath Matrix Double -> IndexOf Matrix -> Double
    forall (c :: * -> *) e. Container c e => c e -> IndexOf c -> e
    `atIndex` (Int
    maxitInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1,Int
    0))
            path = Int -> Matrix Double -> Matrix Double
    forall t. Element t => Int -> Matrix t -> Matrix t
    takeRows Int
    it Matrix Double
    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 (Int -> MinimizeMethod
    MinimizeMethod -> Int
    MinimizeMethod -> [MinimizeMethod]
    MinimizeMethod -> MinimizeMethod
    MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    MinimizeMethod
    -> MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    (MinimizeMethod -> MinimizeMethod)
    -> (MinimizeMethod -> MinimizeMethod)
    -> (Int -> MinimizeMethod)
    -> (MinimizeMethod -> Int)
    -> (MinimizeMethod -> [MinimizeMethod])
    -> (MinimizeMethod -> MinimizeMethod -> [MinimizeMethod])
    -> (MinimizeMethod -> MinimizeMethod -> [MinimizeMethod])
    -> (MinimizeMethod
        -> MinimizeMethod -> MinimizeMethod -> [MinimizeMethod])
    -> Enum MinimizeMethod
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: MinimizeMethod -> MinimizeMethod
    succ :: MinimizeMethod -> MinimizeMethod
    $cpred :: MinimizeMethod -> MinimizeMethod
    pred :: MinimizeMethod -> MinimizeMethod
    $ctoEnum :: Int -> MinimizeMethod
    toEnum :: Int -> MinimizeMethod
    $cfromEnum :: MinimizeMethod -> Int
    fromEnum :: MinimizeMethod -> Int
    $cenumFrom :: MinimizeMethod -> [MinimizeMethod]
    enumFrom :: MinimizeMethod -> [MinimizeMethod]
    $cenumFromThen :: MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    enumFromThen :: MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    $cenumFromTo :: MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    enumFromTo :: MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    $cenumFromThenTo :: MinimizeMethod
    -> MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    enumFromThenTo :: MinimizeMethod
    -> MinimizeMethod -> MinimizeMethod -> [MinimizeMethod]
    Enum,MinimizeMethod -> MinimizeMethod -> Bool
    (MinimizeMethod -> MinimizeMethod -> Bool)
    -> (MinimizeMethod -> MinimizeMethod -> Bool) -> Eq MinimizeMethod
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: MinimizeMethod -> MinimizeMethod -> Bool
    == :: MinimizeMethod -> MinimizeMethod -> Bool
    $c/= :: MinimizeMethod -> MinimizeMethod -> Bool
    /= :: MinimizeMethod -> MinimizeMethod -> Bool
    Eq,Int -> MinimizeMethod -> ShowS
    [MinimizeMethod] -> ShowS
    MinimizeMethod -> String
    (Int -> MinimizeMethod -> ShowS)
    -> (MinimizeMethod -> String)
    -> ([MinimizeMethod] -> ShowS)
    -> Show MinimizeMethod
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> MinimizeMethod -> ShowS
    showsPrec :: Int -> MinimizeMethod -> ShowS
    $cshow :: MinimizeMethod -> String
    show :: MinimizeMethod -> String
    $cshowList :: [MinimizeMethod] -> ShowS
    showList :: [MinimizeMethod] -> ShowS
    Show,MinimizeMethod
    MinimizeMethod -> MinimizeMethod -> Bounded MinimizeMethod
    forall a. a -> a -> Bounded a
    $cminBound :: MinimizeMethod
    minBound :: MinimizeMethod
    $cmaxBound :: MinimizeMethod
    maxBound :: MinimizeMethod
    Bounded)

    -- | Minimization without derivatives
    minimize :: MinimizeMethod
             -> Double              -- ^ desired precision of the solution (size test)
             -> Int                 -- ^ maximum number of iterations allowed
             -> [Double]            -- ^ sizes of the initial search box
             -> ([Double] -> Double) -- ^ function to minimize
             -> [Double]            -- ^ starting point
             -> ([Double], Matrix Double) -- ^ solution vector and optimization path

    -- | Minimization without derivatives (vector version)
    minimizeV :: MinimizeMethod
             -> Double              -- ^ desired precision of the solution (size test)
             -> Int                 -- ^ maximum number of iterations allowed
             -> Vector Double       -- ^ sizes of the initial search box
             -> (Vector Double -> Double) -- ^ function to minimize
             -> Vector Double            -- ^ starting point
             -> (Vector Double, Matrix Double) -- ^ solution vector and optimization path

    minimize :: MinimizeMethod
    -> Double
    -> Int
    -> [Double]
    -> ([Double] -> Double)
    -> [Double]
    -> ([Double], Matrix Double)
    minimize MinimizeMethod
    method Double
    eps Int
    maxit [Double]
    sz [Double] -> Double
    f [Double]
    xi = (Vector Double, Matrix Double) -> ([Double], Matrix Double)
    forall {a} {b}. Storable a => (Vector a, b) -> ([a], b)
    v2l ((Vector Double, Matrix Double) -> ([Double], Matrix Double))
    -> (Vector Double, Matrix Double) -> ([Double], Matrix Double)
    forall a b. (a -> b) -> a -> b
    $ MinimizeMethod
    -> Double
    -> Int
    -> Vector Double
    -> (Vector Double -> Double)
    -> Vector Double
    -> (Vector Double, Matrix Double)
    minimizeV MinimizeMethod
    method Double
    eps Int
    maxit ([Double] -> Vector Double
    forall a. Storable a => [a] -> Vector a
    fromList [Double]
    sz) ([Double] -> Double
    f([Double] -> Double)
    -> (Vector Double -> [Double]) -> Vector Double -> Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Vector Double -> [Double]
    forall a. Storable a => Vector a -> [a]
    toList) ([Double] -> Vector Double
    forall a. Storable a => [a] -> Vector a
    fromList [Double]
    xi)
        where v2l :: (Vector a, b) -> ([a], b)
    v2l (Vector a
    v,b
    m) = (Vector a -> [a]
    forall a. Storable a => Vector a -> [a]
    toList Vector a
    v, b
    m)

    minimizeV :: MinimizeMethod
    -> Double
    -> Int
    -> Vector Double
    -> (Vector Double -> Double)
    -> Vector Double
    -> (Vector Double, Matrix Double)
    minimizeV MinimizeMethod
    method Double
    eps Int
    maxit Vector Double
    szv Vector Double -> Double
    f Vector Double
    xiv = IO (Vector Double, Matrix Double) -> (Vector Double, Matrix Double)
    forall a. IO a -> a
    unsafePerformIO (IO (Vector Double, Matrix Double)
     -> (Vector Double, Matrix Double))
    -> IO (Vector Double, Matrix Double)
    -> (Vector Double, Matrix Double)
    forall a b. (a -> b) -> a -> b
    $ do
        let n :: IndexOf Vector
    n   = Vector Double -> IndexOf Vector
    forall (c :: * -> *) t. Container c t => c t -> IndexOf c
    size Vector Double
    xiv
        fp <- (CInt -> Ptr Double -> Double)
    -> IO (FunPtr (CInt -> Ptr Double -> Double))
    mkVecfun ((Vector Double -> Double) -> CInt -> Ptr Double -> Double
    iv Vector Double -> Double
    f)
        rawpath <- ww2 vec xiv vec szv $ \(CInt -> Ptr Double -> TV (CInt -> CInt -> Ptr Double -> IO CInt))
    -> TV (CInt -> CInt -> Ptr Double -> IO CInt)
    xiv' TV (CInt -> CInt -> Ptr Double -> IO CInt)
    -> CInt -> CInt -> Ptr Double -> IO CInt
    szv' ->
                       Int
    -> Int
    -> (CInt -> CInt -> Ptr Double -> IO CInt)
    -> String
    -> IO (Matrix Double)
    forall {a}.
    Storable a =>
    Int
    -> Int
    -> (CInt -> CInt -> Ptr a -> IO CInt)
    -> String
    -> IO (Matrix a)
    createMIO Int
    maxit (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    3)
                             (CInt
    -> FunPtr (CInt -> Ptr Double -> Double)
    -> Double
    -> CInt
    -> CInt
    -> Ptr Double
    -> TV (CInt -> CInt -> Ptr Double -> IO CInt)
    c_minimize (Int -> CInt
    fi (MinimizeMethod -> Int
    forall a. Enum a => a -> Int
    fromEnum MinimizeMethod
    method)) FunPtr (CInt -> Ptr Double -> Double)
    fp Double
    eps (Int -> CInt
    fi Int
    maxit) (CInt -> Ptr Double -> TV (CInt -> CInt -> Ptr Double -> IO CInt))
    -> ((CInt
         -> Ptr Double -> TV (CInt -> CInt -> Ptr Double -> IO CInt))
        -> TV (CInt -> CInt -> Ptr Double -> IO CInt))
    -> TV (CInt -> CInt -> Ptr Double -> IO CInt)
    forall x y. x -> (x -> y) -> y
    // (CInt -> Ptr Double -> TV (CInt -> CInt -> Ptr Double -> IO CInt))
    -> TV (CInt -> CInt -> Ptr Double -> IO CInt)
    xiv' TV (CInt -> CInt -> Ptr Double -> IO CInt)
    -> (TV (CInt -> CInt -> Ptr Double -> IO CInt)
        -> CInt -> CInt -> Ptr Double -> IO CInt)
    -> CInt
    -> CInt
    -> Ptr Double
    -> IO CInt
    forall x y. x -> (x -> y) -> y
    // TV (CInt -> CInt -> Ptr Double -> IO CInt)
    -> CInt -> CInt -> Ptr Double -> IO CInt
    szv')
                             String
    "minimize"
        let it = Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Matrix Double
    rawpath Matrix Double -> IndexOf Matrix -> Double
    forall (c :: * -> *) e. Container c e => c e -> IndexOf c -> e
    `atIndex` (Int
    maxitInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1,Int
    0))
            path = Int -> Matrix Double -> Matrix Double
    forall t. Element t => Int -> Matrix t -> Matrix t
    takeRows Int
    it Matrix Double
    rawpath
            sol = Matrix Double -> Vector Double
    forall t. Element t => Matrix t -> Vector t
    flatten (Matrix Double -> Vector Double) -> Matrix Double -> Vector Double
    forall a b. (a -> b) -> a -> b
    $ Int -> Matrix Double -> Matrix Double
    forall t. Element t => Int -> Matrix t -> Matrix t
    dropColumns Int
    3 (Matrix Double -> Matrix Double) -> Matrix Double -> Matrix Double
    forall a b. (a -> b) -> a -> b
    $ Int -> Matrix Double -> Matrix Double
    forall t. Element t => Int -> Matrix t -> Matrix t
    dropRows (Int
    itInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) Matrix Double
    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 (Int -> MinimizeMethodD
    MinimizeMethodD -> Int
    MinimizeMethodD -> [MinimizeMethodD]
    MinimizeMethodD -> MinimizeMethodD
    MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    MinimizeMethodD
    -> MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    (MinimizeMethodD -> MinimizeMethodD)
    -> (MinimizeMethodD -> MinimizeMethodD)
    -> (Int -> MinimizeMethodD)
    -> (MinimizeMethodD -> Int)
    -> (MinimizeMethodD -> [MinimizeMethodD])
    -> (MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD])
    -> (MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD])
    -> (MinimizeMethodD
        -> MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD])
    -> Enum MinimizeMethodD
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: MinimizeMethodD -> MinimizeMethodD
    succ :: MinimizeMethodD -> MinimizeMethodD
    $cpred :: MinimizeMethodD -> MinimizeMethodD
    pred :: MinimizeMethodD -> MinimizeMethodD
    $ctoEnum :: Int -> MinimizeMethodD
    toEnum :: Int -> MinimizeMethodD
    $cfromEnum :: MinimizeMethodD -> Int
    fromEnum :: MinimizeMethodD -> Int
    $cenumFrom :: MinimizeMethodD -> [MinimizeMethodD]
    enumFrom :: MinimizeMethodD -> [MinimizeMethodD]
    $cenumFromThen :: MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    enumFromThen :: MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    $cenumFromTo :: MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    enumFromTo :: MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    $cenumFromThenTo :: MinimizeMethodD
    -> MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    enumFromThenTo :: MinimizeMethodD
    -> MinimizeMethodD -> MinimizeMethodD -> [MinimizeMethodD]
    Enum,MinimizeMethodD -> MinimizeMethodD -> Bool
    (MinimizeMethodD -> MinimizeMethodD -> Bool)
    -> (MinimizeMethodD -> MinimizeMethodD -> Bool)
    -> Eq MinimizeMethodD
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: MinimizeMethodD -> MinimizeMethodD -> Bool
    == :: MinimizeMethodD -> MinimizeMethodD -> Bool
    $c/= :: MinimizeMethodD -> MinimizeMethodD -> Bool
    /= :: MinimizeMethodD -> MinimizeMethodD -> Bool
    Eq,Int -> MinimizeMethodD -> ShowS
    [MinimizeMethodD] -> ShowS
    MinimizeMethodD -> String
    (Int -> MinimizeMethodD -> ShowS)
    -> (MinimizeMethodD -> String)
    -> ([MinimizeMethodD] -> ShowS)
    -> Show MinimizeMethodD
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> MinimizeMethodD -> ShowS
    showsPrec :: Int -> MinimizeMethodD -> ShowS
    $cshow :: MinimizeMethodD -> String
    show :: MinimizeMethodD -> String
    $cshowList :: [MinimizeMethodD] -> ShowS
    showList :: [MinimizeMethodD] -> ShowS
    Show,MinimizeMethodD
    MinimizeMethodD -> MinimizeMethodD -> Bounded MinimizeMethodD
    forall a. a -> a -> Bounded a
    $cminBound :: MinimizeMethodD
    minBound :: MinimizeMethodD
    $cmaxBound :: MinimizeMethodD
    maxBound :: MinimizeMethodD
    Bounded)

    -- | Minimization with derivatives.
    minimizeD :: MinimizeMethodD
        -> Double                 -- ^ desired precision of the solution (gradient test)
        -> Int                    -- ^ maximum number of iterations allowed
        -> Double                 -- ^ size of the first trial step
        -> Double                 -- ^ tol (precise meaning depends on method)
        -> ([Double] -> Double)   -- ^ function to minimize
        -> ([Double] -> [Double]) -- ^ gradient
        -> [Double]               -- ^ starting point
        -> ([Double], Matrix Double) -- ^ solution vector and optimization path

    -- | Minimization with derivatives (vector version)
    minimizeVD :: MinimizeMethodD
        -> Double                 -- ^ desired precision of the solution (gradient test)
        -> Int                    -- ^ maximum number of iterations allowed
        -> Double                 -- ^ size of the first trial step
        -> Double                 -- ^ tol (precise meaning depends on method)
        -> (Vector Double -> Double)   -- ^ function to minimize
        -> (Vector Double -> Vector Double) -- ^ gradient
        -> Vector Double               -- ^ starting point
        -> (Vector Double, Matrix Double) -- ^ solution vector and optimization path

    minimizeD :: MinimizeMethodD
    -> Double
    -> Int
    -> Double
    -> Double
    -> ([Double] -> Double)
    -> ([Double] -> [Double])
    -> [Double]
    -> ([Double], Matrix Double)
    minimizeD MinimizeMethodD
    method Double
    eps Int
    maxit Double
    istep Double
    tol [Double] -> Double
    f [Double] -> [Double]
    df [Double]
    xi = (Vector Double, Matrix Double) -> ([Double], Matrix Double)
    forall {a} {b}. Storable a => (Vector a, b) -> ([a], b)
    v2l ((Vector Double, Matrix Double) -> ([Double], Matrix Double))
    -> (Vector Double, Matrix Double) -> ([Double], Matrix Double)
    forall a b. (a -> b) -> a -> b
    $ MinimizeMethodD
    -> Double
    -> Int
    -> Double
    -> Double
    -> (Vector Double -> Double)
    -> (Vector Double -> Vector Double)
    -> Vector Double
    -> (Vector Double, Matrix Double)
    minimizeVD
              MinimizeMethodD
    method Double
    eps Int
    maxit Double
    istep Double
    tol ([Double] -> Double
    f([Double] -> Double)
    -> (Vector Double -> [Double]) -> Vector Double -> Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Vector Double -> [Double]
    forall a. Storable a => Vector a -> [a]
    toList) ([Double] -> Vector Double
    forall a. Storable a => [a] -> Vector a
    fromList([Double] -> Vector Double)
    -> (Vector Double -> [Double]) -> Vector Double -> Vector Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .[Double] -> [Double]
    df([Double] -> [Double])
    -> (Vector Double -> [Double]) -> Vector Double -> [Double]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Vector Double -> [Double]
    forall a. Storable a => Vector a -> [a]
    toList) ([Double] -> Vector Double
    forall a. Storable a => [a] -> Vector a
    fromList [Double]
    xi)
        where v2l :: (Vector a, b) -> ([a], b)
    v2l (Vector a
    v,b
    m) = (Vector a -> [a]
    forall a. Storable a => Vector a -> [a]
    toList Vector a
    v, b
    m)

    minimizeVD :: MinimizeMethodD
    -> Double
    -> Int
    -> Double
    -> Double
    -> (Vector Double -> Double)
    -> (Vector Double -> Vector Double)
    -> Vector Double
    -> (Vector Double, Matrix Double)
    minimizeVD MinimizeMethodD
    method Double
    eps Int
    maxit Double
    istep Double
    tol Vector Double -> Double
    f Vector Double -> Vector Double
    df Vector Double
    xiv = IO (Vector Double, Matrix Double) -> (Vector Double, Matrix Double)
    forall a. IO a -> a
    unsafePerformIO (IO (Vector Double, Matrix Double)
     -> (Vector Double, Matrix Double))
    -> IO (Vector Double, Matrix Double)
    -> (Vector Double, Matrix Double)
    forall a b. (a -> b) -> a -> b
    $ do
        let n :: IndexOf Vector
    n = Vector Double -> IndexOf Vector
    forall (c :: * -> *) t. Container c t => c t -> IndexOf c
    size Vector Double
    xiv
            f' :: Vector Double -> Double
    f' = Vector Double -> Double
    f
            df' :: Vector Double -> Vector Double
    df' = (IndexOf Vector -> Vector Double -> Vector Double
    forall {c :: * -> *} {t}.
    (Eq (IndexOf c), Container c t, Show (IndexOf c)) =>
    IndexOf c -> c t -> c t
    checkdim1 Int
    IndexOf Vector
    n (Vector Double -> Vector Double)
    -> (Vector Double -> Vector Double)
    -> Vector Double
    -> Vector Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector Double -> Vector Double
    df)
        fp <- (CInt -> Ptr Double -> Double)
    -> IO (FunPtr (CInt -> Ptr Double -> Double))
    mkVecfun ((Vector Double -> Double) -> CInt -> Ptr Double -> Double
    iv Vector Double -> Double
    f')
        dfp <- mkVecVecfun (aux_vTov df')
        rawpath <- vec xiv $ \TV (CInt -> CInt -> Ptr Double -> IO CInt)
    -> CInt -> CInt -> Ptr Double -> IO CInt
    xiv' ->
                        Int
    -> Int
    -> (CInt -> CInt -> Ptr Double -> IO CInt)
    -> String
    -> IO (Matrix Double)
    forall {a}.
    Storable a =>
    Int
    -> Int
    -> (CInt -> CInt -> Ptr a -> IO CInt)
    -> String
    -> IO (Matrix a)
    createMIO Int
    maxit (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    2)
                             (CInt
    -> FunPtr (CInt -> Ptr Double -> Double)
    -> FunPtr TVV
    -> Double
    -> Double
    -> Double
    -> CInt
    -> TV (CInt -> CInt -> Ptr Double -> IO CInt)
    c_minimizeD (Int -> CInt
    fi (MinimizeMethodD -> Int
    forall a. Enum a => a -> Int
    fromEnum MinimizeMethodD
    method)) FunPtr (CInt -> Ptr Double -> Double)
    fp FunPtr TVV
    dfp Double
    istep Double
    tol Double
    eps (Int -> CInt
    fi Int
    maxit) TV (CInt -> CInt -> Ptr Double -> IO CInt)
    -> (TV (CInt -> CInt -> Ptr Double -> IO CInt)
        -> CInt -> CInt -> Ptr Double -> IO CInt)
    -> CInt
    -> CInt
    -> Ptr Double
    -> IO CInt
    forall x y. x -> (x -> y) -> y
    // TV (CInt -> CInt -> Ptr Double -> IO CInt)
    -> CInt -> CInt -> Ptr Double -> IO CInt
    xiv')
                             String
    "minimizeD"
        let it = Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Matrix Double
    rawpath Matrix Double -> IndexOf Matrix -> Double
    forall (c :: * -> *) e. Container c e => c e -> IndexOf c -> e
    `atIndex` (Int
    maxitInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1,Int
    0))
            path = Int -> Matrix Double -> Matrix Double
    forall t. Element t => Int -> Matrix t -> Matrix t
    takeRows Int
    it Matrix Double
    rawpath
            sol = Matrix Double -> Vector Double
    forall t. Element t => Matrix t -> Vector t
    flatten (Matrix Double -> Vector Double) -> Matrix Double -> Vector Double
    forall a b. (a -> b) -> a -> b
    $ Int -> Matrix Double -> Matrix Double
    forall t. Element t => Int -> Matrix t -> Matrix t
    dropColumns Int
    2 (Matrix Double -> Matrix Double) -> Matrix Double -> Matrix Double
    forall a b. (a -> b) -> a -> b
    $ Int -> Matrix Double -> Matrix Double
    forall t. Element t => Int -> Matrix t -> Matrix t
    dropRows (Int
    itInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) Matrix Double
    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 :: IndexOf c -> c t -> c t
    checkdim1 IndexOf c
    n c t
    v
        | c t -> IndexOf c
    forall (c :: * -> *) t. Container c t => c t -> IndexOf c
    size c t
    v IndexOf c -> IndexOf c -> Bool
    forall a. Eq a => a -> a -> Bool
    == IndexOf c
    n = c t
    v
        | Bool
    otherwise = String -> c t
    forall a. HasCallStack => String -> a
    error (String -> c t) -> String -> c t
    forall a b. (a -> b) -> a -> b
    $ String
    "Error: "String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ IndexOf c -> String
    forall a. Show a => a -> String
    show IndexOf c
    n
                            String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " components expected in the result of the gradient supplied to minimizeD"