From: Tamas K Papp <tkpapp@gm...>  20100123 09:13:08

Hi, I need to construct matrices which are "semiconstant": many elements are constant, but a few may be calculated runtime. A further complication is that these matrices need to be columnmajor. I am optimizing for speed (and not too much consing). I thought I would write a macro that constructs a matrix and fills it with elements. Since many elements are zero, I thought I would set that in makearray and not set those elements individually. I am counting on the compiler to fold (coerced) constants, so that I don't have to use decimal dots, making usage convenient. Here is the resulting macro, with an example: (defmacro ccolmajormatrixdouble (&body listofrows) "Construct a matrix of doublefloats from given elements (lists of lists). Elements may be constants or forms, and are coerced to the correct type." (let* ((ncol (length (first listofrows))) (nrow (length listofrows)) (arrayname (gensym "vector"))) `(let ((,arrayname (makearray '(,ncol ,nrow) :elementtype 'doublefloat :initialelement 0d0))) ,@(iter outer (for rowlist :in listofrows) (for row :from 0) (assert (= (length rowlist) ncol) () "Invalid number of elements in row ~A." row) (iter (for element :in rowlist) (for col :from 0) (unless (and (numberp element) (zerop element)) (in outer (collect `(setf (aref ,arrayname ,col ,row) (coerce ,element 'doublefloat))))))) ,arrayname))) (defun makespecialmatrix (a b) "Inane example." (declare (optimize speed) (doublefloat a b)) (ccolmajormatrixdouble (0 0 0 1 (* a b)) (12 a b 0 0) (( a b) 0 0 0 7.8))) where the macro expands to (LET ((#:vector1541 (MAKEARRAY '(5 3) :ELEMENTTYPE 'DOUBLEFLOAT :INITIALELEMENT 0.0d0))) (SETF (AREF #:vector1541 3 0) (COERCE 1 'DOUBLEFLOAT)) (SETF (AREF #:vector1541 4 0) (COERCE (* A B) 'DOUBLEFLOAT)) (SETF (AREF #:vector1541 0 1) (COERCE 12 'DOUBLEFLOAT)) (SETF (AREF #:vector1541 1 1) (COERCE A 'DOUBLEFLOAT)) (SETF (AREF #:vector1541 2 1) (COERCE B 'DOUBLEFLOAT)) (SETF (AREF #:vector1541 0 2) (COERCE ( A B) 'DOUBLEFLOAT)) (SETF (AREF #:vector1541 4 2) (COERCE 7.8 'DOUBLEFLOAT)) #:vector1541) However, the disassembly indicates that this may not be the most "natural" way to do this in SBCL. Is there a better one? Thanks, Tamas 
From: Nikodemus Siivola <nikodemus@ra...>  20100226 14:54:13

On 23 January 2010 11:12, Tamas K Papp <tkpapp@...> wrote: > (LET ((#:vector1541 > (MAKEARRAY '(5 3) :ELEMENTTYPE 'DOUBLEFLOAT :INITIALELEMENT 0.0d0))) > (SETF (AREF #:vector1541 3 0) (COERCE 1 'DOUBLEFLOAT)) > (SETF (AREF #:vector1541 4 0) (COERCE (* A B) 'DOUBLEFLOAT)) > (SETF (AREF #:vector1541 0 1) (COERCE 12 'DOUBLEFLOAT)) > (SETF (AREF #:vector1541 1 1) (COERCE A 'DOUBLEFLOAT)) > (SETF (AREF #:vector1541 2 1) (COERCE B 'DOUBLEFLOAT)) > (SETF (AREF #:vector1541 0 2) (COERCE ( A B) 'DOUBLEFLOAT)) > (SETF (AREF #:vector1541 4 2) (COERCE 7.8 'DOUBLEFLOAT)) > #:vector1541) > > However, the disassembly indicates that this may not be the most > "natural" way to do this in SBCL. Is there a better one? The code is fine  problem was that %ARRAYDATAVECTOR was missing a type derivation function. Does the following make the disassembly more to your taste? (inpackage :sbc) (defun maybearraydatavectortypespecifier (arraylvar) (let ((atype (lvartype arraylvar))) (when (arraytypep atype) `(simplearray ,(typespecifier (arraytypespecializedelementtype atype)) (*))))) (defoptimizer (%arraydatavector derivetype) ((array)) (let ((spec (maybearraydatavectortypespecifier array))) (when spec (specifiertype spec)))) (defoptimizer (%datavectorandindex derivetype) ((array index)) (let ((spec (maybearraydatavectortypespecifier array))) (when spec (valuesspecifiertype `(values ,spec index))))) I'll commit something like this after the freeze. Cheers,  Nikodemus 
From: Nikodemus Siivola <nikodemus@ra...>  20100228 20:09:28

On 26 February 2010 16:53, Nikodemus Siivola <nikodemus@...> wrote: > The code is fine  problem was that %ARRAYDATAVECTOR was missing a > type derivation function. Does the following make the disassembly more > to your taste? ... > I'll commit something like this after the freeze. In SBCL 1.0.36.6. > Cheers, > >  Nikodemus 