--------------------------------------------------------------------------------
-- |
-- Module      :  Bindings.LevMar.CurryFriendly
-- Copyright   :  (c) 2009 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
--
-- Curry friendly variants of the Levenberg-Marquardt algorithms in 'Bindings.LevMar'.
--
-- (This module re-exports all the necessary types and function from
-- 'Bindings.LevMar', so there's no need to import that module when
-- you want to use this one.)
--
--------------------------------------------------------------------------------

module Bindings.LevMar.CurryFriendly
    ( LMA_C._LM_VERSION

      -- * Maximum sizes of arrays.
    , LMA_C._LM_OPTS_SZ
    , LMA_C._LM_INFO_SZ

      -- * Errors
    , LMA_C._LM_ERROR
    , LMA_C._LM_ERROR_LAPACK_ERROR
    , LMA_C._LM_ERROR_NO_JACOBIAN
    , LMA_C._LM_ERROR_NO_BOX_CONSTRAINTS
    , LMA_C._LM_ERROR_FAILED_BOX_CHECK
    , LMA_C._LM_ERROR_MEMORY_ALLOCATION_FAILURE
    , LMA_C._LM_ERROR_CONSTRAINT_MATRIX_ROWS_GT_COLS
    , LMA_C._LM_ERROR_CONSTRAINT_MATRIX_NOT_FULL_ROW_RANK
    , LMA_C._LM_ERROR_TOO_FEW_MEASUREMENTS
    , LMA_C._LM_ERROR_SINGULAR_MATRIX
    , LMA_C._LM_ERROR_SUM_OF_SQUARES_NOT_FINITE

      -- * Default values for options.
    , LMA_C._LM_INIT_MU
    , LMA_C._LM_STOP_THRESH
    , LMA_C._LM_DIFF_DELTA

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

    -- * Model & Jacobian
    , LMA_C.Model
    , LMA_C.Jacobian

    , LMA_C.withModel
    , LMA_C.withJacobian

      -- * Handy type synonyms used in the curry friendly types.
    , BoxConstraints
    , LinearConstraints

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

      -- * Curry friendly variants of the Levenberg-Marquardt algorithms in 'Bindings.Levmar'.
    , dlevmar_der
    , slevmar_der
    , dlevmar_dif
    , slevmar_dif
    , dlevmar_bc_der
    , slevmar_bc_der
    , dlevmar_bc_dif
    , slevmar_bc_dif
    , dlevmar_lec_der
    , slevmar_lec_der
    , dlevmar_lec_dif
    , slevmar_lec_dif
    , dlevmar_blec_der
    , slevmar_blec_der
    , dlevmar_blec_dif
    , slevmar_blec_dif

      -- * Jacobian verification
    , LMA_C.Errors
    , LMA_C.LevMarChkJac
    , LMA_C.dlevmar_chkjac
    , LMA_C.slevmar_chkjac

      -- * Utils
    , LMA_C.BestFitParameterIx

    , LMA_C.LevMarStddev
    , LMA_C.LevMarCorCoef
    , LMA_C.LevMarR2

    , LMA_C.Result

    , LMA_C.dlevmar_stddev
    , LMA_C.slevmar_stddev
    , LMA_C.dlevmar_corcoef
    , LMA_C.slevmar_corcoef
    , LMA_C.dlevmar_R2
    , LMA_C.slevmar_R2
    ) where


import Foreign.C.Types ( CFloat, CDouble )
import Foreign.Ptr     ( FunPtr )

import qualified Bindings.LevMar as LMA_C


--------------------------------------------------------------------------------
-- Handy type synonyms used in the curry friendly types.
--------------------------------------------------------------------------------

type BoxConstraints    cr a =  LMA_C.LowerBounds cr
                            -> LMA_C.UpperBounds cr
                            -> a

type LinearConstraints cr a =  LMA_C.ConstraintsMatrix cr
                            -> LMA_C.ConstraintsVector cr
                            -> LMA_C.NrOfConstraints
                            -> a


--------------------------------------------------------------------------------
-- Curry friendly types of the Levenberg-Marquardt algorithms.
--------------------------------------------------------------------------------

type LevMarDif     cr = LMA_C.LevMarDif cr
type LevMarDer     cr = FunPtr (LMA_C.Jacobian cr) -> LevMarDif cr
type LevMarBCDif   cr = BoxConstraints cr (LevMarDif cr)
type LevMarBCDer   cr = BoxConstraints cr (LevMarDer cr)
type LevMarLecDif  cr = LinearConstraints cr (LevMarDif cr)
type LevMarLecDer  cr = LinearConstraints cr (LevMarDer cr)
type LevMarBLecDif cr = BoxConstraints cr (LinearConstraints cr (LMA_C.Weights cr -> (LevMarDif cr)))
type LevMarBLecDer cr = BoxConstraints cr (LinearConstraints cr (LMA_C.Weights cr -> (LevMarDer cr)))


--------------------------------------------------------------------------------
-- Reordering arguments to create curry friendly variants.
--------------------------------------------------------------------------------

mk_levmar_der :: LMA_C.LevMarDer cr -> LevMarDer cr
mk_levmar_der lma j f
            = lma f j

mk_levmar_bc_dif :: LMA_C.LevMarBCDif cr -> LevMarBCDif cr
mk_levmar_bc_dif lma lb ub f p x m n
               = lma f p x m n lb ub

mk_levmar_bc_der :: LMA_C.LevMarBCDer cr -> LevMarBCDer cr
mk_levmar_bc_der lma lb ub j f p x m n
               = lma f j p x m n lb ub

mk_levmar_lec_dif :: LMA_C.LevMarLecDif cr -> LevMarLecDif cr
mk_levmar_lec_dif lma a b k f p x m n
                = lma f p x m n a b k

mk_levmar_lec_der :: LMA_C.LevMarLecDer cr -> LevMarLecDer cr
mk_levmar_lec_der lma a b k j f p x m n
                = lma f j p x m n a b k

mk_levmar_blec_dif :: LMA_C.LevMarBLecDif cr -> LevMarBLecDif cr
mk_levmar_blec_dif lma lb ub a b k wghts f p x m n
                 = lma f p x m n lb ub a b k wghts

mk_levmar_blec_der :: LMA_C.LevMarBLecDer cr -> LevMarBLecDer cr
mk_levmar_blec_der lma lb ub a b k wghts j f p x m n
                 = lma f j p x m n lb ub a b k wghts


--------------------------------------------------------------------------------
-- Curry friendly variants of the Levenberg-Marquardt algorithms in 'Bindings.Levmar'.
--------------------------------------------------------------------------------

slevmar_dif :: LevMarDif CFloat
slevmar_dif = LMA_C.slevmar_dif

dlevmar_dif :: LevMarDif CDouble
dlevmar_dif = LMA_C.dlevmar_dif

slevmar_der :: LevMarDer CFloat
slevmar_der = mk_levmar_der LMA_C.slevmar_der

dlevmar_der :: LevMarDer CDouble
dlevmar_der = mk_levmar_der LMA_C.dlevmar_der

slevmar_bc_dif :: LevMarBCDif CFloat
slevmar_bc_dif = mk_levmar_bc_dif LMA_C.slevmar_bc_dif

dlevmar_bc_dif :: LevMarBCDif CDouble
dlevmar_bc_dif = mk_levmar_bc_dif LMA_C.dlevmar_bc_dif

slevmar_bc_der :: LevMarBCDer CFloat
slevmar_bc_der = mk_levmar_bc_der LMA_C.slevmar_bc_der

dlevmar_bc_der :: LevMarBCDer CDouble
dlevmar_bc_der = mk_levmar_bc_der LMA_C.dlevmar_bc_der

slevmar_lec_dif :: LevMarLecDif CFloat
slevmar_lec_dif = mk_levmar_lec_dif LMA_C.slevmar_lec_dif

dlevmar_lec_dif :: LevMarLecDif CDouble
dlevmar_lec_dif = mk_levmar_lec_dif LMA_C.dlevmar_lec_dif

slevmar_lec_der :: LevMarLecDer CFloat
slevmar_lec_der = mk_levmar_lec_der LMA_C.slevmar_lec_der

dlevmar_lec_der :: LevMarLecDer CDouble
dlevmar_lec_der = mk_levmar_lec_der LMA_C.dlevmar_lec_der

slevmar_blec_dif :: LevMarBLecDif CFloat
slevmar_blec_dif = mk_levmar_blec_dif LMA_C.slevmar_blec_dif

dlevmar_blec_dif :: LevMarBLecDif CDouble
dlevmar_blec_dif = mk_levmar_blec_dif LMA_C.dlevmar_blec_dif

slevmar_blec_der :: LevMarBLecDer CFloat
slevmar_blec_der = mk_levmar_blec_der LMA_C.slevmar_blec_der

dlevmar_blec_der :: LevMarBLecDer CDouble
dlevmar_blec_der = mk_levmar_blec_der LMA_C.dlevmar_blec_der


-- The End ---------------------------------------------------------------------