[pure-lang-svn] SF.net SVN: pure-lang:[780] pure/trunk/runtime.cc
Status: Beta
Brought to you by:
agraef
|
From: <ag...@us...> - 2008-09-18 10:56:32
|
Revision: 780
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=780&view=rev
Author: agraef
Date: 2008-09-18 10:56:42 +0000 (Thu, 18 Sep 2008)
Log Message:
-----------
Finish matrix construction operations (complex matrices).
Modified Paths:
--------------
pure/trunk/runtime.cc
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-09-18 09:57:08 UTC (rev 779)
+++ pure/trunk/runtime.cc 2008-09-18 10:56:42 UTC (rev 780)
@@ -28,6 +28,7 @@
#include <unistd.h>
#include <limits.h>
#include <locale.h>
+#include <math.h>
#include <iostream>
#include <sstream>
@@ -827,7 +828,209 @@
return pure_double_matrix(mat);
}
+static inline bool get_complex(pure_expr *x, double& a, double& b)
+{
+ 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) &&
+ f->tag != interp.symtab.pair_sym().f)
+ return false;
+ u = u->data.x[1];
+ switch (u->tag) {
+ case EXPR::INT:
+ a = (double)u->data.i;
+ break;
+ case EXPR::BIGINT:
+ a = mpz_get_d(x->data.z);
+ break;
+ case EXPR::DBL:
+ a = u->data.d;
+ break;
+ default:
+ return false;
+ }
+ switch (v->tag) {
+ case EXPR::INT:
+ b = (double)v->data.i;
+ break;
+ case EXPR::BIGINT:
+ b = mpz_get_d(x->data.z);
+ break;
+ case EXPR::DBL:
+ b = v->data.d;
+ break;
+ default:
+ return false;
+ }
+ if (polar && f->tag == polar->f) {
+ double r = a, t = b;
+ a = r*cos(t); b = r*sin(t);
+ }
+ return true;
+ } else
+ return false;
+}
+
static pure_expr*
+complex_matrix_rows(size_t nrows, size_t ncols, size_t n, pure_expr **xs)
+{
+ gsl_matrix_complex *mat = create_complex_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++) {
+ pure_expr *x = xs[count];
+ pure_new_internal(x);
+ switch (x->tag) {
+ case EXPR::INT:
+ data[2*i*tda] = (double)x->data.i;
+ data[2*i*tda+1] = 0.0;
+ i++;
+ break;
+ case EXPR::BIGINT:
+ data[2*i*tda] = mpz_get_d(x->data.z);
+ data[2*i*tda+1] = 0.0;
+ i++;
+ break;
+ case EXPR::DBL:
+ data[2*i*tda] = x->data.d;
+ data[2*i*tda+1] = 0.0;
+ i++;
+ break;
+ case EXPR::APP: {
+ double a, b;
+ if (get_complex(x, a, b)) {
+ data[2*i*tda] = a;
+ data[2*i*tda+1] = b;
+ i++;
+ } else {
+ assert(0 && "bad matrix element");
+ }
+ break;
+ }
+ case EXPR::MATRIX: {
+ gsl_matrix *mat1 = (gsl_matrix*)x->data.mat.p;
+ if (mat1)
+ for (size_t j = 0; j < mat1->size1; i++, j++)
+ for (size_t k = 0; k < mat1->size2; k++) {
+ data[2*(i*tda+k)] = mat1->data[j*mat1->tda+k];
+ data[2*(i*tda+k)+1] = 0.0;
+ }
+ break;
+ }
+ case EXPR::IMATRIX: {
+ gsl_matrix_int *mat1 = (gsl_matrix_int*)x->data.mat.p;
+ if (mat1)
+ for (size_t j = 0; j < mat1->size1; i++, j++)
+ for (size_t k = 0; k < mat1->size2; k++) {
+ data[2*(i*tda+k)] = (double)mat1->data[j*mat1->tda+k];
+ data[2*(i*tda+k)+1] = 0.0;
+ }
+ break;
+ }
+ case EXPR::CMATRIX: {
+ gsl_matrix_complex *mat1 = (gsl_matrix_complex*)x->data.mat.p;
+ if (mat1)
+ for (size_t j = 0; j < mat1->size1; i++, j++)
+ memcpy(data+2*i*tda, mat1->data+2*j*mat1->tda,
+ ncols*2*sizeof(double));
+ break;
+ }
+ default:
+ assert(0 && "bad matrix element");
+ break;
+ }
+ }
+ for (size_t i = 0; i < n; i++)
+ pure_free_internal(xs[i]);
+ return pure_complex_matrix(mat);
+}
+
+static pure_expr*
+complex_matrix_columns(size_t nrows, size_t ncols, size_t n, pure_expr **xs)
+{
+ gsl_matrix_complex *mat = create_complex_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++) {
+ pure_expr *x = xs[count];
+ pure_new_internal(x);
+ switch (x->tag) {
+ case EXPR::INT:
+ data[2*i] = (double)x->data.i;
+ data[2*i+1] = 0.0;
+ i++;
+ break;
+ case EXPR::BIGINT:
+ data[2*i] = mpz_get_d(x->data.z);
+ data[2*i+1] = 0.0;
+ i++;
+ break;
+ case EXPR::DBL:
+ data[2*i] = x->data.d;
+ data[2*i+1] = 0.0;
+ i++;
+ break;
+ case EXPR::APP: {
+ double a, b;
+ if (get_complex(x, a, b)) {
+ data[2*i] = a;
+ data[2*i+1] = b;
+ i++;
+ } else {
+ assert(0 && "bad matrix element");
+ }
+ break;
+ }
+ case EXPR::MATRIX: {
+ gsl_matrix *mat1 = (gsl_matrix*)x->data.mat.p;
+ if (mat1)
+ for (size_t j = 0; j < mat1->size1; j++)
+ for (size_t k = 0; k < mat1->size2; k++) {
+ data[2*(j*tda+k+i)] = mat1->data[j*mat1->tda+k];
+ data[2*(j*tda+k+i)+1] = 0.0;
+ }
+ i += mat1->size2;
+ break;
+ }
+ case EXPR::IMATRIX: {
+ gsl_matrix_int *mat1 = (gsl_matrix_int*)x->data.mat.p;
+ if (mat1)
+ for (size_t j = 0; j < mat1->size1; j++)
+ for (size_t k = 0; k < mat1->size2; k++) {
+ data[2*(j*tda+k+i)] = (double)mat1->data[j*mat1->tda+k];
+ data[2*(j*tda+k+i)+1] = 0.0;
+ }
+ i += mat1->size2;
+ break;
+ }
+ case EXPR::CMATRIX: {
+ gsl_matrix_complex *mat1 = (gsl_matrix_complex*)x->data.mat.p;
+ if (mat1)
+ for (size_t j = 0; j < mat1->size1; j++)
+ memcpy(data+2*(j*tda+i), mat1->data+2*j*mat1->tda,
+ mat1->size2*2*sizeof(double));
+ i += mat1->size2;
+ break;
+ }
+ default:
+ assert(0 && "bad matrix element");
+ break;
+ }
+ }
+ for (size_t i = 0; i < n; i++)
+ pure_free_internal(xs[i]);
+ return pure_complex_matrix(mat);
+}
+
+static pure_expr*
int_matrix_rows(size_t nrows, size_t ncols, size_t n, pure_expr **xs)
{
gsl_matrix_int *mat = create_int_matrix(nrows, ncols);
@@ -1845,25 +2048,8 @@
nrows++; k = 1;
break;
case EXPR::APP: {
- 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) &&
- f->tag != interp.symtab.pair_sym().f)
- goto err;
- u = u->data.x[1];
- if (u->tag != EXPR::INT && u->tag != EXPR::BIGINT &&
- u->tag != EXPR::DBL)
- goto err;
- if (v->tag != EXPR::INT && v->tag != EXPR::BIGINT &&
- v->tag != EXPR::DBL)
- goto err;
- } else
- goto err;
+ double a, b;
+ if (!get_complex(x, a, b)) goto err;
if (k >= 0 && k != 1) goto err;
target = EXPR::CMATRIX;
nrows++; k = 1;
@@ -1917,11 +2103,9 @@
case EXPR::MATRIX:
ret = double_matrix_rows(nrows, ncols, n, xs);
break;
-#if 0 // XXXTODO
case EXPR::CMATRIX:
ret = complex_matrix_rows(nrows, ncols, n, xs);
break;
-#endif
case EXPR::IMATRIX:
ret = int_matrix_rows(nrows, ncols, n, xs);
break;
@@ -1973,25 +2157,8 @@
ncols++; k = 1;
break;
case EXPR::APP: {
- 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) &&
- f->tag != interp.symtab.pair_sym().f)
- goto err;
- u = u->data.x[1];
- if (u->tag != EXPR::INT && u->tag != EXPR::BIGINT &&
- u->tag != EXPR::DBL)
- goto err;
- if (v->tag != EXPR::INT && v->tag != EXPR::BIGINT &&
- v->tag != EXPR::DBL)
- goto err;
- } else
- goto err;
+ double a, b;
+ if (!get_complex(x, a, b)) goto err;
if (k >= 0 && k != 1) goto err;
target = EXPR::CMATRIX;
ncols++; k = 1;
@@ -2045,11 +2212,9 @@
case EXPR::MATRIX:
ret = double_matrix_columns(nrows, ncols, n, xs);
break;
-#if 0 // XXXTODO
case EXPR::CMATRIX:
ret = complex_matrix_columns(nrows, ncols, n, xs);
break;
-#endif
case EXPR::IMATRIX:
ret = int_matrix_columns(nrows, ncols, n, xs);
break;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|