In Files

    • complex.c

    Parent

    Class/Module Index [+]

    Quicksearch
    No matching classes.

    Complex

    A complex number can be represented as a paired real number with imaginary unit; a+bi. Where a is real part, b is imaginary part and i is imaginary unit. Real a equals complex a+0i mathematically.

    object can be created as literal, and also by using Kernel#Complex, , or method.

    2+1i #=> (2+1i)
    Complex(1) #=> (1+0i)
    Complex(2, 3) #=> (2+3i)
    Complex.polar(2, 3) #=> (-1.9799849932008908+0.2822400161197344i)
    3.to_c #=> (3+0i)
    

    You can also create complex object from floating-point numbers or strings.

    Complex(0.3) #=> (0.3+0i)
    Complex('0.3-0.5i') #=> (0.3-0.5i)
    Complex('2/3+3/4i') #=> ((2/3)+(3/4)*i)
    Complex('1@2') #=> (-0.4161468365471424+0.9092974268256817i)
    0.3.to_c #=> (0.3+0i)
    '0.3-0.5i'.to_c #=> (0.3-0.5i)
    '2/3+3/4i'.to_c #=> ((2/3)+(3/4)*i)
    '1@2'.to_c #=> (-0.4161468365471424+0.9092974268256817i)
    

    A complex object is either an exact or an inexact number.

    Complex(1, 1) / 2 #=> ((1/2)+(1/2)*i)
    Complex(1, 1) / 2.0 #=> (0.5+0.5i)
    

    Constants

    The imaginary unit.

    Public Class Methods

    polar(abs[, arg]) → complex click to toggle source

    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);
    }
     
    rect(real[, imag]) → complex click to toggle source
    rectangular(real[, imag]) → complex

    Returns a complex object which denotes the given rectangular form.

    Complex.rectangular(1, 2) #=> (1+2i)
    
     static VALUE
    nucomp_s_new(int argc, VALUE *argv, VALUE klass)
    {
     VALUE real, imag;
     switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
     case 1:
     nucomp_real_check(real);
     imag = ZERO;
     break;
     default:
     nucomp_real_check(real);
     nucomp_real_check(imag);
     break;
     }
     return nucomp_s_canonicalize_internal(klass, real, imag);
    }
     
    rectangular(real[, imag]) → complex click to toggle source

    Returns a complex object which denotes the given rectangular form.

    Complex.rectangular(1, 2) #=> (1+2i)
    
     static VALUE
    nucomp_s_new(int argc, VALUE *argv, VALUE klass)
    {
     VALUE real, imag;
     switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
     case 1:
     nucomp_real_check(real);
     imag = ZERO;
     break;
     default:
     nucomp_real_check(real);
     nucomp_real_check(imag);
     break;
     }
     return nucomp_s_canonicalize_internal(klass, real, imag);
    }
     

    Public Instance Methods

    cmp * numeric → complex click to toggle source

    Performs multiplication.

    Complex(2, 3) * Complex(2, 3) #=> (-5+12i)
    Complex(900) * Complex(1) #=> (900+0i)
    Complex(-2, 9) * Complex(-9, 2) #=> (0-85i)
    Complex(9, 8) * 4 #=> (36+32i)
    Complex(20, 9) * 9.8 #=> (196.0+88.2i)
    
     VALUE
    rb_complex_mul(VALUE self, VALUE other)
    {
     if (RB_TYPE_P(other, T_COMPLEX)) {
     VALUE real, imag;
     get_dat2(self, other);
     comp_mul(adat->real, adat->imag, bdat->real, bdat->imag, &real, &imag);
     return f_complex_new2(CLASS_OF(self), real, imag);
     }
     if (k_numeric_p(other) && f_real_p(other)) {
     get_dat1(self);
     return f_complex_new2(CLASS_OF(self),
     f_mul(dat->real, other),
     f_mul(dat->imag, other));
     }
     return rb_num_coerce_bin(self, other, '*');
    }
     
    cmp ** numeric → complex click to toggle source

    Performs exponentiation.

    Complex('i') ** 2 #=> (-1+0i)
    Complex(-8) ** Rational(1, 3) #=> (1.0000000000000002+1.7320508075688772i)
    
     VALUE
    rb_complex_pow(VALUE self, VALUE other)
    {
     if (k_numeric_p(other) && k_exact_zero_p(other))
     return f_complex_new_bang1(CLASS_OF(self), ONE);
     if (RB_TYPE_P(other, T_RATIONAL) && RRATIONAL(other)->den == LONG2FIX(1))
     other = RRATIONAL(other)->num; /* c14n */
     if (RB_TYPE_P(other, T_COMPLEX)) {
     get_dat1(other);
     if (k_exact_zero_p(dat->imag))
     other = dat->real; /* c14n */
     }
     if (RB_TYPE_P(other, T_COMPLEX)) {
     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 (FIXNUM_P(other)) {
     long n = FIX2LONG(other);
     if (n == 0) {
     return nucomp_s_new_internal(CLASS_OF(self), ONE, ZERO);
     }
     if (n < 0) {
     self = f_reciprocal(self);
     other = rb_int_uminus(other);
     n = -n;
     }
     {
     get_dat1(self);
     VALUE xr = dat->real, xi = dat->imag, zr = xr, zi = xi;
     if (f_zero_p(xi)) {
     zr = rb_num_pow(zr, other);
     }
     else if (f_zero_p(xr)) {
     zi = rb_num_pow(zi, other);
     if (n & 2) zi = f_negate(zi);
     if (!(n & 1)) {
     VALUE tmp = zr;
     zr = zi;
     zi = tmp;
     }
     }
     else {
     while (--n) {
     long q, r;
     for (; q = n / 2, r = n % 2, r == 0; n = q) {
     VALUE tmp = f_sub(f_mul(xr, xr), f_mul(xi, xi));
     xi = f_mul(f_mul(TWO, xr), xi);
     xr = tmp;
     }
     comp_mul(zr, zi, xr, xi, &zr, &zi);
     }
     }
     return nucomp_s_new_internal(CLASS_OF(self), zr, zi);
     }
     }
     if (k_numeric_p(other) && f_real_p(other)) {
     VALUE r, theta;
     if (RB_TYPE_P(other, T_BIGNUM))
     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);
    }
     
    cmp + numeric → complex click to toggle source

    Performs addition.

    Complex(2, 3) + Complex(2, 3) #=> (4+6i)
    Complex(900) + Complex(1) #=> (901+0i)
    Complex(-2, 9) + Complex(-9, 2) #=> (-11+11i)
    Complex(9, 8) + 4 #=> (13+8i)
    Complex(20, 9) + 9.8 #=> (29.8+9i)
    
     VALUE
    rb_complex_plus(VALUE self, VALUE other)
    {
     if (RB_TYPE_P(other, T_COMPLEX)) {
     VALUE real, imag;
     get_dat2(self, other);
     real = f_add(adat->real, bdat->real);
     imag = f_add(adat->imag, bdat->imag);
     return f_complex_new2(CLASS_OF(self), real, imag);
     }
     if (k_numeric_p(other) && f_real_p(other)) {
     get_dat1(self);
     return f_complex_new2(CLASS_OF(self),
     f_add(dat->real, other), dat->imag);
     }
     return rb_num_coerce_bin(self, other, '+');
    }
     
    cmp - numeric → complex click to toggle source

    Performs subtraction.

    Complex(2, 3) - Complex(2, 3) #=> (0+0i)
    Complex(900) - Complex(1) #=> (899+0i)
    Complex(-2, 9) - Complex(-9, 2) #=> (7+7i)
    Complex(9, 8) - 4 #=> (5+8i)
    Complex(20, 9) - 9.8 #=> (10.2+9i)
    
     VALUE
    rb_complex_minus(VALUE self, VALUE other)
    {
     if (RB_TYPE_P(other, T_COMPLEX)) {
     VALUE real, imag;
     get_dat2(self, other);
     real = f_sub(adat->real, bdat->real);
     imag = f_sub(adat->imag, bdat->imag);
     return f_complex_new2(CLASS_OF(self), real, imag);
     }
     if (k_numeric_p(other) && f_real_p(other)) {
     get_dat1(self);
     return f_complex_new2(CLASS_OF(self),
     f_sub(dat->real, other), dat->imag);
     }
     return rb_num_coerce_bin(self, other, '-');
    }
     
    -cmp → complex click to toggle source

    Returns negation of the value.

    -Complex(1, 2) #=> (-1-2i)
    
     VALUE
    rb_complex_uminus(VALUE self)
    {
     get_dat1(self);
     return f_complex_new2(CLASS_OF(self),
     f_negate(dat->real), f_negate(dat->imag));
    }
     
    cmp / numeric → complex click to toggle source
    quo(numeric) → complex

    Performs division.

    Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i)
    Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i)
    Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i)
    Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i)
    Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i)
    
     VALUE
    rb_complex_div(VALUE self, VALUE other)
    {
     return f_divide(self, other, f_quo, id_quo);
    }
     
    cmp == object → true or false click to toggle source

    Returns true if cmp equals object numerically.

    Complex(2, 3) == Complex(2, 3) #=> true
    Complex(5) == 5 #=> true
    Complex(0) == 0.0 #=> true
    Complex('1/3') == 0.33 #=> false
    Complex('1/2') == '1/2' #=> false
    
     static VALUE
    nucomp_eqeq_p(VALUE self, VALUE other)
    {
     if (RB_TYPE_P(other, T_COMPLEX)) {
     get_dat2(self, other);
     return f_boolcast(f_eqeq_p(adat->real, bdat->real) &&
     f_eqeq_p(adat->imag, bdat->imag));
     }
     if (k_numeric_p(other) && f_real_p(other)) {
     get_dat1(self);
     return f_boolcast(f_eqeq_p(dat->real, other) && f_zero_p(dat->imag));
     }
     return f_boolcast(f_eqeq_p(other, self));
    }
     
    abs → real click to toggle source

    Returns the absolute part of its polar form.

    Complex(-1).abs #=> 1
    Complex(3.0, -4.0).abs #=> 5.0
    
     VALUE
    rb_complex_abs(VALUE self)
    {
     get_dat1(self);
     if (f_zero_p(dat->real)) {
     VALUE a = f_abs(dat->imag);
     if (RB_FLOAT_TYPE_P(dat->real) && !RB_FLOAT_TYPE_P(dat->imag))
     a = f_to_f(a);
     return a;
     }
     if (f_zero_p(dat->imag)) {
     VALUE a = f_abs(dat->real);
     if (!RB_FLOAT_TYPE_P(dat->real) && RB_FLOAT_TYPE_P(dat->imag))
     a = f_to_f(a);
     return a;
     }
     return rb_math_hypot(dat->real, dat->imag);
    }
     
    abs2 → real click to toggle source

    Returns square of the absolute value.

    Complex(-1).abs2 #=> 1
    Complex(3.0, -4.0).abs2 #=> 25.0
    
     static VALUE
    nucomp_abs2(VALUE self)
    {
     get_dat1(self);
     return f_add(f_mul(dat->real, dat->real),
     f_mul(dat->imag, dat->imag));
    }
     
    angle → float click to toggle source

    Returns the angle part of its polar form.

    Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
    
     VALUE
    rb_complex_arg(VALUE self)
    {
     get_dat1(self);
     return rb_math_atan2(dat->imag, dat->real);
    }
     
    arg → float click to toggle source

    Returns the angle part of its polar form.

    Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
    
     VALUE
    rb_complex_arg(VALUE self)
    {
     get_dat1(self);
     return rb_math_atan2(dat->imag, dat->real);
    }
     
    conj → complex click to toggle source
    conjugate → complex

    Returns the complex conjugate.

    Complex(1, 2).conjugate #=> (1-2i)
    
     VALUE
    rb_complex_conjugate(VALUE self)
    {
     get_dat1(self);
     return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
    }
     
    conjugate → complex click to toggle source

    Returns the complex conjugate.

    Complex(1, 2).conjugate #=> (1-2i)
    
     VALUE
    rb_complex_conjugate(VALUE self)
    {
     get_dat1(self);
     return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
    }
     
    denominator → integer click to toggle source

    Returns the denominator (lcm of both denominator - real and imag).

    See numerator.

     static VALUE
    nucomp_denominator(VALUE self)
    {
     get_dat1(self);
     return rb_lcm(f_denominator(dat->real), f_denominator(dat->imag));
    }
     
    fdiv(numeric) → complex click to toggle source

    Performs division as each part is a float, never returns a float.

    Complex(11, 22).fdiv(3) #=> (3.6666666666666665+7.333333333333333i)
    
     static VALUE
    nucomp_fdiv(VALUE self, VALUE other)
    {
     return f_divide(self, other, f_fdiv, id_fdiv);
    }
     
    finite? → true or false click to toggle source

    Returns true if cmp's real and imaginary parts are both finite numbers, otherwise returns false.

     static VALUE
    rb_complex_finite_p(VALUE self)
    {
     get_dat1(self);
     if (f_finite_p(dat->real) && f_finite_p(dat->imag)) {
     return Qtrue;
     }
     return Qfalse;
    }
     
    imag → real click to toggle source
    imaginary → real

    Returns the imaginary part.

    Complex(7).imaginary #=> 0
    Complex(9, -4).imaginary #=> -4
    
     VALUE
    rb_complex_imag(VALUE self)
    {
     get_dat1(self);
     return dat->imag;
    }
     
    imaginary → real click to toggle source

    Returns the imaginary part.

    Complex(7).imaginary #=> 0
    Complex(9, -4).imaginary #=> -4
    
     VALUE
    rb_complex_imag(VALUE self)
    {
     get_dat1(self);
     return dat->imag;
    }
     
    infinite? → nil or 1 click to toggle source

    Returns 1 if cmp's real or imaginary part is an infinite number, otherwise returns nil.

    For example:
     (1+1i).infinite? #=> nil
     (Float::INFINITY + 1i).infinite? #=> 1
    
     static VALUE
    rb_complex_infinite_p(VALUE self)
    {
     get_dat1(self);
     if (NIL_P(f_infinite_p(dat->real)) && NIL_P(f_infinite_p(dat->imag))) {
     return Qnil;
     }
     return ONE;
    }
     
    inspect → string click to toggle source

    Returns the value as a string for inspection.

    Complex(2).inspect #=> "(2+0i)"
    Complex('-8/6').inspect #=> "((-4/3)+0i)"
    Complex('1/2i').inspect #=> "(0+(1/2)*i)"
    Complex(0, Float::INFINITY).inspect #=> "(0+Infinity*i)"
    Complex(Float::NAN, Float::NAN).inspect #=> "(NaN+NaN*i)"
    
     static VALUE
    nucomp_inspect(VALUE self)
    {
     VALUE s;
     s = rb_usascii_str_new2("(");
     rb_str_concat(s, f_format(self, rb_inspect));
     rb_str_cat2(s, ")");
     return s;
    }
     
    magnitude → real click to toggle source

    Returns the absolute part of its polar form.

    Complex(-1).abs #=> 1
    Complex(3.0, -4.0).abs #=> 5.0
    
     VALUE
    rb_complex_abs(VALUE self)
    {
     get_dat1(self);
     if (f_zero_p(dat->real)) {
     VALUE a = f_abs(dat->imag);
     if (RB_FLOAT_TYPE_P(dat->real) && !RB_FLOAT_TYPE_P(dat->imag))
     a = f_to_f(a);
     return a;
     }
     if (f_zero_p(dat->imag)) {
     VALUE a = f_abs(dat->real);
     if (!RB_FLOAT_TYPE_P(dat->real) && RB_FLOAT_TYPE_P(dat->imag))
     a = f_to_f(a);
     return a;
     }
     return rb_math_hypot(dat->real, dat->imag);
    }
     
    numerator → numeric click to toggle source

    Returns the numerator.

     1 2 3+4i <- numerator
     - + -i -> ----
     2 3 6 <- denominator
    c = Complex('1/2+2/3i') #=> ((1/2)+(2/3)*i)
    n = c.numerator #=> (3+4i)
    d = c.denominator #=> 6
    n / d #=> ((1/2)+(2/3)*i)
    Complex(Rational(n.real, d), Rational(n.imag, d))
     #=> ((1/2)+(2/3)*i)

    See denominator.

     static VALUE
    nucomp_numerator(VALUE self)
    {
     VALUE cd;
     get_dat1(self);
     cd = f_denominator(self);
     return f_complex_new2(CLASS_OF(self),
     f_mul(f_numerator(dat->real),
     f_div(cd, f_denominator(dat->real))),
     f_mul(f_numerator(dat->imag),
     f_div(cd, f_denominator(dat->imag))));
    }
     
    phase → float click to toggle source

    Returns the angle part of its polar form.

    Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
    
     VALUE
    rb_complex_arg(VALUE self)
    {
     get_dat1(self);
     return rb_math_atan2(dat->imag, dat->real);
    }
     
    polar → array click to toggle source

    Returns an array; [cmp.abs, cmp.arg].

    Complex(1, 2).polar #=> [2.23606797749979, 1.1071487177940904]
    
     static VALUE
    nucomp_polar(VALUE self)
    {
     return rb_assoc_new(f_abs(self), f_arg(self));
    }
     
    cmp / numeric → complex click to toggle source
    quo(numeric) → complex

    Performs division.

    Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i)
    Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i)
    Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i)
    Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i)
    Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i)
    
     VALUE
    rb_complex_div(VALUE self, VALUE other)
    {
     return f_divide(self, other, f_quo, id_quo);
    }
     
    rationalize([eps]) → rational click to toggle source

    Returns the value as a rational if possible (the imaginary part should be exactly zero).

    Complex(1.0/3, 0).rationalize #=> (1/3)
    Complex(1, 0.0).rationalize # RangeError
    Complex(1, 2).rationalize # RangeError
    

    See to_r.

     static VALUE
    nucomp_rationalize(int argc, VALUE *argv, VALUE self)
    {
     get_dat1(self);
     rb_check_arity(argc, 0, 1);
     if (!k_exact_zero_p(dat->imag)) {
     rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
     self);
     }
     return rb_funcallv(dat->real, id_rationalize, argc, argv);
    }
     
    real → real click to toggle source

    Returns the real part.

    Complex(7).real #=> 7
    Complex(9, -4).real #=> 9
    
     VALUE
    rb_complex_real(VALUE self)
    {
     get_dat1(self);
     return dat->real;
    }
     
    real? → false click to toggle source

    Returns false.

     static VALUE
    nucomp_false(VALUE self)
    {
     return Qfalse;
    }
     
    rect → array click to toggle source
    rectangular → array

    Returns an array; [cmp.real, cmp.imag].

    Complex(1, 2).rectangular #=> [1, 2]
    
     static VALUE
    nucomp_rect(VALUE self)
    {
     get_dat1(self);
     return rb_assoc_new(dat->real, dat->imag);
    }
     
    rect → array click to toggle source
    rectangular → array

    Returns an array; [cmp.real, cmp.imag].

    Complex(1, 2).rectangular #=> [1, 2]
    
     static VALUE
    nucomp_rect(VALUE self)
    {
     get_dat1(self);
     return rb_assoc_new(dat->real, dat->imag);
    }
     
    to_c → self click to toggle source

    Returns self.

    Complex(2).to_c #=> (2+0i)
    Complex(-8, 6).to_c #=> (-8+6i)
    
     static VALUE
    nucomp_to_c(VALUE self)
    {
     return self;
    }
     
    to_f → float click to toggle source

    Returns the value as a float if possible (the imaginary part should be exactly zero).

    Complex(1, 0).to_f #=> 1.0
    Complex(1, 0.0).to_f # RangeError
    Complex(1, 2).to_f # RangeError
    
     static VALUE
    nucomp_to_f(VALUE self)
    {
     get_dat1(self);
     if (!k_exact_zero_p(dat->imag)) {
     rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Float",
     self);
     }
     return f_to_f(dat->real);
    }
     
    to_i → integer click to toggle source

    Returns the value as an integer if possible (the imaginary part should be exactly zero).

    Complex(1, 0).to_i #=> 1
    Complex(1, 0.0).to_i # RangeError
    Complex(1, 2).to_i # RangeError
    
     static VALUE
    nucomp_to_i(VALUE self)
    {
     get_dat1(self);
     if (!k_exact_zero_p(dat->imag)) {
     rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Integer",
     self);
     }
     return f_to_i(dat->real);
    }
     
    to_r → rational click to toggle source

    Returns the value as a rational if possible (the imaginary part should be exactly zero).

    Complex(1, 0).to_r #=> (1/1)
    Complex(1, 0.0).to_r # RangeError
    Complex(1, 2).to_r # RangeError
    

    See rationalize.

     static VALUE
    nucomp_to_r(VALUE self)
    {
     get_dat1(self);
     if (!k_exact_zero_p(dat->imag)) {
     rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
     self);
     }
     return f_to_r(dat->real);
    }
     
    to_s → string click to toggle source

    Returns the value as a string.

    Complex(2).to_s #=> "2+0i"
    Complex('-8/6').to_s #=> "-4/3+0i"
    Complex('1/2i').to_s #=> "0+1/2i"
    Complex(0, Float::INFINITY).to_s #=> "0+Infinity*i"
    Complex(Float::NAN, Float::NAN).to_s #=> "NaN+NaN*i"
    
     static VALUE
    nucomp_to_s(VALUE self)
    {
     return f_format(self, rb_String);
    }
     

    This page was generated for Ruby

    is a service of and , an erratic source of art, music, and technology.

    Generated with Ruby-doc Rdoc Generator 0.44.0.