From a0adc9021b8019339bc1f6ec9d0156d1ab003130 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Aug 2009 19:46:26 +0800 Subject: [PATCH] Trig: added trig functions Signed-off-by: Marcus Cuda --- src/Managed.UnitTests/AssertHelpers.cs | 21 + .../ComplexTests/ComplexTest.cs | 630 +++++++++++----- .../Managed.UnitTests.csproj | 1 + src/Managed.UnitTests/TrigonometryTest.cs | 694 ++++++++++++++++++ src/Managed/Complex.cs | 183 ++++- src/Managed/Managed.csproj | 1 + src/Managed/Properties/Resources.Designer.cs | 18 + src/Managed/Properties/Resources.resx | 6 + src/Native.UnitTests/Native.UnitTests.csproj | 3 + src/Native/Native.csproj | 3 + 10 files changed, 1368 insertions(+), 192 deletions(-) create mode 100644 src/Managed.UnitTests/TrigonometryTest.cs diff --git a/src/Managed.UnitTests/AssertHelpers.cs b/src/Managed.UnitTests/AssertHelpers.cs index 8729e478..ae6b4cf0 100644 --- a/src/Managed.UnitTests/AssertHelpers.cs +++ b/src/Managed.UnitTests/AssertHelpers.cs @@ -50,5 +50,26 @@ namespace MathNet.Numerics.UnitTests Assert.Fail("Not equal within {0} places. Expected:{1}; Actual:{2}", decimalPlaces, expected, actual); } } + + /// + /// Asserts that the expected value and the actual value are equal up to a certain number of decimal places. + /// + /// The expected value. + /// The actual value. + /// The number of decimal places to agree on. + public static void AlmostEqual(Complex expected, Complex actual, int decimalPlaces) + { + bool pass = expected.Real.AlmostEqualInDecimalPlaces(actual.Real, decimalPlaces); + if (!pass) + { + Assert.Fail("Real components are not equal within {0} places. Expected:{1}; Actual:{2}", decimalPlaces, expected.Real, actual.Real); + } + + pass = expected.Imaginary.AlmostEqualInDecimalPlaces(actual.Imaginary, decimalPlaces); + if (!pass) + { + Assert.Fail("Imaginary components are not equal within {0} places. Expected:{1}; Actual:{2}", decimalPlaces, expected.Imaginary, actual.Imaginary); + } + } } } diff --git a/src/Managed.UnitTests/ComplexTests/ComplexTest.cs b/src/Managed.UnitTests/ComplexTests/ComplexTest.cs index 0457e8cd..f535cebf 100644 --- a/src/Managed.UnitTests/ComplexTests/ComplexTest.cs +++ b/src/Managed.UnitTests/ComplexTests/ComplexTest.cs @@ -1,111 +1,301 @@ -using System; -using System.Globalization; -using MbUnit.Framework; - -namespace MathNet.Numerics.UnitTests +namespace MathNet.Numerics.UnitTests { + using System; + using System.Globalization; + + using MbUnit.Framework; + + /// + /// The complex test. + /// [TestFixture] public class ComplexTest { - [Test, MultipleAsserts] - public void CanCreateComplexNumberUsingTheConstructor() - { - var complex = new Complex(1.1, -2.2); - Assert.AreEqual(1.1, complex.Real, "Real part is 1.1."); - Assert.AreEqual(-2.2, complex.Imaginary, "Imaginary part is -2.2."); - } - [Test, MultipleAsserts] - public void CanCreateComplexNumberWithRealImaginaryIntializer() + /// + /// The can add complex number and double using operartor. + /// + [Test] + [MultipleAsserts] + public void CanAddComplexNumberAndDoubleUsingOperartor() { - var complex = Complex.WithRealImaginary(1.1, -2.2); - Assert.AreEqual(1.1, complex.Real, "Real part is 1.1."); - Assert.AreEqual(-2.2, complex.Imaginary, "Imaginary part is -2.2."); + AssertEx.That(() => (Complex.NaN + double.NaN).IsNaN); + AssertEx.That(() => (double.NaN + Complex.NaN).IsNaN); + AssertEx.That(() => (double.PositiveInfinity + Complex.One).IsInfinity); + AssertEx.That(() => (Complex.Infinity + 1.0).IsInfinity); + AssertEx.That(() => (Complex.One + 0.0) == Complex.One); + AssertEx.That(() => (0.0 + Complex.One) == Complex.One); + AssertEx.That(() => (new Complex(1.1, -2.2) + 1.1 == new Complex(2.2, -2.2))); + AssertEx.That(() => -2.2 + new Complex(-1.1, 2.2) == new Complex(-3.3, 2.2)); } + /// + /// The can add subtract complex numbers using operartor. + /// [Test] - public void WithModulusArgumentThrowsArgumentOutOfRangeException() + [MultipleAsserts] + public void CanAddSubtractComplexNumbersUsingOperartor() { - Assert.Throws(() => Complex.WithModulusArgument(-1, 1), "Throws exception because modulus is negative."); + AssertEx.That(() => (Complex.NaN - Complex.NaN).IsNaN); + AssertEx.That(() => (Complex.Infinity - Complex.One).IsInfinity); + AssertEx.That(() => (Complex.One - Complex.Zero) == Complex.One); + AssertEx.That(() => (new Complex(1.1, -2.2) - new Complex(1.1, -2.2)) == Complex.Zero); } - [Test, MultipleAsserts] - public void CanCreateComplexNumberWithModulusArgument() + /// + /// The can add two complex numbers. + /// + [Test] + [MultipleAsserts] + public void CanAddTwoComplexNumbers() { - var complex = Complex.WithModulusArgument(2, -Math.PI / 6); - Assert.AreApproximatelyEqual(Math.Sqrt(3), complex.Real, 1e-15, "Real part is Sqrt(3)."); - Assert.AreApproximatelyEqual(-1, complex.Imaginary, 1e-15, "Imaginary part is -1."); + AssertEx.That(() => Complex.NaN.Add(Complex.NaN).IsNaN); + AssertEx.That(() => Complex.Infinity.Add(Complex.One).IsInfinity); + AssertEx.That(() => Complex.One.Add(Complex.Zero) == Complex.One); + AssertEx.That(() => new Complex(1.1, -2.2).Add(new Complex(-1.1, 2.2)) == Complex.Zero); } + /// + /// The can add two complex numbers using operartor. + /// [Test] - public void CanDetermineIfZeroValueComplexNumber() + [MultipleAsserts] + public void CanAddTwoComplexNumbersUsingOperartor() { - var complex = new Complex(0, 0); - Assert.IsTrue(complex.IsZero, "Zero complex number."); + AssertEx.That(() => (Complex.NaN + Complex.NaN).IsNaN); + AssertEx.That(() => (Complex.Infinity + Complex.One).IsInfinity); + AssertEx.That(() => (Complex.One + Complex.Zero) == Complex.One); + AssertEx.That(() => (new Complex(1.1, -2.2) + new Complex(-1.1, 2.2)) == Complex.Zero); } + /// + /// The can calculate hash code. + /// [Test] - public void CanDetermineIfOneValueComplexNumber() + [MultipleAsserts] + public void CanCalculateHashCode() { var complex = new Complex(1, 0); - Assert.IsTrue(complex.IsOne, "Complex number with a value of one."); + Assert.AreEqual(1072693248, complex.GetHashCode()); + complex = new Complex(0, 1); + Assert.AreEqual(-1072693248, complex.GetHashCode()); + complex = new Complex(1, 1); + Assert.AreEqual(-2097152, complex.GetHashCode()); } + /// + /// The can compute exponential. + /// + /// + /// The real. + /// + /// + /// The imag. + /// + /// + /// The expected real. + /// + /// + /// The expected imag. + /// [Test] - public void CanDetermineIfImaginaryUnit() + [Row(0.0, 0.0, 1.0, 0.0)] + [Row(0.0, 1.0, 0.54030230586813977, 0.8414709848078965)] + [Row(-1.0, 1.0, 0.19876611034641295, 0.30955987565311222)] + [Row(-111.1, 111.1, -2.3259065941590448e-49, -5.1181940185795617e-49)] + public void CanComputeExponential(double real, double imag, double expectedReal, double expectedImag) + { + var value = new Complex(real, imag); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, value.Exponential(), 15); + } + + /// + /// The can compute natural logarithm. + /// + /// + /// The real. + /// + /// + /// The imag. + /// + /// + /// The expected real. + /// + /// + /// The expected imag. + /// + [Test] + [Row(0.0, 0.0, double.NegativeInfinity, 0.0)] + [Row(0.0, 1.0, 0.0, 1.5707963267948966)] + [Row(-1.0, 1.0, 0.34657359027997264, 2.3561944901923448)] + [Row(-111.1, 111.1, 5.0570042869255571, 2.3561944901923448)] + [Row(111.1, -111.1, 5.0570042869255571, -0.78539816339744828)] + public void CanComputeNaturalLogarithm(double real, double imag, double expectedReal, double expectedImag) { - var complex = new Complex(0, 1); - Assert.IsTrue(complex.IsI, "Imaginary unit"); + var value = new Complex(real, imag); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, value.NaturalLogarithm(), 15); } - [Test, MultipleAsserts] - public void CanDetermineIfNaN() + /// + /// The can compute power. + /// + [Test] + [MultipleAsserts] + public void CanComputePower() + { + var a = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); + var b = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); + AssertHelpers.AlmostEqual( + new Complex(9.99998047207974718744e-1, -1.76553541154378695012e-6), a.Power(b), 15); + a = new Complex(0.0, 1.19209289550780998537e-7); + b = new Complex(0.0, -1.19209289550780998537e-7); + AssertHelpers.AlmostEqual(new Complex(1.00000018725172576491, 1.90048076369011843105e-6), a.Power(b), 15); + a = new Complex(0.0, -1.19209289550780998537e-7); + b = new Complex(0.0, 0.5); + AssertHelpers.AlmostEqual(new Complex(-2.56488189382693049636e-1, -2.17823120666116144959), a.Power(b), 15); + a = new Complex(0.0, 0.5); + b = new Complex(0.0, -0.5); + AssertHelpers.AlmostEqual(new Complex(2.06287223508090495171, 7.45007062179724087859e-1), a.Power(b), 15); + a = new Complex(0.0, -0.5); + b = new Complex(0.0, 1.0); + AssertHelpers.AlmostEqual(new Complex(3.70040633557002510874, -3.07370876701949232239), a.Power(b), 15); + a = new Complex(0.0, 2.0); + b = new Complex(0.0, -2.0); + AssertHelpers.AlmostEqual(new Complex(4.24532146387429353891, -2.27479427903521192648e1), a.Power(b), 15); + a = new Complex(0.0, -8.388608e6); + b = new Complex(1.19209289550780998537e-7, 0.0); + AssertHelpers.AlmostEqual(new Complex(1.00000190048219620166, -1.87253870018168043834e-7), a.Power(b), 15); + } + + /// + /// The can compute root. + /// + [Test] + [MultipleAsserts] + public void CanComputeRoot() + { + var a = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); + var b = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); + AssertHelpers.AlmostEqual(new Complex(0.0, 0.0), a.Root(b), 15); + a = new Complex(0.0, -1.19209289550780998537e-7); + b = new Complex(0.0, 0.5); + AssertHelpers.AlmostEqual(new Complex(0.038550761943650161, 0.019526430428319544), a.Root(b), 15); + a = new Complex(0.0, 0.5); + b = new Complex(0.0, -0.5); + AssertHelpers.AlmostEqual(new Complex(0.007927894711475968, -0.042480480425152213), a.Root(b), 15); + a = new Complex(0.0, -0.5); + b = new Complex(0.0, 1.0); + AssertHelpers.AlmostEqual(new Complex(0.15990905692806806, 0.13282699942462053), a.Root(b), 15); + a = new Complex(0.0, 2.0); + b = new Complex(0.0, -2.0); + AssertHelpers.AlmostEqual(new Complex(0.42882900629436788, 0.15487175246424678), a.Root(b), 15); + a = new Complex(0.0, -8.388608e6); + b = new Complex(1.19209289550780998537e-7, 0.0); + AssertHelpers.AlmostEqual(new Complex(double.PositiveInfinity, double.NegativeInfinity), a.Root(b), 15); + } + + /// + /// The can compute square. + /// + [Test] + [MultipleAsserts] + public void CanComputeSquare() + { + var complex = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); + AssertHelpers.AlmostEqual(new Complex(0, 2.8421709430403888e-14), complex.Square(), 15); + complex = new Complex(0.0, 1.19209289550780998537e-7); + AssertHelpers.AlmostEqual(new Complex(-1.4210854715201944e-14, 0.0), complex.Square(), 15); + complex = new Complex(0.0, -1.19209289550780998537e-7); + AssertHelpers.AlmostEqual(new Complex(-1.4210854715201944e-14, 0.0), complex.Square(), 15); + complex = new Complex(0.0, 0.5); + AssertHelpers.AlmostEqual(new Complex(-0.25, 0.0), complex.Square(), 15); + complex = new Complex(0.0, -0.5); + AssertHelpers.AlmostEqual(new Complex(-0.25, 0.0), complex.Square(), 15); + complex = new Complex(0.0, -8.388608e6); + AssertHelpers.AlmostEqual(new Complex(-70368744177664.0, 0.0), complex.Square(), 15); + } + + /// + /// The can compute square root. + /// + [Test] + [MultipleAsserts] + public void CanComputeSquareRoot() + { + var complex = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); + AssertHelpers.AlmostEqual( + new Complex(0.00037933934912842666, 0.00015712750315077684), complex.SquareRoot(), 15); + complex = new Complex(0.0, 1.19209289550780998537e-7); + AssertHelpers.AlmostEqual( + new Complex(0.00024414062499999973, 0.00024414062499999976), complex.SquareRoot(), 15); + complex = new Complex(0.0, -1.19209289550780998537e-7); + AssertHelpers.AlmostEqual( + new Complex(0.00024414062499999973, -0.00024414062499999976), complex.SquareRoot(), 15); + complex = new Complex(0.0, 0.5); + AssertHelpers.AlmostEqual(new Complex(0.5, 0.5), complex.SquareRoot(), 15); + complex = new Complex(0.0, -0.5); + AssertHelpers.AlmostEqual(new Complex(0.5, -0.5), complex.SquareRoot(), 15); + complex = new Complex(0.0, -8.388608e6); + AssertHelpers.AlmostEqual(new Complex(2048.0, -2048.0), complex.SquareRoot(), 15); + complex = new Complex(8.388608e6, 1.19209289550780998537e-7); + AssertHelpers.AlmostEqual(new Complex(2896.3093757400989, 2.0579515874459933e-11), complex.SquareRoot(), 15); + } + + /// + /// The can convert double to complex. + /// + [Test] + [MultipleAsserts] + public void CanConvertDoubleToComplex() { - var complex = new Complex(double.NaN, 1); - Assert.IsTrue(complex.IsNaN, "Real part is NaN."); - complex = new Complex(1, double.NaN); - Assert.IsTrue(complex.IsNaN, "Imaginary part is NaN."); - complex = new Complex(double.NaN, double.NaN); - Assert.IsTrue(complex.IsNaN, "Both parts are NaN."); - } - - [Test, MultipleAsserts] - public void CanDetermineIfInfinity() - { - var complex = new Complex(double.PositiveInfinity, 1); - Assert.IsTrue(complex.IsInfinity, "Real part is infinity."); - complex = new Complex(1, double.NegativeInfinity); - Assert.IsTrue(complex.IsInfinity, "Imaginary part is infinity."); - complex = new Complex(double.NegativeInfinity, double.PositiveInfinity); - Assert.IsTrue(complex.IsInfinity, "Both parts are infinity."); + AssertEx.That(() => ((Complex)double.NaN).IsNaN); + AssertEx.That(() => ((Complex)double.NegativeInfinity).IsInfinity); + Assert.AreEqual(1.1, new Complex(1.1, 0)); } + /// + /// The can create complex number using the constructor. + /// [Test] - public void CanDetermineIfRealNumber() + [MultipleAsserts] + public void CanCreateComplexNumberUsingTheConstructor() { - var complex = new Complex(-1, 0); - Assert.IsTrue(complex.IsReal, "Is a real number."); + var complex = new Complex(1.1, -2.2); + Assert.AreEqual(1.1, complex.Real, "Real part is 1.1."); + Assert.AreEqual(-2.2, complex.Imaginary, "Imaginary part is -2.2."); } + /// + /// The can create complex number with modulus argument. + /// [Test] - public void CanDetermineIfRealNonNegativeNumber() + [MultipleAsserts] + public void CanCreateComplexNumberWithModulusArgument() { - var complex = new Complex(1, 0); - Assert.IsTrue(complex.IsReal, "Is a real non-negative number."); + var complex = Complex.WithModulusArgument(2, -Math.PI / 6); + Assert.AreApproximatelyEqual(Math.Sqrt(3), complex.Real, 1e-15, "Real part is Sqrt(3)."); + Assert.AreApproximatelyEqual(-1, complex.Imaginary, 1e-15, "Imaginary part is -1."); } - [Test, MultipleAsserts] - public void CanCalculateHashCode() + /// + /// The can create complex number with real imaginary intializer. + /// + [Test] + [MultipleAsserts] + public void CanCreateComplexNumberWithRealImaginaryIntializer() { - var complex = new Complex(1, 0); - Assert.AreEqual(1072693248, complex.GetHashCode()); - complex = new Complex(0, 1); - Assert.AreEqual(-1072693248, complex.GetHashCode()); - complex = new Complex(1, 1); - Assert.AreEqual(-2097152, complex.GetHashCode()); + var complex = Complex.WithRealImaginary(1.1, -2.2); + Assert.AreEqual(1.1, complex.Real, "Real part is 1.1."); + Assert.AreEqual(-2.2, complex.Imaginary, "Imaginary part is -2.2."); } - [Test, MultipleAsserts] + /// + /// The can create string from complex number. + /// + [Test] + [MultipleAsserts] public void CanCreateStringFromComplexNumber() { Assert.AreEqual("NaN", Complex.NaN.ToString()); @@ -116,16 +306,27 @@ namespace MathNet.Numerics.UnitTests Assert.AreEqual("1.1 + 1.1i", new Complex(1.1, 1.1).ToString()); } - [Test, MultipleAsserts] - public void CanTestForEquality() + /// + /// The can create string using format provider. + /// + [Test] + [MultipleAsserts] + public void CanCreateStringUsingFormatProvider() { - Assert.AreNotEqual(Complex.NaN, Complex.NaN); - Assert.AreEqual(Complex.Infinity, Complex.Infinity); - Assert.AreEqual(new Complex(1.1, -2.2), new Complex(1.1, -2.2)); - Assert.AreNotEqual(new Complex(-1.1, 2.2), new Complex(1.1, -2.2)); + var provider = CultureInfo.GetCultureInfo("tr-TR"); + Assert.AreEqual("NaN", Complex.NaN.ToString(provider)); + Assert.AreEqual("Infinity", Complex.Infinity.ToString(provider)); + Assert.AreEqual("1,1", new Complex(1.1, 0).ToString(provider)); + Assert.AreEqual("-1,1i", new Complex(0, -1.1).ToString(provider)); + Assert.AreEqual("1,1i", new Complex(0, 1.1).ToString(provider)); + Assert.AreEqual("1,1 + 1,1i", new Complex(1.1, 1.1).ToString(provider)); } - [Test, MultipleAsserts] + /// + /// The can create string using number format. + /// + [Test] + [MultipleAsserts] public void CanCreateStringUsingNumberFormat() { Assert.AreEqual("NaN", Complex.NaN.ToString("#.000")); @@ -136,113 +337,182 @@ namespace MathNet.Numerics.UnitTests Assert.AreEqual("1.100 + 1.100i", new Complex(1.1, 1.1).ToString("#.000")); } - [Test, MultipleAsserts] - public void CanCreateStringUsingFormatProvider() + /// + /// The can determine if imaginary unit. + /// + [Test] + public void CanDetermineIfImaginaryUnit() { - var provider = CultureInfo.GetCultureInfo("tr-TR"); - Assert.AreEqual("NaN", Complex.NaN.ToString(provider)); - Assert.AreEqual("Infinity", Complex.Infinity.ToString(provider)); - Assert.AreEqual("1,1", new Complex(1.1, 0).ToString(provider)); - Assert.AreEqual("-1,1i", new Complex(0, -1.1).ToString(provider)); - Assert.AreEqual("1,1i", new Complex(0, 1.1).ToString(provider)); - Assert.AreEqual("1,1 + 1,1i", new Complex(1.1, 1.1).ToString(provider)); + var complex = new Complex(0, 1); + Assert.IsTrue(complex.IsI, "Imaginary unit"); } - [Test, MultipleAsserts] - public void CanTestForEqualityUsingOperators() + /// + /// The can determine if infinity. + /// + [Test] + [MultipleAsserts] + public void CanDetermineIfInfinity() { - AssertEx.That(() => Complex.NaN != Complex.NaN); - AssertEx.That(() => Complex.Infinity == Complex.Infinity); - AssertEx.That(() => new Complex(1.1, -2.2) == new Complex(1.1, -2.2)); - AssertEx.That(() => new Complex(-1.1, 2.2) != new Complex(1.1, -2.2)); + var complex = new Complex(double.PositiveInfinity, 1); + Assert.IsTrue(complex.IsInfinity, "Real part is infinity."); + complex = new Complex(1, double.NegativeInfinity); + Assert.IsTrue(complex.IsInfinity, "Imaginary part is infinity."); + complex = new Complex(double.NegativeInfinity, double.PositiveInfinity); + Assert.IsTrue(complex.IsInfinity, "Both parts are infinity."); } - [Test, MultipleAsserts] - public void CanConvertDoubleToComplex() + /// + /// The can determine if na n. + /// + [Test] + [MultipleAsserts] + public void CanDetermineIfNaN() { - AssertEx.That(() => ((Complex) double.NaN).IsNaN); - AssertEx.That(() => ((Complex) double.NegativeInfinity).IsInfinity); - Assert.AreEqual((Complex) 1.1, new Complex(1.1, 0)); + var complex = new Complex(double.NaN, 1); + Assert.IsTrue(complex.IsNaN, "Real part is NaN."); + complex = new Complex(1, double.NaN); + Assert.IsTrue(complex.IsNaN, "Imaginary part is NaN."); + complex = new Complex(double.NaN, double.NaN); + Assert.IsTrue(complex.IsNaN, "Both parts are NaN."); } + /// + /// The can determine if one value complex number. + /// [Test] - public void CanUsePlusOperator() + public void CanDetermineIfOneValueComplexNumber() { - var complex = new Complex(1.1, -2.2); - Assert.AreEqual(complex, +complex); + var complex = new Complex(1, 0); + Assert.IsTrue(complex.IsOne, "Complex number with a value of one."); } + /// + /// The can determine if real non negative number. + /// [Test] - public void CanNegateValueUsingOperator() + public void CanDetermineIfRealNonNegativeNumber() { - var complex = new Complex(1.1, -2.2); - Assert.AreEqual(new Complex(-1.1, 2.2), -complex); + var complex = new Complex(1, 0); + Assert.IsTrue(complex.IsReal, "Is a real non-negative number."); } + /// + /// The can determine if real number. + /// [Test] - public void CanUsePlus() + public void CanDetermineIfRealNumber() { - var complex = new Complex(1.1, -2.2); - Assert.AreEqual(complex, complex.Plus()); + var complex = new Complex(-1, 0); + Assert.IsTrue(complex.IsReal, "Is a real number."); } + /// + /// The can determine if zero value complex number. + /// [Test] - public void CanNegateValue() + public void CanDetermineIfZeroValueComplexNumber() { - var complex = new Complex(1.1, -2.2); - Assert.AreEqual(new Complex(-1.1, 2.2), complex.Negate()); + var complex = new Complex(0, 0); + Assert.IsTrue(complex.IsZero, "Zero complex number."); } - [Test, MultipleAsserts] - public void CanAddTwoComplexNumbersUsingOperartor() + /// + /// The can divide complex number and double using operators. + /// + [Test] + [MultipleAsserts] + public void CanDivideComplexNumberAndDoubleUsingOperators() { - AssertEx.That(() => (Complex.NaN + Complex.NaN).IsNaN); - AssertEx.That(() => (Complex.Infinity + Complex.One).IsInfinity); - AssertEx.That(() => (Complex.One + Complex.Zero) == Complex.One); - AssertEx.That(() => (new Complex(1.1, -2.2) + new Complex(-1.1, 2.2)) == Complex.Zero); + AssertEx.That(() => (Complex.NaN * 1.0).IsNaN); + Assert.AreEqual(new Complex(-2, 2), new Complex(4, -4) / -2); + Assert.AreEqual(new Complex(0.25, 0.25), 2 / new Complex(4, -4)); + Assert.AreEqual(Complex.Infinity, Complex.One / 0); } - [Test, MultipleAsserts] - public void CanAddTwoComplexNumbers() + /// + /// The can divide two complex numbers. + /// + [Test] + [MultipleAsserts] + public void CanDivideTwoComplexNumbers() { - AssertEx.That(() => (Complex.NaN.Add(Complex.NaN)).IsNaN); - AssertEx.That(() => (Complex.Infinity.Add(Complex.One).IsInfinity)); - AssertEx.That(() => (Complex.One.Add(Complex.Zero)) == Complex.One); - AssertEx.That(() => (new Complex(1.1, -2.2).Add(new Complex(-1.1, 2.2))) == Complex.Zero); + AssertEx.That(() => Complex.NaN.Multiply(Complex.One).IsNaN); + Assert.AreEqual(new Complex(-2, 0), new Complex(4, -4).Divide(new Complex(-2, 2))); + Assert.AreEqual(Complex.Infinity, Complex.One.Divide(Complex.Zero)); } - [Test, MultipleAsserts] - public void CanAddComplexNumberAndDoubleUsingOperartor() + /// + /// The can divide two complex numbers using operators. + /// + [Test] + [MultipleAsserts] + public void CanDivideTwoComplexNumbersUsingOperators() { - AssertEx.That(() => (Complex.NaN + double.NaN).IsNaN); - AssertEx.That(() => (double.NaN + Complex.NaN).IsNaN); - AssertEx.That(() => (double.PositiveInfinity + Complex.One).IsInfinity); - AssertEx.That(() => (Complex.Infinity + 1.0).IsInfinity); - AssertEx.That(() => (Complex.One + 0.0) == Complex.One); - AssertEx.That(() => (0.0 + Complex.One) == Complex.One); - AssertEx.That(() => (new Complex(1.1, -2.2) + 1.1 == new Complex(2.2, -2.2))); - AssertEx.That(() => -2.2 + new Complex(-1.1, 2.2) == new Complex(-3.3, 2.2)); + AssertEx.That(() => (Complex.NaN / Complex.One).IsNaN); + Assert.AreEqual(new Complex(-2, 0), new Complex(4, -4) / new Complex(-2, 2)); + Assert.AreEqual(Complex.Infinity, Complex.One / Complex.Zero); } - [Test, MultipleAsserts] - public void CanAddSubtractComplexNumbersUsingOperartor() + /// + /// The can multiple complex number and double using operators. + /// + [Test] + [MultipleAsserts] + public void CanMultipleComplexNumberAndDoubleUsingOperators() { - AssertEx.That(() => (Complex.NaN - Complex.NaN).IsNaN); - AssertEx.That(() => (Complex.Infinity - Complex.One).IsInfinity); - AssertEx.That(() => (Complex.One - Complex.Zero) == Complex.One); - AssertEx.That(() => (new Complex(1.1, -2.2) - new Complex(1.1, -2.2)) == Complex.Zero); + AssertEx.That(() => (Complex.NaN * 1.0).IsNaN); + Assert.AreEqual(new Complex(8, -8), new Complex(4, -4) * 2); + Assert.AreEqual(new Complex(8, -8), 2 * new Complex(4, -4)); } - [Test, MultipleAsserts] - public void CanSubtractTwoComplexNumbers() + /// + /// The can multiple two complex numbers. + /// + [Test] + [MultipleAsserts] + public void CanMultipleTwoComplexNumbers() + { + AssertEx.That(() => Complex.NaN.Multiply(Complex.One).IsNaN); + Assert.AreEqual(new Complex(0, 16), new Complex(4, -4).Multiply(new Complex(-2, 2))); + } + + /// + /// The can multiple two complex numbers using operators. + /// + [Test] + [MultipleAsserts] + public void CanMultipleTwoComplexNumbersUsingOperators() + { + AssertEx.That(() => (Complex.NaN * Complex.One).IsNaN); + Assert.AreEqual(new Complex(0, 16), new Complex(4, -4) * new Complex(-2, 2)); + } + + /// + /// The can negate value. + /// + [Test] + public void CanNegateValue() + { + var complex = new Complex(1.1, -2.2); + Assert.AreEqual(new Complex(-1.1, 2.2), complex.Negate()); + } + + /// + /// The can negate value using operator. + /// + [Test] + public void CanNegateValueUsingOperator() { - AssertEx.That(() => (Complex.NaN.Subtract(Complex.NaN)).IsNaN); - AssertEx.That(() => (Complex.Infinity.Subtract(Complex.One)).IsInfinity); - AssertEx.That(() => (Complex.One.Subtract(Complex.Zero)) == Complex.One); - AssertEx.That(() => (new Complex(1.1, -2.2).Subtract(new Complex(1.1, -2.2))) == Complex.Zero); + var complex = new Complex(1.1, -2.2); + Assert.AreEqual(new Complex(-1.1, 2.2), -complex); } - [Test, MultipleAsserts] + /// + /// The can subtract complex number and double using operartor. + /// + [Test] + [MultipleAsserts] public void CanSubtractComplexNumberAndDoubleUsingOperartor() { AssertEx.That(() => (Complex.NaN - double.NaN).IsNaN); @@ -255,51 +525,73 @@ namespace MathNet.Numerics.UnitTests AssertEx.That(() => -2.2 - new Complex(-1.1, 2.2) == new Complex(-1.1, -2.2)); } - [Test, MultipleAsserts] - public void CanMultipleTwoComplexNumbersUsingOperators() + /// + /// The can subtract two complex numbers. + /// + [Test] + [MultipleAsserts] + public void CanSubtractTwoComplexNumbers() { - AssertEx.That(() => (Complex.NaN * Complex.One).IsNaN); - Assert.AreEqual(new Complex(0, 16), new Complex(4, -4) * new Complex(-2, 2)); + AssertEx.That(() => Complex.NaN.Subtract(Complex.NaN).IsNaN); + AssertEx.That(() => Complex.Infinity.Subtract(Complex.One).IsInfinity); + AssertEx.That(() => Complex.One.Subtract(Complex.Zero) == Complex.One); + AssertEx.That(() => new Complex(1.1, -2.2).Subtract(new Complex(1.1, -2.2)) == Complex.Zero); } - [Test, MultipleAsserts] - public void CanMultipleTwoComplexNumbers() + /// + /// The can test for equality. + /// + [Test] + [MultipleAsserts] + public void CanTestForEquality() { - AssertEx.That(() => (Complex.NaN.Multiply(Complex.One).IsNaN)); - Assert.AreEqual(new Complex(0, 16), new Complex(4, -4).Multiply(new Complex(-2, 2))); + Assert.AreNotEqual(Complex.NaN, Complex.NaN); + Assert.AreEqual(Complex.Infinity, Complex.Infinity); + Assert.AreEqual(new Complex(1.1, -2.2), new Complex(1.1, -2.2)); + Assert.AreNotEqual(new Complex(-1.1, 2.2), new Complex(1.1, -2.2)); } - [Test, MultipleAsserts] - public void CanMultipleComplexNumberAndDoubleUsingOperators() + /// + /// The can test for equality using operators. + /// + [Test] + [MultipleAsserts] + public void CanTestForEqualityUsingOperators() { - AssertEx.That(() => (Complex.NaN * 1.0).IsNaN); - Assert.AreEqual(new Complex(8, -8), new Complex(4, -4) * 2); - Assert.AreEqual(new Complex(8, -8), 2 * new Complex(4, -4)); + AssertEx.That(() => Complex.NaN != Complex.NaN); + AssertEx.That(() => Complex.Infinity == Complex.Infinity); + AssertEx.That(() => new Complex(1.1, -2.2) == new Complex(1.1, -2.2)); + AssertEx.That(() => new Complex(-1.1, 2.2) != new Complex(1.1, -2.2)); } - [Test, MultipleAsserts] - public void CanDivideTwoComplexNumbersUsingOperators() + /// + /// The can use plus. + /// + [Test] + public void CanUsePlus() { - AssertEx.That(() => (Complex.NaN / Complex.One).IsNaN); - Assert.AreEqual(new Complex(-2, 0), new Complex(4, -4) / new Complex(-2, 2)); - Assert.AreEqual(Complex.Infinity, Complex.One / Complex.Zero); + var complex = new Complex(1.1, -2.2); + Assert.AreEqual(complex, complex.Plus()); } - [Test, MultipleAsserts] - public void CanDivideTwoComplexNumbers() + /// + /// The can use plus operator. + /// + [Test] + public void CanUsePlusOperator() { - AssertEx.That(() => (Complex.NaN.Multiply(Complex.One).IsNaN)); - Assert.AreEqual(new Complex(-2, 0), new Complex(4, -4).Divide(new Complex(-2, 2))); - Assert.AreEqual(Complex.Infinity, Complex.One.Divide(Complex.Zero)); + var complex = new Complex(1.1, -2.2); + Assert.AreEqual(complex, +complex); } - [Test, MultipleAsserts] - public void CanDivideComplexNumberAndDoubleUsingOperators() + /// + /// The with modulus argument throws argument out of range exception. + /// + [Test] + public void WithModulusArgumentThrowsArgumentOutOfRangeException() { - AssertEx.That(() => (Complex.NaN * 1.0).IsNaN); - Assert.AreEqual(new Complex(-2, 2), new Complex(4, -4) / -2); - Assert.AreEqual(new Complex(0.25, 0.25), 2 / new Complex(4, -4)); - Assert.AreEqual(Complex.Infinity, Complex.One / 0); + Assert.Throws( + () => Complex.WithModulusArgument(-1, 1), "Throws exception because modulus is negative."); } } } \ No newline at end of file diff --git a/src/Managed.UnitTests/Managed.UnitTests.csproj b/src/Managed.UnitTests/Managed.UnitTests.csproj index 2a773d29..ed40e357 100644 --- a/src/Managed.UnitTests/Managed.UnitTests.csproj +++ b/src/Managed.UnitTests/Managed.UnitTests.csproj @@ -77,6 +77,7 @@ + diff --git a/src/Managed.UnitTests/TrigonometryTest.cs b/src/Managed.UnitTests/TrigonometryTest.cs new file mode 100644 index 00000000..8a49b4b2 --- /dev/null +++ b/src/Managed.UnitTests/TrigonometryTest.cs @@ -0,0 +1,694 @@ +namespace MathNet.Numerics.UnitTests +{ + using System; + + using MbUnit.Framework; + + [TestFixture] + public class TrigonometryTest + { + [Test] + [Row(0.0, 0.0, 1.0, 0.0)] + [Row(8.388608e6, 0.0, -0.90175467375875928, 0.0)] + [Row(-8.388608e6, 0.0, -0.90175467375875928, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 0.99999999999999289, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, 0.99999999999999289, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, -0.90175467375876572, -5.1528001100635277e-8)] + [Row(-1.19209289550780998537e-7, -8.388608e6, double.PositiveInfinity, double.NegativeInfinity)] + public void CanComputeComplexCosine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).Cosine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, 0.0, 0.0, 0.0)] + [Row(8.388608e6, 0.0, 0.43224820225679778, 0.0)] + [Row(-8.388608e6, 0.0, -0.43224820225679778, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.19209289550780998537e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.19209289550780998537e-7, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 0.43224820225680083, -1.0749753400787824e-7)] + [Row(-1.19209289550780998537e-7, -8.388608e6, double.NegativeInfinity, double.NegativeInfinity)] + public void CanComputeComplexSine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).Sine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, 0.0, 0.0, 0.0)] + [Row(8.388608e6, 0.0, -0.47934123862654288, 0.0)] + [Row(-8.388608e6, 0.0, 0.47934123862654288, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078157e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078157e-7, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, -0.47934123862653449, 1.4659977233982276e-7)] + [Row(-8.388608e6, -1.19209289550780998537e-7, 0.47934123862653449, -1.4659977233982276e-7)] + public void CanComputeComplexTangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).Tangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, double.PositiveInfinity)] + [Row(8388608, 2.3134856195559191)] + [Row(1.19209289550780998537e-7, 8388608.0000000376)] + [Row(-8388608, -2.3134856195559191)] + [Row(-1.19209289550780998537e-7, -8388608.0000000376)] + public void CanComputeCosecant(double value, double expected) + { + var actual = Trig.Cosecant(value); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, 1.0)] + [Row(8388608, -0.90175467375875928)] + [Row(1.19209289550780998537e-7, 0.99999999999999289)] + [Row(-8388608, -0.90175467375875928)] + [Row(-1.19209289550780998537e-7, 0.99999999999999289)] + public void CanComputeCosine(double value, double expected) + { + var actual = Trig.Cosine(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, double.PositiveInfinity)] + [Row(8388608, -2.086196470108229)] + [Row(1.19209289550780998537e-7, 8388607.999999978)] + [Row(-8388608, 2.086196470108229)] + [Row(-1.19209289550780998537e-7, -8388607.999999978)] + public void CanComputeCotangent(double value, double expected) + { + var actual = Trig.Cotangent(value); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, double.PositiveInfinity)] + [Row(8388608, 1.3670377960148449e-3643126)] + [Row(1.19209289550780998537e-7, 8388607.9999999978)] + [Row(-8388608, -1.3670377960148449e-3643126)] + [Row(-1.19209289550780998537e-7, -8388607.9999999978)] + public void CanComputeHyperbolicCosecant(double value, double expected) + { + var actual = Trig.HyperbolicCosecant(value); + AssertHelpers.AlmostEqual(expected, actual, 15); + } + + [Test] + [Row(0.0, 1.0)] + [Row(8388608, double.PositiveInfinity)] + [Row(1.19209289550780998537e-7, 1.0000000000000071)] + [Row(-8388608, double.PositiveInfinity)] + [Row(-1.19209289550780998537e-7, 1.0000000000000071)] + public void CanComputeHyperbolicCosine(double value, double expected) + { + var actual = Trig.HyperbolicCosine(value); + AssertHelpers.AlmostEqual(expected, actual, 15); + } + + [Test] + [Row(0.0, double.PositiveInfinity)] + [Row(8388608, 1.0)] + [Row(1.19209289550780998537e-7, 8388608.0000000574)] + [Row(-8388608, -1.0)] + [Row(-1.19209289550780998537e-7, -8388608.0000000574)] + public void CanComputeHyperbolicCotangent(double value, double expected) + { + var actual = Trig.HyperbolicCotangent(value); + AssertHelpers.AlmostEqual(expected, actual, 15); + } + + [Test] + [Row(0.0, 1.0)] + [Row(8388608, 1.3670377960148449e-3643126)] + [Row(1.19209289550780998537e-7, 0.99999999999999289)] + [Row(-8388608, 1.3670377960148449e-3643126)] + [Row(-1.19209289550780998537e-7, 0.99999999999999289)] + public void CanComputeHyperbolicSecant(double value, double expected) + { + var actual = Trig.HyperbolicSecant(value); + AssertHelpers.AlmostEqual(expected, actual, 15); + } + + [Test] + [Row(8388608, double.PositiveInfinity)] + [Row(1.19209289550780998537e-7, 1.1920928955078128e-7)] + [Row(-8388608, double.NegativeInfinity)] + [Row(-1.19209289550780998537e-7, -1.1920928955078128e-7)] + public void CanComputeHyperbolicSine(double value, double expected) + { + var actual = Trig.HyperbolicSine(value); + AssertHelpers.AlmostEqual(expected, actual, 15); + } + + [Test] + [Row(0.0, 0.0)] + [Row(8388608, 1.0)] + [Row(1.19209289550780998537e-7, 1.1920928955078043e-7)] + [Row(-8388608, -1.0)] + [Row(-1.19209289550780998537e-7, -1.1920928955078043e-7)] + public void CanComputeHyperbolicTangent(double value, double expected) + { + var actual = Trig.HyperbolicTangent(value); + AssertHelpers.AlmostEqual(expected, actual, 15); + } + + [Test] + [Row(8388608, 1.1920928955078097e-7)] + [Row(-8388608, -1.1920928955078097e-7)] + [Row(1, 1.5707963267948966)] + [Row(-1, -1.5707963267948966)] + public void CanComputeInverseCosecant(double value, double expected) + { + var actual = Trig.InverseCosecant(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(1, 0)] + [Row(-1, 3.1415926535897931)] + [Row(1.19209289550780998537e-7, 1.570796207585607)] + [Row(-1.19209289550780998537e-7, 1.5707964460041861)] + public void CanComputeInverseCosine(double value, double expected) + { + var actual = Trig.InverseCosine(value); + AssertHelpers.AlmostEqual(expected, actual, 15); + } + + [Test] + [Row(0.0, 1.5707963267948966)] + [Row(8388608, 1.1920928955078069e-7)] + [Row(-8388608, -1.1920928955078069e-7)] + [Row(1.19209289550780998537e-7, 1.5707962075856071)] + [Row(-1.19209289550780998537e-7, -1.5707962075856071)] + public void CanComputeInverseCotangent(double value, double expected) + { + var actual = Trig.InverseCotangent(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, double.PositiveInfinity)] + [Row(8388608, 1.1920928955078097e-7)] + [Row(-8388608, -1.1920928955078097e-7)] + [Row(1.19209289550780998537e-7, 16.635532333438693)] + [Row(-1.19209289550780998537e-7, -16.635532333438693)] + public void CanComputeInverseHyperbolicCosecant(double value, double expected) + { + var actual = Trig.InverseHyperbolicCosecant(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(1.0, 0.0)] + [Row(8388608, 16.635532333438682)] + public void CanComputeInverseHyperbolicCosine(double value, double expected) + { + var actual = Trig.InverseHyperbolicCosine(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8388608, 1.1920928955078181e-7)] + [Row(-8388608, -1.1920928955078181e-7)] + [Row(1, double.PositiveInfinity)] + [Row(-1, double.NegativeInfinity)] + public void CanComputeInverseHyperbolicCotangent(double value, double expected) + { + var actual = Trig.InverseHyperbolicCotangent(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0, double.PositiveInfinity)] + [Row(.5, 1.3169578969248167)] + [Row(1, 0.0)] + public void CanComputeInverseHyperbolicSecant(double value, double expected) + { + var actual = Trig.InverseHyperbolicSecant(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0)] + [Row(8388608, 16.63553233343869)] + [Row(-8388608, -16.63553233343869)] + [Row(1.19209289550780998537e-7, 1.1920928955078072e-7)] + [Row(-1.19209289550780998537e-7, -1.1920928955078072e-7)] + public void CanComputeInverseHyperbolicSine(double value, double expected) + { + var actual = Trig.InverseHyperbolicSine(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0)] + [Row(1.0, double.PositiveInfinity)] + [Row(-1.0, double.NegativeInfinity)] + [Row(1.19209289550780998537e-7, 1.19209289550780998537e-7)] + [Row(-1.19209289550780998537e-7, -1.19209289550780998537e-7)] + public void CanComputeInverseHyperbolicTangent(double value, double expected) + { + var actual = Trig.InverseHyperbolicTangent(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8388608, 1.5707962075856071)] + [Row(-8388608, 1.5707964460041862)] + [Row(1.0, 0.0)] + [Row(-1.0, 3.1415926535897932)] + public void CanComputeInverseSecant(double value, double expected) + { + var actual = Trig.InverseSecant(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0)] + [Row(1.0, 1.5707963267948966)] + [Row(-1.0, -1.5707963267948966)] + [Row(1.19209289550780998537e-7, 1.1920928955078128e-7)] + [Row(-1.19209289550780998537e-7, -1.1920928955078128e-7)] + public void CanComputeInverseSine(double value, double expected) + { + var actual = Trig.InverseSine(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0)] + [Row(8388608, 1.570796207585607)] + [Row(-8388608, -1.570796207585607)] + [Row(1.19209289550780998537e-7, 1.19209289550780998537e-7)] + [Row(-1.19209289550780998537e-7, -1.19209289550780998537e-7)] + public void CanComputeInverseTangent(double value, double expected) + { + var actual = Trig.InverseTangent(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 1.0)] + [Row(8388608, -1.1089490624226292)] + [Row(1.19209289550780998537e-7, 1.0000000000000071)] + [Row(-8388608, -1.1089490624226292)] + [Row(-1.19209289550780998537e-7, 1.0000000000000071)] + public void CanComputeSecant(double value, double expected) + { + var actual = Trig.Secant(value); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0)] + [Row(8388608, 0.43224820225679778)] + [Row(-8388608, -0.43224820225679778)] + [Row(1.19209289550780998537e-7, 1.1920928955078072e-7)] + [Row(-1.19209289550780998537e-7, -1.1920928955078072e-7)] + public void CanComputeSine(double value, double expected) + { + var actual = Trig.Sine(value); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, 0.0)] + [Row(8388608, -0.47934123862654288)] + [Row(-8388608, 0.47934123862654288)] + [Row(1.19209289550780998537e-7, 1.1920928955078157e-7)] + [Row(-1.19209289550780998537e-7, -1.1920928955078157e-7)] + public void CanComputeTangent(double value, double expected) + { + var actual = Trig.Tangent(value); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + public void CanConvertDegreeToGrad() + { + AssertHelpers.AlmostEqual(90 / .9, Trig.DegreeToGrad(90), 15); + } + + [Test] + public void CanConvertDegreeToRadian() + { + AssertHelpers.AlmostEqual(Math.PI / 2, Trig.DegreeToRadian(90), 15); + } + + [Test] + public void CanConvertGradToDegree() + { + AssertHelpers.AlmostEqual(180, Trig.GradToDegree(200), 15); + } + + [Test] + public void CanConvertGradToRadian() + { + AssertHelpers.AlmostEqual(Math.PI, Trig.GradToRadian(200), 15); + } + + [Test] + public void CanConvertRadianToDegree() + { + AssertHelpers.AlmostEqual(60.0, Trig.RadianToDegree(Math.PI / 3.0), 15); + } + + [Test] + public void CanConvertRadianToGrad() + { + AssertHelpers.AlmostEqual(200.0 / 3.0, Trig.RadianToGrad(Math.PI / 3.0), 15); + } + + [Test] + [Row(0.0, 0.0, double.PositiveInfinity, 0.0)] + [Row(8.388608e6, 0.0, -2.086196470108229, 0.0)] + [Row(-8.388608e6, 0.0, 2.086196470108229, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 8388607.999999978, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -8388607.999999978, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, -2.0861964701080704, -6.3803383253713457e-7)] + [Row(-8.388608e6, -1.19209289550780998537e-7, 2.0861964701080704, 6.3803383253713457e-7)] + public void CanComputeComplexCotangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).Cotangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, 0.0, 1.0, 0.0)] + [Row(8.388608e6, 0.0, -1.1089490624226292, 0.0)] + [Row(-8.388608e6, 0.0, -1.1089490624226292, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.0000000000000071, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, 1.0000000000000071, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, -1.1089490624226177, 6.3367488045143761e-8)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.1089490624226177, 6.3367488045143761e-8)] + public void CanComputeComplexSecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).Secant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, 0.0, double.PositiveInfinity, 0.0)] + [Row(8.388608e6, 0.0, 2.3134856195559191, 0.0)] + [Row(-8.388608e6, 0.0, -2.3134856195559191, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 8388608.0000000376, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -8388608.0000000376, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 2.3134856195557596, 5.7534999050657057e-7)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -2.3134856195557596, -5.7534999050657057e-7)] + public void CanComputeComplexCosecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).Cosecant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 13); + } + + [Test] + [Row(0.0, 0.0, 0.0, 0.0)] + [Row(8.388608e6, 0.0, double.PositiveInfinity, 0.0)] + [Row(-8.388608e6, 0.0, double.NegativeInfinity, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078128e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078128e-7, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, double.PositiveInfinity, double.PositiveInfinity)] + [Row(-8.388608e6, -1.19209289550780998537e-7, double.NegativeInfinity, double.NegativeInfinity)] + [Row(0.5, -0.5, 0.45730415318424922, -0.54061268571315335)] + public void CanComputeComplexHyperbolicSine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).HyperbolicSine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, 1.0, 0.0)] + [Row(8.388608e6, 0.0, double.PositiveInfinity, 0.0)] + [Row(-8.388608e6, 0.0, double.PositiveInfinity, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.0000000000000071, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, 1.0000000000000071, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, double.PositiveInfinity, double.PositiveInfinity)] + [Row(-8.388608e6, -1.19209289550780998537e-7, double.PositiveInfinity, double.PositiveInfinity)] + [Row(0.5, -0.5, 0.9895848833999199, -0.24982639750046154)] + public void CanComputeComplexHyperbolicCosine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).HyperbolicCosine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, 0.0, 0.0)] + [Row(8.388608e6, 0.0, 1.0, 0.0)] + [Row(-8.388608e6, 0.0, -1.0, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078043e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078043e-7, 0.0)] + //[Row(8.388608e6, 1.19209289550780998537e-7, 1.0, 0.0)] + //[Row(-8.388608e6, -1.19209289550780998537e-7, -1.0, 0.0)] + [Row(0.5, -0.5, 0.56408314126749848, -0.40389645531602575)] + public void CanComputeComplexHyperbolicTangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).HyperbolicTangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, double.PositiveInfinity, 0.0)] + [Row(8.388608e6, 0.0, 1.0, 0.0)] + [Row(-8.388608e6, 0.0, -1.0, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 8388608.0000000574, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -8388608.0000000574, 0.0)] +// [Row(8.388608e6, 1.19209289550780998537e-7, 1.0, 0.0)] + //[Row(-8.388608e6, -1.19209289550780998537e-7, -1.0, 0.0)] + [Row(0.5, -0.5, 1.1719451445243514, -0.8391395790248311)] + public void CanComputeComplexHyperbolicCotangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).HyperbolicCotangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, 1.0, 0.0)] + [Row(8.388608e6, 0.0, 0.0, 0.0)] + [Row(-8.388608e6, 0.0, 0.0, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 0.99999999999999289, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, 0.99999999999999289, 0.0)] +// [Row(8.388608e6, 1.19209289550780998537e-7, 0.0, 0.0)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -0.0, 0.0)] + [Row(0.5, -0.5, 0.94997886761549463, 0.23982763093808804)] + public void CanComputeComplexHyperbolicSecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).HyperbolicSecant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, double.PositiveInfinity, 0.0)] + [Row(8.388608e6, 0.0, 0.0, 0.0)] + [Row(-8.388608e6, 0.0, 0.0, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 8388607.9999999978, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -8388607.9999999978, 0.0)] +// [Row(8.388608e6, 1.19209289550780998537e-7, 0.0, 0.0)] + [Row(-8.388608e6, -1.19209289550780998537e-7, 0.0, 0.0)] + [Row(0.5, -0.5, 0.91207426403881078, 1.0782296946540223)] + public void CanComputeComplexHyperbolicCosecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).HyperbolicCosecant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0,0.0, 0.0 )] + [Row(8.388608e6, 0.0, 1.5707963267948966, -16.635532333438682)] + [Row(-8.388608e6, 0.0, -1.5707963267948966, 16.635532333438682)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078128e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078128e-7, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.5707963267948966, 16.635532333438682)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.5707963267948966, -16.635532333438682)] + [Row(0.5, -0.5, 0.4522784471511907, -0.53063753095251787)] + public void CanComputeComplexInverseSine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseSine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, 1.5707963267948966, 0.0)] + [Row(8.388608e6, 0.0, 0.0, 16.635532333438682)] + [Row(-8.388608e6, 0.0, 3.1415926535897931, -16.635532333438682)] + [Row(1.19209289550780998537e-7, 0.0, 1.570796207585607, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, 1.5707964460041861, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.4210854715202073e-14, -16.635532333438682)] + [Row(-8.388608e6, -1.19209289550780998537e-7, 3.1415926535897789,16.63553233343868)] + [Row(0.5, -0.5, 1.1185178796437059,0.53063753095251787)] + public void CanComputeComplexInverseCosine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseCosine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, 0.0, 0.0)] + [Row(8.388608e6, 0.0, 1.570796207585607, 0.0 )] + [Row(-8.388608e6, 0.0, -1.570796207585607,0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078043e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078043e-7, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.570796207585607, 0.0)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.570796207585607, 0.0)] + [Row(0.5, -0.5, 0.5535743588970452, -0.40235947810852507)] + public void CanComputeComplexInverseTangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseTangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(0.0, 0.0, Math.PI/2.0, 0.0)] + [Row(8.388608e6, 0.0, 1.1920928955078069e-7, 0.0)] + [Row(-8.388608e6, 0.0, -1.1920928955078069e-7, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.5707962075856071, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.5707962075856071, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.1920928955078069e-7, -1.6907571720583645e-21)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.1920928955078069e-7, 1.6907571720583645e-21)] + [Row(0.5, -0.5, 1.0172219678978514, 0.40235947810852509)] + public void CanComputeComplexInverseCotangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseCotangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 1.5707962075856071, 0.0)] + [Row(-8.388608e6, 0.0, 1.5707964460041862, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 0.0, 16.635532333438686)] + [Row(-1.19209289550780998537e-7, 0.0, 3.1415926535897932, -16.635532333438686)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.5707962075856071, 1.6940658945086007e-21)] + [Row(-8.388608e6, -1.19209289550780998537e-7, 1.5707964460041862, -1.6940658945086007e-21)] + [Row(0.5, -0.5, 0.90455689430238136,-1.0612750619050357)] + public void CanComputeComplexInverseSecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseSecant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 1.1920928955078153e-7, 0.0)] + [Row(-8.388608e6, 0.0, -1.1920928955078153e-7, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.5707963267948966, -16.635532333438686)] + [Row(-1.19209289550780998537e-7, 0.0, -1.5707963267948966, 16.635532333438686)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.1920928955078153e-7, -1.6940658945086007e-21)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.1920928955078153e-7, 1.6940658945086007e-21)] + [Row(0.5, -0.5, 0.66623943249251526, 1.0612750619050357)] + public void CanComputeComplexInverseCosecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseCosecant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 16.63553233343869, 0.0)] + [Row(-8.388608e6, 0.0, -16.63553233343869, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078072e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078072e-7, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 16.63553233343869, 1.4210854715201873e-14)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -16.63553233343869, -1.4210854715201873e-14)] + [Row(0.5, -0.5, 0.53063753095251787, -0.4522784471511907)] + public void CanComputeComplexInverseHyperbolicSine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseHyperbolicSine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 16.635532333438682, 0.0)] + [Row(-8.388608e6, 0.0, 16.635532333438682, 3.1415926535897931)] + [Row(1.19209289550780998537e-7, 0.0, 0.0, 1.570796207585607)] + [Row(-1.19209289550780998537e-7, 0.0, 0.0, 1.5707964460041861)] + [Row(8.388608e6, 1.19209289550780998537e-7, 16.635532333438682, 1.4210854715202073e-14)] + [Row(-8.388608e6, -1.19209289550780998537e-7, 16.635532333438682, -3.1415926535897789)] + [Row(0.5, -0.5, 0.53063753095251787, -1.1185178796437059)] + public void CanComputeComplexInverseHyperbolicCosine(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseHyperbolicCosine(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 1.1920928955078125e-7, -1.5707963267948966)] + [Row(-8.388608e6, 0.0, -1.1920928955078125e-7, 1.5707963267948966)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078157e-7, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078157e-7, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.1920928955078125e-7, 1.5707963267948966)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.1920928955078125e-7, -1.5707963267948966)] + [Row(0.5, -0.5, 0.40235947810852509, -0.55357435889704525)] + public void CanComputeComplexInverseHyperbolicTangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseHyperbolicTangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 1.1920928955078181e-7, 0.0)] + [Row(-8.388608e6, 0.0, -1.1920928955078181e-7, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 1.1920928955078157e-7, -1.5707963267948966)] + [Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078157e-7, 1.5707963267948966)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.1920928955078181e-7, -1.6940658945086212e-21)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.1920928955078181e-7, 1.6940658945086212e-21)] + [Row(0.5, -0.5, 0.40235947810852509, 1.0172219678978514)] + public void CanComputeComplexInverseHyperbolicCotangent(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseHyperbolicCotangent(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 0.0, 1.5707962075856071)] + [Row(-8.388608e6, 0.0, 0.0, 1.5707964460041862)] + [Row(1.19209289550780998537e-7, 0.0, 16.635532333438686, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, 16.635532333438686, 3.1415926535897932)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.6940658945086007e-21, -1.5707962075856071)] + [Row(-8.388608e6, -1.19209289550780998537e-7, 1.6940658945086007e-21, 1.5707964460041862)] + [Row(0.5, -0.5, 1.0612750619050357, 0.90455689430238136)] + public void CanComputeComplexInverseHyperbolicSecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseHyperbolicSecant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + + [Test] + [Row(8.388608e6, 0.0, 1.1920928955078097e-7, 0.0)] + [Row(-8.388608e6, 0.0, -1.1920928955078097e-7, 0.0)] + [Row(1.19209289550780998537e-7, 0.0, 16.635532333438693, 0.0)] + [Row(-1.19209289550780998537e-7, 0.0, -16.635532333438693, 0.0)] + [Row(8.388608e6, 1.19209289550780998537e-7, 1.1920928955078076e-7, -1.6940658945085851e-21)] + [Row(-8.388608e6, -1.19209289550780998537e-7, -1.1920928955078076e-7, 1.6940658945085851e-21)] + [Row(0.5, -0.5, 1.0612750619050357, 0.66623943249251526)] + public void CanComputeComplexInverseHyperbolicCosecant(double real, double imag, double expectedReal, double expectedImag) + { + var actual = new Complex(real, imag).InverseHyperbolicCosecant(); + var expected = new Complex(expectedReal, expectedImag); + AssertHelpers.AlmostEqual(expected, actual, 14); + } + } +} \ No newline at end of file diff --git a/src/Managed/Complex.cs b/src/Managed/Complex.cs index 517f3411..994304a4 100644 --- a/src/Managed/Complex.cs +++ b/src/Managed/Complex.cs @@ -29,7 +29,7 @@ namespace MathNet.Numerics using System.Text; using System.Text.RegularExpressions; - using Properties; + using MathNet.Numerics.Properties; /// /// Complex numbers class. @@ -48,7 +48,7 @@ namespace MathNet.Numerics /// /// In order to avoid possible ambiguities resulting from a /// Complex(double, double) constructor, the static methods - /// and + /// and /// are provided instead. /// /// @@ -432,6 +432,164 @@ namespace MathNet.Numerics } } + #region Exponential Functions + + /// + /// Exponential of this Complex (exp(x), E^x). + /// + /// + /// The exponential of this complex number. + /// + public Complex Exponential() + { + var exp = Math.Exp(_real); + if (IsReal) + { + return new Complex(exp, 0.0); + } + + return new Complex(exp * Trig.Cosine(_imag), exp * Trig.Sine(_imag)); + } + + /// + /// Natural Logarithm of this Complex (Base E). + /// + /// + /// The natural logarithm of this complex number. + /// + public Complex NaturalLogarithm() + { + if (IsRealNonNegative) + { + return new Complex(Math.Log(_real), 0.0); + } + + return new Complex(0.5 * Math.Log(ModulusSquared), Argument); + } + + /// + /// Raise this Complex to the given value. + /// + /// + /// The exponent. + /// + /// + /// The complex number raised to the given exponent. + /// + public Complex Power(Complex exponent) + { + if (IsZero) + { + if (exponent.IsZero) + { + return One; + } + + if (exponent.Real > 0.0) + { + return Zero; + } + + if (exponent.Real < 0) + { + if (exponent.Imaginary.AlmostZero()) + { + return new Complex(double.PositiveInfinity, 0.0); + } + + return new Complex(double.PositiveInfinity, double.PositiveInfinity); + } + + return NaN; + } + + return (exponent * NaturalLogarithm()).Exponential(); + } + + /// + /// Raise this Complex to the inverse of the given value. + /// + /// + /// The root exponent. + /// + /// + /// The complex raised to the inverse of the given exponent. + /// + public Complex Root(Complex rootexponent) + { + return Power(1 / rootexponent); + } + + /// + /// The Square (power 2) of this Complex + /// + /// + /// The square of this complex number. + /// + public Complex Square() + { + if (IsReal) + { + return new Complex(_real * _real, 0.0); + } + + return new Complex((_real * _real) - (_imag * _imag), 2 * _real * _imag); + } + + /// + /// The Square Root (power 1/2) of this Complex + /// + /// + /// The square root of this complex number. + /// + public Complex SquareRoot() + { + if (IsRealNonNegative) + { + return new Complex(Math.Sqrt(_real), 0.0); + } + + Complex result; + + if (Real.AlmostZero() && Imaginary.AlmostZero()) + { + result = Zero; + } + else + { + var absReal = Math.Abs(Real); + var absImag = Math.Abs(Imaginary); + double w; + if (absReal >= absImag) + { + var ratio = Imaginary / Real; + w = Math.Sqrt(absReal) * Math.Sqrt(0.5 * (1.0 + Math.Sqrt(1.0 + (ratio * ratio)))); + } + else + { + var ratio = Real / Imaginary; + w = Math.Sqrt(absImag) * Math.Sqrt(0.5 * (Math.Abs(ratio) + Math.Sqrt(1.0 + (ratio * ratio)))); + } + + if (Real >= 0.0) + { + result = new Complex(w, Imaginary / (2.0 * w)); + } + else if (Imaginary >= 0.0) + { + result = new Complex(absImag / (2.0 * w), w); + } + else + { + result = new Complex(absImag / (2.0 * w), -w); + } + } + + return result; + } + + #endregion + #region Static Initializers /// @@ -903,26 +1061,5 @@ namespace MathNet.Numerics } #endregion - - #region Trigonometric Functions - - /// - /// Trigonometric Sine (sin, Sinus) of this Complex. - /// - /// - /// The sine of the complex number. - /// - public Complex Sine() - { - if (this.IsReal) - { - return new Complex(Math.Sin(this._real), 0.0); - } - - return new Complex( - Math.Sin(this._real) * Math.Cosh(this._imag), Math.Cos(this._real) * Math.Sinh(this._imag)); - } - - #endregion } } \ No newline at end of file diff --git a/src/Managed/Managed.csproj b/src/Managed/Managed.csproj index af99fdf5..a8b5c64d 100644 --- a/src/Managed/Managed.csproj +++ b/src/Managed/Managed.csproj @@ -90,6 +90,7 @@ + diff --git a/src/Managed/Properties/Resources.Designer.cs b/src/Managed/Properties/Resources.Designer.cs index 19baa33c..75491370 100644 --- a/src/Managed/Properties/Resources.Designer.cs +++ b/src/Managed/Properties/Resources.Designer.cs @@ -60,6 +60,15 @@ namespace MathNet.Numerics.Properties { } } + /// + /// Looks up a localized string similar to Value cannot be in the range -1 < x < 1.. + /// + internal static string ArgumentCannotBeBetweenOneAndNegativeOne { + get { + return ResourceManager.GetString("ArgumentCannotBeBetweenOneAndNegativeOne", resourceCulture); + } + } + /// /// Looks up a localized string similar to Value must be even.. /// @@ -96,6 +105,15 @@ namespace MathNet.Numerics.Properties { } } + /// + /// Looks up a localized string similar to Value must be greater than or equal to one.. + /// + internal static string ArgumentLessThanOne { + get { + return ResourceManager.GetString("ArgumentLessThanOne", resourceCulture); + } + } + /// /// Looks up a localized string similar to The matrix indices must not be out of range of the given matrix.. /// diff --git a/src/Managed/Properties/Resources.resx b/src/Managed/Properties/Resources.resx index 5f7c0621..9b0f50e0 100644 --- a/src/Managed/Properties/Resources.resx +++ b/src/Managed/Properties/Resources.resx @@ -252,4 +252,10 @@ The supplied collection is empty. + + Value cannot be in the range -1 < x < 1. + + + Value must be greater than or equal to one. + \ No newline at end of file diff --git a/src/Native.UnitTests/Native.UnitTests.csproj b/src/Native.UnitTests/Native.UnitTests.csproj index 5a368662..b08f8b58 100644 --- a/src/Native.UnitTests/Native.UnitTests.csproj +++ b/src/Native.UnitTests/Native.UnitTests.csproj @@ -110,6 +110,9 @@ ThreadingTests\ParallelTest.cs + + TrigonometryTest.cs + diff --git a/src/Native/Native.csproj b/src/Native/Native.csproj index ac5f1b07..dffba52b 100644 --- a/src/Native/Native.csproj +++ b/src/Native/Native.csproj @@ -164,6 +164,9 @@ Threading\ThreadQueue.cs + + Trigonometry.cs +