[pure-lang-svn] SF.net SVN: pure-lang:[835] pure/trunk
Status: Beta
Brought to you by:
agraef
|
From: <ag...@us...> - 2008-09-23 09:15:38
|
Revision: 835
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=835&view=rev
Author: agraef
Date: 2008-09-23 09:15:34 +0000 (Tue, 23 Sep 2008)
Log Message:
-----------
Bugfixes, make list operations work on matrices.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/lib/primitives.pure
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-09-23 06:32:29 UTC (rev 834)
+++ pure/trunk/ChangeLog 2008-09-23 09:15:34 UTC (rev 835)
@@ -1,3 +1,9 @@
+2008-09-23 Albert Graef <Dr....@t-...>
+
+ * lib/primitives.pure: Added a bunch of new matrix operations. In
+ particular, list operations like filter and map now work on
+ matrices, too.
+
2008-09-20 Albert Graef <Dr....@t-...>
* Implemented basic GSL matrix support, including support for
Modified: pure/trunk/lib/primitives.pure
===================================================================
--- pure/trunk/lib/primitives.pure 2008-09-23 06:32:29 UTC (rev 834)
+++ pure/trunk/lib/primitives.pure 2008-09-23 09:15:34 UTC (rev 835)
@@ -416,6 +416,7 @@
extern int matrix_size(expr *x), int matrix_stride(expr *x);
extern expr* matrix_dim(expr *x);
+null x::matrix = #x==0;
#x::matrix = matrix_size x;
dim x::matrix = matrix_dim x;
stride x::matrix = matrix_stride x;
@@ -447,7 +448,7 @@
nth x n = catch (cst {}) (row x n);
mth x m = catch (cst {}) (col x m);
end;
-x::matrix!!ns = if packed x then rowvector x!!(1,ns)
+x::matrix!!ns = if packed x then rowvector x!!([0],ns)
else colcatmap (nth x) ns with
nth x n = catch (cst {}) {x!n};
end;
@@ -469,16 +470,14 @@
cols x::matrix = map (col x) (0..m-1) when _,m::int = dim x end;
-/* Convert a matrix to a list and vice versa. If x is a row vector then list x
- converts it to a list of its elements; otherwise the result is the list of
- the rows of the matrix. You can also use list2 to convert a matrix to a
- list of lists. Conversely, matrix xs converts a list of lists or matrices
- to the corresponding matrix; otherwise, the result is a row vector.
- NOTE: The matrix function may throw a 'bad_matrix_value x' in case of
- dimension mismatch, where x denotes the offending submatrix. */
+/* Convert a matrix to a list and vice versa. list x converts a matrix x to a
+ flat list of its elements, while list2 converts it to a list of lists.
+ Conversely, matrix xs converts a list of lists or matrices specifying the
+ rows of the matrix to the corresponding matrix; otherwise, the result is a
+ row vector. NOTE: The matrix function may throw a 'bad_matrix_value x' in
+ case of dimension mismatch, where x denotes the offending submatrix. */
-list x::matrix = [x!i|i=0..#x-1] if rowvectorp x;
- = rows x otherwise;
+list x::matrix = [x!i|i=0..#x-1];
list2 x::matrix = [[x!(i,j)|j=0..m-1]|i=0..n-1]
when n::int,m::int = dim x end;
@@ -512,12 +511,17 @@
extern expr* matrix_redim(expr* x, int n, int m);
redim x::matrix (n::int,m::int)
- = matrix_redim x n m if n*m==#x;
+ = matrix_redim x n m if n>=0 && m>=0 && n*m==#x;
+/* You can also redim a matrix to a given positive row size. In this case the
+ row size must divide the total size of the matrix, */
+
+redim x::matrix m::int = redim x (#x div m,m) if m>0 && #x mod m==0;
+
/* Convenience functions for converting a matrix to a row or column vector. */
-rowvector x::matrix = redim x (1,#x);
-colvector x::matrix = redim x (#x,1);
+rowvector x::matrix = redim x (#x);
+colvector x::matrix = redim x 1;
/* Construct matrices from lists of rows and columns. These take either
scalars or submatrices as inputs; corresponding dimensions must match.
@@ -559,6 +563,78 @@
colrev x::matrix = colcat (reverse (cols x));
reverse x::matrix = rowrev (colrev x);
+/* catmap et al on matrices. This allows list and matrix comprehensions to
+ draw values from matrices just as well as from lists, treating the matrix
+ as a flat list of its elements. */
+
+catmap f x::matrix = catmap f (list x);
+rowcatmap f x::matrix = rowcat (map f (list x));
+colcatmap f x::matrix = colcat (map f (list x));
+
+/* Implementations of the other customary list operations, so that these can
+ be used on matrices, too. These operations treat the matrix essentially as
+ if it was a flat list of its elements. Aggregate results are then converted
+ back to matrices with the appropriate dimensions. (This depends on the
+ operation; operations like map and zip keep the dimensions of the input
+ matrix intact, while other functions like filter, take or scanl always
+ return a flat row vector. Also note that the zip-style operations require
+ that the row sizes of all arguments match.) */
+
+cycle x::matrix = cycle (list x);
+cyclen n::int x::matrix = cyclen n (list x) if not null x;
+
+all p x::matrix = all p (list x);
+any p x::matrix = any p (list x);
+do f x::matrix = do f (list x);
+drop k::int x::matrix = x!!(k..#x-1);
+dropwhile p x::matrix = colcat (dropwhile p (list x));
+filter p x::matrix = colcat (filter p (list x));
+foldl f a x::matrix = foldl f a (list x);
+foldl1 f x::matrix = foldl1 f (list x);
+foldr f a x::matrix = foldr f a (list x);
+foldr1 f x::matrix = foldr1 f (list x);
+head x::matrix = x!0 if not null x;
+init x::matrix = x!!(0..#x-2) if not null x;
+last x::matrix = x!(#x-1) if not null x;
+map f x::matrix = flip redim (dim x) $ colcat (map f (list x));
+scanl f a x::matrix = colcat (scanl f a (list x));
+scanl1 f x::matrix = colcat (scanl1 f (list x));
+scanr f a x::matrix = colcat (scanr f a (list x));
+scanr1 f x::matrix = colcat (scanr1 f (list x));
+take k::int x::matrix = x!!(0..k-1);
+takewhile p x::matrix = colcat (takewhile p (list x));
+tail x::matrix = x!!(1..#x-1) if not null x;
+
+zip x::matrix y::matrix = flip redim (dim x!1) $
+ colcat (zip (list x) (list y))
+ if dim x!1==dim y!1;
+zip3 x::matrix y::matrix z::matrix
+ = flip redim (dim x!1) $
+ colcat (zip3 (list x) (list y) (list z))
+ if dim x!1==dim y!1 && dim x!1==dim z!1;
+zipwith f x::matrix y::matrix
+ = flip redim (dim x!1) $
+ colcat (zipwith f (list x) (list y))
+ if dim x!1==dim y!1;
+zipwith3 f x::matrix y::matrix z::matrix
+ = flip redim (dim x!1) $
+ colcat (zipwith3 f (list x) (list y) (list z))
+ if dim x!1==dim y!1 && dim x!1==dim z!1;
+dowith f x::matrix y::matrix
+ = dowith f (list x) (list y)
+ if dim x!1==dim y!1;
+dowith3 f x::matrix y::matrix z::matrix
+ = dowith3 f (list x) (list y) (list z)
+ if dim x!1==dim y!1 && dim x!1==dim z!1;
+
+unzip x::matrix = flip redim (dim x) (colcat u),
+ flip redim (dim x) (colcat v)
+ when u,v = unzip (list x) end;
+unzip3 x::matrix = flip redim (dim x) (colcat u),
+ flip redim (dim x) (colcat v),
+ flip redim (dim x) (colcat w)
+ when u,v,w = unzip3 (list x) end;
+
/* Matrix conversions. */
private matrix_double matrix_complex matrix_int;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|