Integrate version.pm-0.77 into bleadperl
[p5sagit/p5-mst-13.2.git] / lib / Math / Complex.pm
CommitLineData
66730be0 1#
2# Complex numbers and associated mathematical functions
b42d0ec9 3# -- Raphael Manfredi Since Sep 1996
4# -- Jarkko Hietaniemi Since Mar 1997
5# -- Daniel S. Lewart Since Sep 1997
fb73857a 6#
a0d0e21e 7
5aabfad6 8package Math::Complex;
a0d0e21e 9
e7deb4af 10use strict;
11
f1e71051 12use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $Inf $ExpInf);
9fbe1b12 13
e7deb4af 14$VERSION = 1.56;
8b4fe368 15
16use Config;
476757f7 17
9fbe1b12 18BEGIN {
8b4fe368 19 my %DBL_MAX =
20 (
21 4 => '1.70141183460469229e+38',
22 8 => '1.7976931348623157e+308',
57dd0abb 23 # AFAICT the 10, 12, and 16-byte long doubles
24 # all have the same maximum.
8b4fe368 25 10 => '1.1897314953572317650857593266280070162E+4932',
57dd0abb 26 12 => '1.1897314953572317650857593266280070162E+4932',
d3056722 27 16 => '1.1897314953572317650857593266280070162E+4932',
8b4fe368 28 );
57dd0abb 29 my $nvsize = $Config{nvsize} ||
30 ($Config{uselongdouble} && $Config{longdblsize}) ||
31 $Config{doublesize};
32 die "Math::Complex: Could not figure out nvsize\n"
33 unless defined $nvsize;
34 die "Math::Complex: Cannot not figure out max nv (nvsize = $nvsize)\n"
35 unless defined $DBL_MAX{$nvsize};
8b4fe368 36 my $DBL_MAX = eval $DBL_MAX{$nvsize};
57dd0abb 37 die "Math::Complex: Could not figure out max nv (nvsize = $nvsize)\n"
38 unless defined $DBL_MAX;
8b4fe368 39 my $BIGGER_THAN_THIS = 1e30; # Must find something bigger than this.
1515bec6 40 if ($^O eq 'unicosmk') {
8b4fe368 41 $Inf = $DBL_MAX;
1515bec6 42 } else {
f1e71051 43 local $SIG{FPE} = { };
618e05e9 44 local $!;
8b4fe368 45 # We do want an arithmetic overflow, Inf INF inf Infinity.
1515bec6 46 for my $t (
8b4fe368 47 'exp(99999)', # Enough even with 128-bit long doubles.
1515bec6 48 'inf',
49 'Inf',
50 'INF',
51 'infinity',
52 'Infinity',
53 'INFINITY',
8b4fe368 54 '1e99999',
1515bec6 55 ) {
1515bec6 56 local $^W = 0;
57 my $i = eval "$t+1.0";
9f4452f7 58 if (defined $i && $i > $BIGGER_THAN_THIS) {
1515bec6 59 $Inf = $i;
60 last;
61 }
830ec763 62 }
8b4fe368 63 $Inf = $DBL_MAX unless defined $Inf; # Oh well, close enough.
64 die "Math::Complex: Could not get Infinity"
65 unless $Inf > $BIGGER_THAN_THIS;
f1e71051 66 $ExpInf = exp(99999);
ffb4440d 67 }
9f4452f7 68 # print "# On this machine, Inf = '$Inf'\n";
9fbe1b12 69}
fb73857a 70
e7deb4af 71use Scalar::Util qw(set_prototype);
72
73use warnings;
74no warnings 'syntax'; # To avoid the (_) warnings.
75
76BEGIN {
77 # For certain functions that we override, in 5.10 or better
78 # we can set a smarter prototype that will handle the lexical $_
79 # (also a 5.10+ feature).
80 if ($] >= 5.010000) {
81 set_prototype \&abs, '_';
82 set_prototype \&cos, '_';
83 set_prototype \&exp, '_';
84 set_prototype \&log, '_';
85 set_prototype \&sin, '_';
86 set_prototype \&sqrt, '_';
87 }
88}
fb73857a 89
9fbe1b12 90my $i;
91my %LOGN;
0c721ce2 92
91cb744f 93# Regular expression for floating point numbers.
bf5f1b4c 94# These days we could use Scalar::Util::lln(), I guess.
95my $gre = qr'\s*([\+\-]?(?:(?:(?:\d+(?:_\d+)*(?:\.\d*(?:_\d+)*)?|\.\d+(?:_\d+)*)(?:[eE][\+\-]?\d+(?:_\d+)*)?))|inf)'i;
91cb744f 96
9fbe1b12 97require Exporter;
0c721ce2 98
5aabfad6 99@ISA = qw(Exporter);
100
5aabfad6 101my @trig = qw(
102 pi
fb73857a 103 tan
5aabfad6 104 csc cosec sec cot cotan
105 asin acos atan
106 acsc acosec asec acot acotan
107 sinh cosh tanh
108 csch cosech sech coth cotanh
109 asinh acosh atanh
110 acsch acosech asech acoth acotanh
111 );
112
113@EXPORT = (qw(
b42d0ec9 114 i Re Im rho theta arg
fb73857a 115 sqrt log ln
5aabfad6 116 log10 logn cbrt root
117 cplx cplxe
bf5f1b4c 118 atan2
5aabfad6 119 ),
120 @trig);
121
1515bec6 122my @pi = qw(pi pi2 pi4 pip2 pip4 Inf);
affad850 123
124@EXPORT_OK = @pi;
bf5f1b4c 125
5aabfad6 126%EXPORT_TAGS = (
127 'trig' => [@trig],
affad850 128 'pi' => [@pi],
66730be0 129);
a0d0e21e 130
a5f75d66 131use overload
affad850 132 '+' => \&_plus,
133 '-' => \&_minus,
134 '*' => \&_multiply,
135 '/' => \&_divide,
136 '**' => \&_power,
137 '==' => \&_numeq,
138 '<=>' => \&_spaceship,
139 'neg' => \&_negate,
140 '~' => \&_conjugate,
66730be0 141 'abs' => \&abs,
142 'sqrt' => \&sqrt,
143 'exp' => \&exp,
144 'log' => \&log,
145 'sin' => \&sin,
146 'cos' => \&cos,
0c721ce2 147 'tan' => \&tan,
66730be0 148 'atan2' => \&atan2,
affad850 149 '""' => \&_stringify;
66730be0 150
151#
b42d0ec9 152# Package "privates"
66730be0 153#
154
16357284 155my %DISPLAY_FORMAT = ('style' => 'cartesian',
156 'polar_pretty_print' => 1);
157my $eps = 1e-14; # Epsilon
66730be0 158
159#
160# Object attributes (internal):
161# cartesian [real, imaginary] -- cartesian form
162# polar [rho, theta] -- polar form
163# c_dirty cartesian form not up-to-date
164# p_dirty polar form not up-to-date
165# display display format (package's global when not set)
166#
167
b42d0ec9 168# Die on bad *make() arguments.
169
170sub _cannot_make {
bf5f1b4c 171 die "@{[(caller(1))[3]]}: Cannot take $_[0] of '$_[1]'.\n";
b42d0ec9 172}
173
bf5f1b4c 174sub _make {
91cb744f 175 my $arg = shift;
bf5f1b4c 176 my ($p, $q);
91cb744f 177
bf5f1b4c 178 if ($arg =~ /^$gre$/) {
179 ($p, $q) = ($1, 0);
180 } elsif ($arg =~ /^(?:$gre)?$gre\s*i\s*$/) {
91cb744f 181 ($p, $q) = ($1 || 0, $2);
bf5f1b4c 182 } elsif ($arg =~ /^\s*\(\s*$gre\s*(?:,\s*$gre\s*)?\)\s*$/) {
91cb744f 183 ($p, $q) = ($1, $2 || 0);
91cb744f 184 }
185
bf5f1b4c 186 if (defined $p) {
91cb744f 187 $p =~ s/^\+//;
bf5f1b4c 188 $p =~ s/^(-?)inf$/"${1}9**9**9"/e;
91cb744f 189 $q =~ s/^\+//;
bf5f1b4c 190 $q =~ s/^(-?)inf$/"${1}9**9**9"/e;
91cb744f 191 }
192
bf5f1b4c 193 return ($p, $q);
194}
195
196sub _emake {
197 my $arg = shift;
198 my ($p, $q);
199
200 if ($arg =~ /^\s*\[\s*$gre\s*(?:,\s*$gre\s*)?\]\s*$/) {
201 ($p, $q) = ($1, $2 || 0);
202 } elsif ($arg =~ m!^\s*\[\s*$gre\s*(?:,\s*([-+]?\d*\s*)?pi(?:/\s*(\d+))?\s*)?\]\s*$!) {
203 ($p, $q) = ($1, ($2 eq '-' ? -1 : ($2 || 1)) * pi() / ($3 || 1));
204 } elsif ($arg =~ /^\s*\[\s*$gre\s*\]\s*$/) {
205 ($p, $q) = ($1, 0);
206 } elsif ($arg =~ /^\s*$gre\s*$/) {
207 ($p, $q) = ($1, 0);
208 }
209
210 if (defined $p) {
211 $p =~ s/^\+//;
212 $q =~ s/^\+//;
213 $p =~ s/^(-?)inf$/"${1}9**9**9"/e;
214 $q =~ s/^(-?)inf$/"${1}9**9**9"/e;
215 }
216
217 return ($p, $q);
91cb744f 218}
219
66730be0 220#
221# ->make
222#
223# Create a new complex number (cartesian form)
224#
225sub make {
bf5f1b4c 226 my $self = bless {}, shift;
227 my ($re, $im);
228 if (@_ == 0) {
229 ($re, $im) = (0, 0);
230 } elsif (@_ == 1) {
231 return (ref $self)->emake($_[0])
232 if ($_[0] =~ /^\s*\[/);
233 ($re, $im) = _make($_[0]);
234 } elsif (@_ == 2) {
235 ($re, $im) = @_;
236 }
237 if (defined $re) {
91cb744f 238 _cannot_make("real part", $re) unless $re =~ /^$gre$/;
bf5f1b4c 239 }
240 $im ||= 0;
241 _cannot_make("imaginary part", $im) unless $im =~ /^$gre$/;
affad850 242 $self->_set_cartesian([$re, $im ]);
bf5f1b4c 243 $self->display_format('cartesian');
244
245 return $self;
66730be0 246}
247
248#
249# ->emake
250#
251# Create a new complex number (exponential form)
252#
253sub emake {
bf5f1b4c 254 my $self = bless {}, shift;
255 my ($rho, $theta);
256 if (@_ == 0) {
257 ($rho, $theta) = (0, 0);
258 } elsif (@_ == 1) {
259 return (ref $self)->make($_[0])
260 if ($_[0] =~ /^\s*\(/ || $_[0] =~ /i\s*$/);
261 ($rho, $theta) = _emake($_[0]);
262 } elsif (@_ == 2) {
263 ($rho, $theta) = @_;
264 }
265 if (defined $rho && defined $theta) {
fb73857a 266 if ($rho < 0) {
267 $rho = -$rho;
268 $theta = ($theta <= 0) ? $theta + pi() : $theta - pi();
269 }
bf5f1b4c 270 }
271 if (defined $rho) {
91cb744f 272 _cannot_make("rho", $rho) unless $rho =~ /^$gre$/;
bf5f1b4c 273 }
274 $theta ||= 0;
275 _cannot_make("theta", $theta) unless $theta =~ /^$gre$/;
affad850 276 $self->_set_polar([$rho, $theta]);
bf5f1b4c 277 $self->display_format('polar');
278
279 return $self;
66730be0 280}
281
282sub new { &make } # For backward compatibility only.
283
284#
285# cplx
286#
287# Creates a complex number from a (re, im) tuple.
288# This avoids the burden of writing Math::Complex->make(re, im).
289#
290sub cplx {
91cb744f 291 return __PACKAGE__->make(@_);
66730be0 292}
293
294#
295# cplxe
296#
297# Creates a complex number from a (rho, theta) tuple.
298# This avoids the burden of writing Math::Complex->emake(rho, theta).
299#
300sub cplxe {
91cb744f 301 return __PACKAGE__->emake(@_);
66730be0 302}
303
304#
305# pi
306#
fb73857a 307# The number defined as pi = 180 degrees
66730be0 308#
6570f784 309sub pi () { 4 * CORE::atan2(1, 1) }
5cd24f17 310
311#
affad850 312# pi2
5cd24f17 313#
fb73857a 314# The full circle
315#
affad850 316sub pi2 () { 2 * pi }
317
318#
319# pi4
320#
321# The full circle twice.
322#
323sub pi4 () { 4 * pi }
fb73857a 324
5cd24f17 325#
fb73857a 326# pip2
327#
328# The quarter circle
329#
6570f784 330sub pip2 () { pi / 2 }
5cd24f17 331
fb73857a 332#
affad850 333# pip4
d09ae4e6 334#
affad850 335# The eighth circle.
d09ae4e6 336#
affad850 337sub pip4 () { pi / 4 }
d09ae4e6 338
339#
affad850 340# _uplog10
fb73857a 341#
342# Used in log10().
343#
affad850 344sub _uplog10 () { 1 / CORE::log(10) }
66730be0 345
346#
347# i
348#
349# The number defined as i*i = -1;
350#
351sub i () {
5cd24f17 352 return $i if ($i);
353 $i = bless {};
40da2db3 354 $i->{'cartesian'} = [0, 1];
fb73857a 355 $i->{'polar'} = [1, pip2];
66730be0 356 $i->{c_dirty} = 0;
357 $i->{p_dirty} = 0;
358 return $i;
359}
360
361#
affad850 362# _ip2
1fa12f56 363#
364# Half of i.
365#
affad850 366sub _ip2 () { i / 2 }
1fa12f56 367
368#
66730be0 369# Attribute access/set routines
370#
371
affad850 372sub _cartesian {$_[0]->{c_dirty} ?
373 $_[0]->_update_cartesian : $_[0]->{'cartesian'}}
374sub _polar {$_[0]->{p_dirty} ?
375 $_[0]->_update_polar : $_[0]->{'polar'}}
66730be0 376
affad850 377sub _set_cartesian { $_[0]->{p_dirty}++; $_[0]->{c_dirty} = 0;
378 $_[0]->{'cartesian'} = $_[1] }
379sub _set_polar { $_[0]->{c_dirty}++; $_[0]->{p_dirty} = 0;
380 $_[0]->{'polar'} = $_[1] }
66730be0 381
382#
affad850 383# ->_update_cartesian
66730be0 384#
385# Recompute and return the cartesian form, given accurate polar form.
386#
affad850 387sub _update_cartesian {
66730be0 388 my $self = shift;
40da2db3 389 my ($r, $t) = @{$self->{'polar'}};
66730be0 390 $self->{c_dirty} = 0;
a8693bd3 391 return $self->{'cartesian'} = [$r * CORE::cos($t), $r * CORE::sin($t)];
66730be0 392}
393
394#
395#
affad850 396# ->_update_polar
66730be0 397#
398# Recompute and return the polar form, given accurate cartesian form.
399#
affad850 400sub _update_polar {
66730be0 401 my $self = shift;
40da2db3 402 my ($x, $y) = @{$self->{'cartesian'}};
66730be0 403 $self->{p_dirty} = 0;
40da2db3 404 return $self->{'polar'} = [0, 0] if $x == 0 && $y == 0;
1fa12f56 405 return $self->{'polar'} = [CORE::sqrt($x*$x + $y*$y),
406 CORE::atan2($y, $x)];
66730be0 407}
408
409#
affad850 410# (_plus)
66730be0 411#
412# Computes z1+z2.
413#
affad850 414sub _plus {
66730be0 415 my ($z1, $z2, $regular) = @_;
affad850 416 my ($re1, $im1) = @{$z1->_cartesian};
0e505df1 417 $z2 = cplx($z2) unless ref $z2;
affad850 418 my ($re2, $im2) = ref $z2 ? @{$z2->_cartesian} : ($z2, 0);
66730be0 419 unless (defined $regular) {
affad850 420 $z1->_set_cartesian([$re1 + $re2, $im1 + $im2]);
66730be0 421 return $z1;
422 }
423 return (ref $z1)->make($re1 + $re2, $im1 + $im2);
424}
425
426#
affad850 427# (_minus)
66730be0 428#
429# Computes z1-z2.
430#
affad850 431sub _minus {
66730be0 432 my ($z1, $z2, $inverted) = @_;
affad850 433 my ($re1, $im1) = @{$z1->_cartesian};
0e505df1 434 $z2 = cplx($z2) unless ref $z2;
affad850 435 my ($re2, $im2) = @{$z2->_cartesian};
66730be0 436 unless (defined $inverted) {
affad850 437 $z1->_set_cartesian([$re1 - $re2, $im1 - $im2]);
66730be0 438 return $z1;
439 }
440 return $inverted ?
441 (ref $z1)->make($re2 - $re1, $im2 - $im1) :
442 (ref $z1)->make($re1 - $re2, $im1 - $im2);
0e505df1 443
66730be0 444}
445
446#
affad850 447# (_multiply)
66730be0 448#
449# Computes z1*z2.
450#
affad850 451sub _multiply {
fb73857a 452 my ($z1, $z2, $regular) = @_;
453 if ($z1->{p_dirty} == 0 and ref $z2 and $z2->{p_dirty} == 0) {
454 # if both polar better use polar to avoid rounding errors
affad850 455 my ($r1, $t1) = @{$z1->_polar};
456 my ($r2, $t2) = @{$z2->_polar};
fb73857a 457 my $t = $t1 + $t2;
affad850 458 if ($t > pi()) { $t -= pi2 }
459 elsif ($t <= -pi()) { $t += pi2 }
fb73857a 460 unless (defined $regular) {
affad850 461 $z1->_set_polar([$r1 * $r2, $t]);
66730be0 462 return $z1;
fb73857a 463 }
464 return (ref $z1)->emake($r1 * $r2, $t);
465 } else {
affad850 466 my ($x1, $y1) = @{$z1->_cartesian};
fb73857a 467 if (ref $z2) {
affad850 468 my ($x2, $y2) = @{$z2->_cartesian};
fb73857a 469 return (ref $z1)->make($x1*$x2-$y1*$y2, $x1*$y2+$y1*$x2);
470 } else {
471 return (ref $z1)->make($x1*$z2, $y1*$z2);
472 }
66730be0 473 }
66730be0 474}
475
476#
0e505df1 477# _divbyzero
0c721ce2 478#
479# Die on division by zero.
480#
0e505df1 481sub _divbyzero {
5cd24f17 482 my $mess = "$_[0]: Division by zero.\n";
483
484 if (defined $_[1]) {
485 $mess .= "(Because in the definition of $_[0], the divisor ";
1fa12f56 486 $mess .= "$_[1] " unless ("$_[1]" eq '0');
5cd24f17 487 $mess .= "is 0)\n";
488 }
489
0c721ce2 490 my @up = caller(1);
fb73857a 491
5cd24f17 492 $mess .= "Died at $up[1] line $up[2].\n";
493
494 die $mess;
0c721ce2 495}
496
497#
affad850 498# (_divide)
66730be0 499#
500# Computes z1/z2.
501#
affad850 502sub _divide {
66730be0 503 my ($z1, $z2, $inverted) = @_;
fb73857a 504 if ($z1->{p_dirty} == 0 and ref $z2 and $z2->{p_dirty} == 0) {
505 # if both polar better use polar to avoid rounding errors
affad850 506 my ($r1, $t1) = @{$z1->_polar};
507 my ($r2, $t2) = @{$z2->_polar};
fb73857a 508 my $t;
509 if ($inverted) {
0e505df1 510 _divbyzero "$z2/0" if ($r1 == 0);
fb73857a 511 $t = $t2 - $t1;
affad850 512 if ($t > pi()) { $t -= pi2 }
513 elsif ($t <= -pi()) { $t += pi2 }
fb73857a 514 return (ref $z1)->emake($r2 / $r1, $t);
515 } else {
0e505df1 516 _divbyzero "$z1/0" if ($r2 == 0);
fb73857a 517 $t = $t1 - $t2;
affad850 518 if ($t > pi()) { $t -= pi2 }
519 elsif ($t <= -pi()) { $t += pi2 }
fb73857a 520 return (ref $z1)->emake($r1 / $r2, $t);
521 }
522 } else {
523 my ($d, $x2, $y2);
524 if ($inverted) {
affad850 525 ($x2, $y2) = @{$z1->_cartesian};
fb73857a 526 $d = $x2*$x2 + $y2*$y2;
527 _divbyzero "$z2/0" if $d == 0;
528 return (ref $z1)->make(($x2*$z2)/$d, -($y2*$z2)/$d);
529 } else {
affad850 530 my ($x1, $y1) = @{$z1->_cartesian};
fb73857a 531 if (ref $z2) {
affad850 532 ($x2, $y2) = @{$z2->_cartesian};
fb73857a 533 $d = $x2*$x2 + $y2*$y2;
534 _divbyzero "$z1/0" if $d == 0;
535 my $u = ($x1*$x2 + $y1*$y2)/$d;
536 my $v = ($y1*$x2 - $x1*$y2)/$d;
537 return (ref $z1)->make($u, $v);
538 } else {
539 _divbyzero "$z1/0" if $z2 == 0;
540 return (ref $z1)->make($x1/$z2, $y1/$z2);
541 }
542 }
0c721ce2 543 }
66730be0 544}
545
546#
affad850 547# (_power)
66730be0 548#
549# Computes z1**z2 = exp(z2 * log z1)).
550#
affad850 551sub _power {
66730be0 552 my ($z1, $z2, $inverted) = @_;
ace5de91 553 if ($inverted) {
2820d885 554 return 1 if $z1 == 0 || $z2 == 1;
555 return 0 if $z2 == 0 && Re($z1) > 0;
ace5de91 556 } else {
2820d885 557 return 1 if $z2 == 0 || $z1 == 1;
558 return 0 if $z1 == 0 && Re($z2) > 0;
ace5de91 559 }
1fa12f56 560 my $w = $inverted ? &exp($z1 * &log($z2))
561 : &exp($z2 * &log($z1));
d09ae4e6 562 # If both arguments cartesian, return cartesian, else polar.
563 return $z1->{c_dirty} == 0 &&
564 (not ref $z2 or $z2->{c_dirty} == 0) ?
affad850 565 cplx(@{$w->_cartesian}) : $w;
66730be0 566}
567
568#
affad850 569# (_spaceship)
66730be0 570#
571# Computes z1 <=> z2.
2820d885 572# Sorts on the real part first, then on the imaginary part. Thus 2-4i < 3+8i.
66730be0 573#
affad850 574sub _spaceship {
66730be0 575 my ($z1, $z2, $inverted) = @_;
affad850 576 my ($re1, $im1) = ref $z1 ? @{$z1->_cartesian} : ($z1, 0);
577 my ($re2, $im2) = ref $z2 ? @{$z2->_cartesian} : ($z2, 0);
66730be0 578 my $sgn = $inverted ? -1 : 1;
579 return $sgn * ($re1 <=> $re2) if $re1 != $re2;
580 return $sgn * ($im1 <=> $im2);
581}
582
583#
affad850 584# (_numeq)
1fa12f56 585#
586# Computes z1 == z2.
587#
affad850 588# (Required in addition to _spaceship() because of NaNs.)
589sub _numeq {
1fa12f56 590 my ($z1, $z2, $inverted) = @_;
affad850 591 my ($re1, $im1) = ref $z1 ? @{$z1->_cartesian} : ($z1, 0);
592 my ($re2, $im2) = ref $z2 ? @{$z2->_cartesian} : ($z2, 0);
1fa12f56 593 return $re1 == $re2 && $im1 == $im2 ? 1 : 0;
594}
595
596#
affad850 597# (_negate)
66730be0 598#
599# Computes -z.
600#
affad850 601sub _negate {
66730be0 602 my ($z) = @_;
603 if ($z->{c_dirty}) {
affad850 604 my ($r, $t) = @{$z->_polar};
fb73857a 605 $t = ($t <= 0) ? $t + pi : $t - pi;
606 return (ref $z)->emake($r, $t);
66730be0 607 }
affad850 608 my ($re, $im) = @{$z->_cartesian};
66730be0 609 return (ref $z)->make(-$re, -$im);
610}
611
612#
affad850 613# (_conjugate)
66730be0 614#
affad850 615# Compute complex's _conjugate.
66730be0 616#
affad850 617sub _conjugate {
66730be0 618 my ($z) = @_;
619 if ($z->{c_dirty}) {
affad850 620 my ($r, $t) = @{$z->_polar};
66730be0 621 return (ref $z)->emake($r, -$t);
622 }
affad850 623 my ($re, $im) = @{$z->_cartesian};
66730be0 624 return (ref $z)->make($re, -$im);
625}
626
627#
628# (abs)
629#
b42d0ec9 630# Compute or set complex's norm (rho).
66730be0 631#
632sub abs {
e7deb4af 633 my ($z, $rho) = @_ ? @_ : $_;
1fa12f56 634 unless (ref $z) {
635 if (@_ == 2) {
636 $_[0] = $_[1];
637 } else {
638 return CORE::abs($z);
639 }
640 }
b42d0ec9 641 if (defined $rho) {
affad850 642 $z->{'polar'} = [ $rho, ${$z->_polar}[1] ];
b42d0ec9 643 $z->{p_dirty} = 0;
644 $z->{c_dirty} = 1;
645 return $rho;
646 } else {
affad850 647 return ${$z->_polar}[0];
b42d0ec9 648 }
649}
650
651sub _theta {
652 my $theta = $_[0];
653
affad850 654 if ($$theta > pi()) { $$theta -= pi2 }
655 elsif ($$theta <= -pi()) { $$theta += pi2 }
66730be0 656}
657
658#
659# arg
660#
b42d0ec9 661# Compute or set complex's argument (theta).
66730be0 662#
663sub arg {
b42d0ec9 664 my ($z, $theta) = @_;
665 return $z unless ref $z;
666 if (defined $theta) {
667 _theta(\$theta);
affad850 668 $z->{'polar'} = [ ${$z->_polar}[0], $theta ];
b42d0ec9 669 $z->{p_dirty} = 0;
670 $z->{c_dirty} = 1;
671 } else {
affad850 672 $theta = ${$z->_polar}[1];
b42d0ec9 673 _theta(\$theta);
674 }
675 return $theta;
66730be0 676}
677
678#
679# (sqrt)
680#
0c721ce2 681# Compute sqrt(z).
66730be0 682#
b42d0ec9 683# It is quite tempting to use wantarray here so that in list context
684# sqrt() would return the two solutions. This, however, would
685# break things like
686#
687# print "sqrt(z) = ", sqrt($z), "\n";
688#
689# The two values would be printed side by side without no intervening
690# whitespace, quite confusing.
691# Therefore if you want the two solutions use the root().
692#
66730be0 693sub sqrt {
e7deb4af 694 my ($z) = @_ ? $_[0] : $_;
affad850 695 my ($re, $im) = ref $z ? @{$z->_cartesian} : ($z, 0);
1fa12f56 696 return $re < 0 ? cplx(0, CORE::sqrt(-$re)) : CORE::sqrt($re)
697 if $im == 0;
affad850 698 my ($r, $t) = @{$z->_polar};
a8693bd3 699 return (ref $z)->emake(CORE::sqrt($r), $t/2);
66730be0 700}
701
702#
703# cbrt
704#
0c721ce2 705# Compute cbrt(z) (cubic root).
66730be0 706#
b42d0ec9 707# Why are we not returning three values? The same answer as for sqrt().
708#
66730be0 709sub cbrt {
710 my ($z) = @_;
1fa12f56 711 return $z < 0 ?
712 -CORE::exp(CORE::log(-$z)/3) :
713 ($z > 0 ? CORE::exp(CORE::log($z)/3): 0)
fb73857a 714 unless ref $z;
affad850 715 my ($r, $t) = @{$z->_polar};
1fa12f56 716 return 0 if $r == 0;
a8693bd3 717 return (ref $z)->emake(CORE::exp(CORE::log($r)/3), $t/3);
66730be0 718}
719
720#
0e505df1 721# _rootbad
722#
723# Die on bad root.
724#
725sub _rootbad {
bf5f1b4c 726 my $mess = "Root '$_[0]' illegal, root rank must be positive integer.\n";
0e505df1 727
728 my @up = caller(1);
fb73857a 729
0e505df1 730 $mess .= "Died at $up[1] line $up[2].\n";
731
732 die $mess;
733}
734
735#
66730be0 736# root
737#
738# Computes all nth root for z, returning an array whose size is n.
739# `n' must be a positive integer.
740#
741# The roots are given by (for k = 0..n-1):
742#
743# z^(1/n) = r^(1/n) (cos ((t+2 k pi)/n) + i sin ((t+2 k pi)/n))
744#
745sub root {
bf5f1b4c 746 my ($z, $n, $k) = @_;
0e505df1 747 _rootbad($n) if ($n < 1 or int($n) != $n);
1fa12f56 748 my ($r, $t) = ref $z ?
affad850 749 @{$z->_polar} : (CORE::abs($z), $z >= 0 ? 0 : pi);
750 my $theta_inc = pi2 / $n;
66730be0 751 my $rho = $r ** (1/$n);
d09ae4e6 752 my $cartesian = ref $z && $z->{c_dirty} == 0;
bf5f1b4c 753 if (@_ == 2) {
754 my @root;
755 for (my $i = 0, my $theta = $t / $n;
756 $i < $n;
757 $i++, $theta += $theta_inc) {
758 my $w = cplxe($rho, $theta);
759 # Yes, $cartesian is loop invariant.
affad850 760 push @root, $cartesian ? cplx(@{$w->_cartesian}) : $w;
bf5f1b4c 761 }
762 return @root;
763 } elsif (@_ == 3) {
764 my $w = cplxe($rho, $t / $n + $k * $theta_inc);
affad850 765 return $cartesian ? cplx(@{$w->_cartesian}) : $w;
a0d0e21e 766 }
a0d0e21e 767}
768
66730be0 769#
770# Re
771#
b42d0ec9 772# Return or set Re(z).
66730be0 773#
a0d0e21e 774sub Re {
b42d0ec9 775 my ($z, $Re) = @_;
66730be0 776 return $z unless ref $z;
b42d0ec9 777 if (defined $Re) {
affad850 778 $z->{'cartesian'} = [ $Re, ${$z->_cartesian}[1] ];
b42d0ec9 779 $z->{c_dirty} = 0;
780 $z->{p_dirty} = 1;
781 } else {
affad850 782 return ${$z->_cartesian}[0];
b42d0ec9 783 }
a0d0e21e 784}
785
66730be0 786#
787# Im
788#
b42d0ec9 789# Return or set Im(z).
66730be0 790#
a0d0e21e 791sub Im {
b42d0ec9 792 my ($z, $Im) = @_;
178326e7 793 return 0 unless ref $z;
b42d0ec9 794 if (defined $Im) {
affad850 795 $z->{'cartesian'} = [ ${$z->_cartesian}[0], $Im ];
b42d0ec9 796 $z->{c_dirty} = 0;
797 $z->{p_dirty} = 1;
798 } else {
affad850 799 return ${$z->_cartesian}[1];
b42d0ec9 800 }
801}
802
803#
804# rho
805#
806# Return or set rho(w).
807#
808sub rho {
809 Math::Complex::abs(@_);
810}
811
812#
813# theta
814#
815# Return or set theta(w).
816#
817sub theta {
818 Math::Complex::arg(@_);
a0d0e21e 819}
820
66730be0 821#
822# (exp)
823#
824# Computes exp(z).
825#
826sub exp {
e7deb4af 827 my ($z) = @_ ? @_ : $_;
828 return CORE::exp($z) unless ref $z;
829 my ($x, $y) = @{$z->_cartesian};
830 return (ref $z)->emake(CORE::exp($x), $y);
66730be0 831}
832
833#
8c03c583 834# _logofzero
835#
fb73857a 836# Die on logarithm of zero.
8c03c583 837#
838sub _logofzero {
839 my $mess = "$_[0]: Logarithm of zero.\n";
840
841 if (defined $_[1]) {
842 $mess .= "(Because in the definition of $_[0], the argument ";
843 $mess .= "$_[1] " unless ($_[1] eq '0');
844 $mess .= "is 0)\n";
845 }
846
847 my @up = caller(1);
fb73857a 848
8c03c583 849 $mess .= "Died at $up[1] line $up[2].\n";
850
851 die $mess;
852}
853
854#
66730be0 855# (log)
856#
857# Compute log(z).
858#
859sub log {
e7deb4af 860 my ($z) = @_ ? @_ : $_;
fb73857a 861 unless (ref $z) {
862 _logofzero("log") if $z == 0;
a8693bd3 863 return $z > 0 ? CORE::log($z) : cplx(CORE::log(-$z), pi);
fb73857a 864 }
affad850 865 my ($r, $t) = @{$z->_polar};
fb73857a 866 _logofzero("log") if $r == 0;
affad850 867 if ($t > pi()) { $t -= pi2 }
868 elsif ($t <= -pi()) { $t += pi2 }
a8693bd3 869 return (ref $z)->make(CORE::log($r), $t);
66730be0 870}
871
872#
0c721ce2 873# ln
874#
875# Alias for log().
876#
877sub ln { Math::Complex::log(@_) }
878
879#
66730be0 880# log10
881#
882# Compute log10(z).
883#
5cd24f17 884
66730be0 885sub log10 {
affad850 886 return Math::Complex::log($_[0]) * _uplog10;
66730be0 887}
888
889#
890# logn
891#
892# Compute logn(z,n) = log(z) / log(n)
893#
894sub logn {
895 my ($z, $n) = @_;
0c721ce2 896 $z = cplx($z, 0) unless ref $z;
9fbe1b12 897 my $logn = $LOGN{$n};
898 $logn = $LOGN{$n} = CORE::log($n) unless defined $logn; # Cache log(n)
1fa12f56 899 return &log($z) / $logn;
66730be0 900}
901
902#
903# (cos)
904#
905# Compute cos(z) = (exp(iz) + exp(-iz))/2.
906#
907sub cos {
e7deb4af 908 my ($z) = @_ ? @_ : $_;
1fa12f56 909 return CORE::cos($z) unless ref $z;
affad850 910 my ($x, $y) = @{$z->_cartesian};
a8693bd3 911 my $ey = CORE::exp($y);
1fa12f56 912 my $sx = CORE::sin($x);
913 my $cx = CORE::cos($x);
1515bec6 914 my $ey_1 = $ey ? 1 / $ey : Inf();
1fa12f56 915 return (ref $z)->make($cx * ($ey + $ey_1)/2,
916 $sx * ($ey_1 - $ey)/2);
66730be0 917}
918
919#
920# (sin)
921#
922# Compute sin(z) = (exp(iz) - exp(-iz))/2.
923#
924sub sin {
e7deb4af 925 my ($z) = @_ ? @_ : $_;
1fa12f56 926 return CORE::sin($z) unless ref $z;
affad850 927 my ($x, $y) = @{$z->_cartesian};
a8693bd3 928 my $ey = CORE::exp($y);
1fa12f56 929 my $sx = CORE::sin($x);
930 my $cx = CORE::cos($x);
1515bec6 931 my $ey_1 = $ey ? 1 / $ey : Inf();
1fa12f56 932 return (ref $z)->make($sx * ($ey + $ey_1)/2,
933 $cx * ($ey - $ey_1)/2);
66730be0 934}
935
936#
937# tan
938#
939# Compute tan(z) = sin(z) / cos(z).
940#
941sub tan {
942 my ($z) = @_;
1fa12f56 943 my $cz = &cos($z);
944 _divbyzero "tan($z)", "cos($z)" if $cz == 0;
945 return &sin($z) / $cz;
66730be0 946}
947
948#
0c721ce2 949# sec
950#
951# Computes the secant sec(z) = 1 / cos(z).
952#
953sub sec {
954 my ($z) = @_;
1fa12f56 955 my $cz = &cos($z);
0e505df1 956 _divbyzero "sec($z)", "cos($z)" if ($cz == 0);
0c721ce2 957 return 1 / $cz;
958}
959
960#
961# csc
962#
963# Computes the cosecant csc(z) = 1 / sin(z).
964#
965sub csc {
966 my ($z) = @_;
1fa12f56 967 my $sz = &sin($z);
0e505df1 968 _divbyzero "csc($z)", "sin($z)" if ($sz == 0);
0c721ce2 969 return 1 / $sz;
970}
971
66730be0 972#
0c721ce2 973# cosec
66730be0 974#
0c721ce2 975# Alias for csc().
976#
977sub cosec { Math::Complex::csc(@_) }
978
979#
980# cot
981#
fb73857a 982# Computes cot(z) = cos(z) / sin(z).
0c721ce2 983#
984sub cot {
66730be0 985 my ($z) = @_;
1fa12f56 986 my $sz = &sin($z);
0e505df1 987 _divbyzero "cot($z)", "sin($z)" if ($sz == 0);
1fa12f56 988 return &cos($z) / $sz;
66730be0 989}
990
991#
0c721ce2 992# cotan
993#
994# Alias for cot().
995#
996sub cotan { Math::Complex::cot(@_) }
997
998#
66730be0 999# acos
1000#
1001# Computes the arc cosine acos(z) = -i log(z + sqrt(z*z-1)).
1002#
1003sub acos {
fb73857a 1004 my $z = $_[0];
1fa12f56 1005 return CORE::atan2(CORE::sqrt(1-$z*$z), $z)
1006 if (! ref $z) && CORE::abs($z) <= 1;
40b904b7 1007 $z = cplx($z, 0) unless ref $z;
affad850 1008 my ($x, $y) = @{$z->_cartesian};
1fa12f56 1009 return 0 if $x == 1 && $y == 0;
a8693bd3 1010 my $t1 = CORE::sqrt(($x+1)*($x+1) + $y*$y);
1011 my $t2 = CORE::sqrt(($x-1)*($x-1) + $y*$y);
fb73857a 1012 my $alpha = ($t1 + $t2)/2;
1013 my $beta = ($t1 - $t2)/2;
1014 $alpha = 1 if $alpha < 1;
1015 if ($beta > 1) { $beta = 1 }
1016 elsif ($beta < -1) { $beta = -1 }
a8693bd3 1017 my $u = CORE::atan2(CORE::sqrt(1-$beta*$beta), $beta);
1018 my $v = CORE::log($alpha + CORE::sqrt($alpha*$alpha-1));
fb73857a 1019 $v = -$v if $y > 0 || ($y == 0 && $x < -1);
40b904b7 1020 return (ref $z)->make($u, $v);
66730be0 1021}
1022
1023#
1024# asin
1025#
1026# Computes the arc sine asin(z) = -i log(iz + sqrt(1-z*z)).
1027#
1028sub asin {
fb73857a 1029 my $z = $_[0];
1fa12f56 1030 return CORE::atan2($z, CORE::sqrt(1-$z*$z))
1031 if (! ref $z) && CORE::abs($z) <= 1;
40b904b7 1032 $z = cplx($z, 0) unless ref $z;
affad850 1033 my ($x, $y) = @{$z->_cartesian};
1fa12f56 1034 return 0 if $x == 0 && $y == 0;
a8693bd3 1035 my $t1 = CORE::sqrt(($x+1)*($x+1) + $y*$y);
1036 my $t2 = CORE::sqrt(($x-1)*($x-1) + $y*$y);
fb73857a 1037 my $alpha = ($t1 + $t2)/2;
1038 my $beta = ($t1 - $t2)/2;
1039 $alpha = 1 if $alpha < 1;
1040 if ($beta > 1) { $beta = 1 }
1041 elsif ($beta < -1) { $beta = -1 }
a8693bd3 1042 my $u = CORE::atan2($beta, CORE::sqrt(1-$beta*$beta));
1043 my $v = -CORE::log($alpha + CORE::sqrt($alpha*$alpha-1));
fb73857a 1044 $v = -$v if $y > 0 || ($y == 0 && $x < -1);
40b904b7 1045 return (ref $z)->make($u, $v);
66730be0 1046}
1047
1048#
1049# atan
1050#
0c721ce2 1051# Computes the arc tangent atan(z) = i/2 log((i+z) / (i-z)).
66730be0 1052#
1053sub atan {
1054 my ($z) = @_;
a8693bd3 1055 return CORE::atan2($z, 1) unless ref $z;
affad850 1056 my ($x, $y) = ref $z ? @{$z->_cartesian} : ($z, 0);
1fa12f56 1057 return 0 if $x == 0 && $y == 0;
8c03c583 1058 _divbyzero "atan(i)" if ( $z == i);
1fa12f56 1059 _logofzero "atan(-i)" if (-$z == i); # -i is a bad file test...
1060 my $log = &log((i + $z) / (i - $z));
affad850 1061 return _ip2 * $log;
a0d0e21e 1062}
1063
66730be0 1064#
0c721ce2 1065# asec
1066#
1067# Computes the arc secant asec(z) = acos(1 / z).
1068#
1069sub asec {
1070 my ($z) = @_;
0e505df1 1071 _divbyzero "asec($z)", $z if ($z == 0);
fb73857a 1072 return acos(1 / $z);
0c721ce2 1073}
1074
1075#
5cd24f17 1076# acsc
0c721ce2 1077#
8c03c583 1078# Computes the arc cosecant acsc(z) = asin(1 / z).
0c721ce2 1079#
5cd24f17 1080sub acsc {
0c721ce2 1081 my ($z) = @_;
0e505df1 1082 _divbyzero "acsc($z)", $z if ($z == 0);
fb73857a 1083 return asin(1 / $z);
0c721ce2 1084}
1085
1086#
5cd24f17 1087# acosec
66730be0 1088#
5cd24f17 1089# Alias for acsc().
0c721ce2 1090#
5cd24f17 1091sub acosec { Math::Complex::acsc(@_) }
0c721ce2 1092
66730be0 1093#
0c721ce2 1094# acot
1095#
8c03c583 1096# Computes the arc cotangent acot(z) = atan(1 / z)
0c721ce2 1097#
1098sub acot {
66730be0 1099 my ($z) = @_;
1fa12f56 1100 _divbyzero "acot(0)" if $z == 0;
1101 return ($z >= 0) ? CORE::atan2(1, $z) : CORE::atan2(-1, -$z)
1102 unless ref $z;
1103 _divbyzero "acot(i)" if ($z - i == 0);
1104 _logofzero "acot(-i)" if ($z + i == 0);
8c03c583 1105 return atan(1 / $z);
66730be0 1106}
1107
1108#
0c721ce2 1109# acotan
1110#
1111# Alias for acot().
1112#
1113sub acotan { Math::Complex::acot(@_) }
1114
1115#
66730be0 1116# cosh
1117#
1118# Computes the hyperbolic cosine cosh(z) = (exp(z) + exp(-z))/2.
1119#
1120sub cosh {
1121 my ($z) = @_;
fb73857a 1122 my $ex;
0e505df1 1123 unless (ref $z) {
a8693bd3 1124 $ex = CORE::exp($z);
f1e71051 1125 return $ex ? ($ex == $ExpInf ? Inf() : ($ex + 1/$ex)/2) : Inf();
0e505df1 1126 }
affad850 1127 my ($x, $y) = @{$z->_cartesian};
a8693bd3 1128 $ex = CORE::exp($x);
1515bec6 1129 my $ex_1 = $ex ? 1 / $ex : Inf();
a8693bd3 1130 return (ref $z)->make(CORE::cos($y) * ($ex + $ex_1)/2,
1131 CORE::sin($y) * ($ex - $ex_1)/2);
66730be0 1132}
1133
1134#
1135# sinh
1136#
1137# Computes the hyperbolic sine sinh(z) = (exp(z) - exp(-z))/2.
1138#
1139sub sinh {
1140 my ($z) = @_;
fb73857a 1141 my $ex;
0e505df1 1142 unless (ref $z) {
1fa12f56 1143 return 0 if $z == 0;
a8693bd3 1144 $ex = CORE::exp($z);
f1e71051 1145 return $ex ? ($ex == $ExpInf ? Inf() : ($ex - 1/$ex)/2) : -Inf();
0e505df1 1146 }
affad850 1147 my ($x, $y) = @{$z->_cartesian};
1fa12f56 1148 my $cy = CORE::cos($y);
1149 my $sy = CORE::sin($y);
a8693bd3 1150 $ex = CORE::exp($x);
1515bec6 1151 my $ex_1 = $ex ? 1 / $ex : Inf();
5240e574 1152 return (ref $z)->make(CORE::cos($y) * ($ex - $ex_1)/2,
1153 CORE::sin($y) * ($ex + $ex_1)/2);
66730be0 1154}
1155
1156#
1157# tanh
1158#
1159# Computes the hyperbolic tangent tanh(z) = sinh(z) / cosh(z).
1160#
1161sub tanh {
1162 my ($z) = @_;
0c721ce2 1163 my $cz = cosh($z);
0e505df1 1164 _divbyzero "tanh($z)", "cosh($z)" if ($cz == 0);
1515bec6 1165 my $sz = sinh($z);
1166 return 1 if $cz == $sz;
1167 return -1 if $cz == -$sz;
1168 return $sz / $cz;
66730be0 1169}
1170
1171#
0c721ce2 1172# sech
1173#
1174# Computes the hyperbolic secant sech(z) = 1 / cosh(z).
1175#
1176sub sech {
1177 my ($z) = @_;
1178 my $cz = cosh($z);
0e505df1 1179 _divbyzero "sech($z)", "cosh($z)" if ($cz == 0);
0c721ce2 1180 return 1 / $cz;
1181}
1182
1183#
1184# csch
1185#
1186# Computes the hyperbolic cosecant csch(z) = 1 / sinh(z).
66730be0 1187#
0c721ce2 1188sub csch {
1189 my ($z) = @_;
1190 my $sz = sinh($z);
0e505df1 1191 _divbyzero "csch($z)", "sinh($z)" if ($sz == 0);
0c721ce2 1192 return 1 / $sz;
1193}
1194
1195#
1196# cosech
1197#
1198# Alias for csch().
1199#
1200sub cosech { Math::Complex::csch(@_) }
1201
66730be0 1202#
0c721ce2 1203# coth
1204#
1205# Computes the hyperbolic cotangent coth(z) = cosh(z) / sinh(z).
1206#
1207sub coth {
66730be0 1208 my ($z) = @_;
0c721ce2 1209 my $sz = sinh($z);
1fa12f56 1210 _divbyzero "coth($z)", "sinh($z)" if $sz == 0;
1515bec6 1211 my $cz = cosh($z);
1212 return 1 if $cz == $sz;
1213 return -1 if $cz == -$sz;
1214 return $cz / $sz;
66730be0 1215}
1216
1217#
0c721ce2 1218# cotanh
1219#
1220# Alias for coth().
1221#
1222sub cotanh { Math::Complex::coth(@_) }
1223
1224#
66730be0 1225# acosh
1226#
f1e71051 1227# Computes the area/inverse hyperbolic cosine acosh(z) = log(z + sqrt(z*z-1)).
66730be0 1228#
1229sub acosh {
1230 my ($z) = @_;
fb73857a 1231 unless (ref $z) {
fb73857a 1232 $z = cplx($z, 0);
1233 }
affad850 1234 my ($re, $im) = @{$z->_cartesian};
fb73857a 1235 if ($im == 0) {
1fa12f56 1236 return CORE::log($re + CORE::sqrt($re*$re - 1))
1237 if $re >= 1;
1238 return cplx(0, CORE::atan2(CORE::sqrt(1 - $re*$re), $re))
1239 if CORE::abs($re) < 1;
fb73857a 1240 }
9bc5fa8d 1241 my $t = &sqrt($z * $z - 1) + $z;
40b904b7 1242 # Try Taylor if looking bad (this usually means that
1243 # $z was large negative, therefore the sqrt is really
1244 # close to abs(z), summing that with z...)
9bc5fa8d 1245 $t = 1/(2 * $z) - 1/(8 * $z**3) + 1/(16 * $z**5) - 5/(128 * $z**7)
1246 if $t == 0;
1247 my $u = &log($t);
40b904b7 1248 $u->Im(-$u->Im) if $re < 0 && $im == 0;
9bc5fa8d 1249 return $re < 0 ? -$u : $u;
66730be0 1250}
1251
1252#
1253# asinh
1254#
f1e71051 1255# Computes the area/inverse hyperbolic sine asinh(z) = log(z + sqrt(z*z+1))
66730be0 1256#
1257sub asinh {
1258 my ($z) = @_;
1fa12f56 1259 unless (ref $z) {
1260 my $t = $z + CORE::sqrt($z*$z + 1);
1261 return CORE::log($t) if $t;
1262 }
9bc5fa8d 1263 my $t = &sqrt($z * $z + 1) + $z;
40b904b7 1264 # Try Taylor if looking bad (this usually means that
1265 # $z was large negative, therefore the sqrt is really
1266 # close to abs(z), summing that with z...)
9bc5fa8d 1267 $t = 1/(2 * $z) - 1/(8 * $z**3) + 1/(16 * $z**5) - 5/(128 * $z**7)
1268 if $t == 0;
1fa12f56 1269 return &log($t);
66730be0 1270}
1271
1272#
1273# atanh
1274#
f1e71051 1275# Computes the area/inverse hyperbolic tangent atanh(z) = 1/2 log((1+z) / (1-z)).
66730be0 1276#
1277sub atanh {
1278 my ($z) = @_;
fb73857a 1279 unless (ref $z) {
a8693bd3 1280 return CORE::log((1 + $z)/(1 - $z))/2 if CORE::abs($z) < 1;
fb73857a 1281 $z = cplx($z, 0);
1282 }
1fa12f56 1283 _divbyzero 'atanh(1)', "1 - $z" if (1 - $z == 0);
1284 _logofzero 'atanh(-1)' if (1 + $z == 0);
1285 return 0.5 * &log((1 + $z) / (1 - $z));
66730be0 1286}
1287
1288#
0c721ce2 1289# asech
1290#
f1e71051 1291# Computes the area/inverse hyperbolic secant asech(z) = acosh(1 / z).
0c721ce2 1292#
1293sub asech {
1294 my ($z) = @_;
1fa12f56 1295 _divbyzero 'asech(0)', "$z" if ($z == 0);
0c721ce2 1296 return acosh(1 / $z);
1297}
1298
1299#
1300# acsch
66730be0 1301#
f1e71051 1302# Computes the area/inverse hyperbolic cosecant acsch(z) = asinh(1 / z).
66730be0 1303#
0c721ce2 1304sub acsch {
66730be0 1305 my ($z) = @_;
0e505df1 1306 _divbyzero 'acsch(0)', $z if ($z == 0);
0c721ce2 1307 return asinh(1 / $z);
1308}
1309
1310#
1311# acosech
1312#
1313# Alias for acosh().
1314#
1315sub acosech { Math::Complex::acsch(@_) }
1316
1317#
1318# acoth
1319#
f1e71051 1320# Computes the area/inverse hyperbolic cotangent acoth(z) = 1/2 log((1+z) / (z-1)).
0c721ce2 1321#
1322sub acoth {
1323 my ($z) = @_;
1fa12f56 1324 _divbyzero 'acoth(0)' if ($z == 0);
fb73857a 1325 unless (ref $z) {
a8693bd3 1326 return CORE::log(($z + 1)/($z - 1))/2 if CORE::abs($z) > 1;
fb73857a 1327 $z = cplx($z, 0);
1328 }
1fa12f56 1329 _divbyzero 'acoth(1)', "$z - 1" if ($z - 1 == 0);
1330 _logofzero 'acoth(-1)', "1 + $z" if (1 + $z == 0);
1331 return &log((1 + $z) / ($z - 1)) / 2;
66730be0 1332}
1333
1334#
0c721ce2 1335# acotanh
1336#
1337# Alias for acot().
1338#
1339sub acotanh { Math::Complex::acoth(@_) }
1340
1341#
66730be0 1342# (atan2)
1343#
bf5f1b4c 1344# Compute atan(z1/z2), minding the right quadrant.
66730be0 1345#
1346sub atan2 {
1347 my ($z1, $z2, $inverted) = @_;
fb73857a 1348 my ($re1, $im1, $re2, $im2);
1349 if ($inverted) {
affad850 1350 ($re1, $im1) = ref $z2 ? @{$z2->_cartesian} : ($z2, 0);
1351 ($re2, $im2) = ref $z1 ? @{$z1->_cartesian} : ($z1, 0);
66730be0 1352 } else {
affad850 1353 ($re1, $im1) = ref $z1 ? @{$z1->_cartesian} : ($z1, 0);
1354 ($re2, $im2) = ref $z2 ? @{$z2->_cartesian} : ($z2, 0);
fb73857a 1355 }
bf5f1b4c 1356 if ($im1 || $im2) {
1357 # In MATLAB the imaginary parts are ignored.
1358 # warn "atan2: Imaginary parts ignored";
1359 # http://documents.wolfram.com/mathematica/functions/ArcTan
1360 # NOTE: Mathematica ArcTan[x,y] while atan2(y,x)
1361 my $s = $z1 * $z1 + $z2 * $z2;
1362 _divbyzero("atan2") if $s == 0;
1363 my $i = &i;
1364 my $r = $z2 + $z1 * $i;
1365 return -$i * &log($r / &sqrt( $s ));
66730be0 1366 }
bf5f1b4c 1367 return CORE::atan2($re1, $re2);
66730be0 1368}
1369
1370#
1371# display_format
1372# ->display_format
1373#
16357284 1374# Set (get if no argument) the display format for all complex numbers that
fb73857a 1375# don't happen to have overridden it via ->display_format
66730be0 1376#
16357284 1377# When called as an object method, this actually sets the display format for
66730be0 1378# the current object.
1379#
1380# Valid object formats are 'c' and 'p' for cartesian and polar. The first
1381# letter is used actually, so the type can be fully spelled out for clarity.
1382#
1383sub display_format {
16357284 1384 my $self = shift;
1385 my %display_format = %DISPLAY_FORMAT;
66730be0 1386
16357284 1387 if (ref $self) { # Called as an object method
1388 if (exists $self->{display_format}) {
1389 my %obj = %{$self->{display_format}};
1390 @display_format{keys %obj} = values %obj;
1391 }
476757f7 1392 }
1393 if (@_ == 1) {
1394 $display_format{style} = shift;
1395 } else {
1396 my %new = @_;
1397 @display_format{keys %new} = values %new;
66730be0 1398 }
1399
476757f7 1400 if (ref $self) { # Called as an object method
16357284 1401 $self->{display_format} = { %display_format };
1402 return
1403 wantarray ?
1404 %{$self->{display_format}} :
1405 $self->{display_format}->{style};
66730be0 1406 }
1407
476757f7 1408 # Called as a class method
16357284 1409 %DISPLAY_FORMAT = %display_format;
1410 return
1411 wantarray ?
1412 %DISPLAY_FORMAT :
1413 $DISPLAY_FORMAT{style};
66730be0 1414}
1415
1416#
affad850 1417# (_stringify)
66730be0 1418#
1419# Show nicely formatted complex number under its cartesian or polar form,
1420# depending on the current display format:
1421#
1422# . If a specific display format has been recorded for this object, use it.
1423# . Otherwise, use the generic current default for all complex numbers,
1424# which is a package global variable.
1425#
affad850 1426sub _stringify {
66730be0 1427 my ($z) = shift;
66730be0 1428
16357284 1429 my $style = $z->display_format;
1430
1431 $style = $DISPLAY_FORMAT{style} unless defined $style;
66730be0 1432
affad850 1433 return $z->_stringify_polar if $style =~ /^p/i;
1434 return $z->_stringify_cartesian;
66730be0 1435}
1436
1437#
affad850 1438# ->_stringify_cartesian
66730be0 1439#
1440# Stringify as a cartesian representation 'a+bi'.
1441#
affad850 1442sub _stringify_cartesian {
66730be0 1443 my $z = shift;
affad850 1444 my ($x, $y) = @{$z->_cartesian};
66730be0 1445 my ($re, $im);
1446
16357284 1447 my %format = $z->display_format;
1448 my $format = $format{format};
1449
1fa12f56 1450 if ($x) {
1451 if ($x =~ /^NaN[QS]?$/i) {
1452 $re = $x;
1453 } else {
b57c8994 1454 if ($x =~ /^-?\Q$Inf\E$/oi) {
1fa12f56 1455 $re = $x;
1456 } else {
1457 $re = defined $format ? sprintf($format, $x) : $x;
1458 }
1459 }
1460 } else {
1461 undef $re;
1462 }
1463
1464 if ($y) {
40b904b7 1465 if ($y =~ /^(NaN[QS]?)$/i) {
1fa12f56 1466 $im = $y;
1467 } else {
b57c8994 1468 if ($y =~ /^-?\Q$Inf\E$/oi) {
1fa12f56 1469 $im = $y;
1470 } else {
40b904b7 1471 $im =
1472 defined $format ?
1473 sprintf($format, $y) :
1474 ($y == 1 ? "" : ($y == -1 ? "-" : $y));
1fa12f56 1475 }
1476 }
1477 $im .= "i";
1478 } else {
1479 undef $im;
16357284 1480 }
66730be0 1481
1fa12f56 1482 my $str = $re;
1483
16357284 1484 if (defined $im) {
1485 if ($y < 0) {
1486 $str .= $im;
1fa12f56 1487 } elsif ($y > 0 || $im =~ /^NaN[QS]?i$/i) {
16357284 1488 $str .= "+" if defined $re;
1489 $str .= $im;
1490 }
1fa12f56 1491 } elsif (!defined $re) {
1492 $str = "0";
16357284 1493 }
66730be0 1494
1495 return $str;
1496}
1497
d09ae4e6 1498
66730be0 1499#
affad850 1500# ->_stringify_polar
66730be0 1501#
1502# Stringify as a polar representation '[r,t]'.
1503#
affad850 1504sub _stringify_polar {
66730be0 1505 my $z = shift;
affad850 1506 my ($r, $t) = @{$z->_polar};
66730be0 1507 my $theta;
1508
16357284 1509 my %format = $z->display_format;
1fa12f56 1510 my $format = $format{format};
16357284 1511
b57c8994 1512 if ($t =~ /^NaN[QS]?$/i || $t =~ /^-?\Q$Inf\E$/oi) {
1fa12f56 1513 $theta = $t;
1514 } elsif ($t == pi) {
1515 $theta = "pi";
1516 } elsif ($r == 0 || $t == 0) {
1517 $theta = defined $format ? sprintf($format, $t) : $t;
55497cff 1518 }
66730be0 1519
1fa12f56 1520 return "[$r,$theta]" if defined $theta;
1521
66730be0 1522 #
1fa12f56 1523 # Try to identify pi/n and friends.
66730be0 1524 #
1525
affad850 1526 $t -= int(CORE::abs($t) / pi2) * pi2;
1fa12f56 1527
e97e26fa 1528 if ($format{polar_pretty_print} && $t) {
1fa12f56 1529 my ($a, $b);
9bc5fa8d 1530 for $a (2..9) {
1fa12f56 1531 $b = $t * $a / pi;
e97e26fa 1532 if ($b =~ /^-?\d+$/) {
1fa12f56 1533 $b = $b < 0 ? "-" : "" if CORE::abs($b) == 1;
1534 $theta = "${b}pi/$a";
d09ae4e6 1535 last;
66730be0 1536 }
d09ae4e6 1537 }
66730be0 1538 }
1539
16357284 1540 if (defined $format) {
1541 $r = sprintf($format, $r);
1fa12f56 1542 $theta = sprintf($format, $theta) unless defined $theta;
1543 } else {
1544 $theta = $t unless defined $theta;
16357284 1545 }
1546
1fa12f56 1547 return "[$r,$theta]";
a0d0e21e 1548}
a5f75d66 1549
1515bec6 1550sub Inf {
1551 return $Inf;
1552}
1553
a5f75d66 15541;
1555__END__
1556
1cf6bcb8 1557=pod
1558
a5f75d66 1559=head1 NAME
1560
66730be0 1561Math::Complex - complex numbers and associated mathematical functions
a5f75d66 1562
1563=head1 SYNOPSIS
1564
66730be0 1565 use Math::Complex;
fb73857a 1566
66730be0 1567 $z = Math::Complex->make(5, 6);
1568 $t = 4 - 3*i + $z;
1569 $j = cplxe(1, 2*pi/3);
a5f75d66 1570
1571=head1 DESCRIPTION
1572
66730be0 1573This package lets you create and manipulate complex numbers. By default,
1574I<Perl> limits itself to real numbers, but an extra C<use> statement brings
1575full complex support, along with a full set of mathematical functions
1576typically associated with and/or extended to complex numbers.
1577
1578If you wonder what complex numbers are, they were invented to be able to solve
1579the following equation:
1580
1581 x*x = -1
1582
1583and by definition, the solution is noted I<i> (engineers use I<j> instead since
1584I<i> usually denotes an intensity, but the name does not matter). The number
1585I<i> is a pure I<imaginary> number.
1586
1587The arithmetics with pure imaginary numbers works just like you would expect
1588it with real numbers... you just have to remember that
1589
1590 i*i = -1
1591
1592so you have:
1593
1594 5i + 7i = i * (5 + 7) = 12i
1595 4i - 3i = i * (4 - 3) = i
1596 4i * 2i = -8
1597 6i / 2i = 3
1598 1 / i = -i
1599
1600Complex numbers are numbers that have both a real part and an imaginary
1601part, and are usually noted:
1602
1603 a + bi
1604
1605where C<a> is the I<real> part and C<b> is the I<imaginary> part. The
1606arithmetic with complex numbers is straightforward. You have to
1607keep track of the real and the imaginary parts, but otherwise the
1608rules used for real numbers just apply:
1609
1610 (4 + 3i) + (5 - 2i) = (4 + 5) + i(3 - 2) = 9 + i
1611 (2 + i) * (4 - i) = 2*4 + 4i -2i -i*i = 8 + 2i + 1 = 9 + 2i
1612
1613A graphical representation of complex numbers is possible in a plane
1614(also called the I<complex plane>, but it's really a 2D plane).
1615The number
1616
1617 z = a + bi
1618
1619is the point whose coordinates are (a, b). Actually, it would
1620be the vector originating from (0, 0) to (a, b). It follows that the addition
1621of two complex numbers is a vectorial addition.
1622
1623Since there is a bijection between a point in the 2D plane and a complex
1624number (i.e. the mapping is unique and reciprocal), a complex number
1625can also be uniquely identified with polar coordinates:
1626
1627 [rho, theta]
1628
1629where C<rho> is the distance to the origin, and C<theta> the angle between
1630the vector and the I<x> axis. There is a notation for this using the
1631exponential form, which is:
1632
1633 rho * exp(i * theta)
1634
1635where I<i> is the famous imaginary number introduced above. Conversion
1636between this form and the cartesian form C<a + bi> is immediate:
1637
1638 a = rho * cos(theta)
1639 b = rho * sin(theta)
1640
1641which is also expressed by this formula:
1642
fb73857a 1643 z = rho * exp(i * theta) = rho * (cos theta + i * sin theta)
66730be0 1644
1645In other words, it's the projection of the vector onto the I<x> and I<y>
1646axes. Mathematicians call I<rho> the I<norm> or I<modulus> and I<theta>
affad850 1647the I<argument> of the complex number. The I<norm> of C<z> is
1648marked here as C<abs(z)>.
66730be0 1649
affad850 1650The polar notation (also known as the trigonometric representation) is
1651much more handy for performing multiplications and divisions of
1652complex numbers, whilst the cartesian notation is better suited for
1653additions and subtractions. Real numbers are on the I<x> axis, and
1654therefore I<y> or I<theta> is zero or I<pi>.
66730be0 1655
1656All the common operations that can be performed on a real number have
1657been defined to work on complex numbers as well, and are merely
1658I<extensions> of the operations defined on real numbers. This means
1659they keep their natural meaning when there is no imaginary part, provided
1660the number is within their definition set.
1661
1662For instance, the C<sqrt> routine which computes the square root of
fb73857a 1663its argument is only defined for non-negative real numbers and yields a
1664non-negative real number (it is an application from B<R+> to B<R+>).
66730be0 1665If we allow it to return a complex number, then it can be extended to
1666negative real numbers to become an application from B<R> to B<C> (the
1667set of complex numbers):
1668
1669 sqrt(x) = x >= 0 ? sqrt(x) : sqrt(-x)*i
1670
1671It can also be extended to be an application from B<C> to B<C>,
1672whilst its restriction to B<R> behaves as defined above by using
1673the following definition:
1674
1675 sqrt(z = [r,t]) = sqrt(r) * exp(i * t/2)
1676
fb73857a 1677Indeed, a negative real number can be noted C<[x,pi]> (the modulus
1678I<x> is always non-negative, so C<[x,pi]> is really C<-x>, a negative
1679number) and the above definition states that
66730be0 1680
1681 sqrt([x,pi]) = sqrt(x) * exp(i*pi/2) = [sqrt(x),pi/2] = sqrt(x)*i
1682
1683which is exactly what we had defined for negative real numbers above.
b42d0ec9 1684The C<sqrt> returns only one of the solutions: if you want the both,
1685use the C<root> function.
a5f75d66 1686
66730be0 1687All the common mathematical functions defined on real numbers that
1688are extended to complex numbers share that same property of working
1689I<as usual> when the imaginary part is zero (otherwise, it would not
1690be called an extension, would it?).
a5f75d66 1691
66730be0 1692A I<new> operation possible on a complex number that is
1693the identity for real numbers is called the I<conjugate>, and is noted
d1be9408 1694with a horizontal bar above the number, or C<~z> here.
a5f75d66 1695
66730be0 1696 z = a + bi
1697 ~z = a - bi
a5f75d66 1698
66730be0 1699Simple... Now look:
a5f75d66 1700
66730be0 1701 z * ~z = (a + bi) * (a - bi) = a*a + b*b
a5f75d66 1702
66730be0 1703We saw that the norm of C<z> was noted C<abs(z)> and was defined as the
1704distance to the origin, also known as:
a5f75d66 1705
66730be0 1706 rho = abs(z) = sqrt(a*a + b*b)
a5f75d66 1707
66730be0 1708so
1709
1710 z * ~z = abs(z) ** 2
1711
1712If z is a pure real number (i.e. C<b == 0>), then the above yields:
1713
1714 a * a = abs(a) ** 2
1715
1716which is true (C<abs> has the regular meaning for real number, i.e. stands
1717for the absolute value). This example explains why the norm of C<z> is
1718noted C<abs(z)>: it extends the C<abs> function to complex numbers, yet
1719is the regular C<abs> we know when the complex number actually has no
1720imaginary part... This justifies I<a posteriori> our use of the C<abs>
1721notation for the norm.
1722
1723=head1 OPERATIONS
1724
1725Given the following notations:
1726
1727 z1 = a + bi = r1 * exp(i * t1)
1728 z2 = c + di = r2 * exp(i * t2)
1729 z = <any complex or real number>
1730
1731the following (overloaded) operations are supported on complex numbers:
1732
1733 z1 + z2 = (a + c) + i(b + d)
1734 z1 - z2 = (a - c) + i(b - d)
1735 z1 * z2 = (r1 * r2) * exp(i * (t1 + t2))
1736 z1 / z2 = (r1 / r2) * exp(i * (t1 - t2))
1737 z1 ** z2 = exp(z2 * log z1)
b42d0ec9 1738 ~z = a - bi
1739 abs(z) = r1 = sqrt(a*a + b*b)
1740 sqrt(z) = sqrt(r1) * exp(i * t/2)
1741 exp(z) = exp(a) * exp(i * b)
1742 log(z) = log(r1) + i*t
1743 sin(z) = 1/2i (exp(i * z1) - exp(-i * z))
1744 cos(z) = 1/2 (exp(i * z1) + exp(-i * z))
bf5f1b4c 1745 atan2(y, x) = atan(y / x) # Minding the right quadrant, note the order.
1746
1747The definition used for complex arguments of atan2() is
1748
1749 -i log((x + iy)/sqrt(x*x+y*y))
66730be0 1750
affad850 1751Note that atan2(0, 0) is not well-defined.
1752
66730be0 1753The following extra operations are supported on both real and complex
1754numbers:
1755
1756 Re(z) = a
1757 Im(z) = b
1758 arg(z) = t
b42d0ec9 1759 abs(z) = r
66730be0 1760
1761 cbrt(z) = z ** (1/3)
1762 log10(z) = log(z) / log(10)
1763 logn(z, n) = log(z) / log(n)
1764
1765 tan(z) = sin(z) / cos(z)
0c721ce2 1766
5aabfad6 1767 csc(z) = 1 / sin(z)
1768 sec(z) = 1 / cos(z)
0c721ce2 1769 cot(z) = 1 / tan(z)
66730be0 1770
1771 asin(z) = -i * log(i*z + sqrt(1-z*z))
fb73857a 1772 acos(z) = -i * log(z + i*sqrt(1-z*z))
66730be0 1773 atan(z) = i/2 * log((i+z) / (i-z))
0c721ce2 1774
5aabfad6 1775 acsc(z) = asin(1 / z)
1776 asec(z) = acos(1 / z)
8c03c583 1777 acot(z) = atan(1 / z) = -i/2 * log((i+z) / (z-i))
66730be0 1778
1779 sinh(z) = 1/2 (exp(z) - exp(-z))
1780 cosh(z) = 1/2 (exp(z) + exp(-z))
0c721ce2 1781 tanh(z) = sinh(z) / cosh(z) = (exp(z) - exp(-z)) / (exp(z) + exp(-z))
1782
5aabfad6 1783 csch(z) = 1 / sinh(z)
1784 sech(z) = 1 / cosh(z)
0c721ce2 1785 coth(z) = 1 / tanh(z)
fb73857a 1786
66730be0 1787 asinh(z) = log(z + sqrt(z*z+1))
1788 acosh(z) = log(z + sqrt(z*z-1))
1789 atanh(z) = 1/2 * log((1+z) / (1-z))
66730be0 1790
5aabfad6 1791 acsch(z) = asinh(1 / z)
1792 asech(z) = acosh(1 / z)
0c721ce2 1793 acoth(z) = atanh(1 / z) = 1/2 * log((1+z) / (z-1))
1794
b42d0ec9 1795I<arg>, I<abs>, I<log>, I<csc>, I<cot>, I<acsc>, I<acot>, I<csch>,
1796I<coth>, I<acosech>, I<acotanh>, have aliases I<rho>, I<theta>, I<ln>,
1797I<cosec>, I<cotan>, I<acosec>, I<acotan>, I<cosech>, I<cotanh>,
1798I<acosech>, I<acotanh>, respectively. C<Re>, C<Im>, C<arg>, C<abs>,
d1be9408 1799C<rho>, and C<theta> can be used also as mutators. The C<cbrt>
b42d0ec9 1800returns only one of the solutions: if you want all three, use the
1801C<root> function.
0c721ce2 1802
1803The I<root> function is available to compute all the I<n>
66730be0 1804roots of some complex, where I<n> is a strictly positive integer.
1805There are exactly I<n> such roots, returned as a list. Getting the
1806number mathematicians call C<j> such that:
1807
1808 1 + j + j*j = 0;
1809
1810is a simple matter of writing:
1811
1812 $j = ((root(1, 3))[1];
1813
1814The I<k>th root for C<z = [r,t]> is given by:
1815
1816 (root(z, n))[k] = r**(1/n) * exp(i * (t + 2*k*pi)/n)
1817
bf5f1b4c 1818You can return the I<k>th root directly by C<root(z, n, k)>,
1819indexing starting from I<zero> and ending at I<n - 1>.
1820
1515bec6 1821The I<spaceship> numeric comparison operator, E<lt>=E<gt>, is also
1822defined. In order to ensure its restriction to real numbers is conform
1823to what you would expect, the comparison is run on the real part of
1824the complex number first, and imaginary parts are compared only when
1825the real parts match.
66730be0 1826
1827=head1 CREATION
1828
1829To create a complex number, use either:
1830
1831 $z = Math::Complex->make(3, 4);
1832 $z = cplx(3, 4);
1833
1834if you know the cartesian form of the number, or
1835
1836 $z = 3 + 4*i;
1837
fb73857a 1838if you like. To create a number using the polar form, use either:
66730be0 1839
1840 $z = Math::Complex->emake(5, pi/3);
1841 $x = cplxe(5, pi/3);
1842
0c721ce2 1843instead. The first argument is the modulus, the second is the angle
fb73857a 1844(in radians, the full circle is 2*pi). (Mnemonic: C<e> is used as a
1845notation for complex numbers in the polar form).
66730be0 1846
1847It is possible to write:
1848
1849 $x = cplxe(-3, pi/4);
1850
16357284 1851but that will be silently converted into C<[3,-3pi/4]>, since the
1852modulus must be non-negative (it represents the distance to the origin
1853in the complex plane).
66730be0 1854
91cb744f 1855It is also possible to have a complex number as either argument of the
1856C<make>, C<emake>, C<cplx>, and C<cplxe>: the appropriate component of
b42d0ec9 1857the argument will be used.
1858
1859 $z1 = cplx(-2, 1);
1860 $z2 = cplx($z1, 4);
1861
91cb744f 1862The C<new>, C<make>, C<emake>, C<cplx>, and C<cplxe> will also
1863understand a single (string) argument of the forms
1864
1865 2-3i
1866 -3i
1867 [2,3]
bf5f1b4c 1868 [2,-3pi/4]
91cb744f 1869 [2]
1870
1871in which case the appropriate cartesian and exponential components
1872will be parsed from the string and used to create new complex numbers.
1873The imaginary component and the theta, respectively, will default to zero.
1874
bf5f1b4c 1875The C<new>, C<make>, C<emake>, C<cplx>, and C<cplxe> will also
1876understand the case of no arguments: this means plain zero or (0, 0).
1877
1878=head1 DISPLAYING
66730be0 1879
1880When printed, a complex number is usually shown under its cartesian
16357284 1881style I<a+bi>, but there are legitimate cases where the polar style
bf5f1b4c 1882I<[r,t]> is more appropriate. The process of converting the complex
1883number into a string that can be displayed is known as I<stringification>.
66730be0 1884
16357284 1885By calling the class method C<Math::Complex::display_format> and
1886supplying either C<"polar"> or C<"cartesian"> as an argument, you
5287f86b 1887override the default display style, which is C<"cartesian">. Not
16357284 1888supplying any argument returns the current settings.
66730be0 1889
1890This default can be overridden on a per-number basis by calling the
1891C<display_format> method instead. As before, not supplying any argument
5287f86b 1892returns the current display style for this number. Otherwise whatever you
1893specify will be the new display style for I<this> particular number.
66730be0 1894
1895For instance:
1896
1897 use Math::Complex;
1898
1899 Math::Complex::display_format('polar');
16357284 1900 $j = (root(1, 3))[1];
1901 print "j = $j\n"; # Prints "j = [1,2pi/3]"
66730be0 1902 $j->display_format('cartesian');
1903 print "j = $j\n"; # Prints "j = -0.5+0.866025403784439i"
1904
5287f86b 1905The polar style attempts to emphasize arguments like I<k*pi/n>
9bc5fa8d 1906(where I<n> is a positive integer and I<k> an integer within [-9, +9]),
5287f86b 1907this is called I<polar pretty-printing>.
66730be0 1908
bf5f1b4c 1909For the reverse of stringifying, see the C<make> and C<emake>.
1910
16357284 1911=head2 CHANGED IN PERL 5.6
1912
1913The C<display_format> class method and the corresponding
1914C<display_format> object method can now be called using
1915a parameter hash instead of just a one parameter.
1916
1917The old display format style, which can have values C<"cartesian"> or
40b904b7 1918C<"polar">, can be changed using the C<"style"> parameter.
1919
1920 $j->display_format(style => "polar");
1921
1922The one parameter calling convention also still works.
1923
1924 $j->display_format("polar");
16357284 1925
1926There are two new display parameters.
1927
40b904b7 1928The first one is C<"format">, which is a sprintf()-style format string
1929to be used for both numeric parts of the complex number(s). The is
1930somewhat system-dependent but most often it corresponds to C<"%.15g">.
1931You can revert to the default by setting the C<format> to C<undef>.
16357284 1932
1933 # the $j from the above example
1934
1935 $j->display_format('format' => '%.5f');
1936 print "j = $j\n"; # Prints "j = -0.50000+0.86603i"
40b904b7 1937 $j->display_format('format' => undef);
16357284 1938 print "j = $j\n"; # Prints "j = -0.5+0.86603i"
1939
1940Notice that this affects also the return values of the
1941C<display_format> methods: in list context the whole parameter hash
40b904b7 1942will be returned, as opposed to only the style parameter value.
1943This is a potential incompatibility with earlier versions if you
1944have been calling the C<display_format> method in list context.
16357284 1945
5287f86b 1946The second new display parameter is C<"polar_pretty_print">, which can
1947be set to true or false, the default being true. See the previous
1948section for what this means.
16357284 1949
66730be0 1950=head1 USAGE
1951
1952Thanks to overloading, the handling of arithmetics with complex numbers
1953is simple and almost transparent.
1954
1955Here are some examples:
1956
1957 use Math::Complex;
1958
1959 $j = cplxe(1, 2*pi/3); # $j ** 3 == 1
1960 print "j = $j, j**3 = ", $j ** 3, "\n";
1961 print "1 + j + j**2 = ", 1 + $j + $j**2, "\n";
1962
1963 $z = -16 + 0*i; # Force it to be a complex
1964 print "sqrt($z) = ", sqrt($z), "\n";
1965
1966 $k = exp(i * 2*pi/3);
1967 print "$j - $k = ", $j - $k, "\n";
a5f75d66 1968
b42d0ec9 1969 $z->Re(3); # Re, Im, arg, abs,
1970 $j->arg(2); # (the last two aka rho, theta)
1971 # can be used also as mutators.
1972
7637cd07 1973=head1 CONSTANTS
1974
affad850 1975=head2 PI
1976
1977The constant C<pi> and some handy multiples of it (pi2, pi4,
1978and pip2 (pi/2) and pip4 (pi/4)) are also available if separately
1979exported:
1980
1981 use Math::Complex ':pi';
1982 $third_of_circle = pi2 / 3;
1983
1515bec6 1984=head2 Inf
1985
1986The floating point infinity can be exported as a subroutine Inf():
1987
1988 use Math::Complex qw(Inf sinh);
1989 my $AlsoInf = Inf() + 42;
1990 my $AnotherInf = sinh(1e42);
1991 print "$AlsoInf is $AnotherInf\n" if $AlsoInf == $AnotherInf;
1992
1993Note that the stringified form of infinity varies between platforms:
1994it can be for example any of
1995
1996 inf
1997 infinity
1998 INF
1999 1.#INF
2000
2001or it can be something else.
2002
7637cd07 2003Also note that in some platforms trying to use the infinity in
2004arithmetic operations may result in Perl crashing because using
2005an infinity causes SIGFPE or its moral equivalent to be sent.
2006The way to ignore this is
2007
2008 local $SIG{FPE} = sub { };
2009
b42d0ec9 2010=head1 ERRORS DUE TO DIVISION BY ZERO OR LOGARITHM OF ZERO
5aabfad6 2011
2012The division (/) and the following functions
2013
b42d0ec9 2014 log ln log10 logn
2820d885 2015 tan sec csc cot
b42d0ec9 2016 atan asec acsc acot
2017 tanh sech csch coth
2018 atanh asech acsch acoth
5aabfad6 2019
2020cannot be computed for all arguments because that would mean dividing
8c03c583 2021by zero or taking logarithm of zero. These situations cause fatal
2022runtime errors looking like this
5aabfad6 2023
2024 cot(0): Division by zero.
5cd24f17 2025 (Because in the definition of cot(0), the divisor sin(0) is 0)
5aabfad6 2026 Died at ...
2027
8c03c583 2028or
2029
2030 atanh(-1): Logarithm of zero.
2031 Died at...
2032
2033For the C<csc>, C<cot>, C<asec>, C<acsc>, C<acot>, C<csch>, C<coth>,
d1be9408 2034C<asech>, C<acsch>, the argument cannot be C<0> (zero). For the
b42d0ec9 2035logarithmic functions and the C<atanh>, C<acoth>, the argument cannot
2036be C<1> (one). For the C<atanh>, C<acoth>, the argument cannot be
2037C<-1> (minus one). For the C<atan>, C<acot>, the argument cannot be
2038C<i> (the imaginary unit). For the C<atan>, C<acoth>, the argument
2039cannot be C<-i> (the negative imaginary unit). For the C<tan>,
2040C<sec>, C<tanh>, the argument cannot be I<pi/2 + k * pi>, where I<k>
bf5f1b4c 2041is any integer. atan2(0, 0) is undefined, and if the complex arguments
2042are used for atan2(), a division by zero will happen if z1**2+z2**2 == 0.
b42d0ec9 2043
2044Note that because we are operating on approximations of real numbers,
2045these errors can happen when merely `too close' to the singularities
40b904b7 2046listed above.
b42d0ec9 2047
2048=head1 ERRORS DUE TO INDIGESTIBLE ARGUMENTS
2049
2050The C<make> and C<emake> accept both real and complex arguments.
2051When they cannot recognize the arguments they will die with error
2052messages like the following
2053
2054 Math::Complex::make: Cannot take real part of ...
2055 Math::Complex::make: Cannot take real part of ...
2056 Math::Complex::emake: Cannot take rho of ...
2057 Math::Complex::emake: Cannot take theta of ...
5cd24f17 2058
a5f75d66 2059=head1 BUGS
2060
5cd24f17 2061Saying C<use Math::Complex;> exports many mathematical routines in the
bf5f1b4c 2062caller environment and even overrides some (C<sqrt>, C<log>, C<atan2>).
fb73857a 2063This is construed as a feature by the Authors, actually... ;-)
a5f75d66 2064
66730be0 2065All routines expect to be given real or complex numbers. Don't attempt to
2066use BigFloat, since Perl has currently no rule to disambiguate a '+'
2067operation (for instance) between two overloaded entities.
a5f75d66 2068
d09ae4e6 2069In Cray UNICOS there is some strange numerical instability that results
2070in root(), cos(), sin(), cosh(), sinh(), losing accuracy fast. Beware.
2071The bug may be in UNICOS math libs, in UNICOS C compiler, in Math::Complex.
2072Whatever it is, it does not manifest itself anywhere else where Perl runs.
2073
7637cd07 2074=head1 SEE ALSO
2075
2076L<Math::Trig>
2077
0c721ce2 2078=head1 AUTHORS
a5f75d66 2079
affad850 2080Daniel S. Lewart <F<lewart!at!uiuc.edu>>
2081Jarkko Hietaniemi <F<jhi!at!iki.fi>>
2082Raphael Manfredi <F<Raphael_Manfredi!at!pobox.com>>
fb73857a 2083
1515bec6 2084=head1 LICENSE
2085
2086This library is free software; you can redistribute it and/or modify
2087it under the same terms as Perl itself.
2088
5cd24f17 2089=cut
2090
b42d0ec9 20911;
2092
5cd24f17 2093# eof