ANNOUNCE: A Levenberg-Marquardt implementation

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/binding... 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

Our binding consists of three packages:
Which were the changes you needed to do to the library code? I believe this is going to cause you two problems: maintenance (as you can't always be sure the patched version didn't introduce a bug) and license (as levmar is GPL. You can't distribute it linked to non GPL code).
Cool. Don't you think the type level natural numbers deserve their own package?
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.
I'll try to write you a patch to solve that after I study better your code. Best, Maurício

Which were the changes you needed to do to the library code? I believe this is going to cause you two problems: maintenance (as you can't always be sure the patched version didn't introduce a bug) and license (as levmar is GPL. You can't distribute it linked to non GPL code). The C library prints error messages to stderr. We can check some things before calling the C functions to ensure that some erroneous conditions do not occur, but we can't prevent all cases. Since the functions already returned a generic error code we disabled all printing to stderr and created an enumeration of error codes. In Haskell we wrap this error code in a nice data type so if something goes wrong you'll know why. We have send a patch with these changes to the author and we are waiting for a reply.
The license issue is indeed a problem. Either your (linked + distributed) code must be GPL or you must acquire a different (commercial) license from the author of the C library. The benefits of the library we have chosen for this binding is that it is small, just a few .c files, and it has almost no dependencies. If anyone knows of any other implementations of Levenberg-Marquardt that are also easy to bind then we would certainly like to hear it. If the feature set is not to different we might be able to provide a common interface.
Cool.
Don't you think the type level natural numbers deserve their own package? Perhaps in the future. For this release we just focused on levmar. We might also use another package for type level programming if it suits our needs.
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.
I'll try to write you a patch to solve that after I study better your code. Lapack has to be installed on the hackage server in order for the package to build. Another option is to temporarily remove the dependency on lapack from the cabal file. The package would probably build, you just wouldn't be able to link against it. But the downside is that someone won't be able to cabal install it without first modifying the .cabal file. That is unacceptable in my opinion.
Roel

The C library prints error messages to stderr. (...)
Attached is the patch to the C levmar library.
Thanks for the file.
The license issue is indeed a problem. Either your (linked + distributed) code must be GPL or you must acquire a different (commercial) license from the author of the C library.
I don't think the GPL is itself a problem, I just meant that by packaging levmar with your bindings-levmar you probably have to GPL bindings-levmar itself. Although, since you used BSD, I don't think anyone will waste time bothering you about that.
Lapack has to be installed on the hackage server in order for the package to build. Another option is to temporarily remove the dependency on lapack from the cabal file. (...). But the downside is that someone won't be able to cabal install it without first modifying the .cabal file. That is unacceptable in my opinion.
Yes, this is difficult to solve... I've even asked that some nice, trusted C libraries could be installed on hackage so that we could bind to them. Maybe this can be accepted in the future if the idea of having many good quality bindings-* packages grow up. In the mean time, we have a two-sided problem: if we release a package with linking options removed we have to edit cabal file, which is unacceptable in my opinion too; and if we do not, all bindings-*, as well as all packages built on them, will be marked with "Build failure" on hackage and lack documentation, which is also unnaceptable... The good thing is that this problem can be isolated on bindings-* packages. If it is solved, it is solved once and for all. So far, my solution has been this: * to leave a 'pkg-config' line in bindings-* cabal file. This way, your package can be used properly as long as your installed library has pkg-config configuration, and this is easy to add (even for your favorite distribution library package) if it doesn't. * to comment that pkg-config line, so that hackage will build your package. Users can just add something like 'pkgconfig-depends: levmar' to their own packages. Though I have no reason to claim this is the best solution. Also: bindings-common has some macros that could easy your job. You could have used, for instance: #bindings_frac LM_INIT_MU #bindings_frac LM_STOP_THRESH #bindings_frac LM_DIFF_DELTA Although this would add a dependency, so I don't know if it's worth. Best, Maurício

В сообщении от Четверг 10 сентября 2009 17:21:40 автор Bas van Dijk написал:
We like to announce the release of a Haskell binding to Manolis Lourakis's C levmar library
bindings-levmar fails to configure on debian testing with following message: $ cabal install bindings-levmar Resolving dependencies... Configuring bindings-levmar-0.1... cabal: The pkg-config package lapack is required but it could not be found. cabal: Error: some packages failed to install: bindings-levmar-0.1 failed during the configure step. The exception was: exit: ExitFailure 1 Following lapack packages are installed
ii liblapack-dev 3.2.1-1 ii liblapack3gf 3.2.1-1
It seems that debian doesn't provide file `lapack.pc'. So pkg-config fails.

Khudyakov Alexey
В сообщении от Четверг 10 сентября 2009 17:21:40 автор Bas van Dijk написал:
We like to announce the release of a Haskell binding to Manolis Lourakis's C levmar library
bindings-levmar fails to configure on debian testing with following message:
$ cabal install bindings-levmar Resolving dependencies... Configuring bindings-levmar-0.1... cabal: The pkg-config package lapack is required but it could not be found. cabal: Error: some packages failed to install: bindings-levmar-0.1 failed during the configure step. The exception was: exit: ExitFailure 1
Following lapack packages are installed
ii liblapack-dev 3.2.1-1 ii liblapack3gf 3.2.1-1
It seems that debian doesn't provide file `lapack.pc'. So pkg-config fails.
I believe most of the linux distributions do not have `lapack.pc', if you install certain implementation of lapack like the one provided by netlib.org, or the one with `ATLAS', or the one provided by intel mkl. So, using such pkgconfig file is rather useless. A configure system like the one used in `hmatrix' should be used to actually adapt various kinds of systems. - jxy -- c/* __o/* <\ * (__ */\ <

В сообщении от Суббота 12 сентября 2009 18:46:28 автор Xiao-Yong Jin написал:
I believe most of the linux distributions do not have `lapack.pc', if you install certain implementation of lapack like the one provided by netlib.org, or the one with `ATLAS', or the one provided by intel mkl. So, using such pkgconfig file is rather useless. A configure system like the one used in `hmatrix' should be used to actually adapt various kinds of systems.
It fails to build on Fedora too. I think bindings-levmar package is unbuildable on most linux distributions. If pkgconfig-depends lines is removed from cabal file it builds fine.

On Mon, Sep 14, 2009 at 10:50 AM, Khudyakov Alexey
В сообщении от Понедельник 14 сентября 2009 12:41:29 вы написали:
If pkgconfig-depends lines is removed from cabal file it builds fine.
But any program which uses levmar fails to link
Would adding extra-libraries: lapack to the cabal file instead of pkgconfig-depends: lapack be a better solution?

2009/9/14 Khudyakov Alexey
В сообщении от Понедельник 14 сентября 2009 12:59:24 автор Roel van Dijk написал:
Would adding extra-libraries: lapack to the cabal file instead of pkgconfig-depends: lapack be a better solution?
Yes. It works this way. Tested in debian and old fedora
Thank you for testing. I have just released bindings-levmar-0.1.0.1 on hackage. It simply replaces pkgconfig-depends with extra-libraries. I hope this solves the installation problems. http://hackage.haskell.org/package/bindings-levmar-0.1.0.1

В сообщении от 14 сентября 2009 13:28:33 автор Roel van Dijk написал:
Thank you for testing. I have just released bindings-levmar-0.1.0.1 on hackage. It simply replaces pkgconfig-depends with extra-libraries. I hope this solves the installation problems.
Yes. Now it installs fine.

Yes. It works this way. Tested in debian and old fedora
Thank you for testing. I have just released bindings-levmar-0.1.0.1 on hackage. It simply replaces pkgconfig-depends with extra-libraries. I hope this solves the installation problems.
Debian maintainer was willing to add pkg-config to lapack package: http://lists.alioth.debian.org/pipermail/pkg-scicomp-devel/2009-September/00... However, he and also Tollef (pkg-config maintainer) believe it's a better idea to add it to upstream package: http://article.gmane.org/gmane.comp.package-management.pkg-config/346 Unless you think that extra-libraries is a good long term solution, I'll still investigate on how to add pkg-config generation to configuration scripts and try to send a sugestion with a patch to maintainers of libraries wrapped in bindings-*. Although I don't know exactly how that patch should exactly be... Best, Maurício

Maurício CA
Yes. It works this way. Tested in debian and old fedora
Thank you for testing. I have just released bindings-levmar-0.1.0.1 on hackage. It simply replaces pkgconfig-depends with extra-libraries. I hope this solves the installation problems.
Debian maintainer was willing to add pkg-config to lapack package:
http://lists.alioth.debian.org/pipermail/pkg-scicomp-devel/2009-September/00...
However, he and also Tollef (pkg-config maintainer) believe it's a better idea to add it to upstream package:
http://article.gmane.org/gmane.comp.package-management.pkg-config/346
Unless you think that extra-libraries is a good long term solution, I'll still investigate on how to add pkg-config generation to configuration scripts and try to send a sugestion with a patch to maintainers of libraries wrapped in bindings-*. Although I don't know exactly how that patch should exactly be...
It is not practical to use pkg-config for such libraries. After you persuade the reference code[1] of lapack to use pkg-config, are you going to make ATLAS[2] do it also? And what about Intel's mkl[3]? Or even lapack bindings provided by Nvidia's CUDA[4]? [1] http://www.netlib.org/lapack/ [2] http://math-atlas.sourceforge.net/ [3] http://software.intel.com/en-us/intel-mkl/ [4] http://www.nvidia.com/object/cuda_home.html One can install them side by side, but for performance's sake, one really wants to link a particular library/binary to the most useful one. I know it's hard to include every possibilities. But I prefer some configuration switch that I can tune when building the library. That's been said, it is still your package. And people can always change the build scripts for their own needs. Best, Xiao-Yong -- c/* __o/* <\ * (__ */\ <

Unless you think that extra-libraries is a good long term solution, I'll still investigate on how to add pkg-config generation to configuration scripts and try to send a sugestion with a patch to maintainers of libraries wrapped in bindings-*.
It is not practical to use pkg-config for such libraries. After you persuade the reference code[1] of lapack to use pkg-config, are you going to make ATLAS[2] do it also? And what about Intel's mkl[3]? Or even lapack bindings provided by Nvidia's CUDA[4]?
Sure. But only for packages we have direct Haskell bindings to. You only need pkg-config available for the libraries you directly need for a cabal package. For complicated dependencies, just rely on your OS distribution (or Haskell Platform etc.).
I know it's hard to include every possibilities. But I prefer some configuration switch that I can tune when building the library.
The idea is just to provide a default, working configuration. Anyway, I imagine this tunning should be done in a way that is transparent to a cabal package.
That's been said, it is still your package. And people can always change the build scripts for their own needs.
Not actually! I didn't work on bindings-levmar. I'm just the guy who started the idea of having low level bindings packages as basis for higher level bindings (so that this kind of problem can be solved at the same time for many, say, levmar high level bindings). That's why I would like to help acchieving good general guides for easy building. Wrapping of levmar is entirely van Dijk brothers' work. http://hackage.haskell.org/package/bindings-common Best, Maurício

Maurício CA
That's been said, it is still your package. And people can always change the build scripts for their own needs.
Not actually! I didn't work on bindings-levmar. I'm just the guy who started the idea of having low level bindings packages as basis for higher level bindings (so that this kind of problem can be solved at the same time for many, say, levmar high level bindings). That's why I would like to help acchieving good general guides for easy building. Wrapping of levmar is entirely van Dijk brothers' work.
Sorry, I didn't mean that. I was just trying to say that it might be wiser to put in a configure script like most of the open source software do. It does not need to be very complicated, because usually people know what they are doing when they want to link against different optimized libraries. The one[1] provided by hmatrix[2] is sufficient and easy to use for most of the purposes. [1] http://perception.inf.um.es/cgi-bin/darcsweb.cgi?r=hmatrix;a=headblob;f=/con... [2] http://www.hmatrix.googlepages.com/ In the case of hmatrix, it is good that you only need to run $ cabal install hmatrix -fmkl to build it against Intel mkl instead of the default BLAS/LAPACK. And you can also add other shared libraries to link against as a command line switch when you run `cabal install'. I just don't see the problem with bindings-levmar. Because compared with bindings-levmar, hmatrix actually needs GSL, BLAS and LAPACK, but it builds fine on hackage and the documents[3] are very well built. [3] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hmatrix Just my 2 cents. Xiao-Yong -- c/* __o/* <\ * (__ */\ <
participants (5)
-
Bas van Dijk
-
Khudyakov Alexey
-
Maurício CA
-
Roel van Dijk
-
Xiao-Yong Jin