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