[LON-CAPA-cvs] cvs: loncom /xml LCMathComplex.pm
raeburn
raeburn at source.lon-capa.org
Sun Nov 10 18:52:07 EST 2019
raeburn Sun Nov 10 23:52:07 2019 EDT
Modified files:
/loncom/xml LCMathComplex.pm
Log:
- Update to Math::Complex rev. 1.59_01 to eliminate warnings in perl > 5.26
"Undefined value assigned to typeglob" then modify (and rename as:
LONCAPA::LCMathComplex) to eliminate use of Config.pm and Scalar::Util.pm,
when run in perl Safe container).
-------------- next part --------------
Index: loncom/xml/LCMathComplex.pm
diff -u loncom/xml/LCMathComplex.pm:1.1 loncom/xml/LCMathComplex.pm:1.2
--- loncom/xml/LCMathComplex.pm:1.1 Tue Oct 29 21:01:21 2013
+++ loncom/xml/LCMathComplex.pm Sun Nov 10 23:52:07 2019
@@ -4,18 +4,40 @@
# -- Jarkko Hietaniemi Since Mar 1997
# -- Daniel S. Lewart Since Sep 1997
#
-# -- Stuart Raeburn: renamed package as LCMathComplex Oct 2013
+# -- Stuart Raeburn: renamed package (rev. 1.55) as LCMathComplex Oct 2013
+# renamed package (rev. 1.59_01) as LCMathComplex Nov 2019
# with minor changes to allow use in Safe Space
#
package LONCAPA::LCMathComplex;
-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $Inf $ExpInf);
+{ use 5.006; }
+use strict;
+
+our $VERSION = 1.59_01;
-$VERSION = 1.55;
+our ($Inf, $ExpInf);
+our ($vax_float, $has_inf, $has_nan);
BEGIN {
- my %DBL_MAX =
+ $vax_float = (pack("d",1) =~ /^[\x80\x10]\x40/);
+ $has_inf = !$vax_float;
+ $has_nan = !$vax_float;
+
+ unless ($has_inf) {
+ # For example in vax, there is no Inf,
+ # and just mentioning the DBL_MAX (1.70141183460469229e+38)
+ # causes SIGFPE.
+
+ # These are pretty useless without a real infinity,
+ # but setting them makes for less warnings about their
+ # undefined values.
+ $Inf = "Inf";
+ $ExpInf = "Inf";
+ return;
+ }
+
+ my %DBL_MAX = # These are IEEE 754 maxima.
(
4 => '1.70141183460469229e+38',
8 => '1.7976931348623157e+308',
@@ -25,8 +47,9 @@
12 => '1.1897314953572317650857593266280070162E+4932',
16 => '1.1897314953572317650857593266280070162E+4932',
);
+
my $nvsize = 8;
- die "LONCAPA::LCMathComplex: Could not figure out nvsize\n"
+ die "Math::Complex: Could not figure out nvsize\n"
unless defined $nvsize;
die "LONCAPA::LCMathComplex: Cannot not figure out max nv (nvsize = $nvsize)\n"
unless defined $DBL_MAX{$nvsize};
@@ -37,7 +60,7 @@
if ($^O eq 'unicosmk') {
$Inf = $DBL_MAX;
} else {
- local $SIG{FPE} = { };
+ local $SIG{FPE} = sub { };
local $!;
# We do want an arithmetic overflow, Inf INF inf Infinity.
for my $t (
@@ -56,16 +79,17 @@
$Inf = $i;
last;
}
- }
+ }
$Inf = $DBL_MAX unless defined $Inf; # Oh well, close enough.
die "LONCAPA::LCMathComplex: Could not get Infinity"
unless $Inf > $BIGGER_THAN_THIS;
- $ExpInf = exp(99999);
- }
+ $ExpInf = eval 'exp(99999)';
+ }
# print "# On this machine, Inf = '$Inf'\n";
}
-use strict;
+use warnings;
+no warnings 'syntax'; # To avoid the (_) warnings.
my $i;
my %LOGN;
@@ -76,7 +100,7 @@
require Exporter;
- at ISA = qw(Exporter);
+our @ISA = qw(Exporter);
my @trig = qw(
pi
@@ -90,7 +114,7 @@
acsch acosech asech acoth acotanh
);
- at EXPORT = (qw(
+our @EXPORT = (qw(
i Re Im rho theta arg
sqrt log ln
log10 logn cbrt root
@@ -101,18 +125,24 @@
my @pi = qw(pi pi2 pi4 pip2 pip4 Inf);
- at EXPORT_OK = @pi;
+our @EXPORT_OK = @pi;
-%EXPORT_TAGS = (
+our %EXPORT_TAGS = (
'trig' => [@trig],
'pi' => [@pi],
);
use overload
+ '=' => \&_copy,
+ '+=' => \&_plus,
'+' => \&_plus,
+ '-=' => \&_minus,
'-' => \&_minus,
+ '*=' => \&_multiply,
'*' => \&_multiply,
+ '/=' => \&_divide,
'/' => \&_divide,
+ '**=' => \&_power,
'**' => \&_power,
'==' => \&_numeq,
'<=>' => \&_spaceship,
@@ -124,7 +154,6 @@
'log' => \&log,
'sin' => \&sin,
'cos' => \&cos,
- 'tan' => \&tan,
'atan2' => \&atan2,
'""' => \&_stringify;
@@ -165,9 +194,9 @@
if (defined $p) {
$p =~ s/^\+//;
- $p =~ s/^(-?)inf$/"${1}9**9**9"/e;
+ $p =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
$q =~ s/^\+//;
- $q =~ s/^(-?)inf$/"${1}9**9**9"/e;
+ $q =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
}
return ($p, $q);
@@ -190,13 +219,26 @@
if (defined $p) {
$p =~ s/^\+//;
$q =~ s/^\+//;
- $p =~ s/^(-?)inf$/"${1}9**9**9"/e;
- $q =~ s/^(-?)inf$/"${1}9**9**9"/e;
+ $p =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
+ $q =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
}
return ($p, $q);
}
+sub _copy {
+ my $self = shift;
+ my $clone = {%$self};
+ if ($self->{'cartesian'}) {
+ $clone->{'cartesian'} = [@{$self->{'cartesian'}}];
+ }
+ if ($self->{'polar'}) {
+ $clone->{'polar'} = [@{$self->{'polar'}}];
+ }
+ bless $clone,__PACKAGE__;
+ return $clone;
+}
+
#
# ->make
#
@@ -610,7 +652,7 @@
# Compute or set complex's norm (rho).
#
sub abs {
- my ($z, $rho) = @_;
+ my ($z, $rho) = @_ ? @_ : $_;
unless (ref $z) {
if (@_ == 2) {
$_[0] = $_[1];
@@ -671,7 +713,7 @@
# Therefore if you want the two solutions use the root().
#
sub sqrt {
- my ($z) = @_;
+ my ($z) = @_ ? $_[0] : $_;
my ($re, $im) = ref $z ? @{$z->_cartesian} : ($z, 0);
return $re < 0 ? cplx(0, CORE::sqrt(-$re)) : CORE::sqrt($re)
if $im == 0;
@@ -804,9 +846,10 @@
# Computes exp(z).
#
sub exp {
- my ($z) = @_;
- my ($x, $y) = @{$z->_cartesian};
- return (ref $z)->emake(CORE::exp($x), $y);
+ my ($z) = @_ ? @_ : $_;
+ return CORE::exp($z) unless ref $z;
+ my ($x, $y) = @{$z->_cartesian};
+ return (ref $z)->emake(CORE::exp($x), $y);
}
#
@@ -836,7 +879,7 @@
# Compute log(z).
#
sub log {
- my ($z) = @_;
+ my ($z) = @_ ? @_ : $_;
unless (ref $z) {
_logofzero("log") if $z == 0;
return $z > 0 ? CORE::log($z) : cplx(CORE::log(-$z), pi);
@@ -884,7 +927,7 @@
# Compute cos(z) = (exp(iz) + exp(-iz))/2.
#
sub cos {
- my ($z) = @_;
+ my ($z) = @_ ? @_ : $_;
return CORE::cos($z) unless ref $z;
my ($x, $y) = @{$z->_cartesian};
my $ey = CORE::exp($y);
@@ -901,7 +944,7 @@
# Compute sin(z) = (exp(iz) - exp(-iz))/2.
#
sub sin {
- my ($z) = @_;
+ my ($z) = @_ ? @_ : $_;
return CORE::sin($z) unless ref $z;
my ($x, $y) = @{$z->_cartesian};
my $ey = CORE::exp($y);
@@ -1518,7 +1561,7 @@
if (defined $format) {
$r = sprintf($format, $r);
- $theta = sprintf($format, $theta) unless defined $theta;
+ $theta = sprintf($format, $t) unless defined $theta;
} else {
$theta = $t unless defined $theta;
}
@@ -1553,20 +1596,40 @@
Modified for use in Safe Space in LON-CAPA by removing the dependency on
Config.pm introduced in rev. 1.51 (which contains calls that are disallowed
-in Safe Space).
+in Safe Space). In addition, Scalar::Util::set_prototype() is not used for
+abs(), cos(), exp(), log(), sin(), and sqrt(), to avoid warnings in logs:
+of type: "Use of uninitialized value" (Config.pm line 62).
In this LON-CAPA-specific version, the following code changes were made.
15,16d17
< use Config;
-<
-29,31c30
+<
+49,51c50
< my $nvsize = $Config{nvsize} ||
< ($Config{uselongdouble} && $Config{longdblsize}) ||
< $Config{doublesize};
---
> my $nvsize = 8;
+91,92d89
+< use Scalar::Util qw(set_prototype);
+<
+96,109d92
+< BEGIN {
+< # For certain functions that we override, in 5.10 or better
+< # we can set a smarter prototype that will handle the lexical $_
+< # (also a 5.10+ feature).
+< if ($] >= 5.010000) {
+< set_prototype \&abs, '_';
+< set_prototype \&cos, '_';
+< set_prototype \&exp, '_';
+< set_prototype \&log, '_';
+< set_prototype \&sin, '_';
+< set_prototype \&sqrt, '_';
+< }
+< }
+
Note: the value assigned to $nvsize is 8 by default.
Whenever ./UPDATE is run to install or update LON-CAPA, the code which
@@ -2060,7 +2123,7 @@
LONCAPA::LCMathComplex::make: Cannot take real part of ...
LONCAPA::LCMathComplex::make: Cannot take real part of ...
- LONCAPA::LCMathComplex:emake: Cannot take rho of ...
+ LONCAPA::LCMathComplex::emake: Cannot take rho of ...
LONCAPA::LCMathComplex::emake: Cannot take theta of ...
=head1 BUGS
@@ -2084,9 +2147,10 @@
=head1 AUTHORS
-Daniel S. Lewart <F<lewart!at!uiuc.edu>>
-Jarkko Hietaniemi <F<jhi!at!iki.fi>>
-Raphael Manfredi <F<Raphael_Manfredi!at!pobox.com>>
+Daniel S. Lewart <F<lewart!at!uiuc.edu>>,
+Jarkko Hietaniemi <F<jhi!at!iki.fi>>,
+Raphael Manfredi <F<Raphael_Manfredi!at!pobox.com>>,
+Zefram <zefram at fysh.org>
=head1 LICENSE
More information about the LON-CAPA-cvs
mailing list