Browse Source

Apply approximation to Asinh(x) and Acosh(x)

spatial
diluculo 9 years ago
parent
commit
a52e39be05
  1. 14
      src/Numerics/Trigonometry.cs
  2. 3
      src/UnitTests/TrigonometryTest.cs

14
src/Numerics/Trigonometry.cs

@ -713,7 +713,13 @@ namespace MathNet.Numerics
/// <returns>The hyperbolic angle, i.e. the area of its hyperbolic sector.</returns>
public static double Asinh(double value)
{
return Math.Log(value + Math.Sqrt((value * value) + 1), Math.E);
// asinh(x) = Sign(x) * ln(|x| + sqrt(x*x + 1))
// if |x| > huge, asinh(x) ~= Sign(x) * ln(2|x|)
if (Math.Abs(value) >= 268435456.0) // 2^28, taken from freeBSD
return Math.Sign(value) * (Math.Log(Math.Abs(value)) + Math.Log(2.0));
return Math.Sign(value) * Math.Log(Math.Abs(value) + Math.Sqrt((value * value) + 1));
}
/// <summary>
@ -733,6 +739,12 @@ namespace MathNet.Numerics
/// <returns>The hyperbolic angle, i.e. the area of its hyperbolic sector.</returns>
public static double Acosh(double value)
{
// acosh(x) = ln(x + sqrt(x*x - 1))
// if |x| >= 2^28, acosh(x) ~ ln(x) + ln(2)
if (Math.Abs(value) >= 268435456.0) // 2^28, taken from freeBSD
return Math.Log(value) + Math.Log(2.0);
return Math.Log(value + (Math.Sqrt(value - 1) * Math.Sqrt(value + 1)), Math.E);
}

3
src/UnitTests/TrigonometryTest.cs

@ -338,6 +338,7 @@ namespace MathNet.Numerics.UnitTests
/// <param name="expected">Expected value.</param>
[TestCase(1.0, 0.0)]
[TestCase(8388608, 16.635532333438682)]
[TestCase(1.7976931348623157E+308, 710.47586007394394203711)]
public void CanComputeInverseHyperbolicCosine(double value, double expected)
{
var actual = Trig.Acosh(value);
@ -383,6 +384,8 @@ namespace MathNet.Numerics.UnitTests
[TestCase(-8388608, -16.63553233343869)]
[TestCase(1.19209289550780998537e-7, 1.1920928955078072e-7)]
[TestCase(-1.19209289550780998537e-7, -1.1920928955078072e-7)]
[TestCase(1.7976931348623157E+308, 710.47586007394394203711)]
[TestCase(-1.7976931348623157E+308, -710.47586007394394203711)]
public void CanComputeInverseHyperbolicSine(double value, double expected)
{
var actual = Trig.Asinh(value);

Loading…
Cancel
Save