class 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.
You can create a Complex object explicitly with:
You can convert certain objects to Complex objects with:
-
Method Complex.
Complex object can be created as literal, and also by using Kernel#Complex, Complex::rect, Complex::polar or to_c 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
- I
The imaginary unit.
Public Class Methods
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;
argc = rb_scan_args(argc, argv, "11", &abs, &arg);
nucomp_real_check(abs);
if (argc == 2) {
nucomp_real_check(arg);
}
else {
arg = ZERO;
}
if (RB_TYPE_P(abs, T_COMPLEX)) {
get_dat1(abs);
abs = dat->real;
}
if (RB_TYPE_P(arg, T_COMPLEX)) {
get_dat1(arg);
arg = dat->real;
}
return f_complex_polar(klass, abs, arg);
}
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);
}
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
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, '*');
}
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_BIGNUM_TYPE_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);
}
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, '+');
}
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, '-');
}
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));
}