{-# LINE 1 "Numeric/LBFGS/Raw.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface, GeneralizedNewtypeDeriving #-}
{-# LINE 2 "Numeric/LBFGS/Raw.hsc" #-}


{-# LINE 4 "Numeric/LBFGS/Raw.hsc" #-}

{-# LINE 5 "Numeric/LBFGS/Raw.hsc" #-}

module Numeric.LBFGS.Raw (CLineSearchAlgorithm, CLBFGSParameter(..),
                          CEvaluateFun, CProgressFun,
                          defaultCParam, c_lbfgs, c_lbfgs_malloc,
                          c_lbfgs_free, c_lbfgs_evaluate_t_wrap,
                          c_lbfgs_progress_t_wrap,

                          defaultLineSearch, moreThuente, backtrackingArmijo,
                          backtracking, backtrackingWolfe,
                          backtrackingStrongWolfe,

                          CLBFGSResult(..),
                          lbfgsSuccess,
                          lbfgsConvergence,
                          lbfgsStop,
                          lbfgsAlreadyMinimized,
                          lbfgserrUnknownerror,
                          lbfgserrLogicerror,
                          lbfgserrOutofmemory,
                          lbfgserrCanceled,
                          lbfgserrInvalidN,
                          lbfgserrInvalidNSse,
                          lbfgserrInvalidXSse,
                          lbfgserrInvalidEpsilon,
                          lbfgserrInvalidTestperiod,
                          lbfgserrInvalidDelta,
                          lbfgserrInvalidLinesearch,
                          lbfgserrInvalidMinstep,
                          lbfgserrInvalidMaxstep,
                          lbfgserrInvalidFtol,
                          lbfgserrInvalidWolfe,
                          lbfgserrInvalidGtol,
                          lbfgserrInvalidXtol,
                          lbfgserrInvalidMaxlinesearch,
                          lbfgserrInvalidOrthantwise,
                          lbfgserrInvalidOrthantwiseStart,
                          lbfgserrInvalidOrthantwiseEnd,
                          lbfgserrOutofinterval,
                          lbfgserrIncorrectTminmax,
                          lbfgserrRoundingError,
                          lbfgserrMinimumstep,
                          lbfgserrMaximumstep,
                          lbfgserrMaximumlinesearch,
                          lbfgserrMaximumiteration,
                          lbfgserrWidthtoosmall,
                          lbfgserrInvalidparameters,
                          lbfgserrIncreasegradient

) where

import Foreign.Storable (Storable(..))
import Foreign.C.Types (CDouble, CInt)
import Foreign.Ptr (FunPtr, Ptr)

newtype CLineSearchAlgorithm =
    CLineSearchAlgorithm { unCLineSearchAlgorithm :: CInt }
    deriving (Storable, Show)

defaultLineSearch  :: CLineSearchAlgorithm
defaultLineSearch  = CLineSearchAlgorithm 0
moreThuente  :: CLineSearchAlgorithm
moreThuente  = CLineSearchAlgorithm 0
backtrackingArmijo  :: CLineSearchAlgorithm
backtrackingArmijo  = CLineSearchAlgorithm 1
backtracking  :: CLineSearchAlgorithm
backtracking  = CLineSearchAlgorithm 2
backtrackingWolfe  :: CLineSearchAlgorithm
backtrackingWolfe  = CLineSearchAlgorithm 2
backtrackingStrongWolfe  :: CLineSearchAlgorithm
backtrackingStrongWolfe  = CLineSearchAlgorithm 3

{-# LINE 71 "Numeric/LBFGS/Raw.hsc" #-}

newtype CLBFGSResult =
    CLBFGSResult { unCLBFGSResult :: CInt }
    deriving (Eq, Show)

lbfgsSuccess :: CLBFGSResult
lbfgsSuccess = CLBFGSResult 0
lbfgsConvergence :: CLBFGSResult
lbfgsConvergence = CLBFGSResult 0
lbfgsStop :: CLBFGSResult
lbfgsStop = CLBFGSResult 1
lbfgsAlreadyMinimized :: CLBFGSResult
lbfgsAlreadyMinimized = CLBFGSResult 2
lbfgserrUnknownerror :: CLBFGSResult
lbfgserrUnknownerror = CLBFGSResult (-1024)
lbfgserrLogicerror :: CLBFGSResult
lbfgserrLogicerror = CLBFGSResult (-1023)
lbfgserrOutofmemory :: CLBFGSResult
lbfgserrOutofmemory = CLBFGSResult (-1022)
lbfgserrCanceled :: CLBFGSResult
lbfgserrCanceled = CLBFGSResult (-1021)
lbfgserrInvalidN :: CLBFGSResult
lbfgserrInvalidN = CLBFGSResult (-1020)
lbfgserrInvalidNSse :: CLBFGSResult
lbfgserrInvalidNSse = CLBFGSResult (-1019)
lbfgserrInvalidXSse :: CLBFGSResult
lbfgserrInvalidXSse = CLBFGSResult (-1018)
lbfgserrInvalidEpsilon :: CLBFGSResult
lbfgserrInvalidEpsilon = CLBFGSResult (-1017)
lbfgserrInvalidTestperiod :: CLBFGSResult
lbfgserrInvalidTestperiod = CLBFGSResult (-1016)
lbfgserrInvalidDelta :: CLBFGSResult
lbfgserrInvalidDelta = CLBFGSResult (-1015)
lbfgserrInvalidLinesearch :: CLBFGSResult
lbfgserrInvalidLinesearch = CLBFGSResult (-1014)
lbfgserrInvalidMinstep :: CLBFGSResult
lbfgserrInvalidMinstep = CLBFGSResult (-1013)
lbfgserrInvalidMaxstep :: CLBFGSResult
lbfgserrInvalidMaxstep = CLBFGSResult (-1012)
lbfgserrInvalidFtol :: CLBFGSResult
lbfgserrInvalidFtol = CLBFGSResult (-1011)
lbfgserrInvalidWolfe :: CLBFGSResult
lbfgserrInvalidWolfe = CLBFGSResult (-1010)
lbfgserrInvalidGtol :: CLBFGSResult
lbfgserrInvalidGtol = CLBFGSResult (-1009)
lbfgserrInvalidXtol :: CLBFGSResult
lbfgserrInvalidXtol = CLBFGSResult (-1008)
lbfgserrInvalidMaxlinesearch :: CLBFGSResult
lbfgserrInvalidMaxlinesearch = CLBFGSResult (-1007)
lbfgserrInvalidOrthantwise :: CLBFGSResult
lbfgserrInvalidOrthantwise = CLBFGSResult (-1006)
lbfgserrInvalidOrthantwiseStart :: CLBFGSResult
lbfgserrInvalidOrthantwiseStart = CLBFGSResult (-1005)
lbfgserrInvalidOrthantwiseEnd :: CLBFGSResult
lbfgserrInvalidOrthantwiseEnd = CLBFGSResult (-1004)
lbfgserrOutofinterval :: CLBFGSResult
lbfgserrOutofinterval = CLBFGSResult (-1003)
lbfgserrIncorrectTminmax :: CLBFGSResult
lbfgserrIncorrectTminmax = CLBFGSResult (-1002)
lbfgserrRoundingError :: CLBFGSResult
lbfgserrRoundingError = CLBFGSResult (-1001)
lbfgserrMinimumstep :: CLBFGSResult
lbfgserrMinimumstep = CLBFGSResult (-1000)
lbfgserrMaximumstep :: CLBFGSResult
lbfgserrMaximumstep = CLBFGSResult (-999)
lbfgserrMaximumlinesearch :: CLBFGSResult
lbfgserrMaximumlinesearch = CLBFGSResult (-998)
lbfgserrMaximumiteration :: CLBFGSResult
lbfgserrMaximumiteration = CLBFGSResult (-997)
lbfgserrWidthtoosmall :: CLBFGSResult
lbfgserrWidthtoosmall = CLBFGSResult (-996)
lbfgserrInvalidparameters :: CLBFGSResult
lbfgserrInvalidparameters = CLBFGSResult (-995)
lbfgserrIncreasegradient  :: CLBFGSResult
lbfgserrIncreasegradient  = CLBFGSResult (-994)

{-# LINE 94 "Numeric/LBFGS/Raw.hsc" #-}

data CLBFGSParameter = CLBFGSParameter {
      m :: CInt,
      epsilon :: CDouble,
      past :: CInt,
      delta :: CDouble,
      max_iterations :: CInt,
      linesearch :: CLineSearchAlgorithm,
      max_linesearch :: CInt,
      min_step :: CDouble,
      max_step :: CDouble,
      ftol :: CDouble,
      wolfe :: CDouble,
      gtol :: CDouble,
      xtol :: CDouble,
      orthantwise_c :: CDouble,
      orthantwise_start :: CDouble,
      orthantwise_end :: CDouble
} deriving Show

defaultCParam :: CLBFGSParameter
defaultCParam = CLBFGSParameter 6 1e-5 0 1e-5 0 defaultLineSearch 40 1e-20
                1e20 1e-4 0.9 0.9 1.0e-16 0.0 0.0 (-1.0)

instance Storable CLBFGSParameter where
    sizeOf _ = (100)
{-# LINE 120 "Numeric/LBFGS/Raw.hsc" #-}
    alignment _ = 4
{-# LINE 121 "Numeric/LBFGS/Raw.hsc" #-}
    peek ptr = do
      m                 <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
{-# LINE 123 "Numeric/LBFGS/Raw.hsc" #-}
      epsilon           <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) ptr
{-# LINE 124 "Numeric/LBFGS/Raw.hsc" #-}
      past              <- ((\hsc_ptr -> peekByteOff hsc_ptr 12)) ptr
{-# LINE 125 "Numeric/LBFGS/Raw.hsc" #-}
      delta             <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) ptr
{-# LINE 126 "Numeric/LBFGS/Raw.hsc" #-}
      max_iterations    <- ((\hsc_ptr -> peekByteOff hsc_ptr 24)) ptr
{-# LINE 127 "Numeric/LBFGS/Raw.hsc" #-}
      linesearch        <- ((\hsc_ptr -> peekByteOff hsc_ptr 28)) ptr
{-# LINE 128 "Numeric/LBFGS/Raw.hsc" #-}
      max_linesearch    <- ((\hsc_ptr -> peekByteOff hsc_ptr 32)) ptr
{-# LINE 129 "Numeric/LBFGS/Raw.hsc" #-}
      min_step          <- ((\hsc_ptr -> peekByteOff hsc_ptr 36)) ptr
{-# LINE 130 "Numeric/LBFGS/Raw.hsc" #-}
      max_step          <- ((\hsc_ptr -> peekByteOff hsc_ptr 44)) ptr
{-# LINE 131 "Numeric/LBFGS/Raw.hsc" #-}
      ftol              <- ((\hsc_ptr -> peekByteOff hsc_ptr 52)) ptr
{-# LINE 132 "Numeric/LBFGS/Raw.hsc" #-}
      wolfe             <- ((\hsc_ptr -> peekByteOff hsc_ptr 60)) ptr
{-# LINE 133 "Numeric/LBFGS/Raw.hsc" #-}
      gtol              <- ((\hsc_ptr -> peekByteOff hsc_ptr 68)) ptr
{-# LINE 134 "Numeric/LBFGS/Raw.hsc" #-}
      xtol              <- ((\hsc_ptr -> peekByteOff hsc_ptr 76)) ptr
{-# LINE 135 "Numeric/LBFGS/Raw.hsc" #-}
      orthantwise_c     <- ((\hsc_ptr -> peekByteOff hsc_ptr 84)) ptr
{-# LINE 136 "Numeric/LBFGS/Raw.hsc" #-}
      orthantwise_start <- ((\hsc_ptr -> peekByteOff hsc_ptr 92)) ptr
{-# LINE 137 "Numeric/LBFGS/Raw.hsc" #-}
      orthantwise_end   <- ((\hsc_ptr -> peekByteOff hsc_ptr 96)) ptr
{-# LINE 138 "Numeric/LBFGS/Raw.hsc" #-}
      return $ CLBFGSParameter m epsilon past delta max_iterations
             linesearch max_linesearch min_step max_step
             ftol wolfe gtol xtol orthantwise_c
             orthantwise_start orthantwise_end
    poke ptr (CLBFGSParameter m epsilon past delta max_iterations
                              linesearch max_linesearch min_step max_step
                              ftol wolfe gtol xtol orthantwise_c
                              orthantwise_start orthantwise_end
             ) = do
      ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr m
{-# LINE 148 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) ptr epsilon
{-# LINE 149 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 12)) ptr past
{-# LINE 150 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 16)) ptr delta
{-# LINE 151 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 24)) ptr max_iterations
{-# LINE 152 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 28)) ptr linesearch
{-# LINE 153 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 32)) ptr max_linesearch
{-# LINE 154 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 36)) ptr min_step
{-# LINE 155 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 44)) ptr max_step
{-# LINE 156 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 52)) ptr ftol
{-# LINE 157 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 60)) ptr wolfe
{-# LINE 158 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 68)) ptr gtol
{-# LINE 159 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 76)) ptr xtol
{-# LINE 160 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 84)) ptr orthantwise_c
{-# LINE 161 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 92)) ptr orthantwise_start
{-# LINE 162 "Numeric/LBFGS/Raw.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 96)) ptr orthantwise_end
{-# LINE 163 "Numeric/LBFGS/Raw.hsc" #-}

type CEvaluateFun a = (Ptr a -> Ptr CDouble -> Ptr CDouble -> CInt ->
                      CDouble -> IO (CDouble))

type CProgressFun a = (Ptr a -> Ptr CDouble -> Ptr CDouble -> CDouble ->
                      CDouble -> CDouble -> CDouble -> CInt -> CInt ->
                      CInt -> IO (CInt))

foreign import ccall "wrapper"
        c_lbfgs_evaluate_t_wrap :: CEvaluateFun a -> IO (FunPtr (CEvaluateFun a))

foreign import ccall "wrapper"
        c_lbfgs_progress_t_wrap :: CProgressFun a -> IO (FunPtr (CProgressFun a))

foreign import ccall safe "lbfgs.h lbfgs" c_lbfgs ::
    CInt -> Ptr CDouble -> Ptr CDouble -> FunPtr (CEvaluateFun a) ->
    FunPtr (CProgressFun a) -> Ptr a -> Ptr (CLBFGSParameter) -> IO (CInt)

foreign import ccall unsafe "lbfgs.h lbfgs_malloc" c_lbfgs_malloc ::
    CInt -> IO (Ptr CDouble)

foreign import ccall unsafe "lbfgs.h lbfgs_free" c_lbfgs_free ::
    Ptr CDouble -> IO ()