[Haskell-cafe] ANNOUNCE: A Levenberg-Marquardt implementation
Bas van Dijk
v.dijk.bas at gmail.com
Thu Sep 10 09:21:40 EDT 2009
Dear all,
We like to announce the release of a Haskell binding to Manolis
Lourakis's C levmar library at:
http://www.ics.forth.gr/~lourakis/levmar/
This library implements the Levenberg-Marquardt algorithm which is an
iterative technique that finds a local minimum of a function that is
expressed as the sum of squares of nonlinear functions. It has become
a standard technique for nonlinear least-squares problems and can be
thought of as a combination of steepest descent and the Gauss-Newton
method. When the current solution is far from the correct one, the
algorithm behaves like a steepest descent method: slow, but guaranteed
to converge. When the current solution is close to the correct
solution, it becomes a Gauss-Newton method.
Our binding consists of three packages:
* http://hackage.haskell.org/package/bindings-levmar-0.1
A low-level wrapper around the C library. Note that the C library is
lightly patched so that the functions can be safely called inside
unsafePerformIO. The patched C library is bundled with this package.
* http://hackage.haskell.org/package/levmar-0.1
A high-level wrapper around bindings-levmar. It provides a more
familiar Haskell interface. For example, instead of passing a 'Ptr r'
to the levmar function you can pass a [r]. levmar also provides some
higher-level modules that use some type-level programming to add more
type safety.
* http://hackage.haskell.org/package/levmar-chart-0.1
Finally levmar-chart is a small package for quickly viewing the output
of levmar in a chart.
Unfortunately the documentation of these libraries is not available
from hackage because bindings-levmar won't configure because of a
missing dependency (lapack) on the hackage server. Instead I put the
documentation at the following places:
http://code.haskell.org/bindings-levmar/bindings-levmar-0.1/doc/html/bindings-levmar/index.html
http://code.haskell.org/levmar/levmar-0.1/doc/html/levmar/index.html
Here follows a quick example:
Suppose we have the following model functions:
constant :: Num r => Model N1 r r
linear :: Num r => Model N2 r r
quadratic :: Num r => Model N3 r r
cubic :: Num r => Model N4 r r
constant a _ = a
linear b a x = b * x + constant a x
quadratic c b a x = c * x*x + linear b a x
cubic d c b a x = d * x*x*x + quadratic c b a x
And the jacobians:
constantJacob :: Num r => Jacobian N1 r r
linearJacob :: Num r => Jacobian N2 r r
quadraticJacob :: Num r => Jacobian N3 r r
cubicJacob :: Num r => Jacobian N4 r r
constantJacob _ _ = 1 ::: Nil
linearJacob _ a x = x ::: constantJacob a x
quadraticJacob _ b a x = x*x ::: linearJacob b a x
cubicJacob _ c b a x = x*x*x ::: quadraticJacob c b a x
Now assume we have some sample data. If you call levmar like this:
levmar cubic
(Just cubicJacob)
(-0.05 ::: 0.5 ::: -12 ::: 10 ::: Nil)
samples
1000
defaultOpts
Nothing
Nothing
noLinearConstraints
Nothing
You get the following fit (using levmar-chart):
http://code.haskell.org/~roelvandijk/code/levmar-chart/cubicFit.png
Note that levmar contains a demo with a lot more examples:
http://code.haskell.org/levmar/Demo.hs
Happy fitting,
Roel and Bas van Dijk
More information about the Haskell-Cafe
mailing list