Skip to content

Instantly share code, notes, and snippets.

@nh2
Created July 14, 2016 11:54
Show Gist options
  • Save nh2/bd5983ff692aaf50c690813ccb4bda07 to your computer and use it in GitHub Desktop.
Save nh2/bd5983ff692aaf50c690813ccb4bda07 to your computer and use it in GitHub Desktop.
Example on how to use the levmar Haskell package for the Levenberg–Marquardt optimisation algorithm
-- Example made with levmar-1.2.1.5
{-# LANGUAGE ViewPatterns #-}
import qualified Data.Vector.Storable as V
import Numeric.LevMar
-- | Function over X with 1 parameter (a); we want to find
-- the `a` that best fits a set of
fun a x = sin (a*x)
-- `levmar` assumes that you have a pre-chosen set of X-values
-- at which your "samples" (observations to which we want to fit
-- our function) lie.
-- We generate this set of X-values here, called `xs`.
-- These X-values are never given to `levmar` explicitly;
-- instead we give it two things:
-- A) the observed Y-values corresponding to the X-values (these are called "samples")
-- B) a function which, given a guess for the parameters (just `a` in our case),
-- computes the corresponding Y-values at the X-values.
xs :: [Double]
xs = [0.0, 0.1 .. 4.0]
true_a = 3
result = levmar
(\((V.toList -> [a])) -> V.fromList [ fun a x | x <- xs]) -- Function (see (B) above)
Nothing -- We don't want to numerically calculate the derivative of the objective function
(V.fromList [2.5]) -- Initial guess for `a`
(V.fromList [sin (true_a*x) | x <- xs]) -- Observed sambles (see (A) above)
50 -- Max iterations
defaultOpts -- Default optimisation options
(Constraints Nothing Nothing Nothing Nothing) -- We're giving no box constraints
main :: IO ()
main = do
putStrLn "Result:"
print result
let Right (V.toList -> [optimised_a],_,_) = result
putStrLn $ "Optimised parameter (should be close to true parameter, which is " ++ show true_a ++ ")"
print optimised_a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment