[pure-lang-svn] SF.net SVN: pure-lang:[779] pure/trunk/runtime.cc
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-09-18 09:56:57
|
Revision: 779 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=779&view=rev Author: agraef Date: 2008-09-18 09:57:08 +0000 (Thu, 18 Sep 2008) Log Message: ----------- Add support for empty matrices. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-17 21:17:01 UTC (rev 778) +++ pure/trunk/runtime.cc 2008-09-18 09:57:08 UTC (rev 779) @@ -585,6 +585,52 @@ return x; } +#ifdef HAVE_GSL +/* GSL doesn't really support empty matrices, so we fake them by allocating 1 + dummy row or column if the corresponding dimension is actually zero. */ +static inline gsl_matrix* +create_double_matrix(size_t nrows, size_t ncols) +{ + if (nrows == 0 || ncols == 0 ) { + size_t nrows1 = (nrows>0)?nrows:1; + size_t ncols1 = (ncols>0)?ncols:1; + gsl_matrix *m = gsl_matrix_calloc(nrows1, ncols1); + if (!m) return 0; + m->size1 = nrows; m->size2 = ncols; + return m; + } else + return gsl_matrix_alloc(nrows, ncols); +} + +static inline gsl_matrix_complex* +create_complex_matrix(size_t nrows, size_t ncols) +{ + if (nrows == 0 || ncols == 0 ) { + size_t nrows1 = (nrows>0)?nrows:1; + size_t ncols1 = (ncols>0)?ncols:1; + gsl_matrix_complex *m = gsl_matrix_complex_calloc(nrows1, ncols1); + if (!m) return 0; + m->size1 = nrows; m->size2 = ncols; + return m; + } else + return gsl_matrix_complex_alloc(nrows, ncols); +} + +static inline gsl_matrix_int* +create_int_matrix(size_t nrows, size_t ncols) +{ + if (nrows == 0 || ncols == 0 ) { + size_t nrows1 = (nrows>0)?nrows:1; + size_t ncols1 = (ncols>0)?ncols:1; + gsl_matrix_int *m = gsl_matrix_int_calloc(nrows1, ncols1); + if (!m) return 0; + m->size1 = nrows; m->size2 = ncols; + return m; + } else + return gsl_matrix_int_alloc(nrows, ncols); +} +#endif + extern "C" pure_expr *pure_double_matrix(void *p) { @@ -645,8 +691,10 @@ #ifdef HAVE_GSL gsl_matrix *m1 = (gsl_matrix*)p; if (!m1) return 0; - gsl_matrix *m2 = gsl_matrix_alloc(m1->size1, m1->size2); - gsl_matrix_memcpy(m2, m1); + gsl_matrix *m2 = create_double_matrix(m1->size1, m1->size2); + if (!m2) return 0; + if (m1->size1 > 0 && m1->size2 > 0) + gsl_matrix_memcpy(m2, m1); return pure_double_matrix(m2); #else return 0; @@ -659,8 +707,10 @@ #ifdef HAVE_GSL gsl_matrix_complex *m1 = (gsl_matrix_complex*)p; if (!m1) return 0; - gsl_matrix_complex *m2 = gsl_matrix_complex_alloc(m1->size1, m1->size2); - gsl_matrix_complex_memcpy(m2, m1); + gsl_matrix_complex *m2 = create_complex_matrix(m1->size1, m1->size2); + if (!m2) return 0; + if (m1->size1 > 0 && m1->size2 > 0) + gsl_matrix_complex_memcpy(m2, m1); return pure_complex_matrix(m2); #else return 0; @@ -673,8 +723,10 @@ #ifdef HAVE_GSL gsl_matrix_int *m1 = (gsl_matrix_int*)p; if (!m1) return 0; - gsl_matrix_int *m2 = gsl_matrix_int_alloc(m1->size1, m1->size2); - gsl_matrix_int_memcpy(m2, m1); + gsl_matrix_int *m2 = create_int_matrix(m1->size1, m1->size2); + if (!m2) return 0; + if (m1->size1 > 0 && m1->size2 > 0) + gsl_matrix_int_memcpy(m2, m1); return pure_int_matrix(m2); #else return 0; @@ -685,15 +737,8 @@ static pure_expr* double_matrix_rows(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { - gsl_matrix *mat = gsl_matrix_alloc(nrows, ncols); - if (!mat) { - // XXXTODO: empty matrices - for (size_t i = 0; i < n; i++) - pure_new_internal(xs[i]); - for (size_t i = 0; i < n; i++) - pure_free_internal(xs[i]); - return 0; - } + gsl_matrix *mat = create_double_matrix(nrows, ncols); + if (!mat) return 0; double *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { @@ -737,15 +782,8 @@ static pure_expr* double_matrix_columns(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { - gsl_matrix *mat = gsl_matrix_alloc(nrows, ncols); - if (!mat) { - // XXXTODO: empty matrices - for (size_t i = 0; i < n; i++) - pure_new_internal(xs[i]); - for (size_t i = 0; i < n; i++) - pure_free_internal(xs[i]); - return 0; - } + gsl_matrix *mat = create_double_matrix(nrows, ncols); + if (!mat) return 0; double *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { @@ -792,15 +830,8 @@ static pure_expr* int_matrix_rows(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { - gsl_matrix_int *mat = gsl_matrix_int_alloc(nrows, ncols); - if (!mat) { - // XXXTODO: empty matrices - for (size_t i = 0; i < n; i++) - pure_new_internal(xs[i]); - for (size_t i = 0; i < n; i++) - pure_free_internal(xs[i]); - return 0; - } + gsl_matrix_int *mat = create_int_matrix(nrows, ncols); + if (!mat) return 0; int *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { @@ -844,15 +875,8 @@ static pure_expr* int_matrix_columns(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { - gsl_matrix_int *mat = gsl_matrix_int_alloc(nrows, ncols); - if (!mat) { - // XXXTODO: empty matrices - for (size_t i = 0; i < n; i++) - pure_new_internal(xs[i]); - for (size_t i = 0; i < n; i++) - pure_free_internal(xs[i]); - return 0; - } + gsl_matrix_int *mat = create_int_matrix(nrows, ncols); + if (!mat) return 0; int *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |