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