class Complex - Documentation for Ruby 2.3.0 (original) (raw)
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.
Complex object can be created as literal, and also by using Kernel#Complex, Complex::rect, Complex::polar or to_c method.
2+1i
Complex(1)
Complex(2, 3)
Complex.polar(2, 3)
3.to_c
You can also create complex object from floating-point numbers or strings.
Complex(0.3)
Complex('0.3-0.5i')
Complex('2/3+3/4i')
Complex('1@2')
0.3.to_c
'0.3-0.5i'.to_c
'2/3+3/4i'.to_c
'1@2'.to_c
A complex object is either an exact or an inexact number.
Complex(1, 1) / 2
Complex(1, 1) / 2.0
Constants
I
The imaginary unit.
Public Class Methods
json_create(object) click to toggle source
Deserializes JSON string by converting Real value r
, imaginary value i
, to a Complex object.
def self.json_create(object) Complex(object['r'], object['i']) end
polar(abs[, arg]) → complex click to toggle source
Returns a complex object which denotes the given polar form.
Complex.polar(3, 0)
Complex.polar(3, Math::PI/2)
Complex.polar(3, Math::PI)
Complex.polar(3, -Math::PI/2)
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)
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)
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)
Complex(900) * Complex(1)
Complex(-2, 9) * Complex(-9, 2)
Complex(9, 8) * 4
Complex(20, 9) * 9.8
VALUE rb_nucomp_mul(VALUE self, VALUE other) { if (k_complex_p(other)) { VALUE real, imag; VALUE areal, aimag, breal, bimag; int arzero, aizero, brzero, bizero;
get_dat2(self, other);
arzero = !!f_zero_p(areal = adat->real);
aizero = !!f_zero_p(aimag = adat->imag);
brzero = !!f_zero_p(breal = bdat->real);
bizero = !!f_zero_p(bimag = bdat->imag);
real = f_sub(safe_mul(areal, breal, arzero, brzero),
safe_mul(aimag, bimag, aizero, bizero));
imag = f_add(safe_mul(areal, bimag, arzero, bizero),
safe_mul(aimag, breal, aizero, brzero));
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
Complex(-8) ** Rational(1, 3)
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);
}
cmp + numeric → complex click to toggle source
Performs addition.
Complex(2, 3) + Complex(2, 3)
Complex(900) + Complex(1)
Complex(-2, 9) + Complex(-9, 2)
Complex(9, 8) + 4
Complex(20, 9) + 9.8
VALUE rb_nucomp_add(VALUE self, VALUE other) { return f_addsub(self, other, f_add, '+'); }
cmp - numeric → complex click to toggle source
Performs subtraction.
Complex(2, 3) - Complex(2, 3)
Complex(900) - Complex(1)
Complex(-2, 9) - Complex(-9, 2)
Complex(9, 8) - 4
Complex(20, 9) - 9.8
static VALUE nucomp_sub(VALUE self, VALUE other) { return f_addsub(self, other, f_sub, '-'); }
-cmp → complex click to toggle source
Returns negation of the value.
-Complex(1, 2)
static VALUE nucomp_negate(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)
Complex(900) / Complex(1)
Complex(-2, 9) / Complex(-9, 2)
Complex(9, 8) / 4
Complex(20, 9) / 9.8
static VALUE nucomp_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)
Complex(5) == 5
Complex(0) == 0.0
Complex('1/3') == 0.33
Complex('1/2') == '1/2'
static VALUE nucomp_eqeq_p(VALUE self, VALUE other) { if (k_complex_p(other)) { 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_eqeq_p(other, self);
}
abs → real click to toggle source
Returns the absolute part of its polar form.
Complex(-1).abs
Complex(3.0, -4.0).abs
static VALUE nucomp_abs(VALUE self) { get_dat1(self);
if (f_zero_p(dat->real)) {
VALUE a = f_abs(dat->imag);
if (k_float_p(dat->real) && !k_float_p(dat->imag))
a = f_to_f(a);
return a;
}
if (f_zero_p(dat->imag)) {
VALUE a = f_abs(dat->real);
if (!k_float_p(dat->real) && k_float_p(dat->imag))
a = f_to_f(a);
return a;
}
return m_hypot(dat->real, dat->imag);
}
abs2 → real click to toggle source
Returns square of the absolute value.
Complex(-1).abs2
Complex(3.0, -4.0).abs2
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
static VALUE nucomp_arg(VALUE self) { get_dat1(self); return m_atan2_bang(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
static VALUE nucomp_arg(VALUE self) { get_dat1(self); return m_atan2_bang(dat->imag, dat->real); }
as_json(*) click to toggle source
Returns a hash, that will be turned into a JSON object and represent this object.
def as_json(*) { JSON.create_id => self.class.name, 'r' => real, 'i' => imag, } end
conj → complex click to toggle source
conjugate → complex
Returns the complex conjugate.
Complex(1, 2).conjugate
static VALUE nucomp_conj(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
static VALUE nucomp_conj(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)
static VALUE nucomp_fdiv(VALUE self, VALUE other) { return f_divide(self, other, f_fdiv, id_fdiv); }
imag → real click to toggle source
imaginary → real
Returns the imaginary part.
Complex(7).imaginary
Complex(9, -4).imaginary
static VALUE nucomp_imag(VALUE self) { get_dat1(self); return dat->imag; }
imaginary → real click to toggle source
Returns the imaginary part.
Complex(7).imaginary
Complex(9, -4).imaginary
static VALUE nucomp_imag(VALUE self) { get_dat1(self); return dat->imag; }
inspect → string click to toggle source
Returns the value as a string for inspection.
Complex(2).inspect
Complex('-8/6').inspect
Complex('1/2i').inspect
Complex(0, Float::INFINITY).inspect
Complex(Float::NAN, Float::NAN).inspect
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
Complex(3.0, -4.0).abs
static VALUE nucomp_abs(VALUE self) { get_dat1(self);
if (f_zero_p(dat->real)) {
VALUE a = f_abs(dat->imag);
if (k_float_p(dat->real) && !k_float_p(dat->imag))
a = f_to_f(a);
return a;
}
if (f_zero_p(dat->imag)) {
VALUE a = f_abs(dat->real);
if (!k_float_p(dat->real) && k_float_p(dat->imag))
a = f_to_f(a);
return a;
}
return m_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
static VALUE nucomp_arg(VALUE self) { get_dat1(self); return m_atan2_bang(dat->imag, dat->real); }
polar → array click to toggle source
Returns an array; [cmp.abs, cmp.arg].
Complex(1, 2).polar
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)
Complex(900) / Complex(1)
Complex(-2, 9) / Complex(-9, 2)
Complex(9, 8) / 4
Complex(20, 9) / 9.8
static VALUE nucomp_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
Complex(1, 0.0).rationalize
Complex(1, 2).rationalize
See to_r.
static VALUE nucomp_rationalize(int argc, VALUE *argv, VALUE self) { get_dat1(self);
rb_scan_args(argc, argv, "01", NULL);
if (!k_exact_zero_p(dat->imag)) {
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
self);
}
return rb_funcall2(dat->real, rb_intern("rationalize"), argc, argv);
}
real → real click to toggle source
Returns the real part.
Complex(7).real
Complex(9, -4).real
static VALUE nucomp_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
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
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
Complex(-8, 6).to_c
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
Complex(1, 0.0).to_f
Complex(1, 2).to_f
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
Complex(1, 0.0).to_i
Complex(1, 2).to_i
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_json(*) click to toggle source
Stores class name (Complex) along with real value r
and imaginary value i
as JSON string
def to_json(*) as_json.to_json end
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
Complex(1, 0.0).to_r
Complex(1, 2).to_r
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
Complex('-8/6').to_s
Complex('1/2i').to_s
Complex(0, Float::INFINITY).to_s
Complex(Float::NAN, Float::NAN).to_s
static VALUE nucomp_to_s(VALUE self) { return f_format(self, rb_String); }
conj → complex click to toggle source
conjugate → complex
Returns the complex conjugate.
Complex(1, 2).conjugate
static VALUE nucomp_conj(VALUE self) { get_dat1(self); return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag)); }