Liam,
Sorry for being obtuse, but I am having trouble transfering the permutation array from one letm to another using either (setf (data or (setf (maref... . The error is
There is no primary method for the generic function #<STANDARD-GENERIC-FUNCTION (SETF MAREF) (9)> when called with arguments (1 #<PERMUTATION #(211470320 0) {10031FB8A1}> 0). [Condition of type SB-PCL::NO-PRIMARY-METHOD]
I am including the LU decomposition code that I am trying to get to work. What am I doing wrong?
(defun lu-closure (mat) (multiple-value-bind (dim lu per) (letm ((mat* (matrix-double-float mat)) (dim (array-dimension mat 0)) ;; for the commented out code two lines down ;; (per1* (permutation dim)) (per* (permutation dim))) (lu-decomp mat* per*) ;; tried to test transferring per* to per* ;; (setf (data per1*) (data per*)) ;; (dotimes (i dim) ;; (setf (maref per1* i) (maref per* i))) (values dim (data mat*) (data per*))) (lambda (command &rest args) (case command (:lu lu) (:dim dim) (:per per) (:invert ;; cannot set per* (letm ((lu* (matrix-double-float lu)) ;; tried also (per* (permutation per)) (per* (permutation per)) (inv* (matrix-double-float dim dim))) (setf (data per*) per) (lu-invert lu* per* inv*) (data inv*))) (:solve ;; untested (letm ((lu* (matrix-double-float lu)) (per* (permutation dim)) (rhs* (first args)) (x* (vector-double-float dim))) (setf (data per*) per) (lu-solve lu* per* rhs* x*) (data x*)))))))
Thanks,
Mirko
On Wed, Aug 6, 2008 at 7:14 PM, Liam Healy lhealy@common-lisp.net wrote:
Mirko,
If you can't enclose everything dynamically within a letm, then using #'data to get the CL array is the way to go. You need to then recreate the GSLL object with another letm when needed. You'll just wrap in a letm when you need to call GSL functions. You can do the same now, but it requires using #'data to pull out the CL array. When you need to use it again, don't try to reuse the gsl-data object, make a new one based on the CL array you pulled out previously.
Liam
(P.S. You can macroexpand your letms and see how it works with allocation and freers, but I recommend you stay away from that approach. You can work outside a letm now, but it's not fun, and the ffa-based GSLL won't permit it.)
On Wed, Aug 6, 2008 at 12:50 PM, Mirko Vukovic mirko.vukovic@gmail.com wrote:
good news/bad news: the data command seems to preserve the values of the m-variables. But for some reason, the pointer field of those variables
is
now null. So, while the data is still accessible from the closure, it cannot be used with gsl because the pointer information used by gsl to access it is missing.
I think that I am looking for the following type of functionality: we
create
an LU decomposition within a closure, and than can apply it for multiple solutions, inverse, determinant, etc. Here is a sample idea (untested):
(defun lu-closure (mat) (letm ((mat* (matrix-double-float mat)) (dim (array-dimension mat 0)) (per* (permutation dim))) (lu-decomp mmat* per*) (lambda (command &rest args) (case command (:invert (letm ((inv* (matrix-double-float dim dim))) (lu-invert mmat* per* inv*) (data inv*))) (:solve (letm ((rhs* (first args)) (x* (vector-double-float dim))) (lu-solve mmat* per* rhs* x*) (data x*)))))))
(One could of course, just return and save the matrix and permutation vector, and apply them subsequently. I'm not sure which is the more
lispy
way)
Mirko
---------- Forwarded message ---------- From: Mirko Vukovic mirko.vukovic@gmail.com Date: Wed, Aug 6, 2008 at 11:12 AM Subject: Fwd: keeping m-variables in closures To: gsll-devel@common-lisp.net
Actually something else may be going on here, because the m-variable x
can
be accessed later on. I thought that maybe calls to lu-solve may obliterate mmat and mrhs but that does not seem to be the case - I
commented
those calls out, but mmat and mrhs are still nils.
Mirko
---------- Forwarded message ---------- From: Mirko Vukovic mirko.vukovic@gmail.com Date: Wed, Aug 6, 2008 at 11:01 AM Subject: keeping m-variables in closures To: gsll-devel@common-lisp.net
Hello folks
(the following is not a showstopper, but I am just curious).
I am trying to define a closure (still doing LU decompositions and matrix solutions), and would like to keep some of the variables around for
further
processing. Here is one example
(defun parallel-plate-equilibrium (eps0 T0 eps1- eps1+ eps2 T2 &key (q1 0d0)) (letm ((dim 5) (mat (make-array (list dim dim) :element-type 'double-float :initial-contents (list (list 1d0 (1- eps0) 0d0 0d0 0d0) (list (1- eps1-) 1d0 0d0 0d0 (0- eps1-)) (list 0d0 0d0 1d0 (1- eps1+) (0- eps1+)) (list 0d0 0d0 (1- eps2) 1d0 0d0) (list (0- eps1-) 0d0 0d0 (0- eps1+) (+ eps1- eps1+))))) (mmat (matrix-double-float mat)) ;; (mmat0 mmat) (rhs (make-array dim :element-type 'double-float :initial-contents (list (st4 T0 eps0) 0d0 0d0 (st4 T2 eps2) q1))) (mrhs (vector-double-float rhs)) (per (permutation dim)) (res (vector-double-float dim)) (0-vec (vector-double-float (make-array dim :initial-element 0d0))) (x (vector-double-float dim))) (lu-decomp mmat per) (lu-solve mmat per mrhs x) (data x) (lambda (command) (case command ;; these two will fail because mmat, mrhs, mmat0 are nil ;; (:solve (lu-solve mmat per mrhs x)) ;; (:check (gemv :notrans 1d0 mmat0 x 0d0 0-vec)) (:mat mat) (:rhs rhs) (:temp (expt (/ (aref (data x) 4) +sigma+) 0.25)) (:fluxes (data x))))))
However, it seems that gsll's variables are discarded once the letm form
is
done (as per documentation, and also with macroexpansion). But the code
for
letm mentions some "freers", which gave me hope that I can specify the
freer
as NIL. But I could not figure that one out quite yet. So, is it
possible
to save some of gsll's variables for later use?
Thanks,
Mirko
Gsll-devel mailing list Gsll-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/gsll-devel