[Gsll-devel] contrib: using iterate with gsll
Norman Werner
norman at norman-werner.de
Sun Mar 29 17:22:35 UTC 2009
Hello
As it was a little bit cloudy I used this sunday to find a way to use iterate
(http://common-lisp.net/project/iterate/) with gsll.
The following code does not rely on any other libraries than gsll and iterate,
it "should work" - however it was not heavily testet.
As an example try:
(setf m1 (gsll:make-marray 'double-float
:initial-contents '((1 2 3) (0 6 8))))
(iterate:iterate (iterate:for e ELEMENT-IN-GSLL-MATRIX m1)
(format t "~A " e))
(iterate:iterate (iterate:for (row column) INDEXES-IN-GSLL-MATRIX m1)
(format t "~A " (gsll:maref m1 row column)))
===========CODE STARTS HERE ===============
(iterate:defclause-sequence iterate::ROW-IN-GSLL-MATRIX
iterate::ROW-INDEX-OF-GSLL-MATRIX
:access-fn (lambda (marray index)
(typecase marray
(gsll::matrix (gsll:row marray index))
(gsll::vector (error "iterating over the rows in a vector is not supported.
You may want iterate over its elements instead"))
(t (error "only iterating over rows of an gsll:matrix is supported"))))
:size-fn (lambda (marray)
(typecase marray
(gsll::matrix (elt (gsll:dimensions marray) 0))
(gsll::vector (error "iterating over the rows in a vector is not
supported. You may want iterate over its elements instead"))
(t (error "only iterating over rows of an gsll:matrix is
supported"))))
:element-type t :sequence-type t :element-doc-string "(copied) rows of a
gsll matrix" :index-doc-string "index of the rows in a gsll matrix")
(iterate:defclause-sequence iterate::COLUMN-IN-GSLL-MATRIX
COLUMN-INDEX-OF-GSLL-MATRIX
:access-fn (lambda (marray index)
(typecase marray
(gsll::matrix (gsll:column marray index))
(gsll::vector (error "iterating over the columns in a vector is not
supported. You may want iterate over its elements instead"))
(t (error "only iterating over columns of an gsll:matrix is supported"))))
:size-fn (lambda (marray)
(typecase marray
(gsll::matrix (elt (gsll:dimensions marray) 1))
(gsll::vector (error "iterating over the columns in a vector is not
supported. You may want iterate over its elements instead"))
(t (error "only iterating over columns of an gsll:matrix is
supported"))))
:element-type t :sequence-type t :element-doc-string "(copied) columns of a
gsll matrix" :index-doc-string "index of the columns in a gsll matrix")
(iterate:defclause-sequence iterate::ELEMENT-IN-GSLL-VECTOR
iterate::INDEX-OF-GSLL-VECTOR
:access-fn (lambda (vector index)
(typecase vector
(gsll::mvector (gsll:maref vector index))
(t (error "only iterating over elements of an gsll:vector is supported"))))
:size-fn (lambda (vector)
(typecase vector
(gsll::mvector (elt (gsll:dimensions vector) 0))
(t (error "only iterating over elements of an gsll:vector is
supported"))))
:element-type t :sequence-type t :element-doc-string "(copied) elements of a
gsll vector" :index-doc-string "index of elements in a gsll vector")
(iterate:defmacro-driver (iterate:FOR element iterate::ELEMENT-IN-GSLL-MATRIX
matrix)
"Iterates over all (copied) Elements in matrix"
(let ((row-index (gensym "row-index"))
(col-index (gensym "col-index"))
(row-size (gensym "row-size"))
(col-size (gensym "col-size"))
(m (gensym "m")))
(when iterate::generate (error "not yet implemented a generate clause for
iterate::ELEMENT-IN-GSLL-MATRIX"))
`(progn
(iterate:with ,m = ,matrix)
(iterate:with ,row-index = 0)
(iterate:with ,col-index = 0)
(iterate:with ,row-size = (elt (gsll:dimensions ,m) 0))
(iterate:with ,col-size = (elt (gsll:dimensions ,m) 1))
(iterate::for ,element iterate::next (if (>= ,row-index ,row-size)
(iterate::terminate)
(if (>= ,col-index ,col-size)
(progn
(setf ,col-index 0)
(incf ,row-index)
(if (>= ,row-index ,row-size)
(iterate::terminate)
(gsll:maref ,m ,row-index ,col-index)))
(prog1
(gsll:maref ,m ,row-index ,col-index)
(incf ,col-index))))))))
(iterate:defmacro-driver (iterate:FOR indexes iterate::INDEXES-IN-GSLL-MATRIX
matrix)
"Iterates over the indexes in matrix. indexes is a list like (row-index-name
column-index-name) "
(let ((row-index (gensym "row-index"))
(col-index (gensym "col-index"))
(row-size (gensym "row-size"))
(col-size (gensym "col-size"))
(m (gensym "m")))
(when iterate::generate (error "not yet implemented a generate clause for
iterate::INDEXES-IN-GSLL-MATRIX"))
`(progn
(iterate:with ,m = ,matrix)
(iterate:with ,row-index = 0)
(iterate:with ,col-index = 0)
(iterate:with ,row-size = (elt (gsll:dimensions ,m) 0))
(iterate:with ,col-size = (elt (gsll:dimensions ,m) 1))
(iterate::for ,indexes iterate::next (if (>= ,row-index ,row-size)
(iterate::terminate)
(if (>= ,col-index ,col-size)
(progn
(setf ,col-index 0)
(incf ,row-index)
(if (>= ,row-index ,row-size)
(iterate::terminate)
(list ,row-index ,col-index)))
(prog1
(list ,row-index ,col-index)
(incf ,col-index))))))))
============ Code ENDS HERE ===============
If you think this could be usefull for others just include it into the
distribution (be aware that it adds a dependency on iterate) or just add some
paragraphs to the documentation.
Regards
Norman
--
Norman Werner
Im Sommerwind 1a
70563 Stuttgart
More information about the gsll-devel
mailing list