[pure-lang-svn] SF.net SVN: pure-lang:[839] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-09-23 12:56:57
|
Revision: 839 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=839&view=rev Author: agraef Date: 2008-09-23 12:56:30 +0000 (Tue, 23 Sep 2008) Log Message: ----------- Add more matrix creation and pointer->matrix conversion functions. Modified Paths: -------------- pure/trunk/lib/matrices.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/lib/matrices.pure =================================================================== --- pure/trunk/lib/matrices.pure 2008-09-23 10:58:30 UTC (rev 838) +++ pure/trunk/lib/matrices.pure 2008-09-23 12:56:30 UTC (rev 839) @@ -43,6 +43,18 @@ rowvectorp x = matrixp x && dim x!0==1; colvectorp x = matrixp x && dim x!1==1; +/* Convenience functions to create numeric matrices with the given dimensions + (either a pair denoting the number of rows and columns, or just the row + size in order to create a row vector), and all elements zero. */ + +dmatrix (n::int,m::int) = cdmatrix (pointer 0) (n,m); +cmatrix (n::int,m::int) = ccmatrix (pointer 0) (n,m); +imatrix (n::int,m::int) = cimatrix (pointer 0) (n,m); + +dmatrix n::int = cdmatrix (pointer 0) n; +cmatrix n::int = ccmatrix (pointer 0) n; +imatrix n::int = cimatrix (pointer 0) n; + /* Size of a matrix (#x) and its dimensions (dim x=n,m where n is the number of rows, m the number of columns). Note that Pure supports empty matrices, thus the total size may well be zero, meaning that either the number of @@ -332,6 +344,37 @@ pointer x::matrix = pure_pointerval x; +/* Create a numeric matrix from a pointer. The pointer to be converted must + point to a malloc'ed, properly initialized memory area big enough to + accommodate the requested dimensions. The pointer may also be NULL in which + case a suitable pointer is allocated automatically. This memory is taken + over by Pure and will be freed automatically when the matrix object is + garbage-collected. CAVEAT: These are low-level operations and hence should + be used with care. They are useful, in particular, if you need to handle + massive amounts of matrix or vector data generated or processed by external + C software, such as graphics and sound libraries. */ + +private matrix_from_double_array; +private matrix_from_complex_array; +private matrix_from_int_array; +extern expr* matrix_from_double_array(void* p, int n, int m); +extern expr* matrix_from_complex_array(void* p, int n, int m); +extern expr* matrix_from_int_array(void* p, int n, int m); + +cdmatrix p::pointer (n::int,m::int) + = matrix_from_double_array p n m; +ccmatrix p::pointer (n::int,m::int) + = matrix_from_complex_array p n m; +cimatrix p::pointer (n::int,m::int) + = matrix_from_int_array p n m; + +cdmatrix p::pointer n::int + = cdmatrix p (1,n); +ccmatrix p::pointer n::int + = ccmatrix p (1,n); +cimatrix p::pointer n::int + = cimatrix p (1,n); + /* Matrix comparisons. */ x::matrix == y::matrix = x === y Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-23 10:58:30 UTC (rev 838) +++ pure/trunk/runtime.cc 2008-09-23 12:56:30 UTC (rev 839) @@ -105,7 +105,7 @@ s.tda = m->tda; s.block = m->block; s.owner = 0; - view.matrix = s; + view.matrix = s; return view; } } @@ -5010,6 +5010,95 @@ #endif } +extern "C" +pure_expr *matrix_from_double_array(void *p, uint32_t n1, uint32_t n2) +{ +#ifdef HAVE_GSL + if (n1 == 0 || n2 == 0) // empty matrix + return pure_double_matrix(create_double_matrix(n1, n2)); + if (!p) p = calloc(n1*n2, sizeof(double)); + if (!p) return 0; + gsl_matrix_view v = gsl_matrix_view_array((double*)p, n1, n2); + // take a copy of the view matrix + gsl_matrix *m = (gsl_matrix*)malloc(sizeof(gsl_matrix)); + gsl_block *b = (gsl_block*)malloc(sizeof(gsl_block)); + assert(m && v.matrix.data); + *m = v.matrix; + b->size = n1*n2; + b->data = m->data; + m->block = b; + pure_expr *x = new_expr(); + x->tag = EXPR::DMATRIX; + x->data.mat.p = m; + x->data.mat.refc = new uint32_t; + *x->data.mat.refc = 1; + MEMDEBUG_NEW(x) + return x; +#else + return 0; +#endif +} + +extern "C" +pure_expr *matrix_from_complex_array(void *p, uint32_t n1, uint32_t n2) +{ +#ifdef HAVE_GSL + if (n1 == 0 || n2 == 0) // empty matrix + return pure_complex_matrix(create_complex_matrix(n1, n2)); + if (!p) p = calloc(2*n1*n2, sizeof(double)); + if (!p) return 0; + gsl_matrix_complex_view v = + gsl_matrix_complex_view_array((double*)p, n1, n2); + // take a copy of the view matrix + gsl_matrix_complex *m = + (gsl_matrix_complex*)malloc(sizeof(gsl_matrix_complex)); + gsl_block_complex *b = (gsl_block_complex*)malloc(sizeof(gsl_block_complex)); + assert(m && v.matrix.data); + *m = v.matrix; + b->size = n1*n2; + b->data = m->data; + m->block = b; + pure_expr *x = new_expr(); + x->tag = EXPR::CMATRIX; + x->data.mat.p = m; + x->data.mat.refc = new uint32_t; + *x->data.mat.refc = 1; + MEMDEBUG_NEW(x) + return x; +#else + return 0; +#endif +} + +extern "C" +pure_expr *matrix_from_int_array(void *p, uint32_t n1, uint32_t n2) +{ +#ifdef HAVE_GSL + if (n1 == 0 || n2 == 0) // empty matrix + return pure_int_matrix(create_int_matrix(n1, n2)); + if (!p) p = calloc(n1*n2, sizeof(int)); + if (!p) return 0; + gsl_matrix_int_view v = gsl_matrix_int_view_array((int*)p, n1, n2); + // take a copy of the view matrix + gsl_matrix_int *m = (gsl_matrix_int*)malloc(sizeof(gsl_matrix_int)); + gsl_block_int *b = (gsl_block_int*)malloc(sizeof(gsl_block_int)); + assert(m && v.matrix.data); + *m = v.matrix; + b->size = n1*n2; + b->data = m->data; + m->block = b; + pure_expr *x = new_expr(); + x->tag = EXPR::IMATRIX; + x->data.mat.p = m; + x->data.mat.refc = new uint32_t; + *x->data.mat.refc = 1; + MEMDEBUG_NEW(x) + return x; +#else + return 0; +#endif +} + static uint32_t mpz_hash(const mpz_t z) { uint32_t h = 0; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-23 10:58:30 UTC (rev 838) +++ pure/trunk/runtime.h 2008-09-23 12:56:30 UTC (rev 839) @@ -733,6 +733,18 @@ pure_expr *matrix_re(pure_expr *x); pure_expr *matrix_im(pure_expr *x); +/* Create a matrix object of the given dimensions which uses the given pointer + p as its underlying C array. There are no checks whatsoever, so the caller + is responsible for making sure that the memory has the right size and is + properly initialized. p must point to a malloc'ed memory area, which is + taken over by Pure and will be freed automatically when the matrix is + garbage-collected. p may also be NULL in which case a suitable pointer is + allocated automatically. */ + +pure_expr *matrix_from_double_array(void *p, uint32_t n, uint32_t m); +pure_expr *matrix_from_complex_array(void *p, uint32_t n, uint32_t m); +pure_expr *matrix_from_int_array(void *p, uint32_t n, uint32_t m); + /* Compute a 32 bit hash code of a Pure expression. This makes it possible to use arbitary Pure values as keys in a hash table. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |