diff --git a/ext/gsl_native/complex.c b/ext/gsl_native/complex.c index 40b1ac5e..a637787d 100644 --- a/ext/gsl_native/complex.c +++ b/ext/gsl_native/complex.c @@ -41,6 +41,11 @@ gsl_complex rb_gsl_obj_to_gsl_complex(VALUE obj, gsl_complex *z) if (!NIL_P(vre)) GSL_SET_REAL(z, NUM2DBL(vre)); if (!NIL_P(vim)) GSL_SET_IMAG(z, NUM2DBL(vim)); break; + case T_COMPLEX: + vre = rb_funcall(obj, rb_intern("real"), 0); + vim = rb_funcall(obj, rb_intern("imag"), 0); + *z = gsl_complex_rect(NUM2DBL(vre), NUM2DBL(vim)); + break; case T_FLOAT: case T_FIXNUM: case T_BIGNUM: @@ -63,7 +68,7 @@ gsl_complex rb_gsl_obj_to_gsl_complex(VALUE obj, gsl_complex *z) static VALUE rb_gsl_complex_new(int argc, VALUE *argv, VALUE klass) { gsl_complex *c = NULL; - VALUE obj; + VALUE obj, vre, vim; obj = Data_Make_Struct(klass, gsl_complex, 0, free, c); switch (argc) { case 1: @@ -71,6 +76,11 @@ static VALUE rb_gsl_complex_new(int argc, VALUE *argv, VALUE klass) case T_ARRAY: *c = ary2complex(argv[0]); break; + case T_COMPLEX: + vre = rb_funcall(argv[0], rb_intern("real"), 0); + vim = rb_funcall(argv[0], rb_intern("imag"), 0); + *c = gsl_complex_rect(NUM2DBL(vre), NUM2DBL(vim)); + break; case T_FLOAT: case T_FIXNUM: case T_BIGNUM: diff --git a/test/gsl/complex_test.rb b/test/gsl/complex_test.rb index 07e996e4..a1a01167 100644 --- a/test/gsl/complex_test.rb +++ b/test/gsl/complex_test.rb @@ -16,5 +16,16 @@ def test_complex 'gsl_complex_polar imag part at (r=%g,t=%g)' % [r, t] } end - + + # Test if it is possible to create a GSL::Complex from ::Complex + def test_rb_complex_creation + rb_comp = Complex(rand, rand) + + z = GSL::Complex.alloc(rb_comp) + + assert_rel z.real, rb_comp.real, GSL::DBL_EPSILON, + "gsl_complex real part. Re(#{rb_comp}) = #{z.real}" + assert_rel z.imag, rb_comp.imag, GSL::DBL_EPSILON, + "gsl_complex imag part. Im(#{rb_comp}) = #{z.imag}" + end end