コード例 #1
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
inline static VALUE
f_complex_new_bang2(VALUE klass, VALUE x, VALUE y)
{
    assert(!k_complex_p(x));
    assert(!k_complex_p(y));
    return nucomp_s_new_internal(klass, x, y);
}
コード例 #2
0
ファイル: complex.c プロジェクト: 0x00evil/ruby
static VALUE
f_complex_polar(VALUE klass, VALUE x, VALUE y)
{
    assert(!k_complex_p(x));
    assert(!k_complex_p(y));
    if (f_zero_p(x) || f_zero_p(y)) {
	if (canonicalization) return x;
	return nucomp_s_new_internal(klass, x, RFLOAT_0);
    }
    if (RB_FLOAT_TYPE_P(y)) {
	const double arg = RFLOAT_VALUE(y);
	if (arg == M_PI) {
	    x = f_negate(x);
	    if (canonicalization) return x;
	    y = RFLOAT_0;
	}
	else if (arg == M_PI_2) {
	    y = x;
	    x = RFLOAT_0;
	}
	else if (arg == M_PI_2+M_PI) {
	    y = f_negate(x);
	    x = RFLOAT_0;
	}
	else if (RB_FLOAT_TYPE_P(x)) {
	    const double abs = RFLOAT_VALUE(x);
	    const double real = abs * cos(arg), imag = abs * sin(arg);
	    x = DBL2NUM(real);
	    if (canonicalization && imag == 0.0) return x;
	    y = DBL2NUM(imag);
	}
	else {
	    x = f_mul(x, DBL2NUM(cos(arg)));
	    y = f_mul(y, DBL2NUM(sin(arg)));
	    if (canonicalization && f_zero_p(y)) return x;
	}
	return nucomp_s_new_internal(klass, x, y);
    }
    return nucomp_s_canonicalize_internal(klass,
					  f_mul(x, m_cos(y)),
					  f_mul(x, m_sin(y)));
}
コード例 #3
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
inline static VALUE
nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag)
{
#ifdef CANON
#define CL_CANON
#ifdef CL_CANON
    if (k_exact_zero_p(imag) && canonicalization)
	return real;
#else
    if (f_zero_p(imag) && canonicalization)
	return real;
#endif
#endif
    if (f_real_p(real) && f_real_p(imag))
	return nucomp_s_new_internal(klass, real, imag);
    else if (f_real_p(real)) {
	get_dat1(imag);

	return nucomp_s_new_internal(klass,
				     f_sub(real, dat->imag),
				     f_add(ZERO, dat->real));
    }
    else if (f_real_p(imag)) {
	get_dat1(real);

	return nucomp_s_new_internal(klass,
				     dat->real,
				     f_add(dat->imag, imag));
    }
    else {
	get_dat2(real, imag);

	return nucomp_s_new_internal(klass,
				     f_sub(adat->real, bdat->imag),
				     f_add(adat->imag, bdat->real));
    }
}
コード例 #4
0
ファイル: complex.c プロジェクト: 0x00evil/ruby
/*
 * call-seq:
 *    Complex.polar(abs[, arg])  ->  complex
 *
 * Returns a complex object which denotes the given polar form.
 *
 *    Complex.polar(3, 0)            #=> (3.0+0.0i)
 *    Complex.polar(3, Math::PI/2)   #=> (1.836909530733566e-16+3.0i)
 *    Complex.polar(3, Math::PI)     #=> (-3.0+3.673819061467132e-16i)
 *    Complex.polar(3, -Math::PI/2)  #=> (1.836909530733566e-16-3.0i)
 */
static VALUE
nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
{
    VALUE abs, arg;

    switch (rb_scan_args(argc, argv, "11", &abs, &arg)) {
      case 1:
	nucomp_real_check(abs);
	if (canonicalization) return abs;
	return nucomp_s_new_internal(klass, abs, ZERO);
      default:
	nucomp_real_check(abs);
	nucomp_real_check(arg);
	break;
    }
    return f_complex_polar(klass, abs, arg);
}
コード例 #5
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
static VALUE
nucomp_s_new_bang(int argc, VALUE *argv, VALUE klass)
{
    VALUE real, imag;

    switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
      case 1:
	if (!k_numeric_p(real))
	    real = f_to_i(real);
	imag = ZERO;
	break;
      default:
	if (!k_numeric_p(real))
	    real = f_to_i(real);
	if (!k_numeric_p(imag))
	    imag = f_to_i(imag);
	break;
    }

    return nucomp_s_new_internal(klass, real, imag);
}
コード例 #6
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp ** numeric  ->  complex
 *
 * Performs exponentiation.
 *
 *    Complex('i') ** 2              #=> (-1+0i)
 *    Complex(-8) ** Rational(1, 3)  #=> (1.0000000000000002+1.7320508075688772i)
 */
static VALUE
nucomp_expt(VALUE self, VALUE other)
{
    if (k_numeric_p(other) && k_exact_zero_p(other))
	return f_complex_new_bang1(CLASS_OF(self), ONE);

    if (k_rational_p(other) && f_one_p(f_denominator(other)))
	other = f_numerator(other); /* c14n */

    if (k_complex_p(other)) {
	get_dat1(other);

	if (k_exact_zero_p(dat->imag))
	    other = dat->real; /* c14n */
    }

    if (k_complex_p(other)) {
	VALUE r, theta, nr, ntheta;

	get_dat1(other);

	r = f_abs(self);
	theta = f_arg(self);

	nr = m_exp_bang(f_sub(f_mul(dat->real, m_log_bang(r)),
			      f_mul(dat->imag, theta)));
	ntheta = f_add(f_mul(theta, dat->real),
		       f_mul(dat->imag, m_log_bang(r)));
	return f_complex_polar(CLASS_OF(self), nr, ntheta);
    }
    if (k_fixnum_p(other)) {
	if (f_gt_p(other, ZERO)) {
	    VALUE x, z;
	    long n;

	    x = self;
	    z = x;
	    n = FIX2LONG(other) - 1;

	    while (n) {
		long q, r;

		while (1) {
		    get_dat1(x);

		    q = n / 2;
		    r = n % 2;

		    if (r)
			break;

		    x = nucomp_s_new_internal(CLASS_OF(self),
				       f_sub(f_mul(dat->real, dat->real),
					     f_mul(dat->imag, dat->imag)),
				       f_mul(f_mul(TWO, dat->real), dat->imag));
		    n = q;
		}
		z = f_mul(z, x);
		n--;
	    }
	    return z;
	}
	return f_expt(f_reciprocal(self), f_negate(other));
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	VALUE r, theta;

	if (k_bignum_p(other))
	    rb_warn("in a**b, b may be too big");

	r = f_abs(self);
	theta = f_arg(self);

	return f_complex_polar(CLASS_OF(self), f_expt(r, other),
			       f_mul(theta, other));
    }
    return rb_num_coerce_bin(self, other, id_expt);
}
コード例 #7
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
inline static VALUE
f_complex_new_bang1(VALUE klass, VALUE x)
{
    assert(!k_complex_p(x));
    return nucomp_s_new_internal(klass, x, ZERO);
}
コード例 #8
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
static VALUE
nucomp_s_alloc(VALUE klass)
{
    return nucomp_s_new_internal(klass, ZERO, ZERO);
}
コード例 #9
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
VALUE
rb_complex_raw(VALUE x, VALUE y)
{
    return nucomp_s_new_internal(rb_cComplex, x, y);
}