Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[t/spec] Bring the complex trig tests into the new (still not active)…

… system.

git-svn-id: http://svn.pugscode.org/pugs@28398 c213334d-75ef-0310-aa23-eaa082d1ae64
  • Loading branch information...
commit 0676f5217476d2a81afed43d11cc140ce30645f4 1 parent eb5675c
colomon authored
View
244 S32-trig/TrigTestSupport
@@ -86,3 +86,247 @@ my %official_base = (
"degrees" => "degrees",
"revolutions" => 1
);
+
+
+# SHOULD BE IN COMPLEX.PM!
+# but that doesn't work for some reason...
+
+multi sub sin(Complex $x, $base = "radians")
+{
+ $x!to-radians($base).sin;
+}
+
+multi sub cos(Complex $x, $base = "radians")
+{
+ $x!to-radians($base).cos;
+}
+
+multi sub tan(Complex $x, $base = "radians")
+{
+ $x!to-radians($base).tan;
+}
+
+multi sub sec(Complex $x, $base = "radians")
+{
+ $x!to-radians($base).sec;
+}
+
+multi sub cosec(Complex $x, $base = "radians")
+{
+ $x!to-radians($base).cosec;
+}
+
+multi sub cotan(Complex $x, $base = "radians")
+{
+ $x!to-radians($base).cotan;
+}
+
+multi sub sinh(Complex $x, $base = "radians") {
+ $x!to-radians($base).sinh;
+}
+
+multi sub cosh(Complex $x, $base = "radians") {
+ $x!to-radians($base).cosh;
+}
+
+multi sub tanh(Complex $x, $base = "radians") {
+ $x!to-radians($base).tanh;
+}
+
+multi sub sech(Complex $x, $base = "radians") {
+ $x!to-radians($base).sech;
+}
+
+multi sub cosech(Complex $x, $base = "radians") {
+ $x!to-radians($base).cosech;
+}
+
+multi sub cotanh(Complex $x, $base = "radians") {
+ $x!to-radians($base).cotanh;
+}
+
+multi sub asin(Complex $x, $base = "radians")
+{
+ $x.asin!from-radians($base);
+}
+
+multi sub acos(Complex $x, $base = "radians")
+{
+ $x.acos!from-radians($base);
+}
+
+multi sub atan(Complex $x, $base = "radians")
+{
+ $x.atan!from-radians($base);
+}
+
+multi sub asec(Complex $x, $base = "radians")
+{
+ $x.asec!from-radians($base);
+}
+
+multi sub acosec(Complex $x, $base = "radians")
+{
+ $x.acosec!from-radians($base);
+}
+
+multi sub acotan(Complex $x, $base = "radians")
+{
+ $x.acotan!from-radians($base);
+}
+
+multi sub asinh(Complex $x, $base = "radians") {
+ $x.asinh!from-radians($base);
+}
+
+multi sub acosh(Complex $x, $base = "radians") {
+ $x.acosh!from-radians($base);
+}
+
+multi sub atanh(Complex $x, $base = "radians") {
+ $x.atanh!from-radians($base);
+}
+
+multi sub asech(Complex $x, $base = "radians") {
+ $x.asech!from-radians($base);
+}
+
+multi sub acosech(Complex $x, $base = "radians") {
+ $x.acosech!from-radians($base);
+}
+
+multi sub acotanh(Complex $x, $base = "radians") {
+ $x.acotanh!from-radians($base);
+}
+
+# END SHOULD BE IN COMPLEX.PM!
+
+
+# atan2 tests
+
+# First, test atan2 with the default $x parameter of 1
+
+for @sines -> $angle
+{
+ next if abs(cos($angle.num('radians'))) < 1e-6;
+ my $desired_result = sin($angle.num('radians')) / cos($angle.num('radians'));
+
+ # atan2(Num) tests
+ is_approx(tan(atan2($desired_result)), $desired_result,
+ "atan2(Num) - {$angle.num('radians')} default");
+
+ # atan2(:y(Num))
+ #?rakudo skip 'named args'
+ is_approx(tan(atan2(:y($desired_result))), $desired_result,
+ "atan2(:y(Num)) - {$angle.num('radians')} default");
+ for %official_base.keys -> $base {
+ #?rakudo skip 'named args'
+ is_approx(tan(atan2(:y($desired_result), :base(%official_base{$base})),
+ %official_base{$base}), $desired_result,
+ "atan2(:y(Num)) - {$angle.num($base)} $base");
+ }
+
+ # Num.atan2 tests
+ is_approx($desired_result.Num.atan2.tan, $desired_result,
+ "atan2(Num) - {$angle.num('radians')} default");
+}
+
+for (-2/2, -1/2, 1/2, 2/2) -> $desired_result
+{
+ # atan2(Rat) tests
+ is_approx(tan(atan2($desired_result)), $desired_result,
+ "atan2(Rat) - $desired_result default");
+
+ # Rat.atan2 tests
+ is_approx($desired_result.atan2.tan, $desired_result,
+ "atan2(Rat) - $desired_result default");
+
+ next unless $desired_result.denominator == 1;
+
+ # atan2(Int) tests
+ is_approx(tan(atan2($desired_result.numerator)), $desired_result,
+ "atan2(Int) - $desired_result default");
+
+ # Int.atan2 tests
+ is_approx($desired_result.numerator.atan2.tan, $desired_result,
+ "atan2(Int) - $desired_result default");
+}
+
+# Now test the full atan2 interface
+
+for @sines -> $angle
+{
+ next if abs(cos($angle.num('radians'))) < 1e-6;
+ my $desired_result = sin($angle.num('radians')) / cos($angle.num('radians'));
+
+ # atan2(Num) tests
+ is_approx(tan(atan2($desired_result, 1)), $desired_result,
+ "atan2(Num, 1) - {$angle.num('radians')} default");
+ for %official_base.keys -> $base {
+ is_approx(tan(atan2($desired_result, 1, %official_base{$base}), %official_base{$base}), $desired_result,
+ "atan2(Num, 1) - {$angle.num($base)} $base");
+ }
+
+ # atan2(:x(Num))
+ #?rakudo skip 'named args'
+ is_approx(tan(atan2(:y($desired_result), :x(1))), $desired_result,
+ "atan2(:x(Num), :y(1)) - {$angle.num('radians')} default");
+ for %official_base.keys -> $base {
+ #?rakudo skip 'named args'
+ is_approx(tan(atan2(:y($desired_result), :x(1), :base(%official_base{$base})),
+ %official_base{$base}), $desired_result,
+ "atan2(:x(Num), :y(1)) - {$angle.num($base)} $base");
+ }
+
+ # # Num.atan2 tests
+ # is_approx($desired_result.Num.atan2.tan, $desired_result,
+ # "atan2(Num) - {$angle.num('radians')} default");
+ # for %official_base.keys -> $base {
+ # is_approx($desired_result.Num.atan2(%official_base{$base}).tan(%official_base{$base}), $desired_result,
+ # "atan2(Num) - {$angle.num($base)} $base");
+ # }
+}
+
+for (-2/2, -1/2, 1/2, 2/2) -> $desired_result
+{
+ # atan2(Rat) tests
+ is_approx(tan(atan2($desired_result, 1)), $desired_result,
+ "atan2(Rat) - $desired_result default");
+ for %official_base.keys -> $base {
+ is_approx(tan(atan2($desired_result, 1, %official_base{$base}), %official_base{$base}), $desired_result,
+ "atan2(Rat) - $desired_result $base");
+ }
+
+ # # Rat.atan2 tests
+ # is_approx($desired_result.atan2.tan, $desired_result,
+ # "atan2(Rat) - $desired_result default");
+ # for %official_base.keys -> $base {
+ # is_approx($desired_result.atan2(%official_base{$base}).tan(%official_base{$base}), $desired_result,
+ # "atan2(Rat) - $desired_result $base");
+ # }
+
+ next unless $desired_result.denominator == 1;
+
+ # atan2(Int) tests
+ is_approx(tan(atan2($desired_result.numerator, 1)), $desired_result,
+ "atan2(Int) - $desired_result default");
+ for %official_base.keys -> $base {
+ is_approx(tan(atan2($desired_result.numerator, 1, %official_base{$base}), %official_base{$base}), $desired_result,
+ "atan2(Int) - $desired_result $base");
+ }
+
+ # # Int.atan2 tests
+ # is_approx($desired_result.numerator.atan2.tan, $desired_result,
+ # "atan2(Int) - $desired_result default");
+ # for %official_base.keys -> $base {
+ # is_approx($desired_result.numerator.atan2(%official_base{$base}).tan(%official_base{$base}), $desired_result,
+ # "atan2(Int) - $desired_result $base");
+ # }
+}
+
+# check that the proper quadrant is returned
+
+is_approx(atan2(4, 4, "degrees"), 45, "atan2(4, 4) is 45 degrees");
+is_approx(atan2(-4, 4, "degrees"), -45, "atan2(-4, 4) is -45 degrees");
+is_approx(atan2(4, -4, "degrees"), 135, "atan2(4, -4) is 135 degrees");
+is_approx(atan2(-4, -4, "degrees"), -135, "atan2(-4, -4) is -135 degrees");
View
153 S32-trig/generate-tests.pl
@@ -11,6 +11,7 @@
has $.angle_and_results_name;
has $.rational_inverse_tests;
has $.setup_block;
+ has $.complex_check;
has $.plus_inf;
has $.minus_inf;
@@ -19,6 +20,7 @@
Str $angle_and_results_name is copy,
Str $rational_inverse_tests is copy;
Str $setup_block is copy,
+ Str $complex_check is copy,
Str $plus_inf is copy,
Str $minus_inf is copy) {
self.bless(*,
@@ -27,6 +29,7 @@
:$angle_and_results_name,
:$rational_inverse_tests,
:$setup_block,
+ :$complex_check,
:$plus_inf,
:$minus_inf);
}
@@ -46,6 +49,16 @@
is_approx($.function_name($angle.num($base), %official_base{$base}), $desired_result,
"$.function_name(Num) - {$angle.num($base)} $base");
}
+
+ # $.function_name(:x(Num))
+ #?rakudo skip 'named args'
+ is_approx($.function_name(:x($angle.num("radians"))), $desired_result,
+ "$.function_name(:x(Num)) - {$angle.num('radians')} default");
+ for %official_base.keys -> $base {
+ #?rakudo skip 'named args'
+ is_approx($.function_name(:x($angle.num($base)), :base(%official_base{$base})), $desired_result,
+ "$.function_name(:x(Num)) - {$angle.num($base)} $base");
+ }
# Num.$.function_name tests
is_approx($angle.num("radians").$.function_name, $desired_result,
@@ -63,6 +76,16 @@
"$.function_name(Rat) - {$angle.rat($base)} $base");
}
+ # $.function_name(:x(Rat))
+ #?rakudo skip 'named args'
+ is_approx($.function_name(:x($angle.rat("radians"))), $desired_result,
+ "$.function_name(:x(Rat)) - {$angle.rat('radians')} default");
+ for %official_base.keys -> $base {
+ #?rakudo skip 'named args'
+ is_approx($.function_name(:x($angle.rat($base)), :base(%official_base{$base})), $desired_result,
+ "$.function_name(:x(Rat)) - {$angle.rat($base)} $base");
+ }
+
# Rat.$.function_name tests
is_approx($angle.rat("radians").$.function_name, $desired_result,
"Rat.$.function_name - {$angle.rat('radians')} default");
@@ -77,48 +100,48 @@
is_approx($angle.int('degrees').$.function_name(%official_base{'degrees'}), $desired_result,
"Int.$.function_name - {$angle.int('degrees')} degrees");
- # # Complex tests
- # my Complex $zp0 = $angle.complex(0.0, "radians");
- # my Complex $sz0 = $desired_result + 0i;
- # my Complex $zp1 = $angle.complex(1.0, "radians");
- # my Complex $sz1 = (exp($zp1 * 1i) - exp(-$zp1 * 1i)) / 2i;
- # my Complex $zp2 = $angle.complex(2.0, "radians");
- # my Complex $sz2 = (exp($zp2 * 1i) - exp(-$zp2 * 1i)) / 2i;
- #
- # # $.function_name(Complex) tests
- # is_approx($.function_name($zp0), $sz0, "$.function_name(Complex) - $zp0 default");
- # is_approx($.function_name($zp1), $sz1, "$.function_name(Complex) - $zp1 default");
- # is_approx($.function_name($zp2), $sz2, "$.function_name(Complex) - $zp2 default");
- #
- # for %official_base.keys -> $base {
- # my Complex $z = $angle.complex(0.0, $base);
- # is_approx($.function_name($z, %official_base{$base}), $sz0, "$.function_name(Complex) - $z $base");
- #
- # $z = $angle.complex(1.0, $base);
- # is_approx($.function_name($z, %official_base{$base}), $sz1, "$.function_name(Complex) - $z $base");
- #
- # $z = $angle.complex(2.0, $base);
- # is_approx($.function_name($z, %official_base{$base}), $sz2, "$.function_name(Complex) - $z $base");
- # }
- #
- # # Complex.$.function_name tests
- # is_approx($zp0.$.function_name, $sz0, "Complex.$.function_name - $zp0 default");
- # is_approx($zp1.$.function_name, $sz1, "Complex.$.function_name - $zp1 default");
- # is_approx($zp2.$.function_name, $sz2, "Complex.$.function_name - $zp2 default");
- #
- # for %official_base.keys -> $base {
- # my Complex $z = $angle.complex(0.0, $base);
- # #?rakudo skip "Complex.$.function_name plus base doesn't work yet"
- # is_approx($z.$.function_name(%official_base{$base}), $sz0, "Complex.$.function_name - $z $base");
- #
- # $z = $angle.complex(1.0, $base);
- # #?rakudo skip "Complex.$.function_name plus base doesn't work yet"
- # is_approx($z.$.function_name(%official_base{$base}), $sz1, "Complex.$.function_name - $z $base");
- #
- # $z = $angle.complex(2.0, $base);
- # #?rakudo skip "Complex.$.function_name plus base doesn't work yet"
- # is_approx($z.$.function_name(%official_base{$base}), $sz2, "Complex.$.function_name - $z $base");
- # }
+ # Complex tests
+ my Complex $zp0 = $angle.complex(0.0, "radians");
+ my Complex $sz0 = $desired_result + 0i;
+ my Complex $zp1 = $angle.complex(1.0, "radians");
+ my Complex $sz1 = $.complex_check($zp1);
+ my Complex $zp2 = $angle.complex(2.0, "radians");
+ my Complex $sz2 = $.complex_check($zp2);
+
+ # $.function_name(Complex) tests
+ is_approx($.function_name($zp0), $sz0, "$.function_name(Complex) - $zp0 default");
+ is_approx($.function_name($zp1), $sz1, "$.function_name(Complex) - $zp1 default");
+ is_approx($.function_name($zp2), $sz2, "$.function_name(Complex) - $zp2 default");
+
+ for %official_base.keys -> $base {
+ my Complex $z = $angle.complex(0.0, $base);
+ is_approx($.function_name($z, %official_base{$base}), $sz0, "$.function_name(Complex) - $z $base");
+
+ $z = $angle.complex(1.0, $base);
+ is_approx($.function_name($z, %official_base{$base}), $sz1, "$.function_name(Complex) - $z $base");
+
+ $z = $angle.complex(2.0, $base);
+ is_approx($.function_name($z, %official_base{$base}), $sz2, "$.function_name(Complex) - $z $base");
+ }
+
+ # Complex.$.function_name tests
+ is_approx($zp0.$.function_name, $sz0, "Complex.$.function_name - $zp0 default");
+ is_approx($zp1.$.function_name, $sz1, "Complex.$.function_name - $zp1 default");
+ is_approx($zp2.$.function_name, $sz2, "Complex.$.function_name - $zp2 default");
+
+ for %official_base.keys -> $base {
+ my Complex $z = $angle.complex(0.0, $base);
+ #?rakudo skip "Complex.$.function_name plus base doesn't work yet"
+ is_approx($z.$.function_name(%official_base{$base}), $sz0, "Complex.$.function_name - $z $base");
+
+ $z = $angle.complex(1.0, $base);
+ #?rakudo skip "Complex.$.function_name plus base doesn't work yet"
+ is_approx($z.$.function_name(%official_base{$base}), $sz1, "Complex.$.function_name - $z $base");
+
+ $z = $angle.complex(2.0, $base);
+ #?rakudo skip "Complex.$.function_name plus base doesn't work yet"
+ is_approx($z.$.function_name(%official_base{$base}), $sz2, "Complex.$.function_name - $z $base");
+ }
}
is($.function_name(Inf), $.plus_inf, "$.function_name(Inf) - default");
@@ -132,6 +155,7 @@
$code.=subst: '$.function_name', $.function_name, :g;
$code.=subst: '$.inverted_function_name', $.inverted_function_name, :g;
$code.=subst: '$.setup_block', $.setup_block, :g;
+ $code.=subst: '$.complex_check', $.complex_check, :g;
$code.=subst: '$.angle_and_results_name', $.angle_and_results_name, :g;
$code.=subst: '$.rational_inverse_tests', $.rational_inverse_tests, :g;
$code.=subst: '$.plus_inf', $.plus_inf, :g;
@@ -157,6 +181,18 @@
"$.inverted_function_name(Num) - {$angle.num($base)} $base");
}
+ # $.inverted_function_name(:x(Num))
+ #?rakudo skip 'named args'
+ is_approx($.function_name($.inverted_function_name(:x($desired_result))), $desired_result,
+ "$.inverted_function_name(:x(Num)) - {$angle.num('radians')} default");
+ for %official_base.keys -> $base {
+ #?rakudo skip 'named args'
+ is_approx($.function_name($.inverted_function_name(:x($desired_result),
+ :base(%official_base{$base})),
+ %official_base{$base}), $desired_result,
+ "$.inverted_function_name(:x(Num)) - {$angle.num($base)} $base");
+ }
+
# Num.$.inverted_function_name tests
is_approx($desired_result.Num.$.inverted_function_name.$.function_name, $desired_result,
"$.inverted_function_name(Num) - {$angle.num('radians')} default");
@@ -164,6 +200,16 @@
is_approx($desired_result.Num.$.inverted_function_name(%official_base{$base}).$.function_name(%official_base{$base}), $desired_result,
"$.inverted_function_name(Num) - {$angle.num($base)} $base");
}
+
+ # $.inverted_function_name(Complex) tests
+ for ($desired_result + 0i, $desired_result + .5i, $desired_result + 2i) -> $z {
+ is_approx($.function_name($.inverted_function_name($z)), $z,
+ "$.inverted_function_name(Complex) - {$angle.num('radians')} default");
+ for %official_base.keys -> $base {
+ is_approx($.function_name($.inverted_function_name($z, %official_base{$base}), %official_base{$base}), $z,
+ "$.inverted_function_name(Complex) - {$angle.num($base)} $base");
+ }
+ }
}
for $.rational_inverse_tests -> $desired_result
@@ -235,17 +281,20 @@
my Str $angle_and_results_name;
my Str $rational_inverse_tests;
my Str $setup_block;
+my Str $complex_check;
my Str $plus_inf;
my Str $minus_inf;
for $functions.lines {
- when $in_setup && /end\-setup/ { $in_setup = Bool::False; }
- when $in_setup { $setup_block ~= $_; }
+ when /^\#/ { } # skip comment lines
+ when $in_setup && /^\s/ { $setup_block ~= $_; }
+ $in_setup = Bool::False;
when /Function\:\s+(.*)/ {
$function_name = ~$0;
$inverted_function_name = "a$0";
$angle_and_results_name = "";
$rational_inverse_tests = "(-2/2, -1/2, 1/2, 2/2)";
$setup_block = "";
+ $complex_check = "";
$plus_inf = "NaN";
$minus_inf = "NaN";
}
@@ -253,29 +302,17 @@
when /loop_over\:\s+(.*)/ { $angle_and_results_name = ~$0; }
when /inverted_function\:\s+(.*)/ { $inverted_function_name = ~$0; }
when /rational_inverse_tests\:\s+(.*)/ { $rational_inverse_tests = ~$0; }
+ when /complex_check\:\s+(.*)/ { $complex_check = ~$0; }
when /plus_inf\:\s+(.*)/ { $plus_inf = ~$0; }
when /minus_inf\:\s+(.*)/ { $minus_inf = ~$0; }
when /End/ {
my $tf = TrigFunction.new($function_name, $inverted_function_name, $angle_and_results_name,
- $rational_inverse_tests, $setup_block, $plus_inf, $minus_inf);
+ $rational_inverse_tests, $setup_block, $complex_check, $plus_inf, $minus_inf);
$tf.dump_forward_tests($file);
$tf.dump_inverse_tests($file);
}
}
-# $tf = TrigFunction.new("cosech", "acosech", "@sines",
-# "next if abs(sinh(\$angle.num('radians'))) < 1e-6;
-# my \$desired_result = 1.0 / sinh(\$angle.num('radians'));",
-# "0", '"-0"');
-# $tf.dump_forward_tests($file);
-# $tf.dump_inverse_tests($file);
-# $tf = TrigFunction.new("cotanh", "acotanh", "@sines",
-# "next if abs(sinh(\$angle.num('radians'))) < 1e-6;
-# my \$desired_result = cosh(\$angle.num('radians')) / sinh(\$angle.num('radians'));",
-# "1", "-1");
-# $tf.dump_forward_tests($file);
-# $tf.dump_inverse_tests($file);
-
# the {} afer 'vim' just generate an empty string.
# this is to avoid the string constant being interpreted as a modeline
# here in generate-tests.pl
View
14 S32-trig/trig_functions
@@ -1,8 +1,11 @@
+# Simple file to control trig test creation.
+
Function: sin
loop_over: @sines
setup:
my $desired_result = $angle.result;
end-setup
+complex_check: { (exp($_ * 1i) - exp(-$_ * 1i)) / 2i }
End
Function: cos
@@ -10,6 +13,7 @@ loop_over: @cosines
setup:
my $desired_result = $angle.result;
end-setup
+complex_check: { (exp($_ * 1i) + exp(-$_ * 1i)) / 2 }
End
Function: tan
@@ -18,6 +22,7 @@ setup:
next if abs(cos($angle.num('radians'))) < 1e-6;
my $desired_result = sin($angle.num('radians')) / cos($angle.num('radians'));
end-setup
+complex_check: { sin($_) / cos($_) }
End
Function: sec
@@ -27,6 +32,7 @@ setup:
my $desired_result = 1.0 / cos($angle.num('radians'));
end-setup
rational_inverse_tests: (-3/2, -2/2, 2/2, 3/2)
+complex_check: { 1.0 / cos($_) }
End
Function: cosec
@@ -36,6 +42,7 @@ setup:
my $desired_result = 1.0 / sin($angle.num('radians'));
end-setup
rational_inverse_tests: (-3/2, -2/2, 2/2, 3/2)
+complex_check: { 1.0 / sin($_) }
End
Function: cotan
@@ -44,6 +51,7 @@ setup:
next if abs(sin($angle.num('radians'))) < 1e-6;
my $desired_result = cos($angle.num('radians')) / sin($angle.num('radians'));
end-setup
+complex_check: { cos($_) / sin($_) }
End
Function: sinh
@@ -51,6 +59,7 @@ loop_over: @sinhes
setup:
my $desired_result = $angle.result;
end-setup
+complex_check: { (exp($_) - exp(-$_)) / 2 }
plus_inf: Inf
minus_inf: -Inf
End
@@ -61,6 +70,7 @@ setup:
my $desired_result = $angle.result;
end-setup
rational_inverse_tests: (2/2, 3/2, 4/2, 5/2)
+complex_check: { (exp($_) + exp(-$_)) / 2 }
plus_inf: Inf
minus_inf: Inf
End
@@ -72,6 +82,7 @@ setup:
my $desired_result = sinh($angle.num('radians')) / cosh($angle.num('radians'));
end-setup
rational_inverse_tests: (-2/2, -1/2, 0/1, 1/2)
+complex_check: { sinh($_) / cosh($_) }
plus_inf: 1
minus_inf: -1
End
@@ -83,6 +94,7 @@ setup:
my $desired_result = 1.0 / cosh($angle.num('radians'));
end-setup
rational_inverse_tests: (1/4, 1/2, 3/4, 2/2)
+complex_check: { 1.0 / cosh($_) }
plus_inf: 0
minus_inf: 0
End
@@ -93,6 +105,7 @@ setup:
next if abs(sinh($angle.num('radians'))) < 1e-6;
my $desired_result = 1.0 / sinh($angle.num('radians'));
end-setup
+complex_check: { 1.0 / sinh($_) }
plus_inf: 0
minus_inf: "-0"
End
@@ -104,6 +117,7 @@ setup:
my $desired_result = cosh($angle.num('radians')) / sinh($angle.num('radians'));
end-setup
rational_inverse_tests: (-4/2, -3/2, 3/2, 4/2)
+complex_check: { cosh($_) / sinh ($_) }
plus_inf: 1
minus_inf: -1
End
Please sign in to comment.
Something went wrong with that request. Please try again.