From: Rafael Garcia-Suarez Date: Wed, 16 Apr 2008 13:51:36 +0000 (+0000) Subject: Upgrade to Math::Complex 1.54 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=f1e71051a8c6a046755591d71e4c4185227d6042;p=p5sagit%2Fp5-mst-13.2.git Upgrade to Math::Complex 1.54 p4raw-id: //depot/perl@33698 --- diff --git a/lib/Math/Complex.pm b/lib/Math/Complex.pm index f424175..523b11c 100644 --- a/lib/Math/Complex.pm +++ b/lib/Math/Complex.pm @@ -7,9 +7,9 @@ package Math::Complex; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $Inf); +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $Inf $ExpInf); -$VERSION = 1.52; +$VERSION = 1.54; use Config; @@ -38,6 +38,7 @@ BEGIN { if ($^O eq 'unicosmk') { $Inf = $DBL_MAX; } else { + local $SIG{FPE} = { }; local $!; # We do want an arithmetic overflow, Inf INF inf Infinity. for my $t ( @@ -50,7 +51,6 @@ BEGIN { 'INFINITY', '1e99999', ) { - local $SIG{FPE} = { }; local $^W = 0; my $i = eval "$t+1.0"; if (defined $i && $i > $BIGGER_THAN_THIS) { @@ -61,6 +61,7 @@ BEGIN { $Inf = $DBL_MAX unless defined $Inf; # Oh well, close enough. die "Math::Complex: Could not get Infinity" unless $Inf > $BIGGER_THAN_THIS; + $ExpInf = exp(99999); } # print "# On this machine, Inf = '$Inf'\n"; } @@ -1101,7 +1102,7 @@ sub cosh { my $ex; unless (ref $z) { $ex = CORE::exp($z); - return $ex ? ($ex + 1/$ex)/2 : Inf(); + return $ex ? ($ex == $ExpInf ? Inf() : ($ex + 1/$ex)/2) : Inf(); } my ($x, $y) = @{$z->_cartesian}; $ex = CORE::exp($x); @@ -1121,7 +1122,7 @@ sub sinh { unless (ref $z) { return 0 if $z == 0; $ex = CORE::exp($z); - return $ex ? ($ex - 1/$ex)/2 : -Inf(); + return $ex ? ($ex == $ExpInf ? Inf() : ($ex - 1/$ex)/2) : -Inf(); } my ($x, $y) = @{$z->_cartesian}; my $cy = CORE::cos($y); @@ -1203,7 +1204,7 @@ sub cotanh { Math::Complex::coth(@_) } # # acosh # -# Computes the arc hyperbolic cosine acosh(z) = log(z + sqrt(z*z-1)). +# Computes the area/inverse hyperbolic cosine acosh(z) = log(z + sqrt(z*z-1)). # sub acosh { my ($z) = @_; @@ -1231,7 +1232,7 @@ sub acosh { # # asinh # -# Computes the arc hyperbolic sine asinh(z) = log(z + sqrt(z*z+1)) +# Computes the area/inverse hyperbolic sine asinh(z) = log(z + sqrt(z*z+1)) # sub asinh { my ($z) = @_; @@ -1251,7 +1252,7 @@ sub asinh { # # atanh # -# Computes the arc hyperbolic tangent atanh(z) = 1/2 log((1+z) / (1-z)). +# Computes the area/inverse hyperbolic tangent atanh(z) = 1/2 log((1+z) / (1-z)). # sub atanh { my ($z) = @_; @@ -1267,7 +1268,7 @@ sub atanh { # # asech # -# Computes the hyperbolic arc secant asech(z) = acosh(1 / z). +# Computes the area/inverse hyperbolic secant asech(z) = acosh(1 / z). # sub asech { my ($z) = @_; @@ -1278,7 +1279,7 @@ sub asech { # # acsch # -# Computes the hyperbolic arc cosecant acsch(z) = asinh(1 / z). +# Computes the area/inverse hyperbolic cosecant acsch(z) = asinh(1 / z). # sub acsch { my ($z) = @_; @@ -1296,7 +1297,7 @@ sub acosech { Math::Complex::acsch(@_) } # # acoth # -# Computes the arc hyperbolic cotangent acoth(z) = 1/2 log((1+z) / (z-1)). +# Computes the area/inverse hyperbolic cotangent acoth(z) = 1/2 log((1+z) / (z-1)). # sub acoth { my ($z) = @_; diff --git a/lib/Math/Complex.t b/lib/Math/Complex.t index 44f8f35..ee02341 100755 --- a/lib/Math/Complex.t +++ b/lib/Math/Complex.t @@ -13,7 +13,7 @@ BEGIN { } } -use Math::Complex 1.52; +use Math::Complex 1.54; use vars qw($VERSION); diff --git a/lib/Math/Trig.pm b/lib/Math/Trig.pm index 3197d6f..6d4d949 100644 --- a/lib/Math/Trig.pm +++ b/lib/Math/Trig.pm @@ -10,14 +10,14 @@ package Math::Trig; use 5.005; use strict; -use Math::Complex 1.51; +use Math::Complex 1.54; use Math::Complex qw(:trig :pi); use vars qw($VERSION $PACKAGE @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @ISA = qw(Exporter); -$VERSION = 1.16; +$VERSION = 1.18; my @angcnv = qw(rad2deg rad2grad deg2rad deg2grad @@ -181,7 +181,7 @@ sub great_circle_direction { return rad2rad($direction); } -*great_circle_bearing = \&great_circle_direction; +*great_circle_bearing = \&great_circle_direction; sub great_circle_waypoint { my ( $theta0, $phi0, $theta1, $phi1, $point ) = @_; @@ -208,7 +208,7 @@ sub great_circle_waypoint { my $theta = atan2($y, $x); my $phi = acos_real($z); - + return ($theta, $phi); } @@ -221,8 +221,9 @@ sub great_circle_destination { my $lat0 = pip2 - $phi0; - my $phi1 = asin_real(sin($lat0)*cos($dst) + + my $phi1 = asin_real(sin($lat0)*cos($dst) + cos($lat0)*sin($dst)*cos($dir0)); + my $theta1 = $theta0 + atan2(sin($dir0)*sin($dst)*cos($lat0), cos($dst)-sin($lat0)*sin($phi1)); @@ -308,12 +309,12 @@ and cotanh/coth are aliases) B, B, B, B, B -The arcus (also known as the inverse) functions of the hyperbolic +The area (also known as the inverse) functions of the hyperbolic sine, cosine, and tangent B, B, B -The arcus cofunctions of the hyperbolic sine, cosine, and tangent +The area cofunctions of the hyperbolic sine, cosine, and tangent (acsch/acosech and acoth/acotanh are aliases) B, B, B, B, B @@ -589,18 +590,22 @@ The result of great_circle_direction is in radians, zero indicating straight north, pi or -pi straight south, pi/2 straight west, and -pi/2 straight east. +=head2 great_circle_destination + You can inversely compute the destination if you know the starting point, direction, and distance: -=head2 great_circle_destination - use Math::Trig 'great_circle_destination'; - # thetad and phid are the destination coordinates, - # dird is the final direction at the destination. + # $diro is the original direction, + # for example from great_circle_bearing(). + # $distance is the angular distance in radians, + # for example from great_circle_distance(). + # $thetad and $phid are the destination coordinates, + # $dird is the final direction at the destination. ($thetad, $phid, $dird) = - great_circle_destination($theta, $phi, $direction, $distance); + great_circle_destination($theta, $phi, $diro, $distance); or the midpoint if you know the end points: @@ -668,7 +673,18 @@ The midpoint between London and Tokyo being my @M = great_circle_midpoint(@L, @T); -or about 68.93N 89.16E, in the frozen wastes of Siberia. +or about 69 N 89 E, in the frozen wastes of Siberia. + +B: you B get from A to B like this: + + Dist = great_circle_distance(A, B) + Dir = great_circle_direction(A, B) + C = great_circle_destination(A, Dist, Dir) + +and expect C to be B, because the bearing constantly changes when +going from A to B (except in some special case like the meridians or +the circles of latitudes) and in great_circle_destination() one gives +a constant bearing to follow. =head2 CAVEAT FOR GREAT CIRCLE FORMULAS diff --git a/lib/Math/Trig.t b/lib/Math/Trig.t index 618cdb7..91f5486 100755 --- a/lib/Math/Trig.t +++ b/lib/Math/Trig.t @@ -28,8 +28,8 @@ BEGIN { plan(tests => 153); -use Math::Trig 1.16; -use Math::Trig 1.16 qw(:pi Inf); +use Math::Trig 1.18; +use Math::Trig 1.18 qw(:pi Inf); my $pip2 = pi / 2; @@ -312,7 +312,7 @@ print "# Infinity\n"; my $BigDouble = 1e40; # E.g. netbsd-alpha core dumps on Inf arith without this. -local $SIG{FPE} = { }; +local $SIG{FPE} = sub { }; ok(Inf() > $BigDouble); # This passes in netbsd-alpha. ok(Inf() + $BigDouble > $BigDouble); # This coredumps in netbsd-alpha.