diff --git a/MathTrigonometric.Tests/MathTrigTests.ComplexNumbers.cs b/MathTrigonometric.Tests/MathTrigTests.ComplexNumbers.cs
new file mode 100644
index 0000000..20ccf12
--- /dev/null
+++ b/MathTrigonometric.Tests/MathTrigTests.ComplexNumbers.cs
@@ -0,0 +1,657 @@
+using System.Numerics;
+
+namespace MathTrigonometric.Tests;
+
+public partial class MathTrigTests
+{
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.Epsilon, 0d)]
+ [InlineData(-Math.PI / 2, 0d, -1d, 0)]
+ [InlineData(-Math.PI / 3, 0d, -0.8660254037844386d, 0d)]
+ [InlineData(-Math.PI / 4, 0d, -0.70710678118654757d, 0d)]
+ [InlineData(-Math.PI / 6, 0d, -0.49999999999999994d, 0d)]
+ [InlineData(0d, 0d, 0d, 0d)]
+ [InlineData(1d, 0d, 0.8414709848078965d, 0d)]
+ [InlineData(Math.PI / 6, 0d, 0.49999999999999994d, 0d)]
+ [InlineData(Math.PI / 4, 0d, 0.70710678118654757d, 0d)]
+ [InlineData(Math.PI / 3, 0d, 0.8660254037844386d, 0d)]
+ [InlineData(Math.PI / 2, 0d, 1d, 0d)]
+ [InlineData(-Math.PI, 0d, -1.2246467991473532E-16d, 0d)]
+ [InlineData(Math.PI, 0d, 1.2246467991473532E-16d, 0d)]
+ [InlineData(double.PositiveInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(double.NegativeInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(2d, 3d, 9.15449914691143d, -4.168906959966565d)]
+ [InlineData(2d, -3d, 9.15449914691143d, 4.168906959966565d)]
+ [InlineData(-2d, 3d, -9.15449914691143d, -4.168906959966565d)]
+ [InlineData(-2d, -3d, -9.15449914691143d, 4.168906959966565d)]
+ //[InlineData(0.01, 711.0, 3.0E+306, double.PositiveInfinity)]
+ public void MathTrig_SinComplexNumbers_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Sin(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, 1d)]
+ [InlineData(-Math.PI / 2, 0d, 6.123233995736766E-17d)]
+ [InlineData(-Math.PI / 3, 0d, 0.50000000000000011d)]
+ [InlineData(-Math.PI / 4, 0d, 0.70710678118654757d)]
+ [InlineData(-Math.PI / 6, 0d, 0.86602540378443871d)]
+ [InlineData(0d, 0d, 1d)]
+ [InlineData(1d, 0d, 0.54030230586813977d)]
+ [InlineData(Math.PI / 6, 0d, 0.86602540378443871d, 0d)]
+ [InlineData(Math.PI / 4, 0d, 0.70710678118654757d, 0d)]
+ [InlineData(Math.PI / 3, 0d, 0.50000000000000011d, 0d)]
+ [InlineData(Math.PI / 2, 0d, 6.123233995736766E-17d, 0d)]
+ [InlineData(-Math.PI, 0d, -1d)]
+ [InlineData(Math.PI, 0d, -1d)]
+ [InlineData(double.PositiveInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(double.NegativeInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(2d, 3d, -4.189625690968807d, -9.109227893755337d)]
+ [InlineData(2d, -3d, -4.189625690968807d, 9.109227893755337d)]
+ [InlineData(-2d, 3d, -4.189625690968807d, 9.109227893755337d)]
+ [InlineData(-2d, -3d, -4.189625690968807d, -9.109227893755337d)]
+ public void MathTrig_CosComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Cos(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.Epsilon)]
+ [InlineData(-Math.PI / 2, 0d, double.NegativeInfinity, double.NaN)]
+ [InlineData(-Math.PI / 3, 0d, -1.7320508075688767d)]
+ [InlineData(-Math.PI / 4, 0d, -1d)]
+ [InlineData(-Math.PI / 6, 0d, -0.5773502691896257d)]
+ [InlineData(0d, 0d, 0d)]
+ [InlineData(1d, 0d, 1.5574077246549021d)]
+ [InlineData(Math.PI / 6, 0d, 0.5773502691896257d, 0d)]
+ [InlineData(Math.PI / 4, 0d, 1d, 0d)]
+ [InlineData(Math.PI / 3, 0d, 1.7320508075688767d, 0d)]
+ [InlineData(Math.PI / 2, 0d, double.PositiveInfinity, double.NaN)]
+ [InlineData(-Math.PI, 0d, -1.2246467991473532E-16d / -1d)]
+ [InlineData(Math.PI, 0d, 1.2246467991473532E-16d / -1d)]
+ [InlineData(double.PositiveInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(double.NegativeInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(2d, 3d, -0.0037640256415042484, 1.0032386273536098)]
+ [InlineData(2d, -3d, -0.0037640256415042484, -1.0032386273536098)]
+ [InlineData(-2d, 3d, 0.0037640256415042484, 1.0032386273536098)]
+ [InlineData(-2d, -3d, 0.0037640256415042484, -1.0032386273536098)]
+ public void MathTrig_TanComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Tan(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.PositiveInfinity)]
+ [InlineData(-Math.PI / 2, 0d, -1d)]
+ [InlineData(-Math.PI / 3, 0d, 1 / -0.8660254037844386d)]
+ [InlineData(-Math.PI / 4, 0d, 1 / -0.70710678118654757d)]
+ [InlineData(-Math.PI / 6, 0d, 1 / -0.49999999999999994d)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(Math.PI / 6, 0d, 1 / 0.49999999999999994d)]
+ [InlineData(Math.PI / 4, 0d, 1 / 0.70710678118654757d)]
+ [InlineData(Math.PI / 3, 0d, 1 / 0.8660254037844386d)]
+ [InlineData(Math.PI / 2, 0d, 1d, 0d)]
+ [InlineData(-Math.PI, 0d, 1 / -1.2246467991473532E-16d)]
+ [InlineData(Math.PI, 0d, 1 / 1.2246467991473532E-16d)]
+ [InlineData(Math.PI + Math.PI / 2, 0d, -1d)]
+ [InlineData(-Math.PI - Math.PI / 2, 0d, 1d)]
+ [InlineData(double.PositiveInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(double.NegativeInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(2d, 3d, 0.09047320975320743, 0.041200986288574125)]
+ [InlineData(2d, -3d, 0.09047320975320743, -0.041200986288574125)]
+ [InlineData(-2d, 3d, -0.09047320975320743, 0.041200986288574125)]
+ [InlineData(-2d, -3d, -0.09047320975320743, -0.041200986288574125)]
+ public void MathTrig_CscComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Csc(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, 1d)]
+ [InlineData(-Math.PI / 2, 0d, 1 / 6.123233995736766E-17d)]
+ [InlineData(-Math.PI / 3, 0d, 1 / 0.50000000000000011d)]
+ [InlineData(-Math.PI / 4, 0d, 1 / 0.70710678118654757d)]
+ [InlineData(-Math.PI / 6, 0d, 1 / 0.86602540378443871d)]
+ [InlineData(0d, 0d, 1d)]
+ [InlineData(Math.PI / 6, 0d, 1 / 0.86602540378443871d)]
+ [InlineData(Math.PI / 4, 0d, 1 / 0.70710678118654757d)]
+ [InlineData(Math.PI / 3, 0d, 1 / 0.50000000000000011d)]
+ [InlineData(Math.PI / 2, 0d, 1 / 6.123233995736766E-17d)]
+ [InlineData(-Math.PI, 0d, -1d)]
+ [InlineData(Math.PI, 0d, -1d)]
+ [InlineData(-2 * Math.PI, 0d, 1d)]
+ [InlineData(2 * Math.PI, 0d, 1d)]
+ [InlineData(double.PositiveInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(double.NegativeInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(2d, 3d, -0.041674964411144266, 0.0906111371962376)]
+ [InlineData(2d, -3d, -0.041674964411144266, -0.0906111371962376)]
+ [InlineData(-2d, 3d, -0.041674964411144266, -0.0906111371962376)]
+ [InlineData(-2d, -3d, -0.041674964411144266, 0.0906111371962376)]
+ public void MathTrig_SecComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Sec(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.PositiveInfinity)]
+ [InlineData(-Math.PI / 2, 0d, -1 / 16331239353195370d)]
+ [InlineData(-Math.PI / 3, 0d, -1 / 1.7320508075688767d)]
+ [InlineData(-Math.PI / 4, 0d, -1d)]
+ [InlineData(-Math.PI / 6, 0d, -1 / 0.57735026918962562d)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(Math.PI / 6, 0d, 1 / 0.57735026918962562d)]
+ [InlineData(Math.PI / 4, 0d, 1d, 0d)]
+ [InlineData(Math.PI / 3, 0d, 1 / 1.7320508075688767d)]
+ [InlineData(Math.PI / 2, 0d, 1 / 16331239353195370d)]
+ [InlineData(-Math.PI, 0d, -1d / -1.2246467991473532E-16d)]
+ [InlineData(Math.PI, 0d, -1d / 1.2246467991473532E-16d)]
+ [InlineData(double.PositiveInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(double.NegativeInfinity, 0d, double.NaN, double.NaN)]
+ [InlineData(2d, 3d, -0.003739710376336932, -0.9967577965693583)]
+ [InlineData(2d, -3d, -0.003739710376336932, 0.9967577965693583)]
+ [InlineData(-2d, 3d, 0.003739710376336932, -0.9967577965693583)]
+ [InlineData(-2d, -3d, 0.003739710376336932, 0.9967577965693583)]
+ public void MathTrig_CotComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Cot(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d)]
+ [InlineData(double.Epsilon, 0d, double.Epsilon)]
+ [InlineData(0.5d, 0d, 0.52359877559829893d)] //PI / 6
+ [InlineData(1d, 0d, Math.PI / 2)]
+ [InlineData(2d, 0d, Math.PI / 2, 1.3169578969248166d)]
+ [InlineData(double.PositiveInfinity, 0d, Math.PI / 2, double.PositiveInfinity)]
+ [InlineData(-0.5d, 0d, -0.52359877559829893d)] //PI / 6
+ [InlineData(-1d, 0d, -Math.PI / 2, 0d)]
+ [InlineData(-2d, 0d, -Math.PI / 2, 1.3169578969248166d)]
+ [InlineData(double.NegativeInfinity, 0d, -Math.PI / 2, double.PositiveInfinity)]
+ [InlineData(2d, 3d, 0.5706527843210993, 1.9833870299165357)]
+ [InlineData(2d, -3d, 0.5706527843210993, -1.9833870299165357)]
+ [InlineData(-2d, 3d, -0.5706527843210993, 1.9833870299165357)]
+ [InlineData(-2d, -3d, -0.5706527843210993, -1.9833870299165357)]
+ public void MathTrig_AsinComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Asin(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, Math.PI / 2)]
+ [InlineData(double.Epsilon, 0d, Math.PI / 2 - double.Epsilon)]
+ [InlineData(0.5d, 0d, 1.0471975511965979d)] //PI / 3
+ [InlineData(1d, 0d, 0d)]
+ [InlineData(2d, 0d, 0d, 1.3169578969248166d)]
+ [InlineData(double.PositiveInfinity, 0d, 0d, double.PositiveInfinity)]
+ [InlineData(-0.5d, 0d, Math.PI * 2 / 3)]
+ [InlineData(-1d, 0d, Math.PI)]
+ [InlineData(-2d, 0d, Math.PI, 1.3169578969248166d)]
+ [InlineData(double.NegativeInfinity, 0d, Math.PI, double.PositiveInfinity)]
+ [InlineData(2d, 3d, 1.0001435424737972, -1.9833870299165357)]
+ [InlineData(2d, -3d, 1.0001435424737972, 1.9833870299165357)]
+ [InlineData(-2d, 3d, 2.141449111115996, -1.9833870299165357)]
+ [InlineData(-2d, -3d, 2.141449111115996, 1.9833870299165357)]
+ public void MathTrig_AcosComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Acos(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d)]
+ [InlineData(double.Epsilon, 0d, double.Epsilon)]
+ [InlineData(0.5d, 0d, 0.46364760900080609d)]
+ [InlineData(1d, 0d, Math.PI / 4)]
+ [InlineData(2d, 0d, 1.1071487177940904d)]
+ [InlineData(double.PositiveInfinity, 0d, Math.PI / 2)]
+ [InlineData(-0.5d, 0d, -0.46364760900080609d)]
+ [InlineData(-1d, 0d, -Math.PI / 4)]
+ [InlineData(-2d, 0d, -1.1071487177940904d)]
+ [InlineData(double.NegativeInfinity, 0d, -Math.PI / 2)]
+ [InlineData(2d, 3d, 1.4099210495965755, 0.22907268296853878)]
+ [InlineData(2d, -3d, 1.4099210495965755, -0.22907268296853878)]
+ [InlineData(-2d, 3d, -1.4099210495965755, 0.22907268296853878)]
+ [InlineData(-2d, -3d, -1.4099210495965755, -0.22907268296853878)]
+ public void MathTrig_AtanComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Atan(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, Math.PI / 2, double.PositiveInfinity)]
+ [InlineData(double.Epsilon * 10000000000000000, 0d, Math.PI / 2, 708.2918576140364d)]
+ [InlineData(-double.Epsilon, 0d, -Math.PI / 2, double.PositiveInfinity)]
+ [InlineData(0.5d, 0d, Math.PI / 2, 1.3169578969248166d)]
+ [InlineData(1d, 0d, Math.PI / 2)]
+ [InlineData(2d, 0d, 0.52359877559829893d)] //PI / 6
+ [InlineData(double.PositiveInfinity, 0d, 0d)]
+ [InlineData(-0.5d, 0d, -Math.PI / 2, 1.3169578969248166d)]
+ [InlineData(-1d, 0d, -Math.PI / 2)]
+ [InlineData(-2d, 0d, -0.52359877559829893d)] //PI / 6
+ [InlineData(double.NegativeInfinity, 0d, 0d)]
+ [InlineData(2d, 3d, 0.150385604327862, -0.23133469857397337)]
+ [InlineData(2d, -3d, 0.150385604327862, 0.23133469857397337)]
+ [InlineData(-2d, 3d, -0.150385604327862, -0.23133469857397337)]
+ [InlineData(-2d, -3d, -0.150385604327862, 0.23133469857397337)]
+ public void MathTrig_AcscComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Acsc(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, 0d, double.PositiveInfinity)]
+ [InlineData(0.5d, 0d, 0d, 1.3169578969248166d)]
+ [InlineData(1d, 0d, 0d)]
+ [InlineData(2d, 0d, 1.0471975511965979d)] //PI / 3
+ [InlineData(double.PositiveInfinity, 0d, Math.PI / 2)]
+ [InlineData(-0.5d, 0d, Math.PI, 1.3169578969248166d)]
+ [InlineData(-1d, 0d, Math.PI)]
+ [InlineData(-2d, 0d, Math.PI * 2 / 3)]
+ [InlineData(double.NegativeInfinity, 0d, Math.PI / 2)]
+ [InlineData(2d, 3d, 1.4204107224670346, 0.23133469857397337)]
+ [InlineData(2d, -3d, 1.4204107224670346, -0.23133469857397337)]
+ [InlineData(-2d, 3d, 1.7211819311227585, 0.23133469857397337)]
+ [InlineData(-2d, -3d, 1.7211819311227585, -0.23133469857397337)]
+ public void MathTrig_AsecComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Asec(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, Math.PI / 2)]
+ [InlineData(double.Epsilon, 0d, Math.PI / 2 - double.Epsilon)]
+ [InlineData(1E-10, 0d, 1.5707963266948965d, 0)]
+ [InlineData(-1E-10, 0d, Math.PI - 1.5707963266948965d, 0)]
+ [InlineData(-double.Epsilon, 0d, Math.PI / 2 - double.Epsilon)]
+ [InlineData(0.5d, 0d, 1.1071487177940904d)]
+ [InlineData(1d, 0d, Math.PI / 4)]
+ [InlineData(2d, 0d, 0.46364760900080609d)]
+ [InlineData(double.PositiveInfinity, 0d, 0d)]
+ [InlineData(-0.5d, 0d, Math.PI - 1.1071487177940904d)]
+ [InlineData(-1d, 0d, Math.PI - Math.PI / 4)]
+ [InlineData(-2d, 0d, Math.PI - 0.46364760900080609d)]
+ [InlineData(double.NegativeInfinity, 0d, Math.PI)]
+ [InlineData(2d, 3d, 0.16087527719832112, -0.22907268296853883)]
+ [InlineData(2d, -3d, 0.16087527719832112, 0.22907268296853883)]
+ [InlineData(-2d, 3d, 2.980717376391472, -0.22907268296853883)]
+ [InlineData(-2d, -3d, 2.980717376391472, 0.22907268296853883)]
+ public void MathTrig_AcotComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Acot(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d)]
+ [InlineData(double.Epsilon, 0d, double.Epsilon)]
+ [InlineData(1E-10, 0d, 1E-10)]
+ [InlineData(-1E-10, 0d, -1E-10)]
+ [InlineData(0.5d, 0d, 0.52109530549374738d)]
+ [InlineData(1d, 0d, 1.1752011936438014d)]
+ [InlineData(2d, 0d, 3.6268604078470186d)]
+ [InlineData(10, 0d, 11013.232874703393, 0d)]
+ [InlineData(100, 0d, 1.3440585709080678E+43d, 0d)]
+ [InlineData(double.PositiveInfinity, 0d, double.PositiveInfinity)]
+ [InlineData(-0.5d, 0d, -0.52109530549374738d)]
+ [InlineData(-1d, 0d, -1.1752011936438014d)]
+ [InlineData(-2d, 0d, -3.6268604078470186d)]
+ [InlineData(double.NegativeInfinity, 0d, double.NegativeInfinity)]
+ [InlineData(2d, 3d, -3.5905645899857794d, 0.5309210862485197d)]
+ [InlineData(2d, -3d, -3.5905645899857794d, -0.5309210862485197d)]
+ [InlineData(-2d, 3d, 3.5905645899857794d, 0.5309210862485197d)]
+ [InlineData(-2d, -3d, 3.5905645899857794d, -0.5309210862485197d)]
+ public void MathTrig_SinhComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Sinh(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 1d)]
+ [InlineData(double.Epsilon, 0d, 1d)]
+ [InlineData(0.5d, 0d, 1.1276259652063807d)]
+ [InlineData(1d, 0d, 1.5430806348152437d)]
+ [InlineData(2d, 0d, 3.7621956910836314d)]
+ [InlineData(double.PositiveInfinity, 0d, double.PositiveInfinity)]
+ [InlineData(-0.5d, 0d, 1.1276259652063807d)]
+ [InlineData(-1d, 0d, 1.5430806348152437d)]
+ [InlineData(-2d, 0d, 3.7621956910836314d)]
+ [InlineData(double.NegativeInfinity, 0d, double.PositiveInfinity)]
+ [InlineData(2d, 3d, -3.7245455049153224, 0.5118225699873845)]
+ [InlineData(2d, -3d, -3.7245455049153224, -0.5118225699873845)]
+ [InlineData(-2d, 3d, -3.7245455049153224, -0.5118225699873845)]
+ [InlineData(-2d, -3d, -3.7245455049153224, 0.5118225699873845)]
+ public void MathTrig_CoshComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Cosh(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d)]
+ [InlineData(double.Epsilon, 0d, double.Epsilon)]
+ [InlineData(0.5d, 0d, 0.46211715726000974d)]
+ [InlineData(1d, 0d, 0.76159415595576485d)]
+ [InlineData(2d, 0d, 0.9640275800758169d)]
+ [InlineData(double.PositiveInfinity, 0d, 1d)]
+ [InlineData(-0.5d, 0d, -0.46211715726000974d)]
+ [InlineData(-1d, 0d, -0.76159415595576485d)]
+ [InlineData(-2d, 0d, -0.9640275800758169d)]
+ [InlineData(double.NegativeInfinity, 0d, -1d)]
+ [InlineData(2d, 3d, 0.9653858790221331, -0.009884375038322494)]
+ [InlineData(2d, -3d, 0.9653858790221331, 0.009884375038322494)]
+ [InlineData(-2d, 3d, -0.9653858790221331, -0.009884375038322494)]
+ [InlineData(-2d, -3d, -0.9653858790221331, 0.009884375038322494)]
+ public void MathTrig_TanhComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Tanh(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.PositiveInfinity)]
+ [InlineData(0.5d, 0d, 1 / 0.52109530549374738d)]
+ [InlineData(1d, 0d, 1 / 1.1752011936438014d)]
+ [InlineData(2d, 0d, 1 / 3.6268604078470186d)]
+ [InlineData(double.PositiveInfinity, 0d, 0d)]
+ [InlineData(-0.5d, 0d, 1 / -0.52109530549374738d)]
+ [InlineData(-1d, 0d, 1 / -1.1752011936438014d)]
+ [InlineData(-2d, 0d, 1 / -3.6268604078470186d)]
+ [InlineData(double.NegativeInfinity, 0d, 0d)]
+ [InlineData(2d, 3d, -0.2725486614629402, -0.04030057885689153)]
+ [InlineData(2d, -3d, -0.2725486614629402, 0.04030057885689153)]
+ [InlineData(-2d, 3d, 0.2725486614629402, -0.04030057885689153)]
+ [InlineData(-2d, -3d, 0.2725486614629402, 0.04030057885689153)]
+ public void MathTrig_CschComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Csch(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 1d)]
+ [InlineData(double.Epsilon, 0d, 1d)]
+ [InlineData(0.5d, 0d, 1 / 1.1276259652063807d)]
+ [InlineData(1d, 0d, 1 / 1.5430806348152437d)]
+ [InlineData(2d, 0d, 1 / 3.7621956910836314d)]
+ [InlineData(double.PositiveInfinity, 0d, 0d)]
+ [InlineData(-0.5d, 0d, 1 / 1.1276259652063807d)]
+ [InlineData(-1d, 0d, 1 / 1.5430806348152437d)]
+ [InlineData(-2d, 0d, 1 / 3.7621956910836314d)]
+ [InlineData(double.NegativeInfinity, 0d, 0d)]
+ [InlineData(2d, 3d, -0.2635129751583893, -0.036211636558768516)]
+ [InlineData(2d, -3d, -0.2635129751583893, 0.036211636558768516)]
+ [InlineData(-2d, 3d, -0.2635129751583893, 0.036211636558768516)]
+ [InlineData(-2d, -3d, -0.2635129751583893, -0.036211636558768516)]
+ public void MathTrig_SechComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Sech(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.PositiveInfinity)]
+ [InlineData(0.5d, 0d, 1 / 0.46211715726000974d)]
+ [InlineData(1d, 0d, 1 / 0.76159415595576485d)]
+ [InlineData(2d, 0d, 1 / 0.9640275800758169d)]
+ [InlineData(double.PositiveInfinity, 0d, 1d)]
+ [InlineData(-0.5d, 0d, 1 / -0.46211715726000974d)]
+ [InlineData(-1d, 0d, 1 / -0.76159415595576485d)]
+ [InlineData(-2d, 0d, 1 / -0.9640275800758169d)]
+ [InlineData(double.NegativeInfinity, 0d, -1d)]
+ [InlineData(2d, 3d, 1.0357466377649955, 0.0106047834703371)]
+ [InlineData(2d, -3d, 1.0357466377649955, -0.0106047834703371)]
+ [InlineData(-2d, 3d, -1.0357466377649955, 0.0106047834703371)]
+ [InlineData(-2d, -3d, -1.0357466377649955, -0.0106047834703371)]
+ public void MathTrig_CothComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Coth(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d)]
+ [InlineData(double.Epsilon, 0d, 0d)]
+ [InlineData(0.5d, 0d, 0.48121182505960347d)]
+ [InlineData(1d, 0d, 0.88137358701954294d)]
+ [InlineData(2d, 0d, 1.4436354751788103d)]
+ [InlineData(double.PositiveInfinity, 0d, double.PositiveInfinity)]
+ [InlineData(-0.5d, 0d, -0.48121182505960347d)]
+ [InlineData(-1d, 0d, -0.88137358701954294d)]
+ [InlineData(-2d, 0d, -1.4436354751788103d)]
+ [InlineData(double.NegativeInfinity, 0d, double.NegativeInfinity)]
+ [InlineData(double.MinValue, 0d, double.NegativeInfinity)]
+ [InlineData(double.MaxValue, 0d, double.PositiveInfinity)]
+ [InlineData(2d, 3d, 1.9686379257930964, 0.9646585044076028)]
+ [InlineData(2d, -3d, 1.9686379257930964, -0.9646585044076028)]
+ [InlineData(-2d, 3d, -1.9686379257930964, 0.9646585044076028)]
+ [InlineData(-2d, -3d, -1.9686379257930964, -0.9646585044076028)]
+ public void MathTrig_AsinhComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Asinh(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d, Math.PI / 2)]
+ [InlineData(double.Epsilon, 0d, 0d, Math.PI / 2)]
+ [InlineData(0.5d, 0d, 0d, Math.PI / 3)]
+ [InlineData(1d, 0d, 0d)]
+ [InlineData(2d, 0d, 1.3169578969248166d)]
+ [InlineData(double.PositiveInfinity, 0d, double.PositiveInfinity)]
+ [InlineData(-0.5d, 0d, 0d, 2.0943951023931957d)]
+ [InlineData(-1d, 0d, 0d, Math.PI)]
+ [InlineData(-2d, 0d, -1.3169578969248164d, Math.PI)]
+ [InlineData(double.NegativeInfinity, 0d, double.PositiveInfinity)]
+ [InlineData(double.MinValue, 0d, double.PositiveInfinity)]
+ [InlineData(double.MaxValue, 0d, double.PositiveInfinity)]
+ [InlineData(2d, 3d, 1.9833870299165355, 1.0001435424737972)]
+ [InlineData(2d, -3d, 1.9833870299165355, -1.0001435424737972)]
+ [InlineData(-2d, 3d, -1.9833870299165355, -2.1414491111159957)]
+ [InlineData(-2d, -3d, -1.9833870299165355, 2.1414491111159957)]
+ public void MathTrig_AcoshComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Acosh(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d)]
+ [InlineData(double.Epsilon, 0d, 0d)]
+ [InlineData(0.5d, 0d, 0.54930614433405489d)]
+ [InlineData(1d, 0d, double.PositiveInfinity)]
+ [InlineData(2d, 0d, 0.5493061443340549, -Math.PI / 2)]
+ [InlineData(double.PositiveInfinity, 0d, 0d, -Math.PI / 2)]
+ [InlineData(-0.5d, 0d, -0.54930614433405489d)]
+ [InlineData(-1d, 0d, double.NegativeInfinity)]
+ [InlineData(-2d, 0d, -0.5493061443340549, Math.PI / 2)]
+ [InlineData(double.NegativeInfinity, 0d, 0d, Math.PI / 2)]
+ [InlineData(double.MinValue, 0d, 0d, Math.PI / 2)]
+ [InlineData(double.MaxValue, 0d, 0d, -Math.PI / 2)]
+ [InlineData(2d, 3d, 0.14694666622552977, 1.3389725222944935)]
+ [InlineData(2d, -3d, 0.14694666622552977, -1.3389725222944935)]
+ [InlineData(-2d, 3d, -0.14694666622552977, 1.3389725222944935)]
+ [InlineData(-2d, -3d, -0.14694666622552977, -1.3389725222944935)]
+ public void MathTrig_AtanhComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Atanh(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.PositiveInfinity)]
+ [InlineData(-double.Epsilon, 0d, double.NegativeInfinity)]
+ [InlineData(0.5d, 0d, 1.4436354751788103d)]
+ [InlineData(1d, 0d, 0.88137358701954294d)]
+ [InlineData(2d, 0d, 0.48121182505960347d)]
+ [InlineData(double.PositiveInfinity, 0d, 0d)]
+ [InlineData(-0.5d, 0d, -1.4436354751788103d)]
+ [InlineData(-1d, 0d, -0.88137358701954294d)]
+ [InlineData(-2d, 0d, -0.48121182505960347d)]
+ [InlineData(double.NegativeInfinity, 0d, 0d)]
+ [InlineData(2d, 3d, 0.15735549884498526, -0.22996290237720785)]
+ [InlineData(2d, -3d, 0.15735549884498526, 0.22996290237720785)]
+ [InlineData(-2d, 3d, -0.15735549884498526, -0.22996290237720785)]
+ [InlineData(-2d, -3d, -0.15735549884498526, 0.22996290237720785)]
+ public void MathTrig_AcschComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Acsch(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, double.NaN, double.NaN)]
+ [InlineData(double.Epsilon, 0d, double.PositiveInfinity)]
+ [InlineData(-double.Epsilon, 0d, double.PositiveInfinity, Math.PI)]
+ [InlineData(0.5d, 0d, 1.3169578969248166d)]
+ [InlineData(1d, 0d, 0d)]
+ [InlineData(2d, 0d, 0d, Math.PI / 3)]
+ [InlineData(double.PositiveInfinity, 0d, 0d, Math.PI / 2)]
+ [InlineData(-0.5d, 0d, -1.3169578969248164d, Math.PI)]
+ [InlineData(-1d, 0d, 0d, Math.PI)]
+ [InlineData(-2d, 0d, 0d, 2.0943951023931957d)] //2PI / 3
+ [InlineData(double.NegativeInfinity, 0d, 0d, Math.PI / 2)]
+ [InlineData(double.MinValue, 0d, 0d, Math.PI / 2)]
+ [InlineData(double.MaxValue, 0d, 0d, Math.PI / 2)]
+ [InlineData(2d, 3d, 0.23133469857397337, -1.4204107224670346)]
+ [InlineData(2d, -3d, 0.23133469857397337, 1.4204107224670346)]
+ [InlineData(-2d, 3d, -0.23133469857397346, 1.7211819311227585)]
+ [InlineData(-2d, -3d, -0.23133469857397346, -1.7211819311227585)]
+ public void MathTrig_AsechComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Asech(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, 0d, double.NaN, double.NaN)]
+ [InlineData(0d, 0d, 0d, -Math.PI / 2)]
+ [InlineData(double.Epsilon, 0d, 0d, -Math.PI / 2)]
+ [InlineData(0.5d, 0d, 0.5493061443340549, -Math.PI / 2)]
+ [InlineData(1d, 0d, double.PositiveInfinity)]
+ [InlineData(2d, 0d, 0.54930614433405489d)]
+ [InlineData(double.PositiveInfinity, 0d, 0d)]
+ [InlineData(-0.5d, 0d, -0.5493061443340549, -Math.PI / 2)]
+ [InlineData(-1d, 0d, double.NegativeInfinity)]
+ [InlineData(-2d, 0d, -0.54930614433405489d)]
+ [InlineData(double.NegativeInfinity, 0d, 0d)]
+ [InlineData(2d, 3d, 0.14694666622552977, -0.23182380450040305)]
+ [InlineData(2d, -3d, 0.14694666622552977, 0.23182380450040305)]
+ [InlineData(-2d, 3d, -0.14694666622552977, -0.23182380450040305)]
+ [InlineData(-2d, -3d, -0.14694666622552977, 0.23182380450040305)]
+ public void MathTrig_AcothComplexParam_ExpectedValue(double a, double b, double expectedReal, double expectedImaginary = 0)
+ {
+ var expectedValue = new Complex(expectedReal, expectedImaginary);
+
+ var value = MathTrig.Acoth(new Complex(a, b));
+
+ Assert.Equal(expectedValue, value);
+ }
+}
\ No newline at end of file
diff --git a/MathTrigonometric.Tests/MathTrigTests.cs b/MathTrigonometric.Tests/MathTrigTests.cs
index 76ac296..c639227 100644
--- a/MathTrigonometric.Tests/MathTrigTests.cs
+++ b/MathTrigonometric.Tests/MathTrigTests.cs
@@ -1,6 +1,6 @@
namespace MathTrigonometric.Tests;
-public class MathTrigTests
+public partial class MathTrigTests
{
[Theory]
[InlineData(double.NaN, double.NaN)]
@@ -258,8 +258,6 @@ public void MathTrig_Acot_ExpectedValue(double d, double expectedValue)
{
var value = MathTrig.Acot(d);
- var v = MathTrig.Cos(2d * MathTrig.Acos(2d));
-
Assert.Equal(expectedValue, value);
}
diff --git a/MathTrigonometric/MathTrig.cs b/MathTrigonometric/MathTrig.cs
index c73cce3..c189644 100644
--- a/MathTrigonometric/MathTrig.cs
+++ b/MathTrigonometric/MathTrig.cs
@@ -1,4 +1,5 @@
using System;
+using System.Numerics;
namespace MathTrigonometric;
@@ -26,6 +27,22 @@ public static double Sin(double a)
return Math.Sin(a);
}
+ ///
+ /// Sine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The sine of the value.
+ /// This method returns NaN if equals
+ /// NaN, NegativeInfinity, or PositiveInfinity.
+ ///
+ public static Complex Sin(Complex z)
+ {
+ var sin = Math.Sin(z.Real);
+ var cos = Math.Cos(z.Real);
+ return new Complex(sin * Math.Cosh(z.Imaginary), cos * Math.Sinh(z.Imaginary));
+ }
+
///
/// Cosine of the angle is ratio of the adjacent leg to hypotenuse.
///
@@ -41,6 +58,22 @@ public static double Cos(double a)
return Math.Cos(a);
}
+ ///
+ /// Cosine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The cosine of the value.
+ /// This method returns NaN if equals
+ /// NaN, NegativeInfinity, or PositiveInfinity.
+ ///
+ public static Complex Cos(Complex z)
+ {
+ var sin = Math.Sin(z.Real);
+ var cos = Math.Cos(z.Real);
+ return new Complex(cos * Math.Cosh(z.Imaginary), -sin * Math.Sinh(z.Imaginary));
+ }
+
///
/// Tangent of the angle is ratio of the opposite leg to adjacent one.
///
@@ -60,6 +93,43 @@ public static double Tan(double a)
return Math.Sin(a) / cos;
}
+ ///
+ /// Tangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The tangent of the value.
+ /// This method returns NaN if equals
+ /// NaN, NegativeInfinity, or PositiveInfinity.
+ ///
+ public static Complex Tan(Complex z)
+ {
+ // tan z = sin z / cos z, but to avoid unnecessary repeated trig computations, use
+ // tan z = (sin(2x) + i sinh(2y)) / (cos(2x) + cosh(2y))
+ // (see Abramowitz & Stegun 4.3.57 or derive by hand), and compute trig functions here.
+
+ // This approach does not work for |y| > ~355, because sinh(2y) and cosh(2y) overflow,
+ // even though their ratio does not. In that case, divide through by cosh to get:
+ // tan z = (sin(2x) / cosh(2y) + i \tanh(2y)) / (1 + cos(2x) / cosh(2y))
+ // which correctly computes the (tiny) real part and the (normal-sized) imaginary part.
+
+ double x2 = 2.0 * z.Real;
+ double y2 = 2.0 * z.Imaginary;
+ var sin = Math.Sin(x2);
+ var cos = Math.Cos(x2);
+ double cosh = Math.Cosh(y2);
+ if (Math.Abs(z.Imaginary) <= 4.0)
+ {
+ double D = cos + cosh;
+ return new Complex(sin / D, Math.Sinh(y2) / D);
+ }
+ else
+ {
+ double D = 1.0 + cos / cosh;
+ return new Complex(sin / cosh / D, Math.Tanh(y2) / D);
+ }
+ }
+
///
/// Cosecant of the angle is ratio of the hypotenuse to opposite leg.
///
@@ -79,6 +149,24 @@ public static double Csc(double a)
return 1.0 / sin;
}
+ ///
+ /// Cosecant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The cosecant of the value.
+ /// This method returns NaN if equals
+ /// Zero, NaN, NegativeInfinity, or PositiveInfinity.
+ ///
+ public static Complex Csc(Complex z)
+ {
+ var sin = Sin(z);
+ if (sin == Complex.Zero)
+ return new Complex(double.NaN, double.NaN);
+
+ return Complex.One / sin;
+ }
+
///
/// Secant of the angle is ratio of the hypotenuse to adjacent leg.
///
@@ -98,6 +186,24 @@ public static double Sec(double a)
return 1.0 / cos;
}
+ ///
+ /// Secant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The secant of the value.
+ /// This method returns NaN if equals
+ /// NaN, NegativeInfinity, or PositiveInfinity.
+ ///
+ public static Complex Sec(Complex z)
+ {
+ var cos = Cos(z);
+ if (cos == Complex.Zero)
+ return new Complex(double.NaN, double.NaN);
+
+ return Complex.One / cos;
+ }
+
///
/// Cotangent of the angle is ratio of the adjacent leg to opposite one.
///
@@ -117,12 +223,30 @@ public static double Cot(double a)
return Math.Cos(a) / sin;
}
+ ///
+ /// Cotangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The cotangent of the value.
+ /// This method returns NaN if equals
+ /// Zero, NaN, NegativeInfinity, or PositiveInfinity.
+ ///
+ public static Complex Cot(Complex z)
+ {
+ var sin = Math.Sin(z.Real);
+ var cos = Math.Cos(z.Real);
+ var coshI = Math.Cosh(z.Imaginary);
+ var sinhI = Math.Sinh(z.Imaginary);
+ return new Complex(cos * coshI, -sin * sinhI) / new Complex(sin * coshI, cos * sinhI);
+ }
+
#endregion
#region Inverse Trigonometric Functions
///
- /// Arc sine is inverse of the function.
+ /// Arc sine is inverse of the function.
///
/// Value in range: [-1, 1].
///
@@ -137,7 +261,20 @@ public static double Asin(double d)
}
///
- /// Arc cosine is inverse of the function.
+ /// Arc sine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc sine of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Asin(Complex z)
+ {
+ return Complex.Asin(z);
+ }
+
+ ///
+ /// Arc cosine is inverse of the function.
///
/// Value in range: [-1, 1].
///
@@ -152,7 +289,20 @@ public static double Acos(double d)
}
///
- /// Arc tangent is inverse of the function.
+ /// Arc cosine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc cosine of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Acos(Complex z)
+ {
+ return Complex.Acos(z);
+ }
+
+ ///
+ /// Arc tangent is inverse of the function.
///
/// Any real number.
///
@@ -168,7 +318,26 @@ public static double Atan(double d)
}
///
- /// Arc cosecant is inverse of the function.
+ /// Arc tangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc tangent of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Atan(Complex z)
+ {
+ if (IsPositiveInfinity(z))
+ return new Complex(Math.PI / 2, 0);
+
+ if (IsNegativeInfinity(z))
+ return new Complex(-Math.PI / 2, 0);
+
+ return Complex.Atan(z);
+ }
+
+ ///
+ /// Arc cosecant is inverse of the function.
///
/// Value in range: (-∞, -1] ∪ [1, ∞).
///
@@ -180,11 +349,24 @@ public static double Atan(double d)
///
public static double Acsc(double d)
{
- return d == 0.0 ? double.NaN : Math.Asin(1.0 / d);
+ return Math.Asin(1.0 / d);
}
///
- /// Arc secant is inverse of the function.
+ /// Arc cosecant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc cosecant of the value.
+ /// This method returns NaN if equals Zero or NaN.
+ ///
+ public static Complex Acsc(Complex z)
+ {
+ return Complex.Asin(Complex.One / z);
+ }
+
+ ///
+ /// Arc secant is inverse of the function.
///
/// Value in range: (-∞, -1] ∪ [1, ∞).
///
@@ -196,11 +378,24 @@ public static double Acsc(double d)
///
public static double Asec(double d)
{
- return d == 0.0 ? double.NaN : Math.Acos(1.0 / d);
+ return Math.Acos(1.0 / d);
+ }
+
+ ///
+ /// Arc secant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc secant of the value.
+ /// This method returns NaN if equals Zero or NaN.
+ ///
+ public static Complex Asec(Complex z)
+ {
+ return Complex.Acos(Complex.One / z);
}
///
- /// Arc cotangent is inverse of the > function.
+ /// Arc cotangent is inverse of the > function.
///
/// Any real number.
///
@@ -214,11 +409,35 @@ public static double Acot(double d)
{
//the Trigonometric Symmetry is applied: arccot(−x) = π − arccot(x)
if (IsNegative(d))
- return Math.PI - Math.Atan(1 / -d);
+ return Math.PI - Math.Atan(1.0 / -d);
return Math.Atan(1.0 / d);
}
+ ///
+ /// Arc cotangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc cotangent of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Acot(Complex z)
+ {
+ if (z == Complex.Zero)
+ return new Complex(Math.PI / 2, 0d);
+
+ var oneOverZ = Complex.One / z;
+ if (IsInfinity(oneOverZ))
+ return new Complex(Math.PI / 2, 0d);
+
+ //the Trigonometric Symmetry is applied: arccot(−z) = π − arccot(z)
+ if (IsNegative(z.Real))
+ return Math.PI - Complex.Atan(-oneOverZ);
+
+ return Complex.Atan(oneOverZ);
+ }
+
#endregion
#region Hyperbolic Trigonometric Functions
@@ -241,6 +460,24 @@ public static double Sinh(double x)
return Math.Sinh(x);
}
+ ///
+ /// Hyperbolic sine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The hyperbolic sine of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Sinh(Complex z)
+ {
+ if (IsInfinity(z))
+ return z;
+
+ // Use sinh(z) = -i sin(iz) to compute via sin(z).
+ var sin = Sin(new Complex(-z.Imaginary, z.Real));
+ return new Complex(sin.Imaginary, -sin.Real);
+ }
+
///
/// Hyperbolic cosine is defined as Cosh(x) = (e^x + e^−x)/2.
///
@@ -259,6 +496,23 @@ public static double Cosh(double x)
return Math.Cosh(x);
}
+ ///
+ /// Hyperbolic cosine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The hyperbolic cosine of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Cosh(Complex z)
+ {
+ if (IsInfinity(z))
+ return new Complex(double.PositiveInfinity, 0);
+
+ // Use cosh(z) = cos(iz) to compute via cos(z).
+ return Cos(new Complex(-z.Imaginary, z.Real));
+ }
+
///
/// Hyperbolic tangent is defined as Tanh(x) = (e^x − e^−x)/(e^x + e^−x).
///
@@ -275,6 +529,21 @@ public static double Tanh(double x)
return Math.Tanh(x);
}
+ ///
+ /// Hyperbolic tangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The hyperbolic tangent of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Tanh(Complex z)
+ {
+ // Use tanh(z) = -i tan(iz) to compute via tan(z).
+ var tan = Tan(new Complex(-z.Imaginary, z.Real));
+ return new Complex(tan.Imaginary, -tan.Real);
+ }
+
///
/// Hyperbolic cosecant is defined as Csch(x) = 2/(e^x − e^−x).
///
@@ -295,6 +564,23 @@ public static double Csch(double x)
return 1.0 / sin;
}
+ ///
+ /// Hyperbolic cosecant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The hyperbolic cosecant of the value.
+ /// This method returns NaN if equals Zero or NaN.
+ ///
+ public static Complex Csch(Complex z)
+ {
+ var sin = Sinh(z);
+ if (sin == Complex.Zero)
+ return new Complex(double.NaN, double.NaN);
+
+ return Complex.One / sin;
+ }
+
///
/// Hyperbolic secant is defined as Sech(x) = 2/(e^x + e^−x).
///
@@ -309,12 +595,23 @@ public static double Csch(double x)
public static double Sech(double x)
{
var cos = Math.Cosh(x);
- if (cos == 0.0)
- return double.NaN;
-
return 1.0 / cos;
}
+ ///
+ /// Hyperbolic secant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The hyperbolic secant of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Sech(Complex z)
+ {
+ var cos = Cosh(z);
+ return Complex.One / cos;
+ }
+
///
/// Hyperbolic cotangent is defined as Coth(x) = (e^x + e^−x)/(e^x − e^−x).
///
@@ -334,12 +631,28 @@ public static double Coth(double x)
return 1.0 / Math.Tanh(x);
}
+ ///
+ /// Hyperbolic cotangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The hyperbolic cotangent of the value.
+ /// This method returns NaN if equals Zero or NaN.
+ ///
+ public static Complex Coth(Complex z)
+ {
+ if (z == Complex.Zero)
+ return new Complex(double.NaN, double.NaN);
+
+ return Complex.One / Tanh(z);
+ }
+
#endregion
#region Inverse Hyperbolic Trigonometric Functions
///
- /// Arc-hyperbolic sine is inverse of the function is defined as Arsinh(x) = ln[x + √(x^2 + 1)].
+ /// Arc-hyperbolic sine is inverse of the function is defined as Arsinh(x) = ln[x + √(x^2 + 1)].
///
/// Any real number.
///
@@ -353,8 +666,8 @@ public static double Coth(double x)
///
public static double Asinh(double x)
{
- if (double.IsNegativeInfinity(x))
- return double.NegativeInfinity;
+ if (double.IsInfinity(x))
+ return x;
//the Trigonometric Symmetry is applied: arsinh(−x)=−arsinh(x)
if (IsNegative(x))
@@ -364,7 +677,27 @@ public static double Asinh(double x)
}
///
- /// Arc-hyperbolic cosine is inverse of the function is defined as Arcosh(x) = ln[x + √(x^2 - 1)].
+ /// Arc-hyperbolic sine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc-hyperbolic sine of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Asinh(Complex z)
+ {
+ if (IsInfinity(z))
+ return z;
+
+ //the Trigonometric Symmetry is applied: arsinh(−z)=−arsinh(z)
+ if (IsNegative(z.Real))
+ return -Complex.Log(-z + Complex.Sqrt(z * z + Complex.One));
+
+ return Complex.Log(z + Complex.Sqrt(z * z + Complex.One));
+ }
+
+ ///
+ /// Arc-hyperbolic cosine is inverse of the function is defined as Arcosh(x) = ln[x + √(x^2 - 1)].
///
/// Value in range: [1, +∞).
///
@@ -385,7 +718,23 @@ public static double Acosh(double x)
}
///
- /// Arc-hyperbolic tangent is inverse of the function
+ /// Arc-hyperbolic cosine of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc-hyperbolic cosine of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Acosh(Complex z)
+ {
+ if (IsInfinity(z))
+ return new Complex(double.PositiveInfinity, 0d);
+
+ return Complex.Log(z + Complex.Sqrt(z * z - Complex.One));
+ }
+
+ ///
+ /// Arc-hyperbolic tangent is inverse of the function
/// is defined as Artanh(x) = ln[(1 + x)/(1 − x)]/2.
///
/// Value in range: (-1, 1).
@@ -412,7 +761,32 @@ public static double Atanh(double x)
}
///
- /// Arc-hyperbolic cosecant is inverse of the function
+ /// Arc-hyperbolic tangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc-hyperbolic tangent of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Atanh(Complex z)
+ {
+ if (z == Complex.One)
+ return new Complex(double.PositiveInfinity, 0d);
+
+ if (z == -Complex.One)
+ return new Complex(double.NegativeInfinity, 0d);
+
+ if (IsPositiveInfinity(z))
+ return new Complex(0d, -Math.PI / 2);
+
+ if (IsNegativeInfinity(z))
+ return new Complex(0d, Math.PI / 2);
+
+ return Complex.Log((1.0 + z) / (1.0 - z)) / 2.0;
+ }
+
+ ///
+ /// Arc-hyperbolic cosecant is inverse of the function
/// is defined as Arcsch(x) = ln[1/x + √(1/(x^2) + 1)].
///
/// Value in range: (−∞, 0)∪(0, +∞).
@@ -436,7 +810,34 @@ public static double Acsch(double x)
}
///
- /// Arc-hyperbolic secant is inverse of the function
+ /// Arc-hyperbolic cosecant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc-hyperbolic cosecant of the value.
+ /// This method returns NaN if equals Zero or NaN.
+ ///
+ public static Complex Acsch(Complex z)
+ {
+ if (z == Complex.Zero)
+ return new Complex(double.NaN, double.NaN);
+
+ if (IsInfinity(z))
+ return Complex.Zero;
+
+ var zz = z * z;
+ if (zz == Complex.Zero)
+ return new Complex(IsNegative(z.Real) ? double.NegativeInfinity : double.PositiveInfinity, 0d);
+
+ //the Trigonometric Symmetry is applied: arcsch(−z)=−arcsch(z)
+ if (IsNegative(z.Real))
+ return -Complex.Log(1.0 / -z + Complex.Sqrt(1.0 / zz + 1.0));
+
+ return Complex.Log(1.0 / z + Complex.Sqrt(1.0 / zz + 1.0));
+ }
+
+ ///
+ /// Arc-hyperbolic secant is inverse of the function
/// is defined as Arsech(x) = ln([1 + √(1 − x^2)]/x).
///
/// Value in range: (0, 1].
@@ -455,7 +856,30 @@ public static double Asech(double x)
}
///
- /// Arc-hyperbolic cotangent is inverse of the function
+ /// Arc-hyperbolic secant of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc-hyperbolic secant of the value.
+ /// This method returns NaN if equals Zero or NaN.
+ ///
+ public static Complex Asech(Complex z)
+ {
+ if (z == Complex.Zero)
+ return new Complex(double.NaN, double.NaN);
+
+ if (IsInfinity(z))
+ return new Complex(0d, Math.PI / 2);
+
+ var zz = z * z;
+ if (zz == Complex.Zero)
+ return new Complex(double.PositiveInfinity, IsNegative(z.Real) ? Math.PI : 0d);
+
+ return Complex.Log(1.0 / z + Complex.Sqrt(1.0 / zz - 1.0));
+ }
+
+ ///
+ /// Arc-hyperbolic cotangent is inverse of the function
/// is defined as Arcoth(x) = ln[(1 + x)/(x − 1)]/2.
///
/// Value in range: (−∞, -1)∪(1, +∞).
@@ -477,6 +901,28 @@ public static double Acoth(double x)
return Math.Log((x + 1.0) / (x - 1.0)) / 2.0;
}
+ ///
+ /// Arc-hyperbolic cotangent of the specific complex number.
+ ///
+ /// A complex number.
+ ///
+ /// The arc-hyperbolic cotangent of the value.
+ /// This method returns NaN if equals NaN.
+ ///
+ public static Complex Acoth(Complex z)
+ {
+ if (z == Complex.One)
+ return new Complex(double.PositiveInfinity, 0d);
+
+ if (z == -Complex.One)
+ return new Complex(double.NegativeInfinity, 0d);
+
+ if (IsInfinity(z))
+ return Complex.Zero;
+
+ return Complex.Log((z + 1.0) / (z - 1.0)) / 2.0;
+ }
+
#endregion
///
@@ -503,4 +949,19 @@ private static bool IsNegative(double d)
{
return BitConverter.DoubleToInt64Bits(d) < 0;
}
+
+ private static bool IsNegativeInfinity(Complex value)
+ {
+ return (value.Imaginary == 0.0) && double.IsNegativeInfinity(value.Real);
+ }
+
+ private static bool IsPositiveInfinity(Complex value)
+ {
+ return (value.Imaginary == 0.0) && double.IsPositiveInfinity(value.Real);
+ }
+
+ private static bool IsInfinity(Complex value)
+ {
+ return (value.Imaginary == 0.0) && double.IsInfinity(value.Real);
+ }
}
\ No newline at end of file
diff --git a/MathTrigonometric/MathTrigonometric.csproj b/MathTrigonometric/MathTrigonometric.csproj
index e35db64..480466d 100644
--- a/MathTrigonometric/MathTrigonometric.csproj
+++ b/MathTrigonometric/MathTrigonometric.csproj
@@ -15,9 +15,9 @@
git
README.md
math; trigonometric; trigonometry; cot; sec; csc; acot; asec; acsc; coth; sech; csch; acoth; asech; acsch;
- It targets .NET Standard 2.0 and higner version.
+ It targets .NET Standard 2.0 and higher version. Supports double and complex numbers.
LICENSE
- 1.0.7
+ 1.1.0
diff --git a/README.md b/README.md
index 87c6f47..b81edee 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,9 @@ Alternatively, you can install the package using the NuGet Package Manager Conso
Install-Package MathTrigonometric
## Functions Included
+
+In version [1.1.0](https://github.com/AntonovAnton/math.trigonometric/releases/tag/1.1.0), support for complex numbers has been introduced through overloaded methods for the trigonometric functions listed below. This allows the library to handle both real and complex inputs seamlessly.
+
### Basic Trigonometric Functions
1. **Sin**