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