Class: Complex
Overview
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.
In ruby, you can create complex object with Complex, Complex::rect, Complex::polar or to_c method.
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)
Defined Under Namespace
Classes: compatible
Constant Summary collapse
- I =
The imaginary unit.
f_complex_new_bang2(rb_cComplex, ZERO, ONE)
Class Method Summary collapse
-
.polar(abs[, arg]) ⇒ Object
Returns a complex object which denotes the given polar form.
-
.rect(*args) ⇒ Object
Returns a complex object which denotes the given rectangular form.
-
.rectangular(*args) ⇒ Object
Returns a complex object which denotes the given rectangular form.
Instance Method Summary collapse
-
#*(numeric) ⇒ Object
Performs multiplication.
-
#**(numeric) ⇒ Object
Performs exponentiation.
-
#+(numeric) ⇒ Object
Performs addition.
-
#-(numeric) ⇒ Object
Performs subtraction.
-
#- ⇒ Object
Returns negation of the value.
-
#/(other) ⇒ Object
Performs division.
-
#==(object) ⇒ Boolean
Returns true if cmp equals object numerically.
-
#abs ⇒ Object
Returns the absolute part of its polar form.
-
#abs2 ⇒ Object
Returns square of the absolute value.
-
#angle ⇒ Object
Returns the angle part of its polar form.
-
#arg ⇒ Object
Returns the angle part of its polar form.
-
#coerce(other) ⇒ Object
:nodoc:.
-
#complex? ⇒ Boolean
:nodoc:.
-
#conj ⇒ Object
Returns the complex conjugate.
-
#conjugate ⇒ Object
Returns the complex conjugate.
-
#denominator ⇒ Integer
Returns the denominator (lcm of both denominator - real and imag).
-
#eql?(other) ⇒ Boolean
:nodoc:.
-
#exact? ⇒ Boolean
:nodoc:.
-
#fdiv(numeric) ⇒ Object
Performs division as each part is a float, never returns a float.
-
#hash ⇒ Object
:nodoc:.
-
#imag ⇒ Object
Returns the imaginary part.
-
#imaginary ⇒ Object
Returns the imaginary part.
-
#inexact? ⇒ Boolean
:nodoc:.
-
#inspect ⇒ String
Returns the value as a string for inspection.
-
#magnitude ⇒ Object
Returns the absolute part of its polar form.
-
#marshal_dump ⇒ Object
private
:nodoc:.
-
#numerator ⇒ Numeric
Returns the numerator.
-
#phase ⇒ Object
Returns the angle part of its polar form.
-
#polar ⇒ Array
Returns an array; [cmp.abs, cmp.arg].
- #quo ⇒ Object
-
#rationalize([eps]) ⇒ Object
Returns the value as a rational if possible (the imaginary part should be exactly zero).
-
#real ⇒ Object
Returns the real part.
-
#real? ⇒ false
Returns false.
-
#rect ⇒ Object
Returns an array; [cmp.real, cmp.imag].
-
#rectangular ⇒ Object
Returns an array; [cmp.real, cmp.imag].
-
#to_c ⇒ self
Returns self.
-
#to_f ⇒ Float
Returns the value as a float if possible (the imaginary part should be exactly zero).
-
#to_i ⇒ Integer
Returns the value as an integer if possible (the imaginary part should be exactly zero).
-
#to_r ⇒ Object
Returns the value as a rational if possible (the imaginary part should be exactly zero).
-
#to_s ⇒ String
Returns the value as a string.
-
#~ ⇒ Object
Returns the complex conjugate.
Methods inherited from Numeric
#%, #+@, #<=>, #ceil, #div, #divmod, #floor, #i, #initialize_copy, #integer?, #modulo, #nonzero?, #remainder, #round, #singleton_method_added, #step, #to_int, #truncate, #zero?
Methods included from Comparable
Class Method Details
.polar(abs[, arg]) ⇒ Object
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
# File 'complex.c', line 572
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);
arg = ZERO;
break;
default:
nucomp_real_check(abs);
nucomp_real_check(arg);
break;
}
return f_complex_polar(klass, abs, arg);
}
|
.rect(real[, imag]) ⇒ Object .rectangular(real[, imag]) ⇒ Object
Returns a complex object which denotes the given rectangular form.
Complex.rectangular(1, 2) #=> (1+2i)
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'complex.c', line 399
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);
}
|
.rect(real[, imag]) ⇒ Object .rectangular(real[, imag]) ⇒ Object
Returns a complex object which denotes the given rectangular form.
Complex.rectangular(1, 2) #=> (1+2i)
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'complex.c', line 399
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);
}
|
Instance Method Details
#*(numeric) ⇒ Object
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 |
# File 'complex.c', line 710
static VALUE
nucomp_mul(VALUE self, VALUE other)
{
if (k_complex_p(other)) {
VALUE real, imag;
get_dat2(self, other);
real = f_sub(f_mul(adat->real, bdat->real),
f_mul(adat->imag, bdat->imag));
imag = f_add(f_mul(adat->real, bdat->imag),
f_mul(adat->imag, bdat->real));
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, '*');
}
|
#**(numeric) ⇒ Object
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 |
# File 'complex.c', line 839
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);
}
|
#+(numeric) ⇒ Object
674 675 676 677 678 |
# File 'complex.c', line 674
static VALUE
nucomp_add(VALUE self, VALUE other)
{
return f_addsub(self, other, f_add, '+');
}
|
#-(numeric) ⇒ Object
692 693 694 695 696 |
# File 'complex.c', line 692
static VALUE
nucomp_sub(VALUE self, VALUE other)
{
return f_addsub(self, other, f_sub, '-');
}
|
#- ⇒ Object
Returns negation of the value.
-Complex(1, 2) #=> (-1-2i)
631 632 633 634 635 636 637 |
# File 'complex.c', line 631
static VALUE
nucomp_negate(VALUE self)
{
get_dat1(self);
return f_complex_new2(CLASS_OF(self),
f_negate(dat->real), f_negate(dat->imag));
}
|
#/(numeric) ⇒ Object #quo(numeric) ⇒ Object
802 803 804 805 806 |
# File 'complex.c', line 802
static VALUE
nucomp_div(VALUE self, VALUE other)
{
return f_divide(self, other, f_quo, id_quo);
}
|
#==(object) ⇒ Boolean
930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 |
# File 'complex.c', line 930
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 ⇒ Object #magnitude ⇒ Object
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 |
# File 'complex.c', line 971
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 ⇒ Object
1000 1001 1002 1003 1004 1005 1006 |
# File 'complex.c', line 1000
static VALUE
nucomp_abs2(VALUE self)
{
get_dat1(self);
return f_add(f_mul(dat->real, dat->real),
f_mul(dat->imag, dat->imag));
}
|
#arg ⇒ Float #angle ⇒ Float #phase ⇒ Float
1018 1019 1020 1021 1022 1023 |
# File 'complex.c', line 1018
static VALUE
nucomp_arg(VALUE self)
{
get_dat1(self);
return m_atan2_bang(dat->imag, dat->real);
}
|
#arg ⇒ Float #angle ⇒ Float #phase ⇒ Float
1018 1019 1020 1021 1022 1023 |
# File 'complex.c', line 1018
static VALUE
nucomp_arg(VALUE self)
{
get_dat1(self);
return m_atan2_bang(dat->imag, dat->real);
}
|
#coerce(other) ⇒ Object
:nodoc:
948 949 950 951 952 953 954 955 956 957 958 959 |
# File 'complex.c', line 948
static VALUE
nucomp_coerce(VALUE self, VALUE other)
{
if (k_numeric_p(other) && f_real_p(other))
return rb_assoc_new(f_complex_new_bang1(CLASS_OF(self), other), self);
if (RB_TYPE_P(other, T_COMPLEX))
return rb_assoc_new(other, self);
rb_raise(rb_eTypeError, "%s can't be coerced into %s",
rb_obj_classname(other), rb_obj_classname(self));
return Qnil;
}
|
#complex? ⇒ Boolean
:nodoc:
1073 1074 1075 1076 1077 |
# File 'complex.c', line 1073
static VALUE
nucomp_true(VALUE self)
{
return Qtrue;
}
|
#conj ⇒ Object #conjugate ⇒ Object
1064 1065 1066 1067 1068 1069 |
# File 'complex.c', line 1064
static VALUE
nucomp_conj(VALUE self)
{
get_dat1(self);
return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
}
|
#conj ⇒ Object #conjugate ⇒ Object
Returns the complex conjugate.
Complex(1, 2).conjugate #=> (1-2i)
1064 1065 1066 1067 1068 1069 |
# File 'complex.c', line 1064
static VALUE
nucomp_conj(VALUE self)
{
get_dat1(self);
return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
}
|
#denominator ⇒ Integer
Returns the denominator (lcm of both denominator - real and imag).
See numerator.
1117 1118 1119 1120 1121 1122 |
# File 'complex.c', line 1117
static VALUE
nucomp_denominator(VALUE self)
{
get_dat1(self);
return rb_lcm(f_denominator(dat->real), f_denominator(dat->imag));
}
|
#eql?(other) ⇒ Boolean
:nodoc:
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 |
# File 'complex.c', line 1174
static VALUE
nucomp_eql_p(VALUE self, VALUE other)
{
if (k_complex_p(other)) {
get_dat2(self, other);
return f_boolcast((CLASS_OF(adat->real) == CLASS_OF(bdat->real)) &&
(CLASS_OF(adat->imag) == CLASS_OF(bdat->imag)) &&
f_eqeq_p(self, other));
}
return Qfalse;
}
|
#exact? ⇒ Boolean
:nodoc:
1094 1095 1096 1097 1098 1099 |
# File 'complex.c', line 1094
static VALUE
nucomp_exact_p(VALUE self)
{
get_dat1(self);
return f_boolcast(k_exact_p(dat->real) && k_exact_p(dat->imag));
}
|
#fdiv(numeric) ⇒ Object
Performs division as each part is a float, never returns a float.
Complex(11, 22).fdiv(3) #=> (3.6666666666666665+7.333333333333333i)
818 819 820 821 822 |
# File 'complex.c', line 818
static VALUE
nucomp_fdiv(VALUE self, VALUE other)
{
return f_divide(self, other, f_fdiv, id_fdiv);
}
|
#hash ⇒ Object
:nodoc:
1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 |
# File 'complex.c', line 1158
static VALUE
nucomp_hash(VALUE self)
{
st_index_t v, h[2];
VALUE n;
get_dat1(self);
n = rb_hash(dat->real);
h[0] = NUM2LONG(n);
n = rb_hash(dat->imag);
h[1] = NUM2LONG(n);
v = rb_memhash(h, sizeof(h));
return LONG2FIX(v);
}
|
#imag ⇒ Object #imaginary ⇒ Object
616 617 618 619 620 621 |
# File 'complex.c', line 616
static VALUE
nucomp_imag(VALUE self)
{
get_dat1(self);
return dat->imag;
}
|
#imag ⇒ Object #imaginary ⇒ Object
616 617 618 619 620 621 |
# File 'complex.c', line 616
static VALUE
nucomp_imag(VALUE self)
{
get_dat1(self);
return dat->imag;
}
|
#inexact? ⇒ Boolean
:nodoc:
1102 1103 1104 1105 1106 |
# File 'complex.c', line 1102
static VALUE
nucomp_inexact_p(VALUE self)
{
return f_boolcast(!nucomp_exact_p(self));
}
|
#inspect ⇒ String
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 |
# File 'complex.c', line 1258
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;
}
|
#abs ⇒ Object #magnitude ⇒ Object
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 |
# File 'complex.c', line 971
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);
}
|
#marshal_dump ⇒ Object (private)
:nodoc:
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 |
# File 'complex.c', line 1290
static VALUE
nucomp_marshal_dump(VALUE self)
{
VALUE a;
get_dat1(self);
a = rb_assoc_new(dat->real, dat->imag);
rb_copy_generic_ivar(a, self);
return a;
}
|
#numerator ⇒ Numeric
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.
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 |
# File 'complex.c', line 1142
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))));
}
|
#arg ⇒ Float #angle ⇒ Float #phase ⇒ Float
1018 1019 1020 1021 1022 1023 |
# File 'complex.c', line 1018
static VALUE
nucomp_arg(VALUE self)
{
get_dat1(self);
return m_atan2_bang(dat->imag, dat->real);
}
|
#polar ⇒ Array
1049 1050 1051 1052 1053 |
# File 'complex.c', line 1049
static VALUE
nucomp_polar(VALUE self)
{
return rb_assoc_new(f_abs(self), f_arg(self));
}
|
#quo ⇒ Object
#rationalize([eps]) ⇒ Object
1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 |
# File 'complex.c', line 1442
static VALUE
nucomp_rationalize(int argc, VALUE *argv, VALUE self)
{
get_dat1(self);
rb_scan_args(argc, argv, "01", NULL);
if (k_inexact_p(dat->imag) || f_nonzero_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 ⇒ Object
599 600 601 602 603 604 |
# File 'complex.c', line 599
static VALUE
nucomp_real(VALUE self)
{
get_dat1(self);
return dat->real;
}
|
#real? ⇒ false
Returns false.
1086 1087 1088 1089 1090 |
# File 'complex.c', line 1086
static VALUE
nucomp_false(VALUE self)
{
return Qfalse;
}
|
#rect ⇒ Array #rectangular ⇒ Array
Returns an array; [cmp.real, cmp.imag].
Complex(1, 2).rectangular #=> [1, 2]
1034 1035 1036 1037 1038 1039 |
# File 'complex.c', line 1034
static VALUE
nucomp_rect(VALUE self)
{
get_dat1(self);
return rb_assoc_new(dat->real, dat->imag);
}
|
#rect ⇒ Array #rectangular ⇒ Array
Returns an array; [cmp.real, cmp.imag].
Complex(1, 2).rectangular #=> [1, 2]
1034 1035 1036 1037 1038 1039 |
# File 'complex.c', line 1034
static VALUE
nucomp_rect(VALUE self)
{
get_dat1(self);
return rb_assoc_new(dat->real, dat->imag);
}
|
#to_c ⇒ self
1465 1466 1467 1468 1469 |
# File 'complex.c', line 1465
static VALUE
nucomp_to_c(VALUE self)
{
return self;
}
|
#to_f ⇒ Float
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 |
# File 'complex.c', line 1392
static VALUE
nucomp_to_f(VALUE self)
{
get_dat1(self);
if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Float",
self);
}
return f_to_f(dat->real);
}
|
#to_i ⇒ Integer
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 |
# File 'complex.c', line 1369
static VALUE
nucomp_to_i(VALUE self)
{
get_dat1(self);
if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Integer",
self);
}
return f_to_i(dat->real);
}
|
#to_r ⇒ Object
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 |
# File 'complex.c', line 1417
static VALUE
nucomp_to_r(VALUE self)
{
get_dat1(self);
if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
self);
}
return f_to_r(dat->real);
}
|
#to_s ⇒ String
1240 1241 1242 1243 1244 |
# File 'complex.c', line 1240
static VALUE
nucomp_to_s(VALUE self)
{
return f_format(self, rb_String);
}
|