{-# LINE 1 "Bindings/LevMar.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface, NoImplicitPrelude #-}
{-# LINE 2 "Bindings/LevMar.hsc" #-}

{-# OPTIONS_GHC -fno-warn-unused-binds #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  Bindings.LevMar
-- Copyright   :  (c) 2009-2012 Roel van Dijk & Bas van Dijk
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  vandijk.roel@gmail.com, v.dijk.bas@gmail.com
-- Stability   :  Experimental
--
-- A low level binding to the C levmar (Levenberg-Marquardt) library.
--
-- For documentation see: <http://www.ics.forth.gr/~lourakis/levmar/>
--
--------------------------------------------------------------------------------


{-# LINE 21 "Bindings/LevMar.hsc" #-}

{-# LINE 22 "Bindings/LevMar.hsc" #-}

module Bindings.LevMar
    ( c'LM_VERSION

      -- * Maximum sizes of arrays.
    , c'LM_OPTS_SZ
    , c'LM_INFO_SZ

      -- * Errors.
    , c'LM_ERROR
    , c'LM_ERROR_LAPACK_ERROR
    , c'LM_ERROR_NO_JACOBIAN
    , c'LM_ERROR_NO_BOX_CONSTRAINTS
    , c'LM_ERROR_FAILED_BOX_CHECK
    , c'LM_ERROR_MEMORY_ALLOCATION_FAILURE
    , c'LM_ERROR_CONSTRAINT_MATRIX_ROWS_GT_COLS
    , c'LM_ERROR_CONSTRAINT_MATRIX_NOT_FULL_ROW_RANK
    , c'LM_ERROR_TOO_FEW_MEASUREMENTS
    , c'LM_ERROR_SINGULAR_MATRIX
    , c'LM_ERROR_SUM_OF_SQUARES_NOT_FINITE

      -- * Default values for minimization options.
    , c'LM_INIT_MU
    , c'LM_STOP_THRESH
    , c'LM_DIFF_DELTA

      -- * Handy type synonyms
    , Parameters
    , Measurements
    , Options
    , LowerBounds
    , UpperBounds
    , ConstraintsMatrix
    , ConstraintsVector
    , Weights
    , Info
    , Work
    , Covar
    , AData
    , NrOfParameters
    , NrOfMeasurements
    , NrOfConstraints
    , MaxIterations

      -- * Model & Jacobian.
    , Model
    , Jacobian

    , withModel
    , withJacobian

      -- * Types of the Levenberg-Marquardt algorithms.
    , LevMarDer
    , LevMarDif
    , LevMarBCDer
    , LevMarBCDif
    , LevMarLecDer
    , LevMarLecDif
    , LevMarBLecDer
    , LevMarBLecDif

      -- * Levenberg-Marquardt algorithms.
    , c'dlevmar_der
    , c'slevmar_der
    , c'dlevmar_dif
    , c'slevmar_dif
    , c'dlevmar_bc_der
    , c'slevmar_bc_der
    , c'dlevmar_bc_dif
    , c'slevmar_bc_dif
    , c'dlevmar_lec_der
    , c'slevmar_lec_der
    , c'dlevmar_lec_dif
    , c'slevmar_lec_dif
    , c'dlevmar_blec_der
    , c'slevmar_blec_der
    , c'dlevmar_blec_dif
    , c'slevmar_blec_dif

      -- * Jacobian verification
    , Errors
    , LevMarChkJac
    , c'dlevmar_chkjac
    , c'slevmar_chkjac

      -- * Utils
    , BestFitParameterIx

    , LevMarStddev
    , LevMarCorCoef
    , LevMarR2

    , Result

    , c'dlevmar_stddev
    , c'slevmar_stddev
    , c'dlevmar_corcoef
    , c'slevmar_corcoef
    , c'dlevmar_R2
    , c'slevmar_R2
    ) where


--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------

import Prelude           ( Num, Fractional, Double, Float, String )


{-# LINE 134 "Bindings/LevMar.hsc" #-}

import System.IO         ( IO )

import Foreign.C.Types   ( CInt

{-# LINE 139 "Bindings/LevMar.hsc" #-}
                               (..)

{-# LINE 141 "Bindings/LevMar.hsc" #-}
                         )

import Foreign.Ptr       ( Ptr, FunPtr, freeHaskellFunPtr )
import Control.Exception ( bracket )


--------------------------------------------------------------------------------
-- Version
--------------------------------------------------------------------------------

-- | The version of the C levmar library.
c'LM_VERSION :: String
c'LM_VERSION = "2.4 (April 2009)"
{-# LINE 154 "Bindings/LevMar.hsc" #-}


--------------------------------------------------------------------------------
-- Maximum sizes of arrays.
--------------------------------------------------------------------------------

-- | The maximum size of the options array.
c'LM_OPTS_SZ = 5
c'LM_OPTS_SZ :: (Num a) => a

{-# LINE 162 "Bindings/LevMar.hsc" #-}

-- | The size of the info array.
c'LM_INFO_SZ = 10
c'LM_INFO_SZ :: (Num a) => a

{-# LINE 165 "Bindings/LevMar.hsc" #-}


--------------------------------------------------------------------------------
-- Errors.
--------------------------------------------------------------------------------

c'LM_ERROR = -1
c'LM_ERROR :: (Num a) => a

{-# LINE 172 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_LAPACK_ERROR = -2
c'LM_ERROR_LAPACK_ERROR :: (Num a) => a

{-# LINE 173 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_NO_JACOBIAN = -3
c'LM_ERROR_NO_JACOBIAN :: (Num a) => a

{-# LINE 174 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_NO_BOX_CONSTRAINTS = -4
c'LM_ERROR_NO_BOX_CONSTRAINTS :: (Num a) => a

{-# LINE 175 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_FAILED_BOX_CHECK = -5
c'LM_ERROR_FAILED_BOX_CHECK :: (Num a) => a

{-# LINE 176 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_MEMORY_ALLOCATION_FAILURE = -6
c'LM_ERROR_MEMORY_ALLOCATION_FAILURE :: (Num a) => a

{-# LINE 177 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_CONSTRAINT_MATRIX_ROWS_GT_COLS = -7
c'LM_ERROR_CONSTRAINT_MATRIX_ROWS_GT_COLS :: (Num a) => a

{-# LINE 178 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_CONSTRAINT_MATRIX_NOT_FULL_ROW_RANK = -8
c'LM_ERROR_CONSTRAINT_MATRIX_NOT_FULL_ROW_RANK :: (Num a) => a

{-# LINE 179 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_TOO_FEW_MEASUREMENTS = -9
c'LM_ERROR_TOO_FEW_MEASUREMENTS :: (Num a) => a

{-# LINE 180 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_SINGULAR_MATRIX = -10
c'LM_ERROR_SINGULAR_MATRIX :: (Num a) => a

{-# LINE 181 "Bindings/LevMar.hsc" #-}
c'LM_ERROR_SUM_OF_SQUARES_NOT_FINITE = -11
c'LM_ERROR_SUM_OF_SQUARES_NOT_FINITE :: (Num a) => a

{-# LINE 182 "Bindings/LevMar.hsc" #-}


--------------------------------------------------------------------------------
-- Default values for minimization options.
--------------------------------------------------------------------------------

c'LM_INIT_MU = 1.000000e-03
c'LM_INIT_MU :: (Fractional a) => a

{-# LINE 189 "Bindings/LevMar.hsc" #-}
c'LM_STOP_THRESH = 1.000000e-17
c'LM_STOP_THRESH :: (Fractional a) => a

{-# LINE 190 "Bindings/LevMar.hsc" #-}
c'LM_DIFF_DELTA = 1.000000e-06
c'LM_DIFF_DELTA :: (Fractional a) => a

{-# LINE 191 "Bindings/LevMar.hsc" #-}


--------------------------------------------------------------------------------
-- Handy type synonyms
--------------------------------------------------------------------------------

type Parameters        = Ptr
type Measurements      = Ptr
type Options           = Ptr
type LowerBounds       = Ptr
type UpperBounds       = Ptr
type ConstraintsMatrix = Ptr
type ConstraintsVector = Ptr
type Weights           = Ptr
type Info              = Ptr
type Work              = Ptr
type Covar             = Ptr
type AData             = Ptr ()
type NrOfParameters    = CInt
type NrOfMeasurements  = CInt
type NrOfConstraints   = CInt
type MaxIterations     = CInt


--------------------------------------------------------------------------------
-- Model & Jacobian.
--------------------------------------------------------------------------------

-- | Functional relation describing measurements.
type Model r =  Parameters r
             -> Measurements r
             -> NrOfParameters
             -> NrOfMeasurements
             -> AData
             -> IO ()

type Jacobian a = Model a

foreign import ccall "wrapper" mkModel :: Model a -> IO (FunPtr (Model a))

mkJacobian :: Jacobian a -> IO (FunPtr (Jacobian a))
mkJacobian = mkModel

withModel :: Model a -> (FunPtr (Model a) -> IO b) -> IO b
withModel m = bracket (mkModel m) freeHaskellFunPtr

withJacobian :: Jacobian a -> (FunPtr (Jacobian a) -> IO b) -> IO b
withJacobian j = bracket (mkJacobian j) freeHaskellFunPtr


--------------------------------------------------------------------------------
-- Types of the Levenberg-Marquardt algorithms.
--------------------------------------------------------------------------------

type LevMarDer r =  FunPtr (Model r)
                 -> FunPtr (Jacobian r)
                 -> Parameters r
                 -> Measurements r
                 -> NrOfParameters
                 -> NrOfMeasurements
                 -> MaxIterations
                 -> Options r
                 -> Info r
                 -> Work r
                 -> Covar r
                 -> AData
                 -> IO CInt

type LevMarDif r =  FunPtr (Model r)
                 -> Parameters r
                 -> Measurements r
                 -> NrOfParameters
                 -> NrOfMeasurements
                 -> MaxIterations
                 -> Options r
                 -> Info r
                 -> Work r
                 -> Covar r
                 -> AData
                 -> IO CInt

type LevMarBCDer r =  FunPtr (Model r)
                   -> FunPtr (Jacobian r)
                   -> Parameters r
                   -> Measurements r
                   -> NrOfParameters
                   -> NrOfMeasurements
                   -> LowerBounds r
                   -> UpperBounds r
                   -> MaxIterations
                   -> Options r
                   -> Info r
                   -> Work r
                   -> Covar r
                   -> AData
                   -> IO CInt

type LevMarBCDif r =  FunPtr (Model r)
                   -> Parameters r
                   -> Measurements r
                   -> NrOfParameters
                   -> NrOfMeasurements
                   -> LowerBounds r
                   -> UpperBounds r
                   -> MaxIterations
                   -> Options r
                   -> Info r
                   -> Work r
                   -> Covar r
                   -> AData
                   -> IO CInt

type LevMarLecDer r =  FunPtr (Model r)
                    -> FunPtr (Jacobian r)
                    -> Parameters r
                    -> Measurements r
                    -> NrOfParameters
                    -> NrOfMeasurements
                    -> ConstraintsMatrix r
                    -> ConstraintsVector r
                    -> NrOfConstraints
                    -> MaxIterations
                    -> Options r
                    -> Info r
                    -> Work r
                    -> Covar r
                    -> AData
                    -> IO CInt

type LevMarLecDif r =  FunPtr (Model r)
                    -> Parameters r
                    -> Measurements r
                    -> NrOfParameters
                    -> NrOfMeasurements
                    -> ConstraintsMatrix r
                    -> ConstraintsVector r
                    -> NrOfConstraints
                    -> MaxIterations
                    -> Options r
                    -> Info r
                    -> Work r
                    -> Covar r
                    -> AData
                    -> IO CInt

type LevMarBLecDer r =  FunPtr (Model r)
                     -> FunPtr (Jacobian r)
                     -> Parameters r
                     -> Measurements r
                     -> NrOfParameters
                     -> NrOfMeasurements
                     -> LowerBounds r
                     -> UpperBounds r
                     -> ConstraintsMatrix r
                     -> ConstraintsVector r
                     -> NrOfConstraints
                     -> Weights r
                     -> MaxIterations
                     -> Options r
                     -> Info r
                     -> Work r
                     -> Covar r
                     -> AData
                     -> IO CInt

type LevMarBLecDif r =  FunPtr (Model r)
                     -> Parameters r
                     -> Measurements r
                     -> NrOfParameters
                     -> NrOfMeasurements
                     -> LowerBounds r
                     -> UpperBounds r
                     -> ConstraintsMatrix r
                     -> ConstraintsVector r
                     -> NrOfConstraints
                     -> Weights r
                     -> MaxIterations
                     -> Options r
                     -> Info r
                     -> Work r
                     -> Covar r
                     -> AData
                     -> IO CInt


--------------------------------------------------------------------------------
-- Levenberg-Marquardt algorithms.
--------------------------------------------------------------------------------

foreign import ccall "slevmar_der" c'slevmar_der
  :: LevMarDer Float
foreign import ccall "&slevmar_der" p'slevmar_der
  :: FunPtr (LevMarDer Float)

{-# LINE 381 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_der" c'dlevmar_der
  :: LevMarDer Double
foreign import ccall "&dlevmar_der" p'dlevmar_der
  :: FunPtr (LevMarDer Double)

{-# LINE 382 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_dif" c'slevmar_dif
  :: LevMarDif Float
foreign import ccall "&slevmar_dif" p'slevmar_dif
  :: FunPtr (LevMarDif Float)

{-# LINE 383 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_dif" c'dlevmar_dif
  :: LevMarDif Double
foreign import ccall "&dlevmar_dif" p'dlevmar_dif
  :: FunPtr (LevMarDif Double)

{-# LINE 384 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_bc_der" c'slevmar_bc_der
  :: LevMarBCDer Float
foreign import ccall "&slevmar_bc_der" p'slevmar_bc_der
  :: FunPtr (LevMarBCDer Float)

{-# LINE 385 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_bc_der" c'dlevmar_bc_der
  :: LevMarBCDer Double
foreign import ccall "&dlevmar_bc_der" p'dlevmar_bc_der
  :: FunPtr (LevMarBCDer Double)

{-# LINE 386 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_bc_dif" c'slevmar_bc_dif
  :: LevMarBCDif Float
foreign import ccall "&slevmar_bc_dif" p'slevmar_bc_dif
  :: FunPtr (LevMarBCDif Float)

{-# LINE 387 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_bc_dif" c'dlevmar_bc_dif
  :: LevMarBCDif Double
foreign import ccall "&dlevmar_bc_dif" p'dlevmar_bc_dif
  :: FunPtr (LevMarBCDif Double)

{-# LINE 388 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_lec_der" c'slevmar_lec_der
  :: LevMarLecDer Float
foreign import ccall "&slevmar_lec_der" p'slevmar_lec_der
  :: FunPtr (LevMarLecDer Float)

{-# LINE 389 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_lec_der" c'dlevmar_lec_der
  :: LevMarLecDer Double
foreign import ccall "&dlevmar_lec_der" p'dlevmar_lec_der
  :: FunPtr (LevMarLecDer Double)

{-# LINE 390 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_lec_dif" c'slevmar_lec_dif
  :: LevMarLecDif Float
foreign import ccall "&slevmar_lec_dif" p'slevmar_lec_dif
  :: FunPtr (LevMarLecDif Float)

{-# LINE 391 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_lec_dif" c'dlevmar_lec_dif
  :: LevMarLecDif Double
foreign import ccall "&dlevmar_lec_dif" p'dlevmar_lec_dif
  :: FunPtr (LevMarLecDif Double)

{-# LINE 392 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_blec_der" c'slevmar_blec_der
  :: LevMarBLecDer Float
foreign import ccall "&slevmar_blec_der" p'slevmar_blec_der
  :: FunPtr (LevMarBLecDer Float)

{-# LINE 393 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_blec_der" c'dlevmar_blec_der
  :: LevMarBLecDer Double
foreign import ccall "&dlevmar_blec_der" p'dlevmar_blec_der
  :: FunPtr (LevMarBLecDer Double)

{-# LINE 394 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_blec_dif" c'slevmar_blec_dif
  :: LevMarBLecDif Float
foreign import ccall "&slevmar_blec_dif" p'slevmar_blec_dif
  :: FunPtr (LevMarBLecDif Float)

{-# LINE 395 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_blec_dif" c'dlevmar_blec_dif
  :: LevMarBLecDif Double
foreign import ccall "&dlevmar_blec_dif" p'dlevmar_blec_dif
  :: FunPtr (LevMarBLecDif Double)

{-# LINE 396 "Bindings/LevMar.hsc" #-}


--------------------------------------------------------------------------------
-- Jacobian verification
--------------------------------------------------------------------------------

type Errors = Ptr

type LevMarChkJac r =  FunPtr (Model r)
                    -> FunPtr (Jacobian r)
                    -> Parameters r
                    -> NrOfParameters
                    -> NrOfMeasurements
                    -> AData
                    -> Errors r
                    -> IO ()

foreign import ccall "dlevmar_chkjac" c'dlevmar_chkjac
  :: LevMarChkJac Double
foreign import ccall "&dlevmar_chkjac" p'dlevmar_chkjac
  :: FunPtr (LevMarChkJac Double)

{-# LINE 414 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_chkjac" c'slevmar_chkjac
  :: LevMarChkJac Float
foreign import ccall "&slevmar_chkjac" p'slevmar_chkjac
  :: FunPtr (LevMarChkJac Float)

{-# LINE 415 "Bindings/LevMar.hsc" #-}


--------------------------------------------------------------------------------
-- Utils
--------------------------------------------------------------------------------

type BestFitParameterIx = CInt

-- | Standard deviation.
type LevMarStddev r =  Covar r
                    -> NrOfParameters
                    -> BestFitParameterIx
                    -> IO r

-- | Pearson's correlation coefficient for best-fit parameters.
type LevMarCorCoef r =  Covar r
                     -> NrOfParameters
                     -> BestFitParameterIx
                     -> BestFitParameterIx
                     -> IO r

-- | Coefficient of determination (R2).
type LevMarR2 r =  FunPtr (Model r)
                -> Parameters r
                -> Measurements r
                -> NrOfParameters
                -> NrOfMeasurements
                -> AData
                -> Result r
                -> IO CInt

type Result = Ptr

foreign import ccall "dlevmar_stddev" c'dlevmar_stddev
  :: LevMarStddev Double
foreign import ccall "&dlevmar_stddev" p'dlevmar_stddev
  :: FunPtr (LevMarStddev Double)

{-# LINE 449 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_stddev" c'slevmar_stddev
  :: LevMarStddev Float
foreign import ccall "&slevmar_stddev" p'slevmar_stddev
  :: FunPtr (LevMarStddev Float)

{-# LINE 450 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_corcoef" c'dlevmar_corcoef
  :: LevMarCorCoef Double
foreign import ccall "&dlevmar_corcoef" p'dlevmar_corcoef
  :: FunPtr (LevMarCorCoef Double)

{-# LINE 451 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_corcoef" c'slevmar_corcoef
  :: LevMarCorCoef Float
foreign import ccall "&slevmar_corcoef" p'slevmar_corcoef
  :: FunPtr (LevMarCorCoef Float)

{-# LINE 452 "Bindings/LevMar.hsc" #-}
foreign import ccall "dlevmar_R2" c'dlevmar_R2
  :: LevMarR2 Double
foreign import ccall "&dlevmar_R2" p'dlevmar_R2
  :: FunPtr (LevMarR2 Double)

{-# LINE 453 "Bindings/LevMar.hsc" #-}
foreign import ccall "slevmar_R2" c'slevmar_R2
  :: LevMarR2 Float
foreign import ccall "&slevmar_R2" p'slevmar_R2
  :: FunPtr (LevMarR2 Float)

{-# LINE 454 "Bindings/LevMar.hsc" #-}