pure-lang-svn Mailing List for Pure (Page 3)
Status: Beta
Brought to you by:
agraef
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
(5) |
May
(141) |
Jun
(184) |
Jul
(97) |
Aug
(232) |
Sep
(196) |
Oct
|
Nov
|
Dec
|
---|
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. |
From: <ag...@us...> - 2008-09-23 06:32:33
|
Revision: 834 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=834&view=rev Author: agraef Date: 2008-09-23 06:32:29 +0000 (Tue, 23 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/lib/strings.pure Modified: pure/trunk/lib/strings.pure =================================================================== --- pure/trunk/lib/strings.pure 2008-09-23 05:54:38 UTC (rev 833) +++ pure/trunk/lib/strings.pure 2008-09-23 06:32:29 UTC (rev 834) @@ -174,7 +174,7 @@ all p s::string = all p (chars s); any p s::string = any p (chars s); do f s::string = do f (chars s); -drop n s::string = substr s n (#s-n); +drop n::int s::string = substr s n (#s-n); dropwhile p s::string = strcat (dropwhile p (chars s)); filter p s::string = strcat (filter p (chars s)); foldl f a s::string = foldl f a (chars s); @@ -189,7 +189,7 @@ scanl1 f s::string = scanl1 f (chars s); scanr f a s::string = scanr f a (chars s); scanr1 f s::string = scanr1 f (chars s); -take n s::string = substr s 0 n; +take n::int s::string = substr s 0 n; takewhile p s::string = strcat (takewhile p (chars s)); tail s::string = substr s 1 (#s-1) if not null s; zip s::string t::string = zip (chars s) (chars t); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-23 05:54:41
|
Revision: 833 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=833&view=rev Author: agraef Date: 2008-09-23 05:54:38 +0000 (Tue, 23 Sep 2008) Log Message: ----------- Make the matrix construction functions in the library throw a 'bad_matrix_value' exception in case of dimension mismatch. Modified Paths: -------------- pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-23 05:31:30 UTC (rev 832) +++ pure/trunk/lib/primitives.pure 2008-09-23 05:54:38 UTC (rev 833) @@ -473,7 +473,9 @@ 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. */ + 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; @@ -520,7 +522,9 @@ /* Construct matrices from lists of rows and columns. These take either scalars or submatrices as inputs; corresponding dimensions must match. rowcat combines submatrices vertically, like {x;y}; colcat combines them - horizontally, like {x,y}. */ + horizontally, like {x,y}. NOTE: Like the built-in matrix constructs, these + operations may throw a 'bad_matrix_value x' in case of dimension mismatch, + where x denotes the offending submatrix. */ extern expr* matrix_rows(expr *x) = rowcat; extern expr* matrix_columns(expr *x) = colcat; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-23 05:31:30 UTC (rev 832) +++ pure/trunk/runtime.cc 2008-09-23 05:54:38 UTC (rev 833) @@ -4568,13 +4568,227 @@ return y; } +static pure_expr *matrix_rowsv(uint32_t n, pure_expr **xs) +{ + int k = -1; + size_t nrows = 0, ncols = 0; + int32_t target = 0; + bool have_matrix = false; + pure_expr *x = 0; + for (size_t i = 0; i < n; i++) { + x = xs[i]; + switch (x->tag) { + case EXPR::MATRIX: { + gsl_matrix_symbolic *mp = (gsl_matrix_symbolic*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size2 != (size_t)k) + goto err; + nrows += mp->size1; k = mp->size2; + set_target_type(target, EXPR::MATRIX); + have_matrix = true; + } + break; + } +#ifdef HAVE_GSL + case EXPR::DBL: + set_target_type(target, EXPR::DMATRIX); + if (k >= 0 && k != 1) goto err; + nrows++; k = 1; + break; + case EXPR::INT: + set_target_type(target, EXPR::IMATRIX); + if (k >= 0 && k != 1) goto err; + nrows++; k = 1; + break; + case EXPR::APP: { + double a, b; + if (k >= 0 && k != 1) goto err; + nrows++; k = 1; + if (get_complex(x, a, b)) + set_target_type(target, EXPR::CMATRIX); + else + set_target_type(target, EXPR::MATRIX); + break; + } + case EXPR::DMATRIX: { + gsl_matrix *mp = (gsl_matrix*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size2 != (size_t)k) + goto err; + nrows += mp->size1; k = mp->size2; + set_target_type(target, EXPR::DMATRIX); + have_matrix = true; + } + break; + } + case EXPR::CMATRIX: { + gsl_matrix_complex *mp = (gsl_matrix_complex*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size2 != (size_t)k) + goto err; + nrows += mp->size1; k = mp->size2; + set_target_type(target, EXPR::CMATRIX); + have_matrix = true; + } + break; + } + case EXPR::IMATRIX: { + gsl_matrix_int *mp = (gsl_matrix_int*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size2 != (size_t)k) + goto err; + nrows += mp->size1; k = mp->size2; + set_target_type(target, EXPR::IMATRIX); + have_matrix = true; + } + break; + } +#endif + default: + if (k >= 0 && k != 1) goto err; + nrows++; k = 1; + set_target_type(target, EXPR::MATRIX); + break; + } + } + if (n == 1 && have_matrix) return xs[0]; + if (k < 0) k = 0; + ncols = k; + if (target == 0) target = EXPR::MATRIX; + switch (target) { + case EXPR::MATRIX: + return symbolic_matrix_rows(nrows, ncols, n, xs); +#ifdef HAVE_GSL + case EXPR::DMATRIX: + return double_matrix_rows(nrows, ncols, n, xs); + case EXPR::CMATRIX: + return complex_matrix_rows(nrows, ncols, n, xs); + case EXPR::IMATRIX: + return int_matrix_rows(nrows, ncols, n, xs); +#endif + default: + assert(0 && "this can't happen"); + return 0; + } + err: + pure_throw(bad_matrix_exception(x)); + return 0; +} + +static pure_expr *matrix_columnsv(uint32_t n, pure_expr **xs) +{ + int k = -1; + size_t nrows = 0, ncols = 0; + int32_t target = 0; + bool have_matrix = false; + pure_expr *x = 0; + for (size_t i = 0; i < n; i++) { + x = xs[i]; + switch (x->tag) { + case EXPR::MATRIX: { + gsl_matrix_symbolic *mp = (gsl_matrix_symbolic*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size1 != (size_t)k) + goto err; + ncols += mp->size2; k = mp->size1; + set_target_type(target, EXPR::MATRIX); + have_matrix = true; + } + break; + } +#ifdef HAVE_GSL + case EXPR::DBL: + set_target_type(target, EXPR::DMATRIX); + if (k >= 0 && k != 1) goto err; + ncols++; k = 1; + break; + case EXPR::INT: + set_target_type(target, EXPR::IMATRIX); + if (k >= 0 && k != 1) goto err; + ncols++; k = 1; + break; + case EXPR::APP: { + double a, b; + if (k >= 0 && k != 1) goto err; + ncols++; k = 1; + if (get_complex(x, a, b)) + set_target_type(target, EXPR::CMATRIX); + else + set_target_type(target, EXPR::MATRIX); + break; + } + case EXPR::DMATRIX: { + gsl_matrix *mp = (gsl_matrix*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size1 != (size_t)k) + goto err; + ncols += mp->size2; k = mp->size1; + set_target_type(target, EXPR::DMATRIX); + have_matrix = true; + } + break; + } + case EXPR::CMATRIX: { + gsl_matrix_complex *mp = (gsl_matrix_complex*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size1 != (size_t)k) + goto err; + ncols += mp->size2; k = mp->size1; + set_target_type(target, EXPR::CMATRIX); + have_matrix = true; + } + break; + } + case EXPR::IMATRIX: { + gsl_matrix_int *mp = (gsl_matrix_int*)x->data.mat.p; + if (mp->size1 > 0 && mp->size2 > 0) { + if (k >= 0 && mp->size1 != (size_t)k) + goto err; + ncols += mp->size2; k = mp->size1; + set_target_type(target, EXPR::IMATRIX); + have_matrix = true; + } + break; + } +#endif + default: + if (k >= 0 && k != 1) goto err; + ncols++; k = 1; + set_target_type(target, EXPR::MATRIX); + break; + } + } + if (n == 1 && have_matrix) return xs[0]; + if (k < 0) k = 0; + nrows = k; + if (target == 0) target = EXPR::MATRIX; + switch (target) { + case EXPR::MATRIX: + return symbolic_matrix_columns(nrows, ncols, n, xs); +#ifdef HAVE_GSL + case EXPR::DMATRIX: + return double_matrix_columns(nrows, ncols, n, xs); + case EXPR::CMATRIX: + return complex_matrix_columns(nrows, ncols, n, xs); + case EXPR::IMATRIX: + return int_matrix_columns(nrows, ncols, n, xs); +#endif + default: + assert(0 && "this can't happen"); + return 0; + } + err: + pure_throw(bad_matrix_exception(x)); + return 0; +} + extern "C" pure_expr *matrix_rows(pure_expr *xs) { size_t n; pure_expr **elems; if (pure_is_listv(xs, &n, &elems)) { - pure_expr *ret = pure_matrix_rowsv(n, elems); + pure_expr *ret = matrix_rowsv(n, elems); if (elems) free(elems); return ret; } else @@ -4587,7 +4801,7 @@ size_t n; pure_expr **elems; if (pure_is_listv(xs, &n, &elems)) { - pure_expr *ret = pure_matrix_columnsv(n, elems); + pure_expr *ret = matrix_columnsv(n, elems); if (elems) free(elems); return ret; } else Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-23 05:31:30 UTC (rev 832) +++ pure/trunk/runtime.h 2008-09-23 05:54:38 UTC (rev 833) @@ -703,9 +703,9 @@ pure_expr *matrix_subdiag(pure_expr *x, int32_t k); pure_expr *matrix_supdiag(pure_expr *x, int32_t k); -/* Matrix construction. These work like the pure_matrix_rows/ - pure_matrix_columns functions in the public API, but take their input from - a Pure list. */ +/* Matrix construction. These work like the corresponding functions in the + public API, but take their input from a Pure list and raise the appropriate + exception in case of dimension mismatch. */ pure_expr *matrix_rows(pure_expr *xs); pure_expr *matrix_columns(pure_expr *xs); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-23 05:31:32
|
Revision: 832 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=832&view=rev Author: agraef Date: 2008-09-23 05:31:30 +0000 (Tue, 23 Sep 2008) Log Message: ----------- Overhaul of matrix/list conversion operations. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-22 21:36:31 UTC (rev 831) +++ pure/trunk/lib/primitives.pure 2008-09-23 05:31:30 UTC (rev 832) @@ -433,7 +433,7 @@ when n::int,m::int = dim x end); = throw out_of_bounds otherwise; -/* Slices. */ +/* Matrix slices. */ x::matrix!!(ns,ms) = case ns,ms of // optimize the case of contiguous slices @@ -469,24 +469,26 @@ cols x::matrix = map (col x) (0..m-1) when _,m::int = dim x end; -/* Convert a matrix to a list and vice versa. */ +/* 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. */ -list x::matrix = [[x!(i,j) | j=0..m-1] | i=0..n-1] +list x::matrix = [x!i|i=0..#x-1] if rowvectorp x; + = rows x otherwise; +list2 x::matrix = [[x!(i,j)|j=0..m-1]|i=0..n-1] when n::int,m::int = dim x end; + matrix [] = {}; -matrix xs@(x:_) = rowcatmap colcat xs; +matrix xs@(x:_) = rowcatmap colcat xs if all listp xs; + = rowcat xs if any matrixp xs; + = colcat xs otherwise; -/* Convenience functions to create vectors from lists. */ - -rowvector xs@[] | rowvector xs@(_:_) - = colcat xs; -colvector xs@[] | colvector xs@(_:_) - = rowcat xs; - /* Extract (sub-,super-) diagonals from a matrix. Sub- and super-diagonals for k=0 return the main diagonal. Indices for sub- and super-diagonals can also be negative, in which case the corresponding super- or sub-diagonal is - returned instead. */ + returned instead. In each case the result is a row vector. */ private matrix_diag matrix_subdiag matrix_supdiag; extern expr* matrix_diag(expr* x) = diag; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 21:52:50
|
Revision: 831 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=831&view=rev Author: agraef Date: 2008-09-22 21:36:31 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Add matrix/list conversion operations. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-22 21:14:10 UTC (rev 830) +++ pure/trunk/lib/primitives.pure 2008-09-22 21:36:31 UTC (rev 831) @@ -469,6 +469,20 @@ cols x::matrix = map (col x) (0..m-1) when _,m::int = dim x end; +/* Convert a matrix to a list and vice versa. */ + +list x::matrix = [[x!(i,j) | j=0..m-1] | i=0..n-1] + when n::int,m::int = dim x end; +matrix [] = {}; +matrix xs@(x:_) = rowcatmap colcat xs; + +/* Convenience functions to create vectors from lists. */ + +rowvector xs@[] | rowvector xs@(_:_) + = colcat xs; +colvector xs@[] | colvector xs@(_:_) + = rowcat xs; + /* Extract (sub-,super-) diagonals from a matrix. Sub- and super-diagonals for k=0 return the main diagonal. Indices for sub- and super-diagonals can also be negative, in which case the corresponding super- or sub-diagonal is This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 21:14:19
|
Revision: 830 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=830&view=rev Author: agraef Date: 2008-09-22 21:14:10 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Add matrix reversal operations. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-22 20:53:37 UTC (rev 829) +++ pure/trunk/lib/primitives.pure 2008-09-22 21:14:10 UTC (rev 830) @@ -532,6 +532,13 @@ x::matrix' = matrix_transpose x; +/* Reverse a matrix. rowrev reverses the rows, colrev the columns, reverse + both dimensions. */ + +rowrev x::matrix = rowcat (reverse (rows x)); +colrev x::matrix = colcat (reverse (cols x)); +reverse x::matrix = rowrev (colrev x); + /* 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. |
From: <ag...@us...> - 2008-09-22 20:53:45
|
Revision: 829 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=829&view=rev Author: agraef Date: 2008-09-22 20:53:37 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Add (sub-,super-) diagonal operations. Modified Paths: -------------- pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-22 19:20:24 UTC (rev 828) +++ pure/trunk/lib/primitives.pure 2008-09-22 20:53:37 UTC (rev 829) @@ -469,6 +469,16 @@ cols x::matrix = map (col x) (0..m-1) when _,m::int = dim x end; +/* Extract (sub-,super-) diagonals from a matrix. Sub- and super-diagonals for + k=0 return the main diagonal. Indices for sub- and super-diagonals can also + be negative, in which case the corresponding super- or sub-diagonal is + returned instead. */ + +private matrix_diag matrix_subdiag matrix_supdiag; +extern expr* matrix_diag(expr* x) = diag; +extern expr* matrix_subdiag(expr* x, int k) = subdiag; +extern expr* matrix_supdiag(expr* x, int k) = supdiag; + /* Extract a submatrix of a given size at a given offset. The result shares the underlying storage with the input matrix (i.e., matrix elements are *not* copied) and so this is a comparatively cheap operation. */ Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-22 19:20:24 UTC (rev 828) +++ pure/trunk/runtime.cc 2008-09-22 20:53:37 UTC (rev 829) @@ -4313,6 +4313,154 @@ } extern "C" +pure_expr *matrix_diag(pure_expr *x) +{ + switch (x->tag) { + case EXPR::MATRIX: { + gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n = (n1<n2)?n1:n2; + gsl_matrix_symbolic *m1 = create_symbolic_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[i*(m->tda+1)]; + return pure_symbolic_matrix(m1); + } +#ifdef HAVE_GSL + case EXPR::DMATRIX: { + gsl_matrix *m = (gsl_matrix*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n = (n1<n2)?n1:n2; + gsl_matrix *m1 = create_double_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[i*(m->tda+1)]; + return pure_double_matrix(m1); + } + case EXPR::CMATRIX: { + gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n = (n1<n2)?n1:n2; + gsl_matrix_complex *m1 = create_complex_matrix(1, n); + for (size_t i = 0; i < n; i++) { + const size_t k = 2*i*(m->tda+1); + m1->data[2*i] = m->data[k]; + m1->data[2*i+1] = m->data[k+1]; + } + return pure_complex_matrix(m1); + } + case EXPR::IMATRIX: { + gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n = (n1<n2)?n1:n2; + gsl_matrix_int *m1 = create_int_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[i*(m->tda+1)]; + return pure_int_matrix(m1); + } +#endif + default: + return 0; + } +} + +extern "C" +pure_expr *matrix_subdiag(pure_expr *x, int32_t k) +{ + if (k<0) return matrix_supdiag(x, -k); + switch (x->tag) { + case EXPR::MATRIX: { + gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k*m->tda; + gsl_matrix_symbolic *m1 = create_symbolic_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[k0+i*(m->tda+1)]; + return pure_symbolic_matrix(m1); + } +#ifdef HAVE_GSL + case EXPR::DMATRIX: { + gsl_matrix *m = (gsl_matrix*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k*m->tda; + gsl_matrix *m1 = create_double_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[k0+i*(m->tda+1)]; + return pure_double_matrix(m1); + } + case EXPR::CMATRIX: { + gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k*m->tda; + gsl_matrix_complex *m1 = create_complex_matrix(1, n); + for (size_t i = 0; i < n; i++) { + const size_t k = 2*k0+2*i*(m->tda+1); + m1->data[2*i] = m->data[k]; + m1->data[2*i+1] = m->data[k+1]; + } + return pure_complex_matrix(m1); + } + case EXPR::IMATRIX: { + gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k*m->tda; + gsl_matrix_int *m1 = create_int_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[k0+i*(m->tda+1)]; + return pure_int_matrix(m1); + } +#endif + default: + return 0; + } +} + +extern "C" +pure_expr *matrix_supdiag(pure_expr *x, int32_t k) +{ + if (k<0) return matrix_subdiag(x, -k); + switch (x->tag) { + case EXPR::MATRIX: { + gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k; + gsl_matrix_symbolic *m1 = create_symbolic_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[k0+i*(m->tda+1)]; + return pure_symbolic_matrix(m1); + } +#ifdef HAVE_GSL + case EXPR::DMATRIX: { + gsl_matrix *m = (gsl_matrix*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k; + gsl_matrix *m1 = create_double_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[k0+i*(m->tda+1)]; + return pure_double_matrix(m1); + } + case EXPR::CMATRIX: { + gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k; + gsl_matrix_complex *m1 = create_complex_matrix(1, n); + for (size_t i = 0; i < n; i++) { + const size_t k = 2*k0+2*i*(m->tda+1); + m1->data[2*i] = m->data[k]; + m1->data[2*i+1] = m->data[k+1]; + } + return pure_complex_matrix(m1); + } + case EXPR::IMATRIX: { + gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; + const size_t n1 = m->size1, n2 = m->size2, n0 = (n1<n2)?n1:n2; + const size_t n = (n0>(size_t)k)?n0-k:0, k0 = k; + gsl_matrix_int *m1 = create_int_matrix(1, n); + for (size_t i = 0; i < n; i++) + m1->data[i] = m->data[k0+i*(m->tda+1)]; + return pure_int_matrix(m1); + } +#endif + default: + return 0; + } +} + +extern "C" pure_expr *matrix_redim(pure_expr *x, int32_t n, int32_t m) { void *p = 0; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-22 19:20:24 UTC (rev 828) +++ pure/trunk/runtime.h 2008-09-22 20:53:37 UTC (rev 829) @@ -697,6 +697,12 @@ pure_expr *matrix_redim(pure_expr *x, int32_t n, int32_t m); +/* Retrieve (sub-,super-)diagonals of a matrix, as a 1xn matrix. */ + +pure_expr *matrix_diag(pure_expr *x); +pure_expr *matrix_subdiag(pure_expr *x, int32_t k); +pure_expr *matrix_supdiag(pure_expr *x, int32_t k); + /* Matrix construction. These work like the pure_matrix_rows/ pure_matrix_columns functions in the public API, but take their input from a Pure list. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 19:20:32
|
Revision: 828 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=828&view=rev Author: agraef Date: 2008-09-22 19:20:24 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Add operation to change the dimensions of a matrix without changing its size. Modified Paths: -------------- pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-22 17:46:47 UTC (rev 827) +++ pure/trunk/lib/primitives.pure 2008-09-22 19:20:24 UTC (rev 828) @@ -447,7 +447,8 @@ nth x n = catch (cst {}) (row x n); mth x m = catch (cst {}) (col x m); end; -x::matrix!!ns = colcatmap (nth x) ns with +x::matrix!!ns = if packed x then rowvector x!!(1,ns) + else colcatmap (nth x) ns with nth x n = catch (cst {}) {x!n}; end; @@ -468,11 +469,28 @@ cols x::matrix = map (col x) (0..m-1) when _,m::int = dim x end; -/* Extract a submatrix of a given size at a given offset. */ +/* Extract a submatrix of a given size at a given offset. The result shares + the underlying storage with the input matrix (i.e., matrix elements are + *not* copied) and so this is a comparatively cheap operation. */ submat x::matrix (i::int,j::int) (n::int,m::int) = matrix_slice x i j (i+n-1) (j+m-1); +/* Change the dimensions of a matrix without changing its size. The total + number of elements must match that of the input matrix. Reuses the + underlying storage of the input matrix if possible. */ + +private matrix_redim; +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; + +/* 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); + /* Construct matrices from lists of rows and columns. These take either scalars or submatrices as inputs; corresponding dimensions must match. rowcat combines submatrices vertically, like {x;y}; colcat combines them Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-22 17:46:47 UTC (rev 827) +++ pure/trunk/runtime.cc 2008-09-22 19:20:24 UTC (rev 828) @@ -4313,6 +4313,114 @@ } extern "C" +pure_expr *matrix_redim(pure_expr *x, int32_t n, int32_t m) +{ + void *p = 0; + if (n<0 || m<0) return 0; + const size_t n1 = (size_t)n, n2 = (size_t)m; + switch (x->tag) { + case EXPR::MATRIX: { + gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; + if (n1*n2!=m->size1*m->size2) return 0; + if (m->tda == m->size2) { + // No copying necessary, just create a new view of this matrix. + gsl_matrix_symbolic *m1 = + (gsl_matrix_symbolic*)malloc(sizeof(gsl_matrix_symbolic)); + assert(m1); + *m1 = *m; + m1->size1 = n1; m1->tda = m1->size2 = n2; + p = m1; + } else { + // Create a new matrix containing the same elements. + pure_expr *y = pure_symbolic_matrix_dup(m); + if (y) { + gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)y->data.mat.p; + m->size1 = n1; m->tda = m->size2 = n2; + } + return y; + } + break; + } +#ifdef HAVE_GSL + case EXPR::DMATRIX: { + gsl_matrix *m = (gsl_matrix*)x->data.mat.p; + if (n1*n2!=m->size1*m->size2) return 0; + if (m->tda == m->size2) { + // No copying necessary, just create a new view of this matrix. + gsl_matrix *m1 = (gsl_matrix*)malloc(sizeof(gsl_matrix)); + assert(m1); + *m1 = *m; + m1->size1 = n1; m1->tda = m1->size2 = n2; + p = m1; + } else { + // Create a new matrix containing the same elements. + pure_expr *y = pure_double_matrix_dup(m); + if (y) { + gsl_matrix *m = (gsl_matrix*)y->data.mat.p; + m->size1 = n1; m->tda = m->size2 = n2; + } + return y; + } + break; + } + case EXPR::CMATRIX: { + gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; + if (n1*n2!=m->size1*m->size2) return 0; + if (m->tda == m->size2) { + // No copying necessary, just create a new view of this matrix. + gsl_matrix_complex *m1 = + (gsl_matrix_complex*)malloc(sizeof(gsl_matrix_complex)); + assert(m1); + *m1 = *m; + m1->size1 = n1; m1->tda = m1->size2 = n2; + p = m1; + } else { + // Create a new matrix containing the same elements. + pure_expr *y = pure_complex_matrix_dup(m); + if (y) { + gsl_matrix_complex *m = (gsl_matrix_complex*)y->data.mat.p; + m->size1 = n1; m->tda = m->size2 = n2; + } + return y; + } + break; + } + case EXPR::IMATRIX: { + gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; + if (n1*n2!=m->size1*m->size2) return 0; + if (m->tda == m->size2) { + // No copying necessary, just create a new view of this matrix. + gsl_matrix_int *m1 = + (gsl_matrix_int*)malloc(sizeof(gsl_matrix_int)); + assert(m1); + *m1 = *m; + m1->size1 = n1; m1->tda = m1->size2 = n2; + p = m1; + } else { + // Create a new matrix containing the same elements. + pure_expr *y = pure_int_matrix_dup(m); + if (y) { + gsl_matrix_int *m = (gsl_matrix_int*)y->data.mat.p; + m->size1 = n1; m->tda = m->size2 = n2; + } + return y; + } + break; + } +#endif + default: + return 0; + } + pure_expr *y = new_expr(); + y->tag = x->tag; + y->data.mat.p = p; + y->data.mat.refc = x->data.mat.refc; + (*y->data.mat.refc)++; + MEMDEBUG_NEW(y) + return y; +} + +extern "C" pure_expr *matrix_rows(pure_expr *xs) { size_t n; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-22 17:46:47 UTC (rev 827) +++ pure/trunk/runtime.h 2008-09-22 19:20:24 UTC (rev 828) @@ -692,6 +692,11 @@ pure_expr *matrix_slice(pure_expr *x, int32_t i1, int32_t j1, int32_t i2, int32_t j2); +/* Convert a matrix to a new matrix with same size but different dimensions. + Reuse the storage of the original matrix if its data is contiguous. */ + +pure_expr *matrix_redim(pure_expr *x, int32_t n, int32_t m); + /* Matrix construction. These work like the pure_matrix_rows/ pure_matrix_columns functions in the public API, but take their input from a Pure list. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 17:46:52
|
Revision: 827 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=827&view=rev Author: agraef Date: 2008-09-22 17:46:47 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Add operation to pack matrices obtained as slices from larger matrices. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-22 17:24:18 UTC (rev 826) +++ pure/trunk/lib/primitives.pure 2008-09-22 17:46:47 UTC (rev 827) @@ -489,6 +489,14 @@ colcatmap f [] = {}; colcatmap f xs@(_:_) = colcat (map f xs); +/* 'Pack' a matrix. This creates a copy of the matrix which has the data in + contiguous storage. If possible, it also frees up extra memory if the + matrix was created as a slice from a bigger matrix. The 'packed' predicate + can be used to verify whether a matrix is already packed. */ + +pack x::matrix = colcat [x,{}]; +packed x::matrix = stride x==dim x!1; + /* Transpose a matrix. */ private matrix_transpose; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 17:24:22
|
Revision: 826 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=826&view=rev Author: agraef Date: 2008-09-22 17:24:18 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Comment change. Modified Paths: -------------- pure/trunk/runtime.h Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-22 10:05:45 UTC (rev 825) +++ pure/trunk/runtime.h 2008-09-22 17:24:18 UTC (rev 826) @@ -714,8 +714,10 @@ pure_expr *matrix_int(pure_expr *x); /* Extract the real and imaginary parts of a numeric matrix. If the input is a - complex matrix, the result is a double matrix. Otherwise the type of the - result is the same as that of the input matrix. */ + complex matrix, the result is a new double matrix. Otherwise the type of + the result is the same as that of the input matrix (in this case matrix_re + just returns the same matrix, and matrix_im returns a new zero matrix of + the same dimensions). */ pure_expr *matrix_re(pure_expr *x); pure_expr *matrix_im(pure_expr *x); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 10:05:54
|
Revision: 825 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=825&view=rev Author: agraef Date: 2008-09-22 10:05:45 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Add missing HAVE_GSL ifdefs. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-22 09:18:10 UTC (rev 824) +++ pure/trunk/runtime.cc 2008-09-22 10:05:45 UTC (rev 825) @@ -1350,6 +1350,7 @@ memcpy(data+i*tda, mat1->data+j*mat1->tda, ncols*sizeof(pure_expr*)); break; } +#ifdef HAVE_GSL case EXPR::DMATRIX: { gsl_matrix *mat1 = (gsl_matrix*)x->data.mat.p; if (mat1) @@ -1380,6 +1381,7 @@ } break; } +#endif default: data[i++*tda] = x; break; @@ -1411,6 +1413,7 @@ i += mat1->size2; break; } +#ifdef HAVE_GSL case EXPR::DMATRIX: { gsl_matrix *mat1 = (gsl_matrix*)x->data.mat.p; if (mat1) @@ -1444,6 +1447,7 @@ i += mat1->size2; break; } +#endif default: data[i++] = x; break; @@ -1565,12 +1569,14 @@ switch (target) { case EXPR::MATRIX: return symbolic_matrix_rows(nrows, ncols, n, xs); +#ifdef HAVE_GSL case EXPR::DMATRIX: return double_matrix_rows(nrows, ncols, n, xs); case EXPR::CMATRIX: return complex_matrix_rows(nrows, ncols, n, xs); case EXPR::IMATRIX: return int_matrix_rows(nrows, ncols, n, xs); +#endif default: return 0; } @@ -1678,12 +1684,14 @@ switch (target) { case EXPR::MATRIX: return symbolic_matrix_columns(nrows, ncols, n, xs); +#ifdef HAVE_GSL case EXPR::DMATRIX: return double_matrix_columns(nrows, ncols, n, xs); case EXPR::CMATRIX: return complex_matrix_columns(nrows, ncols, n, xs); case EXPR::IMATRIX: return int_matrix_columns(nrows, ncols, n, xs); +#endif default: return 0; } @@ -2668,12 +2676,14 @@ switch (target) { case EXPR::MATRIX: return symbolic_matrix_rows(nrows, ncols, n, xs); +#ifdef HAVE_GSL case EXPR::DMATRIX: return double_matrix_rows(nrows, ncols, n, xs); case EXPR::CMATRIX: return complex_matrix_rows(nrows, ncols, n, xs); case EXPR::IMATRIX: return int_matrix_rows(nrows, ncols, n, xs); +#endif default: assert(0 && "this can't happen"); return 0; @@ -2788,12 +2798,14 @@ switch (target) { case EXPR::MATRIX: return symbolic_matrix_columns(nrows, ncols, n, xs); +#ifdef HAVE_GSL case EXPR::DMATRIX: return double_matrix_columns(nrows, ncols, n, xs); case EXPR::CMATRIX: return complex_matrix_columns(nrows, ncols, n, xs); case EXPR::IMATRIX: return int_matrix_columns(nrows, ncols, n, xs); +#endif default: assert(0 && "this can't happen"); return 0; @@ -4656,6 +4668,7 @@ return 0; return 1; } +#ifdef HAVE_GSL case EXPR::DMATRIX: { gsl_matrix *m1 = (gsl_matrix*)x->data.mat.p; gsl_matrix *m2 = (gsl_matrix*)y->data.mat.p; @@ -4695,6 +4708,7 @@ return 0; return 1; } +#endif default: return 1; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 09:18:28
|
Revision: 824 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=824&view=rev Author: agraef Date: 2008-09-22 09:18:10 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/interpreter.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-22 00:42:36 UTC (rev 823) +++ pure/trunk/interpreter.cc 2008-09-22 09:18:10 UTC (rev 824) @@ -133,9 +133,9 @@ // Complex numbers (complex double). { std::vector<const Type*> elts; - //elts.push_back(ArrayType::get(Type::DoubleTy, 2)); - elts.push_back(Type::DoubleTy); - elts.push_back(Type::DoubleTy); + elts.push_back(ArrayType::get(Type::DoubleTy, 2)); + //elts.push_back(Type::DoubleTy); + //elts.push_back(Type::DoubleTy); ComplexTy = StructType::get(elts); ComplexPtrTy = PointerType::get(ComplexTy, 0); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 00:42:41
|
Revision: 823 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=823&view=rev Author: agraef Date: 2008-09-22 00:42:36 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Update syntax highlighting. Modified Paths: -------------- pure/trunk/etc/gpure.lang pure/trunk/etc/pure.lang pure/trunk/etc/pure.vim pure/trunk/etc/pure.xml Modified: pure/trunk/etc/gpure.lang =================================================================== --- pure/trunk/etc/gpure.lang 2008-09-22 00:23:30 UTC (rev 822) +++ pure/trunk/etc/gpure.lang 2008-09-22 00:42:36 UTC (rev 823) @@ -126,6 +126,10 @@ <keyword>void</keyword> <keyword>string</keyword> <keyword>pointer</keyword> + <keyword>matrix</keyword> + <keyword>dmatrix</keyword> + <keyword>cmatrix</keyword> + <keyword>imatrix</keyword> </context> <!-- http://www.lysator.liu.se/c/ANSI-C-grammar-l.html --> Modified: pure/trunk/etc/pure.lang =================================================================== --- pure/trunk/etc/pure.lang 2008-09-22 00:23:30 UTC (rev 822) +++ pure/trunk/etc/pure.lang 2008-09-22 00:42:36 UTC (rev 823) @@ -12,6 +12,7 @@ # Type identifiers used as tags and in extern declarations. $KW_LIST(kwc)=bigint bool char short int long double expr string pointer void +matrix dmatrix cmatrix imatrix # Numbers. $DIGIT=regex(0[xX][0-9a-fA-F]+L?|\d+(?:\.\d+)?(?:[eE][\-\+]\d+)?L?) Modified: pure/trunk/etc/pure.vim =================================================================== --- pure/trunk/etc/pure.vim 2008-09-22 00:23:30 UTC (rev 822) +++ pure/trunk/etc/pure.vim 2008-09-22 00:42:36 UTC (rev 823) @@ -38,6 +38,7 @@ syn keyword pureSpecial catch throw syn keyword pureType bigint bool char short int long double syn keyword pureType expr string pointer void +syn keyword pureType matrix dmatrix cmatrix imatrix syn match pureNumber "\<[0-9]*\>" syn match pureHexNumber "\<0[Xx][0-9A-Fa-f]*\>" Modified: pure/trunk/etc/pure.xml =================================================================== --- pure/trunk/etc/pure.xml 2008-09-22 00:23:30 UTC (rev 822) +++ pure/trunk/etc/pure.xml 2008-09-22 00:42:36 UTC (rev 823) @@ -45,6 +45,10 @@ <item> string </item> <item> pointer </item> <item> void </item> + <item> matrix </item> + <item> dmatrix </item> + <item> cmatrix </item> + <item> imatrix </item> </list> <contexts> <context attribute="Normal Text" lineEndContext="#stay" name="Normal"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-22 00:23:33
|
Revision: 822 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=822&view=rev Author: agraef Date: 2008-09-22 00:23:30 +0000 (Mon, 22 Sep 2008) Log Message: ----------- Optimize the case of contiguous slices. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-21 23:02:11 UTC (rev 821) +++ pure/trunk/lib/primitives.pure 2008-09-22 00:23:30 UTC (rev 822) @@ -435,7 +435,15 @@ /* Slices. */ -x::matrix!!(ns,ms) = colcatmap (mth (rowcatmap (nth x) ns)) ms with +x::matrix!!(ns,ms) = case ns,ms of + // optimize the case of contiguous slices + ns@(n:_),ms@(m:_) = submat x (n,m) (#ns,#ms) + if cont ns && cont ms; + _ = colcatmap (mth (rowcatmap (nth x) ns)) ms; + end with + cont [n] = 1; + cont (n::int:ns@(m::int:_)) = cont ns if m==n+1; + cont _ = 0 otherwise; nth x n = catch (cst {}) (row x n); mth x m = catch (cst {}) (col x m); end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 23:02:17
|
Revision: 821 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=821&view=rev Author: agraef Date: 2008-09-21 23:02:11 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Optimize the case of contiguous matrices in direct indexing. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-21 22:53:28 UTC (rev 820) +++ pure/trunk/runtime.cc 2008-09-21 23:02:11 UTC (rev 821) @@ -4139,24 +4139,38 @@ switch (x->tag) { case EXPR::MATRIX: { gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; - const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; - return m->data[k]; + if (m->tda > m->size2) { + const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; + return m->data[k]; + } else + return m->data[_i]; } #ifdef HAVE_GSL case EXPR::DMATRIX: { gsl_matrix *m = (gsl_matrix*)x->data.mat.p; - const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; - return pure_double(m->data[k]); + if (m->tda > m->size2) { + const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; + return pure_double(m->data[k]); + } else + return pure_double(m->data[_i]); } case EXPR::CMATRIX: { gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; - const size_t i = _i/m->size2, j = _i%m->size2, k = 2*(i*m->tda+j); - return make_complex(m->data[k], m->data[k+1]); + if (m->tda > m->size2) { + const size_t i = _i/m->size2, j = _i%m->size2, k = 2*(i*m->tda+j); + return make_complex(m->data[k], m->data[k+1]); + } else { + const size_t k = 2*_i; + return make_complex(m->data[k], m->data[k+1]); + } } case EXPR::IMATRIX: { gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; - const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; - return pure_int(m->data[k]); + if (m->tda > m->size2) { + const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; + return pure_int(m->data[k]); + } else + return pure_int(m->data[_i]); } #endif default: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 22:53:34
|
Revision: 820 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=820&view=rev Author: agraef Date: 2008-09-21 22:53:28 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Add function to determine the stride of a matrix. Modified Paths: -------------- pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-21 22:32:31 UTC (rev 819) +++ pure/trunk/lib/primitives.pure 2008-09-21 22:53:28 UTC (rev 820) @@ -412,11 +412,13 @@ /* Basic matrix operations: size, dimensions and indexing. */ -private matrix_size matrix_dim; -extern int matrix_size(expr *x), expr* matrix_dim(expr *x); +private matrix_size matrix_dim matrix_stride; +extern int matrix_size(expr *x), int matrix_stride(expr *x); +extern expr* matrix_dim(expr *x); #x::matrix = matrix_size x; dim x::matrix = matrix_dim x; +stride x::matrix = matrix_stride x; private matrix_elem_at matrix_elem_at2; extern expr* matrix_elem_at(expr* x, int i); Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-21 22:32:31 UTC (rev 819) +++ pure/trunk/runtime.cc 2008-09-21 22:53:28 UTC (rev 820) @@ -4096,6 +4096,33 @@ } extern "C" +uint32_t matrix_stride(pure_expr *x) +{ + switch (x->tag) { + case EXPR::MATRIX: { + gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; + return m->tda; + } +#ifdef HAVE_GSL + case EXPR::DMATRIX: { + gsl_matrix *m = (gsl_matrix*)x->data.mat.p; + return m->tda; + } + case EXPR::CMATRIX: { + gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; + return m->tda; + } + case EXPR::IMATRIX: { + gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; + return m->tda; + } +#endif + default: + return 0; + } +} + +extern "C" int32_t matrix_type(pure_expr *x) { uint32_t t = (uint32_t)x->tag; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-21 22:32:31 UTC (rev 819) +++ pure/trunk/runtime.h 2008-09-21 22:53:28 UTC (rev 820) @@ -660,13 +660,19 @@ /* Basic matrix operations. These work with all supported GSL matrix types. matrix_size determines the number of elements in a matrix, matrix_dim the - number of rows and columns, which are returned as a pair (n,m). matrix_type - determines the exact type of a matrix, returning an integer denoting the - subtype tag (0 = symbolic, 1 = double, 2 = complex, 3 = integer matrix; -1 - is returned if the given object is not a matrix). */ + number of rows and columns, which are returned as a pair (n,m). + matrix_stride returns the real row length of a matrix, which may be larger + than its column count if the matrix is actually a slice of a larger matrix. + (This value won't be of much use in Pure programs since there is no way to + access the "extra" elements in each row, but may be useful if the data + pointer is passed to an external C routine.) matrix_type determines the + exact type of a matrix, returning an integer denoting the subtype tag (0 = + symbolic, 1 = double, 2 = complex, 3 = integer matrix; -1 is returned if + the given object is not a matrix). */ uint32_t matrix_size(pure_expr *x); pure_expr *matrix_dim(pure_expr *x); +uint32_t matrix_stride(pure_expr *x); int32_t matrix_type(pure_expr *x); /* Matrix elements can be retrieved either by a single index (using row-major This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 22:32:36
|
Revision: 819 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=819&view=rev Author: agraef Date: 2008-09-21 22:32:31 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-21 22:10:36 UTC (rev 818) +++ pure/trunk/runtime.cc 2008-09-21 22:32:31 UTC (rev 819) @@ -4107,25 +4107,29 @@ } extern "C" -pure_expr *matrix_elem_at(pure_expr *x, int32_t i) +pure_expr *matrix_elem_at(pure_expr *x, int32_t _i) { switch (x->tag) { case EXPR::MATRIX: { gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; - return m->data[i]; + const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; + return m->data[k]; } #ifdef HAVE_GSL case EXPR::DMATRIX: { gsl_matrix *m = (gsl_matrix*)x->data.mat.p; - return pure_double(m->data[i]); + const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; + return pure_double(m->data[k]); } case EXPR::CMATRIX: { gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; - return make_complex(m->data[2*i], m->data[2*i+1]); + const size_t i = _i/m->size2, j = _i%m->size2, k = 2*(i*m->tda+j); + return make_complex(m->data[k], m->data[k+1]); } case EXPR::IMATRIX: { gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; - return pure_int(m->data[i]); + const size_t i = _i/m->size2, j = _i%m->size2, k = i*m->tda+j; + return pure_int(m->data[k]); } #endif default: @@ -4139,23 +4143,23 @@ switch (x->tag) { case EXPR::MATRIX: { gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; - size_t k = i*m->tda+j; + const size_t k = i*m->tda+j; return m->data[k]; } #ifdef HAVE_GSL case EXPR::DMATRIX: { gsl_matrix *m = (gsl_matrix*)x->data.mat.p; - size_t k = i*m->tda+j; + const size_t k = i*m->tda+j; return pure_double(m->data[k]); } case EXPR::CMATRIX: { gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; - size_t k = 2*(i*m->tda+j); + const size_t k = 2*(i*m->tda+j); return make_complex(m->data[k], m->data[k+1]); } case EXPR::IMATRIX: { gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; - size_t k = i*m->tda+j; + const size_t k = i*m->tda+j; return pure_int(m->data[k]); } #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 22:10:45
|
Revision: 818 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=818&view=rev Author: agraef Date: 2008-09-21 22:10:36 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-21 12:42:34 UTC (rev 817) +++ pure/trunk/runtime.cc 2008-09-21 22:10:36 UTC (rev 818) @@ -3536,10 +3536,24 @@ #else return pure_pointer((void*)(uint32_t)pure_get_int(x)); #endif - case EXPR::MATRIX: - case EXPR::DMATRIX: - case EXPR::CMATRIX: - case EXPR::IMATRIX: return pure_pointer(x->data.mat.p); + case EXPR::MATRIX: { + gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; + return pure_pointer(m->data); + } +#ifdef HAVE_GSL + case EXPR::DMATRIX: { + gsl_matrix *m = (gsl_matrix*)x->data.mat.p; + return pure_pointer(m->data); + } + case EXPR::CMATRIX: { + gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; + return pure_pointer(m->data); + } + case EXPR::IMATRIX:{ + gsl_matrix_int *m = (gsl_matrix_int*)x->data.mat.p; + return pure_pointer(m->data); + } +#endif default: return 0; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 12:42:44
|
Revision: 817 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=817&view=rev Author: agraef Date: 2008-09-21 12:42:34 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Eliminate broken complex number marshalling support. No easy way to make this work. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-21 07:44:02 UTC (rev 816) +++ pure/trunk/interpreter.cc 2008-09-21 12:42:34 UTC (rev 817) @@ -133,7 +133,9 @@ // Complex numbers (complex double). { std::vector<const Type*> elts; - elts.push_back(ArrayType::get(Type::DoubleTy, 2)); + //elts.push_back(ArrayType::get(Type::DoubleTy, 2)); + elts.push_back(Type::DoubleTy); + elts.push_back(Type::DoubleTy); ComplexTy = StructType::get(elts); ComplexPtrTy = PointerType::get(ComplexTy, 0); } @@ -375,16 +377,6 @@ declare_extern((void*)pure_get_matrix, "pure_get_matrix", "void*", 1, "expr*"); -#if COMPLEX_NUMBERS - /* Marshalling of complex numbers. This doesn't work yet and is disabled. */ - declare_extern((void*)pure_complex, - "pure_complex", "expr*", 1, "complex"); - declare_extern((void*)pure_is_complex, - "pure_is_complex", "bool", 1, "expr*"); - declare_extern((void*)pure_get_complex, - "pure_get_complex", "complex", 1, "expr*"); -#endif - declare_extern((void*)pure_catch, "pure_catch", "expr*", 2, "expr*", "expr*"); declare_extern((void*)pure_throw, @@ -3673,10 +3665,6 @@ return Type::FloatTy; else if (name == "double") return Type::DoubleTy; -#if COMPLEX_NUMBERS - else if (name == "complex") - return ComplexTy; -#endif else if (name == "char*") return CharPtrTy; else if (name == "short*") @@ -3687,10 +3675,6 @@ return PointerType::get(Type::Int64Ty, 0); else if (name == "double*") return PointerType::get(Type::DoubleTy, 0); -#if COMPLEX_NUMBERS - else if (name == "complex*") - return ComplexPtrTy; -#endif else if (name == "expr*") return ExprPtrTy; else if (name == "expr**") @@ -3730,10 +3714,6 @@ return "float"; else if (type == Type::DoubleTy) return "double"; -#if COMPLEX_NUMBERS - else if (type == ComplexTy) - return "complex"; -#endif else if (type == CharPtrTy) return "char*"; else if (type == PointerType::get(Type::Int16Ty, 0)) @@ -3744,10 +3724,6 @@ return "long*"; else if (type == PointerType::get(Type::DoubleTy, 0)) return "double*"; -#if COMPLEX_NUMBERS - else if (type == ComplexPtrTy) - return "complex*"; -#endif else if (type == ExprPtrTy) return "expr*"; else if (type == ExprPtrPtrTy) @@ -4093,19 +4069,6 @@ idx[1] = ValFldIndex; Value *dv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "dblval"); unboxed[i] = dv; -#if COMPLEX_NUMBERS - } else if (argt[i] == ComplexTy) { - BasicBlock *okbb = BasicBlock::Create("ok"); - // Pure's complex values are a special algebraic data type defined in - // math.pure, hence we have to go to some lengths here to get these - // values. - Value *chk = b.CreateCall(module->getFunction("pure_is_complex"), x); - b.CreateCondBr(chk, okbb, failedbb); - f->getBasicBlockList().push_back(okbb); - b.SetInsertPoint(okbb); - Value *cv = b.CreateCall(module->getFunction("pure_get_complex"), x); - unboxed[i] = cv; -#endif } else if (argt[i] == CharPtrTy) { BasicBlock *okbb = BasicBlock::Create("ok"); Value *idx[2] = { Zero, Zero }; @@ -4120,11 +4083,7 @@ argt[i] == PointerType::get(Type::Int32Ty, 0) || argt[i] == PointerType::get(Type::Int64Ty, 0) || argt[i] == PointerType::get(Type::FloatTy, 0) || - argt[i] == PointerType::get(Type::DoubleTy, 0) -#if COMPLEX_NUMBERS - || argt[i] == ComplexPtrTy -#endif - ) { + argt[i] == PointerType::get(Type::DoubleTy, 0)) { BasicBlock *okbb = BasicBlock::Create("ok"); Value *idx[2] = { Zero, Zero }; Value *tagv = b.CreateLoad(b.CreateGEP(x, idx, idx+2), "tag"); @@ -4230,21 +4189,13 @@ b.CreateFPExt(u, Type::DoubleTy)); else if (type == Type::DoubleTy) u = b.CreateCall(module->getFunction("pure_double"), u); -#if COMPLEX_NUMBERS - else if (type == ComplexTy) - u = b.CreateCall(module->getFunction("pure_complex"), u); -#endif else if (type == CharPtrTy) u = b.CreateCall(module->getFunction("pure_cstring_dup"), u); else if (type == PointerType::get(Type::Int16Ty, 0) || type == PointerType::get(Type::Int32Ty, 0) || type == PointerType::get(Type::Int64Ty, 0) || type == PointerType::get(Type::FloatTy, 0) || - type == PointerType::get(Type::DoubleTy, 0) -#if COMPLEX_NUMBERS - || type == ComplexPtrTy -#endif - ) + type == PointerType::get(Type::DoubleTy, 0)) u = b.CreateCall(module->getFunction("pure_pointer"), b.CreateBitCast(u, VoidPtrTy)); else if (type == GSLMatrixPtrTy) Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-09-21 07:44:02 UTC (rev 816) +++ pure/trunk/interpreter.hh 2008-09-21 12:42:34 UTC (rev 817) @@ -41,13 +41,6 @@ default, use 0 to disable this option). */ #define LIST_KLUDGE 10 -/* Experimental support for marshalling of complex numbers in the C - interface. This doesn't work right now and is disabled. LLVM doesn't seem - to provide a transparent way to handle complex values in function calls - yet, and maybe this isn't even possible because different compilers might - specify different ABIs to do that kind of thing. */ -#define COMPLEX_NUMBERS 0 - using namespace std; /* The Pure interpreter. */ Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-21 07:44:02 UTC (rev 816) +++ pure/trunk/runtime.cc 2008-09-21 12:42:34 UTC (rev 817) @@ -2048,6 +2048,26 @@ } extern "C" +pure_expr *pure_complex(double c[2]) +{ + return make_complex(c[0], c[1]); +} + +extern "C" +bool pure_is_complex(pure_expr *x, double *c) +{ + double a, b; + if (get_complex(x, a, b)) { + if (c) { + c[0] = a; + c[1] = b; + } + return true; + } else + return false; +} + +extern "C" pure_expr *pure_new(pure_expr *x) { return pure_new_internal(x); @@ -2543,33 +2563,7 @@ return &x->data.z; } -#if COMPLEX_NUMBERS extern "C" -pure_expr *pure_complex(__complex_double c) -{ - return make_complex(c.x[0], c.x[1]); -} - -extern "C" -bool pure_is_complex(pure_expr *x) -{ - return is_complex(x); -} - -extern "C" -__complex_double pure_get_complex(pure_expr *x) -{ - __complex_double res = {{0.0,0.0}}; - double a, b; - if (get_complex(x, a, b)) { - res.x[0] = a; - res.x[1] = b; - } - return res; -} -#endif - -extern "C" void *pure_get_matrix(pure_expr *x) { assert(x && x->tag == EXPR::MATRIX || x->tag == EXPR::DMATRIX || Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-21 07:44:02 UTC (rev 816) +++ pure/trunk/runtime.h 2008-09-21 12:42:34 UTC (rev 817) @@ -290,6 +290,15 @@ bool pure_is_listv(pure_expr *x, size_t *size, pure_expr ***elems); bool pure_is_tuplev(pure_expr *x, size_t *size, pure_expr ***elems); +/* Complex number support. These are actually defined as an algebraic type in + math.pure, but some applications may require access to these values in the + C interface. Note that we don't want to rely on ISOC99 complex number + support or any kind of third-party library here, so this API represents + complex values simply as a double[2]. */ + +pure_expr *pure_complex(double c[2]); +bool pure_is_complex(pure_expr *x, double *c); + /* Memory management. */ /* Count a new reference to an expression. This should be called whenever you @@ -438,21 +447,6 @@ int64_t pure_get_long(pure_expr *x); int32_t pure_get_int(pure_expr *x); -#if 0 -// This stuff is disabled right now as it doesn't work yet. -/* Marshall complex numbers. These are actually defined as an algebraic type - in math.pure, but we need some basic support for these values in the C - interface. */ - -/* We don't want to rely on ISO complex number support here. The following - should do the job on all supported systems. */ -typedef struct { double x[2]; } __complex_double; - -pure_expr *pure_complex(__complex_double c); -bool pure_is_complex(pure_expr *x); -__complex_double pure_get_complex(pure_expr *x); -#endif - /* Convert a matrix expression to a pointer to the corresponding GSL matrix struct. This is used to marshall matrix arguments in the C interface. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 07:44:08
|
Revision: 816 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=816&view=rev Author: agraef Date: 2008-09-21 07:44:02 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Experimental support for marshalling complex numbers (this doesn't work right now, and so is disabled). Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-21 05:29:14 UTC (rev 815) +++ pure/trunk/interpreter.cc 2008-09-21 07:44:02 UTC (rev 816) @@ -133,8 +133,7 @@ // Complex numbers (complex double). { std::vector<const Type*> elts; - elts.push_back(Type::DoubleTy); - elts.push_back(Type::DoubleTy); + elts.push_back(ArrayType::get(Type::DoubleTy, 2)); ComplexTy = StructType::get(elts); ComplexPtrTy = PointerType::get(ComplexTy, 0); } @@ -376,6 +375,16 @@ declare_extern((void*)pure_get_matrix, "pure_get_matrix", "void*", 1, "expr*"); +#if COMPLEX_NUMBERS + /* Marshalling of complex numbers. This doesn't work yet and is disabled. */ + declare_extern((void*)pure_complex, + "pure_complex", "expr*", 1, "complex"); + declare_extern((void*)pure_is_complex, + "pure_is_complex", "bool", 1, "expr*"); + declare_extern((void*)pure_get_complex, + "pure_get_complex", "complex", 1, "expr*"); +#endif + declare_extern((void*)pure_catch, "pure_catch", "expr*", 2, "expr*", "expr*"); declare_extern((void*)pure_throw, @@ -3664,7 +3673,7 @@ return Type::FloatTy; else if (name == "double") return Type::DoubleTy; -#if 0 // no marshalling available yet, does LLVM support these? +#if COMPLEX_NUMBERS else if (name == "complex") return ComplexTy; #endif @@ -3678,7 +3687,7 @@ return PointerType::get(Type::Int64Ty, 0); else if (name == "double*") return PointerType::get(Type::DoubleTy, 0); -#if 0 +#if COMPLEX_NUMBERS else if (name == "complex*") return ComplexPtrTy; #endif @@ -3721,8 +3730,10 @@ return "float"; else if (type == Type::DoubleTy) return "double"; +#if COMPLEX_NUMBERS else if (type == ComplexTy) return "complex"; +#endif else if (type == CharPtrTy) return "char*"; else if (type == PointerType::get(Type::Int16Ty, 0)) @@ -3733,8 +3744,10 @@ return "long*"; else if (type == PointerType::get(Type::DoubleTy, 0)) return "double*"; +#if COMPLEX_NUMBERS else if (type == ComplexPtrTy) return "complex*"; +#endif else if (type == ExprPtrTy) return "expr*"; else if (type == ExprPtrPtrTy) @@ -4080,6 +4093,19 @@ idx[1] = ValFldIndex; Value *dv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "dblval"); unboxed[i] = dv; +#if COMPLEX_NUMBERS + } else if (argt[i] == ComplexTy) { + BasicBlock *okbb = BasicBlock::Create("ok"); + // Pure's complex values are a special algebraic data type defined in + // math.pure, hence we have to go to some lengths here to get these + // values. + Value *chk = b.CreateCall(module->getFunction("pure_is_complex"), x); + b.CreateCondBr(chk, okbb, failedbb); + f->getBasicBlockList().push_back(okbb); + b.SetInsertPoint(okbb); + Value *cv = b.CreateCall(module->getFunction("pure_get_complex"), x); + unboxed[i] = cv; +#endif } else if (argt[i] == CharPtrTy) { BasicBlock *okbb = BasicBlock::Create("ok"); Value *idx[2] = { Zero, Zero }; @@ -4094,7 +4120,11 @@ argt[i] == PointerType::get(Type::Int32Ty, 0) || argt[i] == PointerType::get(Type::Int64Ty, 0) || argt[i] == PointerType::get(Type::FloatTy, 0) || - argt[i] == PointerType::get(Type::DoubleTy, 0)) { + argt[i] == PointerType::get(Type::DoubleTy, 0) +#if COMPLEX_NUMBERS + || argt[i] == ComplexPtrTy +#endif + ) { BasicBlock *okbb = BasicBlock::Create("ok"); Value *idx[2] = { Zero, Zero }; Value *tagv = b.CreateLoad(b.CreateGEP(x, idx, idx+2), "tag"); @@ -4200,13 +4230,21 @@ b.CreateFPExt(u, Type::DoubleTy)); else if (type == Type::DoubleTy) u = b.CreateCall(module->getFunction("pure_double"), u); +#if COMPLEX_NUMBERS + else if (type == ComplexTy) + u = b.CreateCall(module->getFunction("pure_complex"), u); +#endif else if (type == CharPtrTy) u = b.CreateCall(module->getFunction("pure_cstring_dup"), u); else if (type == PointerType::get(Type::Int16Ty, 0) || type == PointerType::get(Type::Int32Ty, 0) || type == PointerType::get(Type::Int64Ty, 0) || type == PointerType::get(Type::FloatTy, 0) || - type == PointerType::get(Type::DoubleTy, 0)) + type == PointerType::get(Type::DoubleTy, 0) +#if COMPLEX_NUMBERS + || type == ComplexPtrTy +#endif + ) u = b.CreateCall(module->getFunction("pure_pointer"), b.CreateBitCast(u, VoidPtrTy)); else if (type == GSLMatrixPtrTy) Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-09-21 05:29:14 UTC (rev 815) +++ pure/trunk/interpreter.hh 2008-09-21 07:44:02 UTC (rev 816) @@ -41,6 +41,13 @@ default, use 0 to disable this option). */ #define LIST_KLUDGE 10 +/* Experimental support for marshalling of complex numbers in the C + interface. This doesn't work right now and is disabled. LLVM doesn't seem + to provide a transparent way to handle complex values in function calls + yet, and maybe this isn't even possible because different compilers might + specify different ABIs to do that kind of thing. */ +#define COMPLEX_NUMBERS 0 + using namespace std; /* The Pure interpreter. */ Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-21 05:29:14 UTC (rev 815) +++ pure/trunk/runtime.cc 2008-09-21 07:44:02 UTC (rev 816) @@ -890,6 +890,28 @@ #endif } +static inline bool is_complex(pure_expr *x) +{ + if (x->tag != EXPR::APP) return false; + pure_expr *u = x->data.x[0], *v = x->data.x[1]; + if (u->tag == EXPR::APP) { + interpreter& interp = *interpreter::g_interp; + pure_expr *f = u->data.x[0]; + symbol *rect = interp.symtab.complex_rect_sym(), + *polar = interp.symtab.complex_polar_sym(); + if ((!rect || f->tag != rect->f) && + (!polar || f->tag != polar->f)) + return false; + u = u->data.x[1]; + if (u->tag != EXPR::INT && u->tag != EXPR::DBL || + v->tag != EXPR::INT && v->tag != EXPR::DBL) + return false; + else + return true; + } else + return false; +} + static inline bool get_complex(pure_expr *x, double& a, double& b) { if (x->tag != EXPR::APP) return false; @@ -2521,7 +2543,33 @@ return &x->data.z; } +#if COMPLEX_NUMBERS extern "C" +pure_expr *pure_complex(__complex_double c) +{ + return make_complex(c.x[0], c.x[1]); +} + +extern "C" +bool pure_is_complex(pure_expr *x) +{ + return is_complex(x); +} + +extern "C" +__complex_double pure_get_complex(pure_expr *x) +{ + __complex_double res = {{0.0,0.0}}; + double a, b; + if (get_complex(x, a, b)) { + res.x[0] = a; + res.x[1] = b; + } + return res; +} +#endif + +extern "C" void *pure_get_matrix(pure_expr *x) { assert(x && x->tag == EXPR::MATRIX || x->tag == EXPR::DMATRIX || Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-21 05:29:14 UTC (rev 815) +++ pure/trunk/runtime.h 2008-09-21 07:44:02 UTC (rev 816) @@ -438,6 +438,21 @@ int64_t pure_get_long(pure_expr *x); int32_t pure_get_int(pure_expr *x); +#if 0 +// This stuff is disabled right now as it doesn't work yet. +/* Marshall complex numbers. These are actually defined as an algebraic type + in math.pure, but we need some basic support for these values in the C + interface. */ + +/* We don't want to rely on ISO complex number support here. The following + should do the job on all supported systems. */ +typedef struct { double x[2]; } __complex_double; + +pure_expr *pure_complex(__complex_double c); +bool pure_is_complex(pure_expr *x); +__complex_double pure_get_complex(pure_expr *x); +#endif + /* Convert a matrix expression to a pointer to the corresponding GSL matrix struct. This is used to marshall matrix arguments in the C interface. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 05:29:17
|
Revision: 815 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=815&view=rev Author: agraef Date: 2008-09-21 05:29:14 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Updated NEWS and ChangeLog. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/NEWS Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-09-21 05:24:34 UTC (rev 814) +++ pure/trunk/ChangeLog 2008-09-21 05:29:14 UTC (rev 815) @@ -3,7 +3,9 @@ * Implemented basic GSL matrix support, including support for symbolic matrices (which is independent from GSL, so these will also work when building the interpreter without GSL) and matrix - comprehensions. This required many additions and changes to the + comprehensions. Marshalling of matrices in the C interface is also + implemented, so that you can interface to GSL matrix functions + without much ado. This required many additions and changes to the parser, interpreter, compiler, runtime and the prelude; details can be found in the svn log (see r759 and r769ff.). Modified: pure/trunk/NEWS =================================================================== --- pure/trunk/NEWS 2008-09-21 05:24:34 UTC (rev 814) +++ pure/trunk/NEWS 2008-09-21 05:29:14 UTC (rev 815) @@ -67,7 +67,10 @@ type-checking and various conversions between the different kinds of matrices. To these ends, various basic operations to deal with matrix objects have been added to the runtime, including some public API operations to create -and inspect Pure matrix values from external C modules. +and inspect Pure matrix values from external C modules. Moreover, the +'pointer' function in the prelude can be used to convert matrices to Pure +pointer values, and marshalling of GSL matrices in the C interface is also +available. Here is a brief synopsis of some important operations which are already implemented in the prelude (you can find the definitions of these and the @@ -81,6 +84,8 @@ - x!!is, x!!(is,js) slicing (is and js are lists of machine ints) - x==y, x!=y matrix comparisons +Adding other operations by interfacing to GSL should be a piece of cake. + Other user-visible changes prompted by the introduction of the matrix syntax are listed below: @@ -96,11 +101,6 @@ lower precedence than the ',' operator, which makes writing matrix slices like x!!(i..j,k..l) much more convenient. -Stuff that's still missing: - -- Marshalling of GSL matrices in the C interface, so that it becomes possible -to access all the advanced functionality available in GSL. - ** Pure 0.6 2008-09-12 New stuff in this release (please see the ChangeLog and the manual for This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-21 05:24:41
|
Revision: 814 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=814&view=rev Author: agraef Date: 2008-09-21 05:24:34 +0000 (Sun, 21 Sep 2008) Log Message: ----------- Marshalling of matrix values in the C interface. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-20 20:53:03 UTC (rev 813) +++ pure/trunk/interpreter.cc 2008-09-21 05:24:34 UTC (rev 814) @@ -126,6 +126,98 @@ // Char pointer type. CharPtrTy = PointerType::get(Type::Int8Ty, 0); + // int and double pointers. + IntPtrTy = PointerType::get(Type::Int32Ty, 0); + DoublePtrTy = PointerType::get(Type::DoubleTy, 0); + + // Complex numbers (complex double). + { + std::vector<const Type*> elts; + elts.push_back(Type::DoubleTy); + elts.push_back(Type::DoubleTy); + ComplexTy = StructType::get(elts); + ComplexPtrTy = PointerType::get(ComplexTy, 0); + } + + // GSL matrix types. These are used to marshall GSL matrices in the C + // interface. + { + std::vector<const Type*> elts; + if (sizeof(size_t) == 4) { + elts.push_back(Type::Int32Ty); // size1 + elts.push_back(Type::Int32Ty); // size2 + elts.push_back(Type::Int32Ty); // tda + } else { + assert(sizeof(size_t) == 8); + elts.push_back(Type::Int64Ty); // size1 + elts.push_back(Type::Int64Ty); // size2 + elts.push_back(Type::Int64Ty); // tda + } + elts.push_back(VoidPtrTy); // data + elts.push_back(VoidPtrTy); // block + elts.push_back(Type::Int32Ty); // owner + GSLMatrixTy = StructType::get(elts); + module->addTypeName("struct.gsl_matrix", GSLMatrixTy); + GSLMatrixPtrTy = PointerType::get(GSLMatrixTy, 0); + } + { + std::vector<const Type*> elts; + if (sizeof(size_t) == 4) { + elts.push_back(Type::Int32Ty); // size1 + elts.push_back(Type::Int32Ty); // size2 + elts.push_back(Type::Int32Ty); // tda + } else { + assert(sizeof(size_t) == 8); + elts.push_back(Type::Int64Ty); // size1 + elts.push_back(Type::Int64Ty); // size2 + elts.push_back(Type::Int64Ty); // tda + } + elts.push_back(DoublePtrTy); // data + elts.push_back(VoidPtrTy); // block + elts.push_back(Type::Int32Ty); // owner + GSLDoubleMatrixTy = StructType::get(elts); + module->addTypeName("struct.gsl_matrix_double", GSLDoubleMatrixTy); + GSLDoubleMatrixPtrTy = PointerType::get(GSLDoubleMatrixTy, 0); + } + { + std::vector<const Type*> elts; + if (sizeof(size_t) == 4) { + elts.push_back(Type::Int32Ty); // size1 + elts.push_back(Type::Int32Ty); // size2 + elts.push_back(Type::Int32Ty); // tda + } else { + assert(sizeof(size_t) == 8); + elts.push_back(Type::Int64Ty); // size1 + elts.push_back(Type::Int64Ty); // size2 + elts.push_back(Type::Int64Ty); // tda + } + elts.push_back(ComplexPtrTy); // data + elts.push_back(VoidPtrTy); // block + elts.push_back(Type::Int32Ty); // owner + GSLComplexMatrixTy = StructType::get(elts); + module->addTypeName("struct.gsl_matrix_complex", GSLComplexMatrixTy); + GSLComplexMatrixPtrTy = PointerType::get(GSLComplexMatrixTy, 0); + } + { + std::vector<const Type*> elts; + if (sizeof(size_t) == 4) { + elts.push_back(Type::Int32Ty); // size1 + elts.push_back(Type::Int32Ty); // size2 + elts.push_back(Type::Int32Ty); // tda + } else { + assert(sizeof(size_t) == 8); + elts.push_back(Type::Int64Ty); // size1 + elts.push_back(Type::Int64Ty); // size2 + elts.push_back(Type::Int64Ty); // tda + } + elts.push_back(IntPtrTy); // data + elts.push_back(VoidPtrTy); // block + elts.push_back(Type::Int32Ty); // owner + GSLIntMatrixTy = StructType::get(elts); + module->addTypeName("struct.gsl_matrix_int", GSLIntMatrixTy); + GSLIntMatrixPtrTy = PointerType::get(GSLIntMatrixTy, 0); + } + // Create the expr struct type. /* NOTE: This is in fact just a part of the prologue of the expression data @@ -248,9 +340,17 @@ "pure_apply", "expr*", 2, "expr*", "expr*"); declare_extern((void*)pure_matrix_rows, - "pure_matrix_rows", "expr*", -1, "int"); + "pure_matrix_rows", "expr*", -1, "int"); declare_extern((void*)pure_matrix_columns, "pure_matrix_columns", "expr*", -1, "int"); + declare_extern((void*)pure_symbolic_matrix, + "pure_symbolic_matrix", "expr*", 1, "void*"); + declare_extern((void*)pure_double_matrix, + "pure_double_matrix", "expr*", 1, "void*"); + declare_extern((void*)pure_complex_matrix, + "pure_complex_matrix", "expr*", 1, "void*"); + declare_extern((void*)pure_int_matrix, + "pure_int_matrix", "expr*", 1, "void*"); declare_extern((void*)pure_listl, "pure_listl", "expr*", -1, "int"); @@ -273,6 +373,8 @@ "pure_get_long", "long", 1, "expr*"); declare_extern((void*)pure_get_int, "pure_get_int", "int", 1, "expr*"); + declare_extern((void*)pure_get_matrix, + "pure_get_matrix", "void*", 1, "expr*"); declare_extern((void*)pure_catch, "pure_catch", "expr*", 2, "expr*", "expr*"); @@ -3562,6 +3664,10 @@ return Type::FloatTy; else if (name == "double") return Type::DoubleTy; +#if 0 // no marshalling available yet, does LLVM support these? + else if (name == "complex") + return ComplexTy; +#endif else if (name == "char*") return CharPtrTy; else if (name == "short*") @@ -3572,10 +3678,22 @@ return PointerType::get(Type::Int64Ty, 0); else if (name == "double*") return PointerType::get(Type::DoubleTy, 0); +#if 0 + else if (name == "complex*") + return ComplexPtrTy; +#endif else if (name == "expr*") return ExprPtrTy; else if (name == "expr**") return ExprPtrPtrTy; + else if (name == "matrix*") + return GSLMatrixPtrTy; + else if (name == "dmatrix*") + return GSLDoubleMatrixPtrTy; + else if (name == "cmatrix*") + return GSLComplexMatrixPtrTy; + else if (name == "imatrix*") + return GSLIntMatrixPtrTy; else if (name == "void*") return VoidPtrTy; else if (name.size() > 0 && name[name.size()-1] == '*') @@ -3603,6 +3721,8 @@ return "float"; else if (type == Type::DoubleTy) return "double"; + else if (type == ComplexTy) + return "complex"; else if (type == CharPtrTy) return "char*"; else if (type == PointerType::get(Type::Int16Ty, 0)) @@ -3613,10 +3733,20 @@ return "long*"; else if (type == PointerType::get(Type::DoubleTy, 0)) return "double*"; + else if (type == ComplexPtrTy) + return "complex*"; else if (type == ExprPtrTy) return "expr*"; else if (type == ExprPtrPtrTy) return "expr**"; + else if (type == GSLMatrixPtrTy) + return "matrix*"; + else if (type == GSLDoubleMatrixPtrTy) + return "dmatrix*"; + else if (type == GSLComplexMatrixPtrTy) + return "cmatrix*"; + else if (type == GSLIntMatrixPtrTy) + return "imatrix*"; else if (type == VoidPtrTy) return "void*"; else if (type->getTypeID() == Type::PointerTyID) @@ -3794,7 +3924,6 @@ Value *x = args[i]; // check for thunks which must be forced if (argt[i] != ExprPtrTy) { -#if 1 // do a quick check on the tag value Value *idx[2] = { Zero, Zero }; Value *tagv = b.CreateLoad(b.CreateGEP(x, idx, idx+2), "tag"); @@ -3808,9 +3937,6 @@ b.CreateBr(skipbb); f->getBasicBlockList().push_back(skipbb); b.SetInsertPoint(skipbb); -#else - b.CreateCall(module->getFunction("pure_force"), x); -#endif } if (argt[i] == Type::Int1Ty) { BasicBlock *okbb = BasicBlock::Create("ok"); @@ -3980,6 +4106,28 @@ idx[1] = ValFldIndex; Value *ptrv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "ptrval"); unboxed[i] = b.CreateBitCast(ptrv, argt[i]); + } else if (argt[i] == GSLMatrixPtrTy || + argt[i] == GSLDoubleMatrixPtrTy || + argt[i] == GSLComplexMatrixPtrTy || + argt[i] == GSLIntMatrixPtrTy) { + BasicBlock *okbb = BasicBlock::Create("ok"); + Value *idx[2] = { Zero, Zero }; + Value *tagv = b.CreateLoad(b.CreateGEP(x, idx, idx+2), "tag"); + int32_t ttag = -99; + if (argt[i] == GSLMatrixPtrTy) + ttag = EXPR::MATRIX; + else if (argt[i] == GSLDoubleMatrixPtrTy) + ttag = EXPR::DMATRIX; + else if (argt[i] == GSLComplexMatrixPtrTy) + ttag = EXPR::CMATRIX; + else if (argt[i] == GSLIntMatrixPtrTy) + ttag = EXPR::IMATRIX; + b.CreateCondBr + (b.CreateICmpEQ(tagv, SInt(ttag), "cmp"), okbb, failedbb); + f->getBasicBlockList().push_back(okbb); + b.SetInsertPoint(okbb); + Value *matv = b.CreateCall(module->getFunction("pure_get_matrix"), x); + unboxed[i] = b.CreateBitCast(matv, argt[i]); } else if (argt[i] == ExprPtrTy) { // passed through unboxed[i] = x; @@ -4061,6 +4209,18 @@ type == PointerType::get(Type::DoubleTy, 0)) u = b.CreateCall(module->getFunction("pure_pointer"), b.CreateBitCast(u, VoidPtrTy)); + else if (type == GSLMatrixPtrTy) + u = b.CreateCall(module->getFunction("pure_symbolic_matrix"), + b.CreateBitCast(u, VoidPtrTy)); + else if (type == GSLDoubleMatrixPtrTy) + u = b.CreateCall(module->getFunction("pure_double_matrix"), + b.CreateBitCast(u, VoidPtrTy)); + else if (type == GSLComplexMatrixPtrTy) + u = b.CreateCall(module->getFunction("pure_complex_matrix"), + b.CreateBitCast(u, VoidPtrTy)); + else if (type == GSLIntMatrixPtrTy) + u = b.CreateCall(module->getFunction("pure_int_matrix"), + b.CreateBitCast(u, VoidPtrTy)); else if (type == ExprPtrTy) { // check that we actually got a valid pointer; otherwise the call failed BasicBlock *okbb = BasicBlock::Create("ok"); Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-09-20 20:53:03 UTC (rev 813) +++ pure/trunk/interpreter.hh 2008-09-21 05:24:34 UTC (rev 814) @@ -493,9 +493,13 @@ llvm::ExecutionEngine *JIT; llvm::FunctionPassManager *FPM; llvm::StructType *ExprTy, *IntExprTy, *DblExprTy, *StrExprTy, *PtrExprTy; + llvm::StructType *ComplexTy, *GSLMatrixTy, *GSLDoubleMatrixTy, + *GSLComplexMatrixTy, *GSLIntMatrixTy; llvm::PointerType *ExprPtrTy, *ExprPtrPtrTy; llvm::PointerType *IntExprPtrTy, *DblExprPtrTy, *StrExprPtrTy, *PtrExprPtrTy; - llvm::PointerType *VoidPtrTy, *CharPtrTy; + llvm::PointerType *VoidPtrTy, *CharPtrTy, *IntPtrTy, *DoublePtrTy; + llvm::PointerType *ComplexPtrTy, *GSLMatrixPtrTy, *GSLDoubleMatrixPtrTy, + *GSLComplexMatrixPtrTy, *GSLIntMatrixPtrTy; const llvm::Type *named_type(string name); const char *type_name(const llvm::Type *type); map<int32_t,GlobalVar> globalvars; Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-09-20 20:53:03 UTC (rev 813) +++ pure/trunk/lib/primitives.pure 2008-09-21 05:24:34 UTC (rev 814) @@ -117,7 +117,8 @@ pointer x::int | pointer x::bigint | pointer x::double | -pointer x::string = pure_pointerval x; +pointer x::string | +pointer x::matrix = pure_pointerval x; /* Convert signed (8/16/32/64) bit integers to the corresponding unsigned quantities. These functions behave as if the value was "cast" to the Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-20 20:53:03 UTC (rev 813) +++ pure/trunk/runtime.cc 2008-09-21 05:24:34 UTC (rev 814) @@ -2522,6 +2522,14 @@ } extern "C" +void *pure_get_matrix(pure_expr *x) +{ + assert(x && x->tag == EXPR::MATRIX || x->tag == EXPR::DMATRIX || + x->tag == EXPR::CMATRIX || x->tag == EXPR::IMATRIX); + return x->data.mat.p; +} + +extern "C" pure_expr *pure_matrix_rows(uint32_t n, ...) { va_list ap; @@ -3486,6 +3494,10 @@ #else return pure_pointer((void*)(uint32_t)pure_get_int(x)); #endif + case EXPR::MATRIX: + case EXPR::DMATRIX: + case EXPR::CMATRIX: + case EXPR::IMATRIX: return pure_pointer(x->data.mat.p); default: return 0; } } Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-20 20:53:03 UTC (rev 813) +++ pure/trunk/runtime.h 2008-09-21 05:24:34 UTC (rev 814) @@ -438,6 +438,11 @@ int64_t pure_get_long(pure_expr *x); int32_t pure_get_int(pure_expr *x); +/* Convert a matrix expression to a pointer to the corresponding GSL matrix + struct. This is used to marshall matrix arguments in the C interface. */ + +void *pure_get_matrix(pure_expr *x); + /* Additional matrix constructors. These work like pure_matrix_rowsl and pure_matrix_columnsl in the public API, but are intended to be called directly from generated code and raise the appropriate Pure exceptions in @@ -546,7 +551,8 @@ an expression denoting an int, double, bigint or pointer value. The numeric value of a pointer is its address, cast to a suitably large integer type, which can be converted to/from an integer, but not a double value. Strings - can be converted to pointers as well, but not the other way round. */ + and matrices can be converted to pointers as well, but not the other way + round. */ pure_expr *pure_intval(pure_expr *x); pure_expr *pure_dblval(pure_expr *x); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-20 20:53:12
|
Revision: 813 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=813&view=rev Author: agraef Date: 2008-09-20 20:53:03 +0000 (Sat, 20 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-20 20:33:16 UTC (rev 812) +++ pure/trunk/runtime.cc 2008-09-20 20:53:03 UTC (rev 813) @@ -375,6 +375,12 @@ switch (x->tag) { case EXPR::MATRIX: { gsl_matrix_symbolic *m = (gsl_matrix_symbolic*)x->data.mat.p; + if (owner) { + const size_t k = m->size1, l = m->size2, tda = m->tda;; + for (size_t i = 0; i < k; i++) + for (size_t j = 0; j < l; j++) + pure_free(m->data[i*tda+j]); + } m->owner = owner; gsl_matrix_symbolic_free(m); break; @@ -756,6 +762,11 @@ pure_expr *x = new_expr(); x->tag = EXPR::MATRIX; x->data.mat.p = p; + // count references + const size_t k = m->size1, l = m->size2, tda = m->tda;; + for (size_t i = 0; i < k; i++) + for (size_t j = 0; j < l; j++) + pure_new_internal(m->data[i*tda+j]); x->data.mat.refc = new uint32_t; *x->data.mat.refc = 1; MEMDEBUG_NEW(x) @@ -1348,13 +1359,14 @@ break; } default: - data[i++*tda] = pure_new_internal(x); + data[i++*tda] = x; break; } } + pure_expr *ret = pure_symbolic_matrix(mat); for (size_t i = 0; i < n; i++) pure_free_internal(xs[i]); - return pure_symbolic_matrix(mat); + return ret; } static pure_expr* @@ -1411,13 +1423,14 @@ break; } default: - data[i++] = pure_new_internal(x); + data[i++] = x; break; } } + pure_expr *ret = pure_symbolic_matrix(mat); for (size_t i = 0; i < n; i++) pure_free_internal(xs[i]); - return pure_symbolic_matrix(mat); + return ret; } static inline void set_target_type(int32_t& target, int32_t t) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-20 20:33:23
|
Revision: 812 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=812&view=rev Author: agraef Date: 2008-09-20 20:33:16 +0000 (Sat, 20 Sep 2008) Log Message: ----------- Update ChangeLog and NEWS. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/NEWS Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-09-20 18:50:23 UTC (rev 811) +++ pure/trunk/ChangeLog 2008-09-20 20:33:16 UTC (rev 812) @@ -1,69 +1,15 @@ -2008-09-19 Albert Graef <Dr....@t-...> - - * runtime.cc, interpreter.cc et al: Support for symbolic matrices. +2008-09-20 Albert Graef <Dr....@t-...> - These work like the numeric GSL matrices, but can contain an - arbitrary mixture of Pure values, and also work if GSL support - isn't available. Numeric matrices will now only be created for - matrices consisting of machine int, double and complex values, if - all values are of the same type (and GSL support is available). In - all other cases a symbolic matrix is created (this also includes - the case of bigints, which are now considered as symbolic values - in matrix creation). + * Implemented basic GSL matrix support, including support for + symbolic matrices (which is independent from GSL, so these will + also work when building the interpreter without GSL) and matrix + comprehensions. This required many additions and changes to the + parser, interpreter, compiler, runtime and the prelude; details + can be found in the svn log (see r759 and r769ff.). - There's now only a single 'matrix' type tag which matches all - kinds of symbolic and numeric matrices. The matrixp family of - predicates in primitives.pure can be used to distinguish the - different kinds of matrices. Predicates to check for row and - column vectors (which are simply matrices with one row or column) - are also provided, as are some routines for transposing and - converting matrix values, see primitives.pure for details. + Preliminary documentation is in the NEWS file for now (the manual + still needs to be updated). -2008-09-18 Albert Graef <Dr....@t-...> - - * lib/primitives.pure: Add definitions of basic matrix operations. - Currently only size, dimensions and indexing are supported. - - Synopsis: - - #x total number of elements - - dim x number of rows and columns (as a pair) - - x!i ith matrix element in row-major order - - x!(i,j) jth element in ith row of the matrix - - * expr.cc, interpreter.cc, runtime.cc, printer.cc: Add basic GSL - matrix support. GSL double, complex and integer matrices can be - created with the new {x,y;u,v} syntax, which works more or less - like Octave/MATLAB matrices, but using curly braces instead of - brackets. Moreover, various basic operations to handle this kind - of objects (conversions, determining sizes, indexing, slicing) - have been added to the runtime, including some public API - operations to create and inspect matrix objects. - - Note that the {...} syntax can be used only on the right-hand side - of a definition, matrix patterns are not supported right now. As a - remedy, there are three new type tags, matrix, cmatrix and - imatrix, which can be used in patterns to match double, complex - and integer matrices, respectively. - - GSL matrices are always homogeneous, i.e., they only contain - values from one numeric type. Integer matrices can be created from - any combination of Pure machine int and bigint values (the latter - are converted to machine ints automatically). Matrices with at - least one double or complex element become double and complex - matrices, respectively, casting the other matrix elements as - needed. - - Complex matrices can be created from either pairs of double or - integer values, such as {(1,2),(3,4)}, or from Pure complex - values, such as {1+:2,3<:4} (the latter requires math.pure to be - loaded). The expression printer uses the former notation, unless - math.pure has been loaded in which case complex values are printed - in rectangular format x+:y. Also note that, for performance - reasons, the expression printer doesn't use the __show__ function - to print individual matrix elements, but of course it is possible - to override the default print representation of matrix values as a - whole. - 2008-09-15 Albert Graef <Dr....@t-...> * configure.ac: Bump version number. Modified: pure/trunk/NEWS =================================================================== --- pure/trunk/NEWS 2008-09-20 18:50:23 UTC (rev 811) +++ pure/trunk/NEWS 2008-09-20 20:33:16 UTC (rev 812) @@ -1,8 +1,106 @@ ** Pure 0.7 (in progress) -GSL matrix support. (Work in progress.) +Basic GSL (GNU Scientific Library) matrix support has been implemented, +including matrix comprehensions. Here's some preliminary documentation (at the +time of this writing, the manual still needs to be updated). For more +information on GSL please refer to http://www.gnu.org/software/gsl. +GSL double, complex and integer matrices can be created with the new {x,y;u,v} +syntax, which works more or less like Octave/MATLAB matrices, but using curly +braces instead of brackets. Also, indices are zero-based (rather than +one-based) to be consistent with Pure's list and tuple structures. + +Here are some simple examples of matrices: + +- {1,2,3} a row vector consisting of machine ints +- {1.0;2.0;3.0} a column vector of double values (';' separates rows) +- {1,2;3,4} a 2x2 int matrix +- {1L,y+1;foo,bar} a "symbolic" matrix (see explanation below) + +Note that the {...} syntax can be used only on the right-hand side of a +definition to construct new matrices. Matrix patterns are not supported. +However, the new 'matrix' type tag can be used in patterns to match matrix +values, e.g.: + +foo a::matrix = {a!(i,j)+1 | i=0..n-1; j=0..m-1} when n,m = dim a end; + +(Additional predicates to check for the different subtypes of matrices are +available in the prelude.) + +As mentioned above, there's also a special built-in type of "symbolic" +matrices. These work like the numeric matrices, but can contain an arbitrary +mixture of Pure values, and also work if GSL support isn't available. + +GSL matrices are always homogeneous, i.e., they only contain values from one +numeric type, which in the Pure implementation can be machine ints, double and +complex double values. (The latter are represented using Pure's infix notation +for complex values defined in math.pure; this requires math.pure to be +loaded. The same notation is also used to print complex matrices. Note that, +for performance reasons, the expression printer doesn't use the __show__ +function to print individual matrix elements. It is possible to override the +default print representation of matrix values as a whole, though.) + +If a matrix contains values of different types, or Pure values which cannot be +stored in a GSL matrix, then a symbolic matrix is created instead (this also +includes the case of bigints, which are considered as symbolic values as far +as matrix construction is concerned). If the interpreter was built without GSL +support then symbolic matrices are the only kind of matrices supported by the +interpreter. + +Pure also provides so-called matrix comprehensions as a convenient means to +create matrices from a template expression (which can denote either a scalar +or a submatrix), drawing values from lists and (optionally) filtering the +elements with predicates. These work pretty much like list comprehensions, but +return matrices instead of lists. Generator clauses in matrix comprehensions +alternate between row and column generation so that most common mathematical +abbreviations carry over quite easily. E.g., here's a simple example which +illustrates how you can define a function which returns a square identity +matrix of a given dimension: + +> eye n = {i==j|i=1..n;j=1..n}; +> eye 3; +{1,0,0;0,1,0;0,0,1} + +The prelude provides some additional basic matrix operations like determining +the size and dimensions of a matrix, indexing and slicing, transposition, +type-checking and various conversions between the different kinds of +matrices. To these ends, various basic operations to deal with matrix objects +have been added to the runtime, including some public API operations to create +and inspect Pure matrix values from external C modules. + +Here is a brief synopsis of some important operations which are already +implemented in the prelude (you can find the definitions of these and the +other matrix operations in primitives.pure): + +- #x total number of elements +- dim x number of rows and columns (as a pair) +- x' transposed matrix +- x!i ith matrix element in row-major order (zero-based) +- x!(i,j) jth element in ith row of the matrix (zero-based) +- x!!is, x!!(is,js) slicing (is and js are lists of machine ints) +- x==y, x!=y matrix comparisons + +Other user-visible changes prompted by the introduction of the matrix syntax +are listed below: + +- Changes in the comprehension syntax: '|' is now used to separate the +template expression and the generator and filter clauses. This change was +necessary to accommodate the matrix syntax which uses ';' to separate +different rows in a matrix. For consistency, this applies to both list and +matrix comprehensions. The old [x;...] syntax is still supported in list +comprehensions, but is flagged with a "deprecated" warning by the compiler. + +- Arithmetic sequences with a stepsize different from 1 are now written +x:y..z instead of x,y..z. This makes it possible to give the .. operator a +lower precedence than the ',' operator, which makes writing matrix slices like +x!!(i..j,k..l) much more convenient. + +Stuff that's still missing: + +- Marshalling of GSL matrices in the C interface, so that it becomes possible +to access all the advanced functionality available in GSL. + ** Pure 0.6 2008-09-12 New stuff in this release (please see the ChangeLog and the manual for This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-20 18:50:30
|
Revision: 811 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=811&view=rev Author: agraef Date: 2008-09-20 18:50:23 +0000 (Sat, 20 Sep 2008) Log Message: ----------- Get rid of the pair representation for complex values in GSL matrices, as it interferes with symbolic matrices containing pairs. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/printer.cc pure/trunk/runtime.cc pure/trunk/symtable.cc pure/trunk/symtable.hh Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-20 17:56:26 UTC (rev 810) +++ pure/trunk/interpreter.cc 2008-09-20 18:50:23 UTC (rev 811) @@ -928,8 +928,8 @@ if (x->data.mat.p) { gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; exprll *xs = new exprll; - symbol *rect = symtab.complex_rect_sym(); - expr f = rect?rect->x:symtab.pair_sym().x; + symbol *rect = symtab.complex_rect_sym(true); + expr f = rect->x; for (size_t i = 0; i < m->size1; i++) { xs->push_back(exprl()); exprl& ys = xs->back(); Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-09-20 17:56:26 UTC (rev 810) +++ pure/trunk/printer.cc 2008-09-20 18:50:23 UTC (rev 811) @@ -817,38 +817,25 @@ } return os << "}"; case EXPR::CMATRIX: + /* Print complex values in rectangular format using the infix notation + defined in math.pure. FIXME: We require the +: symbol to be predefined + no matter whether math.pure has actually been loaded. */ os << "{"; if (x->data.mat.p) { + interpreter& interp = *interpreter::g_interp; + symbol *rect = interp.symtab.complex_rect_sym(true); + string& rectsym = rect->s; gsl_matrix_complex *m = (gsl_matrix_complex*)x->data.mat.p; if (m->size1>0 && m->size2>0) { - /* GSL represents complex matrices using pairs of double values, while - Pure provides its own complex type in math.pure. If math.pure has - been loaded, then the '+:' operator is defined and we use this - representation. Otherwise, we print complex values as pairs of real - and imaginary part. */ - symbol *rect = interpreter::g_interp->symtab.complex_rect_sym(); - if (rect) - for (size_t i = 0; i < m->size1; i++) { - if (i > 0) os << ";"; - for (size_t j = 0; j < m->size2; j++) { - if (j > 0) os << ","; - print_double(os, m->data[2*(i * m->tda + j)]); - os << rect->s; - print_double(os, m->data[2*(i * m->tda + j) + 1]); - } + for (size_t i = 0; i < m->size1; i++) { + if (i > 0) os << ";"; + for (size_t j = 0; j < m->size2; j++) { + if (j > 0) os << ","; + print_double(os, m->data[2*(i * m->tda + j)]); + os << rectsym; + print_double(os, m->data[2*(i * m->tda + j) + 1]); } - else - for (size_t i = 0; i < m->size1; i++) { - if (i > 0) os << ";"; - for (size_t j = 0; j < m->size2; j++) { - if (j > 0) os << ","; - os << "("; - print_double(os, m->data[2*(i * m->tda + j)]); - os << ","; - print_double(os, m->data[2*(i * m->tda + j) + 1]); - os << ")"; - } - } + } } } return os << "}"; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-20 17:56:26 UTC (rev 810) +++ pure/trunk/runtime.cc 2008-09-20 18:50:23 UTC (rev 811) @@ -889,8 +889,7 @@ symbol *rect = interp.symtab.complex_rect_sym(), *polar = interp.symtab.complex_polar_sym(); if ((!rect || f->tag != rect->f) && - (!polar || f->tag != polar->f) && - f->tag != interp.symtab.pair_sym().f) + (!polar || f->tag != polar->f)) return false; u = u->data.x[1]; switch (u->tag) { @@ -927,13 +926,13 @@ if (rect) return pure_appl(pure_symbol(rect->f), 2, pure_double(a), pure_double(b)); else - return pure_tuplel(2, pure_double(a), pure_double(b)); + return 0; } static inline pure_expr *make_complex(double a, double b) { interpreter& interp = *interpreter::g_interp; - symbol *rect = interp.symtab.complex_rect_sym(); + symbol *rect = interp.symtab.complex_rect_sym(true); return make_complex2(rect, a, b); } @@ -1338,7 +1337,7 @@ gsl_matrix_complex *mat1 = (gsl_matrix_complex*)x->data.mat.p; if (mat1) { interpreter& interp = *interpreter::g_interp; - symbol *rect = interp.symtab.complex_rect_sym(); + symbol *rect = interp.symtab.complex_rect_sym(true); for (size_t j = 0; j < mat1->size1; i++, j++) for (size_t k = 0; k < mat1->size2; k++) { size_t l = 2*(j*mat1->tda+k); @@ -1400,7 +1399,7 @@ gsl_matrix_complex *mat1 = (gsl_matrix_complex*)x->data.mat.p; if (mat1) { interpreter& interp = *interpreter::g_interp; - symbol *rect = interp.symtab.complex_rect_sym(); + symbol *rect = interp.symtab.complex_rect_sym(true); for (size_t j = 0; j < mat1->size1; j++) for (size_t k = 0; k < mat1->size2; k++) { size_t l = 2*(j*mat1->tda+k); Modified: pure/trunk/symtable.cc =================================================================== --- pure/trunk/symtable.cc 2008-09-20 17:56:26 UTC (rev 810) +++ pure/trunk/symtable.cc 2008-09-20 18:50:23 UTC (rev 811) @@ -374,3 +374,21 @@ else return sym("&", 9, postfix); } + +symbol* symtable::complex_rect_sym(bool force) +{ + symbol *_sym = lookup("+:"); + if (!force || _sym) + return _sym; + else + return &sym("+:", 5, infix); +} + +symbol* symtable::complex_polar_sym(bool force) +{ + symbol *_sym = lookup("<:"); + if (!force || _sym) + return _sym; + else + return &sym("<:", 5, infix); +} Modified: pure/trunk/symtable.hh =================================================================== --- pure/trunk/symtable.hh 2008-09-20 17:56:26 UTC (rev 810) +++ pure/trunk/symtable.hh 2008-09-20 18:50:23 UTC (rev 811) @@ -100,9 +100,11 @@ symbol& segfault_sym() { return sym("stack_fault"); } symbol& bad_matrix_sym() { return sym("bad_matrix_value"); } symbol& amp_sym(); - // these may be undefined - symbol* complex_rect_sym() { return lookup("+:"); } - symbol* complex_polar_sym() { return lookup("<:"); } + // These aren't predefined and aren't in the prelude either, so they may be + // undefined in which case a null pointer is returned. Pass force=true to + // forcibly create these symbols. + symbol* complex_rect_sym(bool force = false); + symbol* complex_polar_sym(bool force = false); }; #endif // ! SYMTABLE_HH This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |