#!./perl
-# $RCSfile$
+# $RCSfile: complex.t,v $
#
# Regression tests for the Math::Complex pacakge
-# -- Raphael Manfredi, September 1996
-# -- Jarkko Hietaniemi, March-April 1997
+# -- Raphael Manfredi since Sep 1996
+# -- Jarkko Hietaniemi since Mar 1997
+# -- Daniel S. Lewart since Sep 1997
BEGIN {
chdir 't' if -d 't';
use Math::Complex;
+use vars qw($VERSION);
+
+$VERSION = 1.91;
+
+my ($args, $op, $target, $test, $test_set, $try, $val, $zvalue, @set, @val);
+
$test = 0;
$| = 1;
-@script = ();
-my $eps = 1e-11;
+my @script = (
+ 'my ($res, $s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10, $z0,$z1,$z2);' .
+ "\n\n"
+);
+my $eps = 1e-13;
+
+if ($^O eq 'unicos') { # For some reason root() produces very inaccurate
+ $eps = 1e-10; # results in Cray UNICOS, and occasionally also
+} # cos(), sin(), cosh(), sinh(). The division
+ # of doubles is the current suspect.
while (<DATA>) {
s/^\s+//;
}
}
+#
+
+sub test_mutators {
+ my $op;
+
+ $test++;
+push(@script, <<'EOT');
+{
+ my $z = cplx( 1, 1);
+ $z->Re(2);
+ $z->Im(3);
+ print "# $test Re(z) = ",$z->Re(), " Im(z) = ", $z->Im(), " z = $z\n";
+ print 'not ' unless Re($z) == 2 and Im($z) == 3;
+EOT
+ push(@script, qq(print "ok $test\\n"}\n));
+
+ $test++;
+push(@script, <<'EOT');
+{
+ my $z = cplx( 1, 1);
+ $z->abs(3 * sqrt(2));
+ print "# $test Re(z) = ",$z->Re(), " Im(z) = ", $z->Im(), " z = $z\n";
+ print 'not ' unless (abs($z) - 3 * sqrt(2)) < $eps and
+ (arg($z) - pi / 4 ) < $eps and
+ (Re($z) - 3 ) < $eps and
+ (Im($z) - 3 ) < $eps;
+EOT
+ push(@script, qq(print "ok $test\\n"}\n));
+
+ $test++;
+push(@script, <<'EOT');
+{
+ my $z = cplx( 1, 1);
+ $z->arg(-3 / 4 * pi);
+ print "# $test Re(z) = ",$z->Re(), " Im(z) = ", $z->Im(), " z = $z\n";
+ print 'not ' unless (arg($z) + 3 / 4 * pi) < $eps and
+ (abs($z) - sqrt(2) ) < $eps and
+ (Re($z) + 1 ) < $eps and
+ (Im($z) + 1 ) < $eps;
+EOT
+ push(@script, qq(print "ok $test\\n"}\n));
+}
+
+test_mutators();
+
+my $constants = '
+my $i = cplx(0, 1);
+my $pi = cplx(pi, 0);
+my $pii = cplx(0, pi);
+my $pip2 = cplx(pi/2, 0);
+my $zero = cplx(0, 0);
+';
+
+push(@script, $constants);
+
+
# test the divbyzeros
sub test_dbz {
for my $op (@_) {
$test++;
-
-# push(@script, qq(print "# '$op'\n";));
- push(@script, qq(eval '$op';));
- push(@script, qq(print 'not ' unless (\$@ =~ /Division by zero/);));
- push(@script, qq(print "ok $test\n";));
+ push(@script, <<EOT);
+ eval '$op';
+ (\$bad) = (\$@ =~ /(.+)/);
+ print "# $test op = $op divbyzero? \$bad...\n";
+ print 'not ' unless (\$@ =~ /Division by zero/);
+EOT
+ push(@script, qq(print "ok $test\\n";\n));
}
}
sub test_loz {
for my $op (@_) {
$test++;
-
-# push(@script, qq(print "# '$op'\n";));
- push(@script, qq(eval '$op';));
- push(@script, qq(print 'not ' unless (\$@ =~ /Logarithm of zero/);));
- push(@script, qq(print "ok $test\n";));
+ push(@script, <<EOT);
+ eval '$op';
+ (\$bad) = (\$@ =~ /(.+)/);
+ print "# $test op = $op logofzero? \$bad...\n";
+ print 'not ' unless (\$@ =~ /Logarithm of zero/);
+EOT
+ push(@script, qq(print "ok $test\\n";\n));
}
}
-my $minusi = cplx(0, -1);
-
test_dbz(
'i/0',
-# 'tan(pi/2)', # may succeed thanks to floating point inaccuracies
-# 'sec(pi/2)', # may succeed thanks to floating point inaccuracies
- 'csc(0)',
- 'cot(0)',
- 'atan(i)',
- 'atan($minusi)',
- 'asec(0)',
+ 'acot(0)',
+ 'acot(+$i)',
+# 'acoth(-1)', # Log of zero.
+ 'acoth(0)',
+ 'acoth(+1)',
'acsc(0)',
- 'acot(i)',
- 'acot($minusi)',
-# 'tanh(pi/2)', # may succeed thanks to floating point inaccuracies
-# 'sech(pi/2)', # may succeed thanks to floating point inaccuracies
- 'csch(0)',
- 'coth(0)',
- 'atanh(1)',
- 'asech(0)',
'acsch(0)',
- 'acoth(1)',
+ 'asec(0)',
+ 'asech(0)',
+ 'atan($i)',
+# 'atanh(-1)', # Log of zero.
+ 'atanh(+1)',
+ 'cot(0)',
+ 'coth(0)',
+ 'csc(0)',
+ 'csch(0)',
);
test_loz(
+ 'log($zero)',
+ 'atan(-$i)',
+ 'acot(-$i)',
'atanh(-1)',
'acoth(-1)',
);
-# test the 0**0
-
-sub test_ztz {
- $test++;
-
-# push(@script, qq(print "# 0**0\n";));
- push(@script, qq(eval 'cplx(0)**cplx(0)';));
- push(@script, qq(print 'not ' unless (\$@ =~ /zero raised to the/);));
- push(@script, qq(print "ok $test\n";));
-}
-
-test_ztz;
-
# test the bad roots
sub test_broot {
for my $op (@_) {
$test++;
-
-# push(@script, qq(print "# root(2, $op)\n";));
- push(@script, qq(eval 'root(2, $op)';));
- push(@script, qq(print 'not ' unless (\$@ =~ /root must be/);));
- push(@script, qq(print "ok $test\n";));
+ push(@script, <<EOT);
+ eval 'root(2, $op)';
+ (\$bad) = (\$@ =~ /(.+)/);
+ print "# $test op = $op badroot? \$bad...\n";
+ print 'not ' unless (\$@ =~ /root rank must be/);
+EOT
+ push(@script, qq(print "ok $test\\n";\n));
}
}
test_broot(qw(-3 -2.1 0 0.99));
+sub test_display_format {
+ $test++;
+ push @script, <<EOS;
+ print "# package display_format cartesian?\n";
+ print "not " unless Math::Complex->display_format eq 'cartesian';
+ print "ok $test\n";
+EOS
+
+ push @script, <<EOS;
+ my \$j = (root(1,3))[1];
+
+ \$j->display_format('polar');
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# j display_format polar?\n";
+ print "not " unless \$j->display_format eq 'polar';
+ print "ok $test\n";
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# j = \$j\n";
+ print "not " unless "\$j" eq "[1,2pi/3]";
+ print "ok $test\n";
+
+ my %display_format;
+
+ %display_format = \$j->display_format;
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# display_format{style} polar?\n";
+ print "not " unless \$display_format{style} eq 'polar';
+ print "ok $test\n";
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# keys %display_format == 2?\n";
+ print "not " unless keys %display_format == 2;
+ print "ok $test\n";
+
+ \$j->display_format('style' => 'cartesian', 'format' => '%.5f');
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# j = \$j\n";
+ print "not " unless "\$j" eq "-0.50000+0.86603i";
+ print "ok $test\n";
+
+ %display_format = \$j->display_format;
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# display_format{format} %.5f?\n";
+ print "not " unless \$display_format{format} eq '%.5f';
+ print "ok $test\n";
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# keys %display_format == 3?\n";
+ print "not " unless keys %display_format == 3;
+ print "ok $test\n";
+
+ \$j->display_format('format' => undef);
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# j = \$j\n";
+ print "not " unless "\$j" =~ /^-0(?:\\.5(?:0000\\d+)?|\\.49999\\d+)\\+0.86602540\\d+i\$/;
+ print "ok $test\n";
+
+ \$j->display_format('style' => 'polar', 'polar_pretty_print' => 0);
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# j = \$j\n";
+ print "not " unless "\$j" =~ /^\\[1,2\\.09439510\\d+\\]\$/;
+ print "ok $test\n";
+
+ \$j->display_format('style' => 'cartesian', 'format' => '(%.5g)');
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# j = \$j\n";
+ print "not " unless "\$j" eq "(-0.5)+(0.86603)i";
+ print "ok $test\n";
+EOS
+
+ $test++;
+ push @script, <<EOS;
+ print "# j display_format cartesian?\n";
+ print "not " unless \$j->display_format eq 'cartesian';
+ print "ok $test\n";
+EOS
+}
+
+test_display_format();
+
print "1..$test\n";
eval join '', @script;
die $@ if $@;
# check the op= works
push @script, <<EOB;
{
- my \$za = cplx(ref \$z0 ? \@{\$z0->cartesian} : (\$z0, 0));
+ my \$za = cplx(ref \$z0 ? \@{\$z0->cartesian} : (\$z0, 0));
my (\$z1r, \$z1i) = ref \$z1 ? \@{\$z1->cartesian} : (\$z1, 0);
- my \$zb = cplx(\$z1r, \$z1i);
+ my \$zb = cplx(\$z1r, \$z1i);
\$za $op= \$zb;
my (\$zbr, \$zbi) = \@{\$zb->cartesian};
$test++;
# check that the rhs has not changed
push @script, qq(print "not " unless (\$zbr == \$z1r and \$zbi == \$z1i););
- push @script, qq(print "ok $test\n";);
+ push @script, qq(print "ok $test\\n";\n);
push @script, "}\n";
}
}
if (/^\s*\((.*),(.*)\)/) {
return "cplx($1,$2)";
}
+ elsif (/^\s*([\-\+]?(?:\d+(\.\d+)?|\.\d+)(?:[e[\-\+]\d+])?)/) {
+ return "cplx($1,0)";
+ }
elsif (/^\s*\[(.*),(.*)\]/) {
return "cplxe($1,$2)";
}
sub check {
my ($test, $try, $got, $expected, @z) = @_;
-# print "# @_\n";
+ print "# @_\n";
if ("$got" eq "$expected"
||
print "# '$try' expected: '$expected' got: '$got' for $args\n";
}
}
+
+sub addsq {
+ my ($z1, $z2) = @_;
+ return ($z1 + i*$z2) * ($z1 - i*$z2);
+}
+
+sub subsq {
+ my ($z1, $z2) = @_;
+ return ($z1 + $z2) * ($z1 - $z2);
+}
+
__END__
&+;=
(3,4):(3,4):(6,8)
(1,0):(2,3):(1,0)
(2,3):(0,0):(1,0)
(2,3):(1,0):(2,3)
+(0,0):(0,0):(1,0)
&Re
(3,4):3
|'abs(z)':'r'
|'acot(z)':'acotan(z)'
|'acsc(z)':'acosec(z)'
-|'abs(acsc(z))':'abs(asin(1 / z))'
-|'abs(asec(z))':'abs(acos(1 / z))'
+|'acsc(z)':'asin(1 / z)'
+|'asec(z)':'acos(1 / z)'
|'cbrt(z)':'cbrt(r) * exp(i * t/3)'
|'cos(acos(z))':'z'
-|'cos(z) ** 2 + sin(z) ** 2':1
+|'addsq(cos(z), sin(z))':1
|'cos(z)':'cosh(i*z)'
-|'cosh(z) ** 2 - sinh(z) ** 2':1
+|'subsq(cosh(z), sinh(z))':1
|'cot(acot(z))':'z'
|'cot(z)':'1 / tan(z)'
|'cot(z)':'cotan(z)'
|'atan(tan(z))':'z'
|'atanh(tanh(z))':'z'
+&log
+(-2.0,0):( 0.69314718055995, 3.14159265358979)
+(-1.0,0):( 0 , 3.14159265358979)
+(-0.5,0):( -0.69314718055995, 3.14159265358979)
+( 0.5,0):( -0.69314718055995, 0 )
+( 1.0,0):( 0 , 0 )
+( 2.0,0):( 0.69314718055995, 0 )
+
+&log
+( 2, 3):( 1.28247467873077, 0.98279372324733)
+(-2, 3):( 1.28247467873077, 2.15879893034246)
+(-2,-3):( 1.28247467873077, -2.15879893034246)
+( 2,-3):( 1.28247467873077, -0.98279372324733)
+
&sin
(-2.0,0):( -0.90929742682568, 0 )
(-1.0,0):( -0.84147098480790, 0 )
( 2,-3):( 1.96863792579310, -0.96465850440760)
&acosh
-(-2.0,0):( -1.31695789692482, 3.14159265358979)
+(-2.0,0):( 1.31695789692482, 3.14159265358979)
(-1.0,0):( 0, 3.14159265358979)
(-0.5,0):( 0, 2.09439510239320)
( 0.0,0):( 0, 1.57079632679490)
&acosh
( 2, 3):( 1.98338702991654, 1.00014354247380)
-(-2, 3):( -1.98338702991653, -2.14144911111600)
-(-2,-3):( -1.98338702991653, 2.14144911111600)
+(-2, 3):( 1.98338702991653, 2.14144911111600)
+(-2,-3):( 1.98338702991653, -2.14144911111600)
( 2,-3):( 1.98338702991654, -1.00014354247380)
&atanh
&asech
(-2.0,0):( 0 , 2.09439510239320)
(-1.0,0):( 0 , 3.14159265358979)
-(-0.5,0):( -1.31695789692482, 3.14159265358979)
+(-0.5,0):( 1.31695789692482, 3.14159265358979)
( 0.5,0):( 1.31695789692482, 0 )
( 1.0,0):( 0 , 0 )
( 2.0,0):( 0 , 1.04719755119660)
&asech
( 2, 3):( 0.23133469857397, -1.42041072246703)
-(-2, 3):( -0.23133469857397, 1.72118193112276)
-(-2,-3):( -0.23133469857397, -1.72118193112276)
+(-2, 3):( 0.23133469857397, -1.72118193112276)
+(-2,-3):( 0.23133469857397, 1.72118193112276)
( 2,-3):( 0.23133469857397, 1.42041072246703)
&acsch