From: Jarkko Hietaniemi Date: Fri, 5 May 2000 14:30:45 +0000 (+0000) Subject: Complex tweaks. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=40b904b7dc5e7264325426225ded40aa595efba1;p=p5sagit%2Fp5-mst-13.2.git Complex tweaks. p4raw-id: //depot/cfgperl@6073 --- diff --git a/lib/Math/Complex.pm b/lib/Math/Complex.pm index 82872b7..e5434f4 100644 --- a/lib/Math/Complex.pm +++ b/lib/Math/Complex.pm @@ -874,7 +874,8 @@ sub acos { my $z = $_[0]; return CORE::atan2(CORE::sqrt(1-$z*$z), $z) if (! ref $z) && CORE::abs($z) <= 1; - my ($x, $y) = ref $z ? @{$z->cartesian} : ($z, 0); + $z = cplx($z, 0) unless ref $z; + my ($x, $y) = @{$z->cartesian}; return 0 if $x == 1 && $y == 0; my $t1 = CORE::sqrt(($x+1)*($x+1) + $y*$y); my $t2 = CORE::sqrt(($x-1)*($x-1) + $y*$y); @@ -886,7 +887,7 @@ sub acos { my $u = CORE::atan2(CORE::sqrt(1-$beta*$beta), $beta); my $v = CORE::log($alpha + CORE::sqrt($alpha*$alpha-1)); $v = -$v if $y > 0 || ($y == 0 && $x < -1); - return __PACKAGE__->make($u, $v); + return (ref $z)->make($u, $v); } # @@ -898,7 +899,8 @@ sub asin { my $z = $_[0]; return CORE::atan2($z, CORE::sqrt(1-$z*$z)) if (! ref $z) && CORE::abs($z) <= 1; - my ($x, $y) = ref $z ? @{$z->cartesian} : ($z, 0); + $z = cplx($z, 0) unless ref $z; + my ($x, $y) = @{$z->cartesian}; return 0 if $x == 0 && $y == 0; my $t1 = CORE::sqrt(($x+1)*($x+1) + $y*$y); my $t2 = CORE::sqrt(($x-1)*($x-1) + $y*$y); @@ -910,7 +912,7 @@ sub asin { my $u = CORE::atan2($beta, CORE::sqrt(1-$beta*$beta)); my $v = -CORE::log($alpha + CORE::sqrt($alpha*$alpha-1)); $v = -$v if $y > 0 || ($y == 0 && $x < -1); - return __PACKAGE__->make($u, $v); + return (ref $z)->make($u, $v); } # @@ -1101,11 +1103,13 @@ sub acosh { if CORE::abs($re) < 1; } my $t = &sqrt($z * $z - 1) + $z; - # Try MacLaurin if looking bad. + # Try Taylor if looking bad (this usually means that + # $z was large negative, therefore the sqrt is really + # close to abs(z), summing that with z...) $t = 1/(2 * $z) - 1/(8 * $z**3) + 1/(16 * $z**5) - 5/(128 * $z**7) if $t == 0; my $u = &log($t); - $u->Im(-$u->Im) if $im == 0; + $u->Im(-$u->Im) if $re < 0 && $im == 0; return $re < 0 ? -$u : $u; } @@ -1121,7 +1125,9 @@ sub asinh { return CORE::log($t) if $t; } my $t = &sqrt($z * $z + 1) + $z; - # Try MacLaurin if looking bad. + # Try Taylor if looking bad (this usually means that + # $z was large negative, therefore the sqrt is really + # close to abs(z), summing that with z...) $t = 1/(2 * $z) - 1/(8 * $z**3) + 1/(16 * $z**5) - 5/(128 * $z**7) if $t == 0; return &log($t); @@ -1324,15 +1330,16 @@ sub stringify_cartesian { } if ($y) { - if ($y == 1) { $im = "" } - elsif ($y == -1) { $im = "-" } - elsif ($y =~ /^(NaN[QS]?)$/i) { + if ($y =~ /^(NaN[QS]?)$/i) { $im = $y; } else { if ($y =~ /^-?$Inf$/oi) { $im = $y; } else { - $im = defined $format ? sprintf($format, $y) : $y; + $im = + defined $format ? + sprintf($format, $y) : + ($y == 1 ? "" : ($y == -1 ? "-" : $y)); } } $im .= "i"; @@ -1742,29 +1749,33 @@ C object method can now be called using a parameter hash instead of just a one parameter. The old display format style, which can have values C<"cartesian"> or -C<"polar">, can be changed using the C<"style"> parameter. (The one -parameter calling convention also still works.) +C<"polar">, can be changed using the C<"style"> parameter. + + $j->display_format(style => "polar"); + +The one parameter calling convention also still works. + + $j->display_format("polar"); There are two new display parameters. -The first one is C<"format">, which is a sprintf()-style format -string to be used for both parts of the complex number(s). The -default is C, which corresponds usually (this is somewhat -system-dependent) to C<"%.15g">. You can revert to the default by -setting the format string to C. +The first one is C<"format">, which is a sprintf()-style format string +to be used for both numeric parts of the complex number(s). The is +somewhat system-dependent but most often it corresponds to C<"%.15g">. +You can revert to the default by setting the C to C. # the $j from the above example $j->display_format('format' => '%.5f'); print "j = $j\n"; # Prints "j = -0.50000+0.86603i" - $j->display_format('format' => '%.6f'); + $j->display_format('format' => undef); print "j = $j\n"; # Prints "j = -0.5+0.86603i" Notice that this affects also the return values of the C methods: in list context the whole parameter hash -will be returned, as opposed to only the style parameter value. If -you want to know the whole truth for a complex number, you must call -both the class method and the object method: +will be returned, as opposed to only the style parameter value. +This is a potential incompatibility with earlier versions if you +have been calling the C method in list context. The second new display parameter is C<"polar_pretty_print">, which can be set to true or false, the default being true. See the previous @@ -1828,8 +1839,7 @@ is any integer. Note that because we are operating on approximations of real numbers, these errors can happen when merely `too close' to the singularities -listed above. For example C will die of -division by zero. +listed above. =head1 ERRORS DUE TO INDIGESTIBLE ARGUMENTS