📄 complex.t
字号:
#!./perl# $RCSfile: complex.t,v $## Regression tests for the Math::Complex pacakge# -- Raphael Manfredi since Sep 1996# -- Jarkko Hietaniemi since Mar 1997# -- Daniel S. Lewart since Sep 1997BEGIN { chdir 't' if -d 't'; @INC = '../lib';}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;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+//; next if $_ eq '' || /^\#/; chomp; $test_set = 0; # Assume not a test over a set of values if (/^&(.+)/) { $op = $1; next; } elsif (/^\{(.+)\}/) { set($1, \@set, \@val); next; } elsif (s/^\|//) { $test_set = 1; # Requests we loop over the set... } my @args = split(/:/); if ($test_set == 1) { my $i; for ($i = 0; $i < @set; $i++) { # complex number $target = $set[$i]; # textual value as found in set definition $zvalue = $val[$i]; test($zvalue, $target, @args); } } else { test($op, undef, @args); }}#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 divbyzerossub test_dbz { for my $op (@_) { $test++; 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)); }}# test the logofzerossub test_loz { for my $op (@_) { $test++; 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)); }}test_dbz( 'i/0', 'acot(0)', 'acot(+$i)',# 'acoth(-1)', # Log of zero. 'acoth(0)', 'acoth(+1)', 'acsc(0)', 'acsch(0)', '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 bad rootssub test_broot { for my $op (@_) { $test++; 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 $@;sub abop { my ($op) = @_; push(@script, qq(print "# $op=\n";));}sub test { my ($op, $z, @args) = @_; my ($baop) = 0; $test++; my $i; $baop = 1 if ($op =~ s/;=$//); for ($i = 0; $i < @args; $i++) { $val = value($args[$i]); push @script, "\$z$i = $val;\n"; } if (defined $z) { $args = "'$op'"; # Really the value $try = "abs(\$z0 - \$z1) <= $eps ? \$z1 : \$z0"; push @script, "\$res = $try; "; push @script, "check($test, $args[0], \$res, \$z$#args, $args);\n"; } else { my ($try, $args); if (@args == 2) { $try = "$op \$z0"; $args = "'$args[0]'"; } else { $try = ($op =~ /^\w/) ? "$op(\$z0, \$z1)" : "\$z0 $op \$z1"; $args = "'$args[0]', '$args[1]'"; } push @script, "\$res = $try; "; push @script, "check($test, '$try', \$res, \$z$#args, $args);\n"; if (@args > 2 and $baop) { # binary assignment ops $test++; # check the op= works push @script, <<EOB;{ my \$za = cplx(ref \$z0 ? \@{\$z0->cartesian} : (\$z0, 0)); my (\$z1r, \$z1i) = ref \$z1 ? \@{\$z1->cartesian} : (\$z1, 0); my \$zb = cplx(\$z1r, \$z1i); \$za $op= \$zb; my (\$zbr, \$zbi) = \@{\$zb->cartesian}; check($test, '\$z0 $op= \$z1', \$za, \$z$#args, $args);EOB $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";\n); push @script, "}\n"; } }}sub set { my ($set, $setref, $valref) = @_; @{$setref} = (); @{$valref} = (); my @set = split(/;\s*/, $set); my @res; my $i; for ($i = 0; $i < @set; $i++) { push(@{$valref}, $set[$i]); my $val = value($set[$i]); push @script, "\$s$i = $val;\n"; push @{$setref}, "\$s$i"; }}sub value { local ($_) = @_; if (/^\s*\((.*),(.*)\)/) { return "cplx($1,$2)"; } elsif (/^\s*([\-\+]?(?:\d+(\.\d+)?|\.\d+)(?:[e[\-\+]\d+])?)/) { return "cplx($1,0)"; } elsif (/^\s*\[(.*),(.*)\]/) { return "cplxe($1,$2)"; } elsif (/^\s*'(.*)'/) { my $ex = $1; $ex =~ s/\bz\b/$target/g; $ex =~ s/\br\b/abs($target)/g; $ex =~ s/\bt\b/arg($target)/g; $ex =~ s/\ba\b/Re($target)/g; $ex =~ s/\bb\b/Im($target)/g; return $ex; } elsif (/^\s*"(.*)"/) { return "\"$1\""; } return $_;}sub check { my ($test, $try, $got, $expected, @z) = @_; print "# @_\n"; if ("$got" eq "$expected" || ($expected =~ /^-?\d/ && $got == $expected) || (abs($got - $expected) < $eps) ) { print "ok $test\n"; } else { print "not ok $test\n"; my $args = (@z == 1) ? "z = $z[0]" : "z0 = $z[0], z1 = $z[1]"; 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)(-3,4):(3,-4):(0,0)(3,4):-3:(0,4)1:(4,2):(5,2)[2,0]:[2,pi]:(0,0)&++(2,1):(3,1)&-;=(2,3):(-2,-3)[2,pi/2]:[2,-(pi)/2]2:[2,0]:(0,0)[3,0]:2:(1,0)3:(4,5):(-1,-5)(4,5):3:(1,5)(2,1):(3,5):(-1,-4)&--(1,2):(0,2)[2,pi]:[3,pi]&*;=(0,1):(0,1):(-1,0)(4,5):(1,0):(4,5)[2,2*pi/3]:(1,0):[2,2*pi/3]2:(0,1):(0,2)(0,1):3:(0,3)(0,1):(4,1):(-1,4)(2,1):(4,-1):(9,2)&/;=(3,4):(3,4):(1,0)(4,-5):1:(4,-5)1:(0,1):(0,-1)(0,6):(0,2):(3,0)(9,2):(4,-1):(2,1)[4,pi]:[2,pi/2]:[2,pi/2][2,pi/2]:[4,pi]:[0.5,-(pi)/2]&**;=(2,0):(3,0):(8,0)(3,0):(2,0):(9,0)(2,3):(4,0):(-119,-120)(0,0):(1,0):(0,0)(0,0):(2,3):(0,0)(1,0):(0,0):(1,0)(1,0):(1,0):(1,0)(1,0):(2,3):(1,0)(2,3):(0,0):(1,0)(2,3):(1,0):(2,3)(0,0):(0,0):(1,0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -