lib/Math/BigInt/t/bigintc.t + VMS + perl@16925
[p5sagit/p5-mst-13.2.git] / lib / Math / Complex.pm
index e5434f4..400366c 100644 (file)
@@ -7,15 +7,28 @@
 
 package Math::Complex;
 
-$VERSION = "1.30";
-
 our($VERSION, @ISA, @EXPORT, %EXPORT_TAGS, $Inf);
 
+$VERSION = 1.34;
+
 BEGIN {
-    my $e = $!;
-    $Inf = CORE::exp(CORE::exp(30)); # We do want an arithmetic overflow.
-    $! = $e; # Clear ERANGE.
-    undef $Inf unless $Inf =~ /^inf(?:inity)?$/i; # Inf INF inf Infinity
+    unless ($^O eq 'unicosmk') {
+        my $e = $!;
+       # We do want an arithmetic overflow, Inf INF inf Infinity:.
+        undef $Inf unless eval <<'EOE' and $Inf =~ /^inf(?:inity)?$/i;
+         local $SIG{FPE} = sub {die};
+         my $t = CORE::exp 30;
+         $Inf = CORE::exp $t;
+EOE
+       if (!defined $Inf) {            # Try a different method
+         undef $Inf unless eval <<'EOE' and $Inf =~ /^inf(?:inity)?$/i;
+           local $SIG{FPE} = sub {die};
+           my $t = 1;
+           $Inf = $t + "1e99999999999999999999999999999999";
+EOE
+       }
+        $! = $e; # Clear ERANGE.
+    }
     $Inf = "Inf" if !defined $Inf || !($Inf > 0); # Desperation.
 }
 
@@ -24,6 +37,9 @@ use strict;
 my $i;
 my %LOGN;
 
+# Regular expression for floating point numbers.
+my $gre = qr'\s*([\+\-]?(?:(?:(?:\d+(?:_\d+)*(?:\.\d*(?:_\d+)*)?|\.\d+(?:_\d+)*)(?:[eE][\+\-]?\d+(?:_\d+)*)?)))';
+
 require Exporter;
 
 @ISA = qw(Exporter);
@@ -95,6 +111,26 @@ sub _cannot_make {
     die "@{[(caller(1))[3]]}: Cannot take $_[0] of $_[1].\n";
 }
 
+sub _remake {
+    my $arg = shift;
+    my ($made, $p, $q);
+
+    if ($arg =~ /^(?:$gre)?$gre\s*i\s*$/) {
+       ($p, $q) = ($1 || 0, $2);
+       $made = 'cart';
+    } elsif ($arg =~ /^\s*\[\s*$gre\s*(?:,\s*$gre\s*)?\]\s*$/) {
+       ($p, $q) = ($1, $2 || 0);
+       $made = 'exp';
+    }
+
+    if ($made) {
+       $p =~ s/^\+//;
+       $q =~ s/^\+//;
+    }
+
+    return ($made, $p, $q);
+}
+
 #
 # ->make
 #
@@ -103,6 +139,16 @@ sub _cannot_make {
 sub make {
        my $self = bless {}, shift;
        my ($re, $im) = @_;
+       if (@_ == 1) {
+           my ($remade, $p, $q) = _remake($re);
+           if ($remade) {
+               if ($remade eq 'cart') {
+                   ($re, $im) = ($p, $q);
+               } else {
+                   return (ref $self)->emake($p, $q);
+               }
+           }
+       }
        my $rre = ref $re;
        if ( $rre ) {
            if ( $rre eq ref $self ) {
@@ -119,6 +165,9 @@ sub make {
                _cannot_make("imaginary part", $rim);
            }
        }
+       _cannot_make("real part",      $re) unless $re =~ /^$gre$/;
+       $im ||= 0;
+       _cannot_make("imaginary part", $im) unless $im =~ /^$gre$/;
        $self->{'cartesian'} = [ $re, $im ];
        $self->{c_dirty} = 0;
        $self->{p_dirty} = 1;
@@ -134,6 +183,16 @@ sub make {
 sub emake {
        my $self = bless {}, shift;
        my ($rho, $theta) = @_;
+       if (@_ == 1) {
+           my ($remade, $p, $q) = _remake($rho);
+           if ($remade) {
+               if ($remade eq 'exp') {
+                   ($rho, $theta) = ($p, $q);
+               } else {
+                   return (ref $self)->make($p, $q);
+               }
+           }
+       }
        my $rrh = ref $rho;
        if ( $rrh ) {
            if ( $rrh eq ref $self ) {
@@ -154,6 +213,9 @@ sub emake {
            $rho   = -$rho;
            $theta = ($theta <= 0) ? $theta + pi() : $theta - pi();
        }
+       _cannot_make("rho",   $rho)   unless $rho   =~ /^$gre$/;
+       $theta ||= 0;
+       _cannot_make("theta", $theta) unless $theta =~ /^$gre$/;
        $self->{'polar'} = [$rho, $theta];
        $self->{p_dirty} = 0;
        $self->{c_dirty} = 1;
@@ -170,8 +232,7 @@ sub new { &make }           # For backward compatibility only.
 # This avoids the burden of writing Math::Complex->make(re, im).
 #
 sub cplx {
-       my ($re, $im) = @_;
-       return __PACKAGE__->make($re, defined $im ? $im : 0);
+       return __PACKAGE__->make(@_);
 }
 
 #
@@ -181,8 +242,7 @@ sub cplx {
 # This avoids the burden of writing Math::Complex->emake(rho, theta).
 #
 sub cplxe {
-       my ($rho, $theta) = @_;
-       return __PACKAGE__->emake($rho, defined $theta ? $theta : 0);
+       return __PACKAGE__->emake(@_);
 }
 
 #
@@ -661,7 +721,7 @@ sub Re {
 #
 sub Im {
        my ($z, $Im) = @_;
-       return $z unless ref $z;
+       return 0 unless ref $z;
        if (defined $Im) {
            $z->{'cartesian'} = [ ${$z->cartesian}[0], $Im ];
            $z->{c_dirty} = 0;
@@ -1250,23 +1310,15 @@ sub display_format {
                my %obj = %{$self->{display_format}};
                @display_format{keys %obj} = values %obj;
            }
-           if (@_ == 1) {
-               $display_format{style} = shift;
-           } else {
-               my %new = @_;
-               @display_format{keys %new} = values %new;
-           }
-       } else {                                # Called as a class method
-           if (@_ = 1) {
-               $display_format{style} = $self;
-           } else {
-               my %new = @_;
-               @display_format{keys %new} = values %new;
-           }
-           undef $self;
+       }
+       if (@_ == 1) {
+           $display_format{style} = shift;
+       } else {
+           my %new = @_;
+           @display_format{keys %new} = values %new;
        }
 
-       if (defined $self) {
+       if (ref $self) { # Called as an object method
            $self->{display_format} = { %display_format };
            return
                wantarray ?
@@ -1274,6 +1326,7 @@ sub display_format {
                    $self->{display_format}->{style};
        }
 
+        # Called as a class method
        %DISPLAY_FORMAT = %display_format;
        return
            wantarray ?
@@ -1393,11 +1446,11 @@ sub stringify_polar {
 
        $t -= int(CORE::abs($t) / pit2) * pit2;
 
-       if ($format{polar_pretty_print}) {
+       if ($format{polar_pretty_print} && $t) {
            my ($a, $b);
            for $a (2..9) {
                $b = $t * $a / pi;
-               if (int($b) == $b) {
+               if ($b =~ /^-?\d+$/) {
                    $b = $b < 0 ? "-" : "" if CORE::abs($b) == 1;
                    $theta = "${b}pi/$a";
                    last;
@@ -1418,6 +1471,8 @@ sub stringify_polar {
 1;
 __END__
 
+=pod
+
 =head1 NAME
 
 Math::Complex - complex numbers and associated mathematical functions
@@ -1553,7 +1608,7 @@ be called an extension, would it?).
 
 A I<new> operation possible on a complex number that is
 the identity for real numbers is called the I<conjugate>, and is noted
-with an horizontal bar above the number, or C<~z> here.
+with a horizontal bar above the number, or C<~z> here.
 
         z = a + bi
        ~z = a - bi
@@ -1652,7 +1707,7 @@ I<arg>, I<abs>, I<log>, I<csc>, I<cot>, I<acsc>, I<acot>, I<csch>,
 I<coth>, I<acosech>, I<acotanh>, have aliases I<rho>, I<theta>, I<ln>,
 I<cosec>, I<cotan>, I<acosec>, I<acotan>, I<cosech>, I<cotanh>,
 I<acosech>, I<acotanh>, respectively.  C<Re>, C<Im>, C<arg>, C<abs>,
-C<rho>, and C<theta> can be used also also mutators.  The C<cbrt>
+C<rho>, and C<theta> can be used also as mutators.  The C<cbrt>
 returns only one of the solutions: if you want all three, use the
 C<root> function.
 
@@ -1705,13 +1760,25 @@ but that will be silently converted into C<[3,-3pi/4]>, since the
 modulus must be non-negative (it represents the distance to the origin
 in the complex plane).
 
-It is also possible to have a complex number as either argument of
-either the C<make> or C<emake>: the appropriate component of
+It is also possible to have a complex number as either argument of the
+C<make>, C<emake>, C<cplx>, and C<cplxe>: the appropriate component of
 the argument will be used.
 
        $z1 = cplx(-2,  1);
        $z2 = cplx($z1, 4);
 
+The C<new>, C<make>, C<emake>, C<cplx>, and C<cplxe> will also
+understand a single (string) argument of the forms
+
+       2-3i
+       -3i
+       [2,3]
+       [2]
+
+in which case the appropriate cartesian and exponential components
+will be parsed from the string and used to create new complex numbers.
+The imaginary component and the theta, respectively, will default to zero.
+
 =head1 STRINGIFICATION
 
 When printed, a complex number is usually shown under its cartesian
@@ -1828,7 +1895,7 @@ or
        Died at...
 
 For the C<csc>, C<cot>, C<asec>, C<acsc>, C<acot>, C<csch>, C<coth>,
-C<asech>, C<acsch>, the argument cannot be C<0> (zero).  For the the
+C<asech>, C<acsch>, the argument cannot be C<0> (zero).  For the
 logarithmic functions and the C<atanh>, C<acoth>, the argument cannot
 be C<1> (one).  For the C<atanh>, C<acoth>, the argument cannot be
 C<-1> (minus one).  For the C<atan>, C<acot>, the argument cannot be
@@ -1869,10 +1936,10 @@ Whatever it is, it does not manifest itself anywhere else where Perl runs.
 
 =head1 AUTHORS
 
-Raphael Manfredi <F<Raphael_Manfredi@pobox.com>> and
-Jarkko Hietaniemi <F<jhi@iki.fi>>.
+Daniel S. Lewart <F<d-lewart@uiuc.edu>>
 
-Extensive patches by Daniel S. Lewart <F<d-lewart@uiuc.edu>>.
+Original authors Raphael Manfredi <F<Raphael_Manfredi@pobox.com>> and
+Jarkko Hietaniemi <F<jhi@iki.fi>>
 
 =cut