Permalink
Browse files

Enhance NArray compatibility

* Add Vector::Complex support to NArray conversions

* Raise exception when trying to create View from NArray object of
  incompatible type.

git-svn-id: http://rb-gsl.rubyforge.org/svn/trunk/rb-gsl@141 6e764f74-f39f-46f8-8c54-8307d62afe8d
  • Loading branch information...
davidm
davidm committed Feb 24, 2011
1 parent 7790821 commit 5f043d59178fe0f2b8f003b8a92f17cb7849975b
Showing with 185 additions and 22 deletions.
  1. +176 −19 ext/gsl_narray.c
  2. +2 −0 include/rb_gsl_with_narray.h
  3. +7 −3 rdoc/narray.rdoc
View
@@ -18,6 +18,7 @@ static VALUE rb_gsl_vector_int_to_na(VALUE obj);
static VALUE rb_gsl_na_to_gsl_vector_int(VALUE obj, VALUE na);
/* GSL::Vector -> NArray */
+
static VALUE rb_gsl_vector_to_narray(VALUE obj, VALUE klass)
{
gsl_vector *v = NULL;
@@ -39,23 +40,68 @@ static VALUE rb_gsl_vector_to_narray(VALUE obj, VALUE klass)
return nary;
}
+static VALUE rb_gsl_vector_complex_to_narray(VALUE obj, VALUE klass)
+{
+ gsl_vector_complex *v = NULL;
+ VALUE nary;
+ int shape[1];
+ Data_Get_Struct(obj, gsl_vector_complex, v);
+ shape[0] = v->size;
+ nary = na_make_object(NA_DCOMPLEX, 1, shape, klass);
+ if (v->stride == 1) {
+ memcpy(NA_PTR_TYPE(nary,double*), v->data, shape[0]*2*sizeof(double));
+ } else {
+ int i;
+ struct NARRAY *na;
+ GetNArray(nary, na);
+ for(i=0; i < 2*v->size; i++) {
+ (NA_PTR_TYPE(nary,gsl_complex*))[i] = gsl_vector_complex_get(v, i);
+ }
+ }
+ return nary;
+}
+
static VALUE rb_gsl_vector_to_na(VALUE obj)
{
- return rb_gsl_vector_to_narray(obj, cNArray);
+ VALUE na = Qnil;
+
+ if(VECTOR_P(obj))
+ na = rb_gsl_vector_to_narray(obj, cNArray);
+ else if(VECTOR_COMPLEX_P(obj))
+ na = rb_gsl_vector_complex_to_narray(obj, cNArray);
+ else
+ rb_raise(rb_eRuntimeError, "unexpected type '%s'",
+ rb_obj_classname(obj));
+
+ return na;
+}
+
+static VALUE rb_gsl_vector_complex_to_na(VALUE obj)
+{
+ return rb_gsl_vector_complex_to_narray(obj, cNArray);
}
static VALUE rb_gsl_vector_to_nvector(VALUE obj)
{
return rb_gsl_vector_to_narray(obj, cNVector);
}
+static VALUE rb_gsl_vector_complex_to_nvector(VALUE obj)
+{
+ return rb_gsl_vector_complex_to_narray(obj, cNVector);
+}
+
+/* GSL::Vector -> NArray view */
+
static struct NARRAY* rb_gsl_na_view_alloc(int rank, int total, int type)
{
struct NARRAY *na;
na = (struct NARRAY*) malloc(sizeof(struct NARRAY));
na->rank = rank;
na->total = total;
na->type = type;
+ // TODO Set na->ref to a one element NArray of type NAObject that contains
+ // the GSL::Vector being referenced.
na->ref = Qtrue; /* to initialize */
na->shape = (int *) malloc(sizeof(int)*rank);
return na;
@@ -70,6 +116,7 @@ static void rb_gsl_na_view_free(struct NARRAY *na)
static VALUE rb_gsl_vector_to_narray_ref(VALUE obj, VALUE klass)
{
gsl_vector *v = NULL;
+ gsl_vector_complex *vc = NULL;
gsl_vector_int *vi = NULL;
VALUE nary;
struct NARRAY *na;
@@ -89,8 +136,17 @@ static VALUE rb_gsl_vector_to_narray_ref(VALUE obj, VALUE klass)
na = rb_gsl_na_view_alloc(1, vi->size, NA_LINT);
na->shape[0] = vi->size;
na->ptr = (char *) vi->data;
+ } else if (VECTOR_COMPLEX_P(obj)) {
+ Data_Get_Struct(obj, gsl_vector_complex, vc);
+ if (vc->stride != 1) {
+ rb_raise(rb_eRuntimeError, "Cannot make a reference obj: stride!=1");
+ }
+ na = rb_gsl_na_view_alloc(1, vc->size, NA_DCOMPLEX);
+ na->shape[0] = vc->size;
+ na->ptr = (char *) vc->data;
} else {
- rb_raise(rb_eRuntimeError, "???");
+ rb_raise(rb_eRuntimeError, "cannot convert %s to NArray reference object",
+ rb_obj_classname(obj));
}
nary = Data_Wrap_Struct(klass, 0, rb_gsl_na_view_free, na);
return nary;
@@ -150,6 +206,18 @@ static VALUE rb_gsl_na_to_gsl_vector_view(VALUE obj, VALUE na)
na_to_gv_view(na));
}
+static VALUE rb_gsl_na_to_gsl_vector_complex(VALUE obj, VALUE na)
+{
+ return Data_Wrap_Struct(cgsl_vector_complex, 0, gsl_vector_complex_free,
+ na_to_gv_complex(na));
+}
+
+static VALUE rb_gsl_na_to_gsl_vector_complex_view(VALUE obj, VALUE na)
+{
+ return Data_Wrap_Struct(cgsl_vector_complex_view, 0, gsl_vector_complex_view_free,
+ na_to_gv_complex_view(na));
+}
+
static VALUE rb_gsl_na_to_gsl_vector_int(VALUE obj, VALUE na)
{
return Data_Wrap_Struct(cgsl_vector_int, 0, gsl_vector_int_free,
@@ -164,14 +232,30 @@ static VALUE rb_gsl_na_to_gsl_vector_int_view(VALUE obj, VALUE na)
static VALUE rb_gsl_na_to_gsl_vector_method(VALUE na)
{
- return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free,
- na_to_gv(na));
+ VALUE v;
+
+ if(NA_TYPE(na) == NA_SCOMPLEX || NA_TYPE(na) == NA_DCOMPLEX)
+ v = Data_Wrap_Struct(cgsl_vector_complex, 0, gsl_vector_complex_free,
+ na_to_gv_complex(na));
+ else
+ v = Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free,
+ na_to_gv(na));
+
+ return v;
}
static VALUE rb_gsl_na_to_gsl_vector_view_method(VALUE na)
{
- return Data_Wrap_Struct(cgsl_vector_view, 0, gsl_vector_view_free,
- na_to_gv_view(na));
+ VALUE v;
+
+ if(NA_TYPE(na) == NA_SCOMPLEX || NA_TYPE(na) == NA_DCOMPLEX)
+ v = Data_Wrap_Struct(cgsl_vector_complex_view, 0, gsl_vector_complex_view_free,
+ na_to_gv_complex_view(na));
+ else
+ v = Data_Wrap_Struct(cgsl_vector_view, 0, gsl_vector_view_free,
+ na_to_gv_view(na));
+
+ return v;
}
static VALUE rb_gsl_na_to_gsl_vector_int_method(VALUE na)
@@ -189,20 +273,53 @@ static VALUE rb_gsl_na_to_gsl_vector_int_view_method(VALUE na)
gsl_vector* na_to_gv(VALUE na)
{
gsl_vector *v = NULL;
- VALUE nary;
+ VALUE nary = na;
v = gsl_vector_alloc(NA_TOTAL(na));
- nary = na_change_type(na, NA_DFLOAT);
- memcpy(v->data, NA_PTR_TYPE(nary,double*), v->size*sizeof(double));
+ if(NA_TYPE(na) != NA_DFLOAT) {
+ nary = na_change_type(na, NA_DFLOAT);
+ }
+ memcpy(v->data, NA_PTR_TYPE(na,double*), v->size*sizeof(double));
return v;
}
gsl_vector_view* na_to_gv_view(VALUE na)
{
gsl_vector_view *v = NULL;
- VALUE ary2;
+
+ // Raise exception if na's type is not NA_DFLOAT.
+ if(NA_TYPE(na) != NA_DFLOAT)
+ rb_raise(rb_eTypeError, "GSL::Vector::View requires NArray be DFLOAT");
+
v = gsl_vector_view_alloc();
- ary2 = na_change_type(na, NA_DFLOAT);
- v->vector.data = NA_PTR_TYPE(ary2,double*);
+ v->vector.data = NA_PTR_TYPE(na,double*);
+ v->vector.size = NA_TOTAL(na);
+ v->vector.stride = 1;
+ v->vector.owner = 0;
+ return v;
+}
+
+gsl_vector_complex* na_to_gv_complex(VALUE na)
+{
+ gsl_vector_complex *v = NULL;
+ VALUE nary = na;
+ v = gsl_vector_complex_alloc(NA_TOTAL(na));
+ if(NA_TYPE(na) != NA_DCOMPLEX) {
+ nary = na_change_type(na, NA_DCOMPLEX);
+ }
+ memcpy(v->data, NA_PTR_TYPE(na,gsl_complex*), v->size*sizeof(gsl_complex));
+ return v;
+}
+
+gsl_vector_complex_view* na_to_gv_complex_view(VALUE na)
+{
+ gsl_vector_complex_view *v = NULL;
+
+ // Raise exception if na's type is not NA_DCOMPLEX
+ if(NA_TYPE(na) != NA_DCOMPLEX)
+ rb_raise(rb_eTypeError, "GSL::Vector::Complex::View requires NArray be DCOMPLEX");
+
+ v = gsl_vector_complex_view_alloc();
+ v->vector.data = NA_PTR_TYPE(na,double*);
v->vector.size = NA_TOTAL(na);
v->vector.stride = 1;
v->vector.owner = 0;
@@ -212,20 +329,24 @@ gsl_vector_view* na_to_gv_view(VALUE na)
gsl_vector_int* na_to_gv_int(VALUE na)
{
gsl_vector_int *v = NULL;
- VALUE nary;
+ VALUE nary = na;
v = gsl_vector_int_alloc(NA_TOTAL(na));
- nary = na_change_type(na, NA_LINT);
+ if(NA_TYPE(na) != NA_LINT) {
+ nary = na_change_type(na, NA_LINT);
+ }
memcpy(v->data, NA_PTR_TYPE(nary,int*), v->size*sizeof(int));
return v;
}
gsl_vector_int_view* na_to_gv_int_view(VALUE na)
{
gsl_vector_int_view *v = NULL;
- VALUE ary2;
+
+ // Raise exception if na's type is not NA_LINT
+ if(NA_TYPE(na) != NA_LINT)
+ rb_raise(rb_eTypeError, "GSL::Vector::Int::View requires NArray be LINT");
v = rb_gsl_vector_int_view_alloc(NA_TOTAL(na));
- ary2 = na_change_type(na, NA_LINT);
- v->vector.data = NA_PTR_TYPE(ary2,int*);
+ v->vector.data = NA_PTR_TYPE(na,int*);
v->vector.size = NA_TOTAL(na);
v->vector.stride = 1;
v->vector.owner = 0;
@@ -414,6 +535,10 @@ gsl_matrix_view* na_to_gm_view(VALUE nna)
gsl_matrix_view *m = NULL;
VALUE ary2;
struct NARRAY *na = NULL;
+
+ // Raise exception if nna's type is not NA_DFLOAT
+ if(NA_TYPE(nna) != NA_DFLOAT)
+ rb_raise(rb_eTypeError, "GSL::Matrix::View requires NArray be DFLOAT");
GetNArray(nna, na);
m = gsl_matrix_view_alloc();
ary2 = na_change_type(nna, NA_DFLOAT);
@@ -442,6 +567,10 @@ gsl_matrix_int_view* na_to_gm_int_view(VALUE nna)
gsl_matrix_int_view *m = NULL;
VALUE ary2;
struct NARRAY *na = NULL;
+
+ // Raise exception if nna's type is not NA_LINT
+ if(NA_TYPE(nna) != NA_LINT)
+ rb_raise(rb_eTypeError, "GSL::Matrix::Int::View requires NArray be LINT");
GetNArray(nna, na);
m = rb_gsl_matrix_int_view_alloc(na->shape[1], na->shape[0]);
ary2 = na_change_type(nna, NA_LINT);
@@ -556,14 +685,39 @@ void Init_gsl_narray(VALUE module)
rb_define_singleton_method(cgsl_vector, "to_gv_view", rb_gsl_na_to_gsl_vector_view, 1);
rb_define_singleton_method(cgsl_vector, "na_to_gslv_view", rb_gsl_na_to_gsl_vector_view, 1);
- rb_define_singleton_method(cgsl_vector, "na_to_gv_view", rb_gsl_na_to_gsl_vector, 1);
+ rb_define_singleton_method(cgsl_vector, "na_to_gv_view", rb_gsl_na_to_gsl_vector_view, 1);
rb_define_method(cNArray, "to_gv", rb_gsl_na_to_gsl_vector_method, 0);
rb_define_alias(cNArray, "to_gslv", "to_gv");
rb_define_method(cNArray, "to_gv_view", rb_gsl_na_to_gsl_vector_view_method, 0);
rb_define_alias(cNArray, "to_gslv_view", "to_gv_view");
rb_define_alias(cNArray, "to_gv2", "to_gv_view");
rb_define_alias(cNArray, "to_gv_ref", "to_gv_view");
+ /*****/
+ rb_define_method(cgsl_vector_complex, "to_na", rb_gsl_vector_complex_to_na, 0);
+ rb_define_alias(cgsl_vector_complex, "to_narray", "to_na");
+
+ rb_define_method(cgsl_vector_complex, "to_na2", rb_gsl_vector_to_na_ref, 0);
+ rb_define_alias(cgsl_vector_complex, "to_narray_ref", "to_na2");
+ rb_define_alias(cgsl_vector_complex, "to_na_ref", "to_na2");
+
+ rb_define_method(cgsl_vector_complex, "to_nv", rb_gsl_vector_complex_to_nvector, 0);
+ rb_define_alias(cgsl_vector_complex, "to_nvector", "to_nv");
+
+ rb_define_method(cgsl_vector_complex, "to_nv2", rb_gsl_vector_to_nvector_ref, 0);
+ rb_define_alias(cgsl_vector_complex, "to_nv_ref", "to_nv2");
+ rb_define_alias(cgsl_vector_complex, "to_nvector_ref", "to_nv2");
+
+ rb_define_singleton_method(cgsl_vector_complex, "to_gslv", rb_gsl_na_to_gsl_vector_complex, 1);
+ rb_define_singleton_method(cgsl_vector_complex, "to_gv", rb_gsl_na_to_gsl_vector_complex, 1);
+ rb_define_singleton_method(cgsl_vector_complex, "na_to_gslv", rb_gsl_na_to_gsl_vector_complex, 1);
+ rb_define_singleton_method(cgsl_vector_complex, "na_to_gv", rb_gsl_na_to_gsl_vector_complex, 1);
+
+ rb_define_singleton_method(cgsl_vector_complex, "to_gslv_view", rb_gsl_na_to_gsl_vector_complex_view, 1);
+ rb_define_singleton_method(cgsl_vector_complex, "to_gv_view", rb_gsl_na_to_gsl_vector_complex_view, 1);
+ rb_define_singleton_method(cgsl_vector_complex, "na_to_gslv_view", rb_gsl_na_to_gsl_vector_complex_view, 1);
+ rb_define_singleton_method(cgsl_vector_complex, "na_to_gv_view", rb_gsl_na_to_gsl_vector_complex_view, 1);
+
/*****/
rb_define_method(cgsl_vector_int, "to_na", rb_gsl_vector_int_to_na, 0);
rb_define_alias(cgsl_vector_int, "to_narray", "to_na");
@@ -584,7 +738,7 @@ void Init_gsl_narray(VALUE module)
rb_define_singleton_method(cgsl_vector_int, "to_gslv_view", rb_gsl_na_to_gsl_vector_int_view, 1);
rb_define_singleton_method(cgsl_vector_int, "to_gv_view", rb_gsl_na_to_gsl_vector_int_view, 1);
- rb_define_singleton_method(cgsl_vector_int, "na_to_gslv_view", rb_gsl_na_to_gsl_vector_int, 1);
+ rb_define_singleton_method(cgsl_vector_int, "na_to_gslv_view", rb_gsl_na_to_gsl_vector_int_view, 1);
rb_define_singleton_method(cgsl_vector_int, "na_to_gv_view", rb_gsl_na_to_gsl_vector_int_view, 1);
rb_define_method(cNArray, "to_gv_int", rb_gsl_na_to_gsl_vector_int_method, 0);
@@ -620,6 +774,9 @@ void Init_gsl_narray(VALUE module)
rb_define_method(cNArray, "to_gslm_view", rb_gsl_na_to_gsl_matrix_view_method, 0);
rb_define_alias(cNArray, "to_gm_view", "to_gslm_view");
+ /*****/
+ // TODO Complex matrix
+
/*****/
rb_define_method(cgsl_matrix_int, "to_na", rb_gsl_matrix_int_to_na, 0);
rb_define_alias(cgsl_matrix_int, "to_narray", "to_na");
@@ -19,4 +19,6 @@ gsl_matrix* na_to_gm(VALUE nna);
gsl_matrix_int* na_to_gm_int(VALUE nna);
extern VALUE cNVector, cNMatrix;
+gsl_vector_complex* na_to_gv_complex(VALUE na);
+gsl_vector_complex_view* na_to_gv_complex_view(VALUE na);
#endif
View
@@ -10,16 +10,19 @@
# ---
# * GSL::Vector#to_na
# * GSL::Vector#to_nvector
+# * GSL::Vector::Complex#to_na
+# * GSL::Vector::Complex#to_nvector
# * GSL::Matrix#to_na
# * GSL::Matrix#to_nmatrix
#
# Convert GSL objects to NArray. The data contained by the GSL objects
# are copied to a newly allocated memory block of the NArray objects created.
#
-#
# ---
# * GSL::Vector#to_na_ref
# * GSL::Vector#to_nvector_ref
+# * GSL::Vector::Complex#to_na_ref
+# * GSL::Vector::Complex#to_nvector_ref
# * GSL::Matrix#to_na_ref
# * GSL::Matrix#to_nmatrix_ref
#
@@ -44,8 +47,9 @@
# * NArray#to_gv
# * NArray#to_gm
#
-# Convert NArray objects to <tt>GSL::Vector</tt> or <tt>GSL::Matrix</tt>.
-# The data contained by the NArray objects
+# <tt>NArray#to_gv</tt> converts NArray objects to <tt>GSL::Vector</tt> or
+# <tt>GSL::Vector::Complex</tt>. <tt>NArray#to_gm</tt> converts NArray
+# objects to <tt>GSL::Matrix</tt>. The data contained by the NArray objects
# are copied to a newly allocated memory block of the GSL objects created.
#
# ---

0 comments on commit 5f043d5

Please sign in to comment.