From dd51fd8dcabe610a5ece0fb905bbf7b98cfdf565 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Tue, 11 Aug 2009 21:56:08 +0800 Subject: [PATCH] Trig: suggestion for handling extreme cases Signed-off-by: Christoph Ruegg --- src/Managed.UnitTests/TrigonometryTest.cs | 12 ++++++------ src/Managed/Trigonometry.cs | 24 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Managed.UnitTests/TrigonometryTest.cs b/src/Managed.UnitTests/TrigonometryTest.cs index 8a49b4b2..1e31ea4f 100644 --- a/src/Managed.UnitTests/TrigonometryTest.cs +++ b/src/Managed.UnitTests/TrigonometryTest.cs @@ -449,8 +449,8 @@ [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(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) { @@ -465,8 +465,8 @@ [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(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) { @@ -481,7 +481,7 @@ [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(-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) @@ -497,7 +497,7 @@ [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(-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) diff --git a/src/Managed/Trigonometry.cs b/src/Managed/Trigonometry.cs index b691e979..8fcecba1 100644 --- a/src/Managed/Trigonometry.cs +++ b/src/Managed/Trigonometry.cs @@ -232,6 +232,12 @@ namespace MathNet.Numerics } var exp = value.Exponential(); + + if (exp.IsInfinity) + { + return Complex.Zero; + } + return 2 * exp / (exp.Square() - 1); } @@ -314,6 +320,12 @@ namespace MathNet.Numerics var sini = Sine(value.Imaginary); var sinhr = HyperbolicSine(value.Real); + + if (double.IsInfinity(sinhr)) + { + return new Complex(double.IsPositiveInfinity(sinhr) ? 1 : -1, 0.0); + } + var denom = (sini * sini) + (sinhr * sinhr); return new Complex(sinhr * HyperbolicCosine(value.Real) / denom, sini * Cosine(value.Imaginary) / denom); @@ -350,6 +362,12 @@ namespace MathNet.Numerics } var exp = value.Exponential(); + + if (exp.IsInfinity) + { + return Complex.Zero; + } + return 2 * exp / (exp.Square() + 1); } @@ -432,6 +450,12 @@ namespace MathNet.Numerics var cosi = Cosine(value.Imaginary); var sinhr = HyperbolicSine(value.Real); + + if (double.IsInfinity(sinhr)) + { + return new Complex(double.IsPositiveInfinity(sinhr) ? 1 : -1, 0.0); + } + var denom = (cosi * cosi) + (sinhr * sinhr); return new Complex(HyperbolicCosine(value.Real) * sinhr / denom, cosi * Sine(value.Imaginary) / denom);