Forwarded on behalf of Sebastian Sturm:
Dear all,
I have been trying to use gsll for some numerical minimization. Allocating the multi-dimensional-root-solver-fdf with scalarsp set to false, I understand that I should provide functions f, df and fdf which accept (pointers to) foreign-arrays (some point x in configuration space, some output vector f(x) and the corresponding Jacobian matrix J(x)) and store the corresponding results within these arrays. Being a complete Lisp newbie, I've taken a ballistic approach to optimization by liberally scattering type declarations and (the double-float )'s throughout my code.
Still, if I use grid:gref to access the given arrays, my functions have to do a lot of consing and, as a result, take a long time to complete. If I replace the grid:gref calls by (aref )'s acting on lisp arrays that have previously been set to (cl-array the-foreign-array), consing is eliminated (using (speed 3) (safety 0) (debug 0)), provided that I explicitly generate the foreign-arrays x, f(x) and J which are then passed on to f and df. Passing these optimized functions to multi-dimensional-root-solver-fdf, however, produces a crash (using speed 3 safety 0 debug 0) or an error message (speed 0 safety 3 debug 3) indicating that the cl-array slot of the function arguments is nil. It seems to me that this is default behaviour for arrays created externally by libgsl. Is this true, and if yes, is there a way to circumvent this? Or am I simply misusing grid:gref? I have attached a fairly minimal example minimization-issue.lisp. Compiling this using sbcl 1.0.43 (on Mac OS X) yields the following output:
"using grid:gref" Evaluation took: 0.003 seconds of real time 0.003419 seconds of total run time (0.003216 user, 0.000203 system) 100.00% CPU 6,943,409 processor cycles 286,496 bytes consed
#m(-0.5397677311665408d0 -1.0671897833207353d0 -1.3289868354749306d0 -1.4592646132527087d0 -1.4992646132527088d0 -1.4592646132527087d0 -1.328986835474931d0 -1.0671897833207358d0 -0.5397677311665405d0) "using aref" Evaluation took: 0.000 seconds of real time 0.000010 seconds of total run time (0.000009 user, 0.000001 system) 100.00% CPU 15,158 processor cycles 0 bytes consed
#m(-0.5397677311665408d0 -1.0671897833207353d0 -1.3289868354749306d0 -1.4592646132527087d0 -1.4992646132527088d0 -1.4592646132527087d0 -1.328986835474931d0 -1.0671897833207358d0 -0.5397677311665405d0)
Best regards, Sebastian Sturm
Typically, if you get a nil from cl-array, it means you're either on an implementation not supported by static-vectors (however you're on SBCL, which is supported), or the array was made outside of the grid:make-foreign-array function (or calls equivalent to that). So, for example, when GSL (or any foreign code) makes an array, it will not have the CL equivalent defined. That's a limitation of basically all the CL implementations. The GSL minimization function creates the array to pass to the function needing minimization, so you're out of luck there.
Why not just use foreign arrays and grid:gref (instead of CL arrays and aref) everywhere? You're not using any of the CL array functions; there's little reason to convert all arrays to CL on every iteration. Actually, now that I look at it, it seems the array you cons every iteration is just of length 2; wouldn't it be easier and faster to just use two scalars? Though truthfully, I don't think CL arrays should be that slow. I'm really surprised there's any speed difference.
As a side point, in your unusable-but-fast-force-function, you make two arrays in the let binding of cl-output and cl-zv which you then immediately throw away upon rebinding to the outputs of cl-array. Though this won't work anyway as I've explained above.
Liam
On Fri, Oct 8, 2010 at 11:55 AM, Liam Healy lhealy@common-lisp.net wrote:
Forwarded on behalf of Sebastian Sturm:
Dear all,
I have been trying to use gsll for some numerical minimization. Allocating the multi-dimensional-root-solver-fdf with scalarsp set to false, I understand that I should provide functions f, df and fdf which accept (pointers to) foreign-arrays (some point x in configuration space, some output vector f(x) and the corresponding Jacobian matrix J(x)) and store the corresponding results within these arrays. Being a complete Lisp newbie, I've taken a ballistic approach to optimization by liberally scattering type declarations and (the double-float )'s throughout my code.
Still, if I use grid:gref to access the given arrays, my functions have to do a lot of consing and, as a result, take a long time to complete. If I replace the grid:gref calls by (aref )'s acting on lisp arrays that have previously been set to (cl-array the-foreign-array), consing is eliminated (using (speed 3) (safety 0) (debug 0)), provided that I explicitly generate the foreign-arrays x, f(x) and J which are then passed on to f and df. Passing these optimized functions to multi-dimensional-root-solver-fdf, however, produces a crash (using speed 3 safety 0 debug 0) or an error message (speed 0 safety 3 debug 3) indicating that the cl-array slot of the function arguments is nil. It seems to me that this is default behaviour for arrays created externally by libgsl. Is this true, and if yes, is there a way to circumvent this? Or am I simply misusing grid:gref? I have attached a fairly minimal example minimization-issue.lisp. Compiling this using sbcl 1.0.43 (on Mac OS X) yields the following output:
"using grid:gref" Evaluation took: 0.003 seconds of real time 0.003419 seconds of total run time (0.003216 user, 0.000203 system) 100.00% CPU 6,943,409 processor cycles 286,496 bytes consed
#m(-0.5397677311665408d0 -1.0671897833207353d0 -1.3289868354749306d0 -1.4592646132527087d0 -1.4992646132527088d0 -1.4592646132527087d0 -1.328986835474931d0 -1.0671897833207358d0 -0.5397677311665405d0) "using aref" Evaluation took: 0.000 seconds of real time 0.000010 seconds of total run time (0.000009 user, 0.000001 system) 100.00% CPU 15,158 processor cycles 0 bytes consed
#m(-0.5397677311665408d0 -1.0671897833207353d0 -1.3289868354749306d0 -1.4592646132527087d0 -1.4992646132527088d0 -1.4592646132527087d0 -1.328986835474931d0 -1.0671897833207358d0 -0.5397677311665405d0)
Best regards, Sebastian Sturm