/* vector_int.c Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library) (C) Copyright 2004 by Yoshiki Tsunesada Modified by Seiya Nishizawa 14/Apr/2004 Ruby/GSL is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. */ #include "include/rb_gsl_array.h" #include "include/rb_gsl_complex.h" #ifdef HAVE_NARRAY_H #include "include/rb_gsl_with_narray.h" #endif VALUE rb_gsl_vector_int_inner_product(int argc, VALUE *argv, VALUE obj); VALUE rb_gsl_vector_int_do_something(VALUE obj, void (*func)(gsl_vector_int*)); static VALUE rb_gsl_vector_int_to_i(VALUE obj) { return obj; } VALUE rb_gsl_vector_int_to_f(VALUE obj) { gsl_vector_int *v; gsl_vector *vnew; size_t i; Data_Get_Struct(obj, gsl_vector_int, v); vnew = gsl_vector_alloc(v->size); for (i = 0; i < v->size; i++) gsl_vector_set(vnew, i, (double) gsl_vector_int_get(v, i)); if (VECTOR_INT_COL_P(obj)) return Data_Wrap_Struct(cgsl_vector_col, 0, gsl_vector_free, vnew); else return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew); } static VALUE rb_gsl_vector_int_to_complex(VALUE obj) { gsl_vector_int *v; gsl_vector_complex *vnew; gsl_complex z; size_t i; Data_Get_Struct(obj, gsl_vector_int, v); vnew = gsl_vector_complex_alloc(v->size); for (i = 0; i < v->size; i++) { GSL_SET_REAL(&z, (double) gsl_vector_int_get(v, i)); GSL_SET_IMAG(&z, 0.0); gsl_vector_complex_set(vnew, i, z); } if (VECTOR_INT_COL_P(obj)) return Data_Wrap_Struct(cgsl_vector_complex_col, 0, gsl_vector_complex_free, vnew); else return Data_Wrap_Struct(cgsl_vector_complex, 0, gsl_vector_complex_free, vnew); } static VALUE rb_gsl_vector_int_coerce(VALUE obj, VALUE other) { gsl_vector_int *v = NULL, *vnew = NULL; VALUE vv; Data_Get_Struct(obj, gsl_vector_int, v); switch (TYPE(other)) { case T_FIXNUM: vnew = gsl_vector_int_alloc(v->size); if (vnew == NULL) rb_raise(rb_eNoMemError, "gsl_vector_int_alloc failed"); gsl_vector_int_set_all(vnew, FIX2INT(other)); vv = Data_Wrap_Struct(VECTOR_INT_ROW_COL(obj), 0, gsl_vector_int_free, vnew); return rb_ary_new3(2, vv, obj); break; default: return rb_ary_new3(2, other, rb_gsl_vector_int_to_f(obj)); } // return rb_ary_new3(2, other, rb_gsl_vector_int_to_f(obj)); } VALUE rb_gsl_vector_add(VALUE obj, VALUE b); VALUE rb_gsl_vector_sub(VALUE obj, VALUE b); VALUE rb_gsl_vector_mul(VALUE obj, VALUE b); VALUE rb_gsl_vector_div(VALUE obj, VALUE b); static VALUE rb_gsl_vector_int_add(VALUE obj, VALUE b) { gsl_vector_int *v, *vnew, *vb; switch (TYPE(b)) { case T_FIXNUM: return rb_gsl_vector_int_add_constant(obj, b); break; case T_FLOAT: return rb_gsl_vector_add_constant(rb_gsl_vector_int_to_f(obj), b); break; default: if (rb_obj_is_kind_of(b, cgsl_vector_int)) { Data_Get_Struct(obj, gsl_vector_int, v); Data_Get_Struct(b, gsl_vector_int, vb); vnew = gsl_vector_int_alloc(v->size); gsl_vector_int_memcpy(vnew, v); gsl_vector_int_add(vnew, vb); return Data_Wrap_Struct(VECTOR_INT_ROW_COL(obj), 0, gsl_vector_int_free, vnew); } else { return rb_gsl_vector_add(rb_gsl_vector_int_to_f(obj), b); } break; } } static VALUE rb_gsl_vector_int_sub(VALUE obj, VALUE b) { gsl_vector_int *v, *vnew, *vb; switch (TYPE(b)) { case T_FIXNUM: return rb_gsl_vector_int_add_constant(obj, INT2FIX(-FIX2INT(b))); break; case T_FLOAT: return rb_gsl_vector_add_constant(rb_gsl_vector_int_to_f(obj), rb_float_new(-NUM2DBL(b))); break; default: if (rb_obj_is_kind_of(b, cgsl_vector_int)) { Data_Get_Struct(obj, gsl_vector_int, v); Data_Get_Struct(b, gsl_vector_int, vb); vnew = gsl_vector_int_alloc(v->size); gsl_vector_int_memcpy(vnew, v); gsl_vector_int_sub(vnew, vb); return Data_Wrap_Struct(VECTOR_INT_ROW_COL(obj), 0, gsl_vector_int_free, vnew); } else { return rb_gsl_vector_sub(rb_gsl_vector_int_to_f(obj), b); } break; } } gsl_vector_int* mygsl_vector_int_mul_matrix(gsl_vector_int *v, gsl_matrix_int *m); static VALUE rb_gsl_vector_int_mul(VALUE obj, VALUE b) { VALUE argv[2]; gsl_vector_int *v, *vnew, *v2; gsl_matrix_int *m; int val; size_t i, j; switch (TYPE(b)) { case T_FIXNUM: case T_FLOAT: return rb_gsl_vector_int_scale(obj, b); break; default: if (VECTOR_INT_ROW_P(obj) && VECTOR_INT_COL_P(b)) { argv[0] = obj; argv[1] = b; return rb_gsl_vector_int_inner_product(2, argv, CLASS_OF(obj)); } else if (VECTOR_INT_ROW_P(obj) && MATRIX_INT_P(b)) { Data_Get_Struct(obj, gsl_vector_int, v); Data_Get_Struct(b, gsl_matrix_int, m); vnew = mygsl_vector_int_mul_matrix(v, m); return Data_Wrap_Struct(cgsl_vector_int, 0, gsl_vector_int_free, vnew); } else if (VECTOR_INT_COL_P(obj) && VECTOR_INT_ROW_P(b)) { Data_Get_Struct(obj, gsl_vector_int, v); Data_Get_Struct(b, gsl_vector_int, v2); if (v->size != v2->size) rb_raise(rb_eIndexError, "Vector sizes does not match."); m = gsl_matrix_int_alloc(v->size, v2->size); for (i = 0; i < v->size; i++) { for (j = 0; j < v2->size; j++) { val = gsl_vector_int_get(v, i)*gsl_vector_int_get(v2, j); gsl_matrix_int_set(m, i, j, val); } } return Data_Wrap_Struct(cgsl_matrix_int, 0, gsl_matrix_int_free, m); } else { return rb_gsl_vector_mul(rb_gsl_vector_int_to_f(obj), b); } break; } } static VALUE rb_gsl_vector_int_div(VALUE obj, VALUE b) { return rb_gsl_vector_div(rb_gsl_vector_int_to_f(obj), b); } void Init_gsl_vector_int(VALUE module) { rb_define_method(cgsl_vector_int, "to_f", rb_gsl_vector_int_to_f, 0); rb_define_method(cgsl_vector_int, "to_i", rb_gsl_vector_int_to_i, 0); rb_define_method(cgsl_vector_int, "to_complex", rb_gsl_vector_int_to_complex, 0); /*****/ rb_define_method(cgsl_vector_int, "coerce", rb_gsl_vector_int_coerce, 1); rb_define_method(cgsl_vector_int, "add", rb_gsl_vector_int_add, 1); rb_define_method(cgsl_vector_int, "sub", rb_gsl_vector_int_sub, 1); rb_define_method(cgsl_vector_int, "mul", rb_gsl_vector_int_mul, 1); rb_define_method(cgsl_vector_int, "div", rb_gsl_vector_int_div, 1); rb_define_alias(cgsl_vector_int, "+", "add"); rb_define_alias(cgsl_vector_int, "-", "sub"); rb_define_alias(cgsl_vector_int, "*", "mul"); rb_define_alias(cgsl_vector_int, "/", "div"); Init_gsl_vector_int_init(module); }