[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