// // Math.NET Numerics, part of the Math.NET Project // http://mathnet.opensourcedotnet.info // Copyright (c) 2009 Math.NET // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // namespace MathNet.Numerics { using System; /// /// Double-precision trigonometry toolkit. /// public static class Trig { /// /// Constant to convert a degree to grad. /// private const double DegreeToGradConstant = 10.0 / 9.0; /// /// Trigonometric Cosecant of an angle in radian. /// /// /// The angle in radian. /// /// /// Cosecant of an angle in radian. /// public static double Cosecant(double radian) { return 1 / Math.Sin(radian); } /// /// Trigonometric Cosecant of a Complex number. /// /// /// The complex value. /// /// /// The cosecant of a complex number. /// public static Complex Cosecant(this Complex value) { if (value.IsReal) { return new Complex(Cosecant(value.Real), 0d); } var sinr = Sine(value.Real); var sinhi = HyperbolicSine(value.Imaginary); var denom = (sinr * sinr) + (sinhi * sinhi); return new Complex(sinr * HyperbolicCosine(value.Imaginary) / denom, -Cosine(value.Real) * sinhi / denom); } /// /// Trigonometric Cosine of an angle in radian. /// /// /// The angle in radian. /// /// /// The cosine of an angle in radian. /// public static double Cosine(double radian) { return Math.Cos(radian); } /// /// Trigonometric Cosine of a Complex number. /// /// /// The complex value. /// /// /// The cosine of a complex number. /// public static Complex Cosine(this Complex value) { if (value.IsReal) { return new Complex(Cosine(value.Real), 0.0); } return new Complex( Cosine(value.Real) * HyperbolicCosine(value.Imaginary), -Sine(value.Real) * HyperbolicSine(value.Imaginary)); } /// /// Trigonometric Cotangent of an angle in radian. /// /// /// The angle in radian. /// /// /// The cotangent of an angle in radian. /// public static double Cotangent(double radian) { return 1 / Math.Tan(radian); } /// /// Trigonometric Cotangent of a Complex number. /// /// /// The complex value. /// /// /// The cotangent of the complex number. /// public static Complex Cotangent(this Complex value) { if (value.IsReal) { return new Complex(Cotangent(value.Real), 0d); } var sinr = Sine(value.Real); var sinhi = HyperbolicSine(value.Imaginary); var denom = (sinr * sinr) + (sinhi * sinhi); return new Complex(sinr * Cosine(value.Real) / denom, -sinhi * HyperbolicCosine(value.Imaginary) / denom); } /// /// Converts a degree (360-periodic) angle to a grad (400-periodic) angle. /// /// /// The degree to convert. /// /// /// The converted grad angle. /// public static double DegreeToGrad(double degree) { return degree * DegreeToGradConstant; } /// /// Converts a degree (360-periodic) angle to a radian (2*Pi-periodic) angle. /// /// /// The degree to convert. /// /// /// The converted radian angle. /// public static double DegreeToRadian(double degree) { return degree * Constants.Degree; } /// /// Converts a grad (400-periodic) angle to a degree (360-periodic) angle. /// /// /// The grad to convert. /// /// /// The converted degree. /// public static double GradToDegree(double grad) { return grad * 0.9; } /// /// Converts a grad (400-periodic) angle to a radian (2*Pi-periodic) angle. /// /// /// The grad to convert. /// /// /// The converted radian. /// public static double GradToRadian(double grad) { return grad * Constants.Grad; } /// /// Trigonometric Hyperbolic Cosecant /// /// /// The angle in radian. /// /// /// The hyperbolic cosecant of the radian angle. /// public static double HyperbolicCosecant(double radian) { return 1 / HyperbolicSine(radian); } /// /// Trigonometric Hyperbolic Cosecant of a Complex number. /// /// /// The complex value. /// /// /// The hyperbolic cosecant of a complex number. /// public static Complex HyperbolicCosecant(this Complex value) { if (value.IsReal) { return new Complex(HyperbolicCosecant(value.Real), 0.0); } var exp = value.Exponential(); if (exp.IsInfinity) { return Complex.Zero; } return 2 * exp / (exp.Square() - 1); } /// /// Trigonometric Hyperbolic Cosine /// /// /// The angle in radian. /// /// /// The hyperbolic Cosine of the radian angle. /// public static double HyperbolicCosine(double radian) { return (Math.Exp(radian) + Math.Exp(-radian)) / 2; } /// /// Trigonometric Hyperbolic Cosine of a Complex number. /// /// /// The complex value. /// /// /// The hyperbolic cosine of a complex number. /// public static Complex HyperbolicCosine(this Complex value) { if (value.IsReal) { return new Complex(HyperbolicCosine(value.Real), 0.0); } return new Complex( HyperbolicCosine(value.Real) * Cosine(value.Imaginary), HyperbolicSine(value.Real) * Sine(value.Imaginary)); } /// /// Trigonometric Hyperbolic Cotangent /// /// /// The angle in radian angle. /// /// /// The hyperbolic cotangent of the radian angle. /// public static double HyperbolicCotangent(double radian) { if (radian > 19.115) { return 1.0; } if (radian < -19.115) { return -1; } var e1 = Math.Exp(radian); var e2 = Math.Exp(-radian); return (e1 + e2) / (e1 - e2); } /// /// Trigonometric Hyperbolic Cotangent of a Complex number. /// /// /// The complex value. /// /// /// The hyperbolic cotangent of a complex number. /// public static Complex HyperbolicCotangent(this Complex value) { if (value.IsReal) { return new Complex(HyperbolicCotangent(value.Real), 0.0); } 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); } /// /// Trigonometric Hyperbolic Secant /// /// /// The angle in radian angle. /// /// /// The hyperbolic secant of the radian angle. /// public static double HyperbolicSecant(double radian) { return 1 / HyperbolicCosine(radian); } /// /// Trigonometric Hyperbolic Secant of a Complex number. /// /// /// The complex value. /// /// /// The hyperbolic secant of a complex number. /// public static Complex HyperbolicSecant(this Complex value) { if (value.IsReal) { return new Complex(HyperbolicSecant(value.Real), 0.0); } var exp = value.Exponential(); if (exp.IsInfinity) { return Complex.Zero; } return 2 * exp / (exp.Square() + 1); } /// /// Trigonometric Hyperbolic Sine /// /// /// The angle in radian angle. /// /// /// The hyperbolic sine of the radian angle. /// public static double HyperbolicSine(double radian) { return (Math.Exp(radian) - Math.Exp(-radian)) / 2; } /// /// Trigonometric Hyperbolic Sine of a Complex number. /// /// /// The complex value. /// /// /// The hyperbolic sine of a complex number. /// public static Complex HyperbolicSine(this Complex value) { if (value.IsReal) { return new Complex(HyperbolicSine(value.Real), 0.0); } return new Complex( HyperbolicSine(value.Real) * Cosine(value.Imaginary), HyperbolicCosine(value.Real) * Sine(value.Imaginary)); } /// /// Trigonometric Hyperbolic Tangent in radian /// /// /// The angle in radian angle. /// /// /// The hyperbolic tangent of the radian angle. /// public static double HyperbolicTangent(double radian) { if (radian > 19.1) { return 1.0; } if (radian < -19.1) { return -1; } var e1 = Math.Exp(radian); var e2 = Math.Exp(-radian); return (e1 - e2) / (e1 + e2); } /// /// Trigonometric Hyperbolic Tangent of a Complex number. /// /// /// The complex value. /// /// /// The hyperbolic tangent of a complex number. /// public static Complex HyperbolicTangent(this Complex value) { if (value.IsReal) { return new Complex(HyperbolicTangent(value.Real), 0.0); } 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); } /// /// Trigonometric Arc Cosecant in radian /// /// /// The angle in radian angle. /// /// /// The inverse cosecant of the radian angle. /// /// /// if -1 < < 1. /// public static double InverseCosecant(double radian) { return Math.Asin(1 / radian); } /// /// Trigonometric Arc Cosecant of this Complex number. /// /// /// The complex value. /// /// /// The arc cosecant of a complex number. /// public static Complex InverseCosecant(this Complex value) { var inv = 1 / value; return -Complex.I * ((Complex.I * inv) + (1 - inv.Square()).SquareRoot()).NaturalLogarithm(); } /// /// Trigonometric Arc Cosine in radian /// /// /// The angle in radian angle. /// /// /// The inverse cosine of the radian angle. /// /// /// if 1 < or < -1. /// public static double InverseCosine(double radian) { return Math.Acos(radian); } /// /// Trigonometric Arc Cosine of this Complex number. /// /// /// The complex value. /// /// /// The arc cosine of a complex number. /// public static Complex InverseCosine(this Complex value) { return -Complex.I * (value + (Complex.I * (1 - value.Square()).SquareRoot())).NaturalLogarithm(); } /// /// Trigonometric Arc Cotangent in radian /// /// /// The angle in radian angle. /// /// /// The inverse cotangent of the radian angle. /// public static double InverseCotangent(double radian) { return Math.Atan(1 / radian); } /// /// Trigonometric Arc Cotangent of this Complex number. /// /// /// The complex value. /// /// /// The arc cotangent of a complex number. /// public static Complex InverseCotangent(this Complex value) { if (value.IsZero) { return Math.PI / 2.0; } var inv = Complex.I / value; return (Complex.I * 0.5) * ((1.0 - inv).NaturalLogarithm() - (1.0 + inv).NaturalLogarithm()); } /// /// Trigonometric Hyperbolic Arc Cosecant /// /// /// The angle in radian angle. /// /// /// The inverse hyperbolic cosecant of the radian angle. /// public static double InverseHyperbolicCosecant(double radian) { return InverseHyperbolicSine(1 / radian); } /// /// Trigonometric Hyperbolic Arc Cosecant of this Complex number. /// /// /// The complex value. /// /// /// The hyperbolic arc cosecant of a complex number. /// public static Complex InverseHyperbolicCosecant(this Complex value) { var inv = 1 / value; return (inv + (inv.Square() + 1).SquareRoot()).NaturalLogarithm(); } /// /// Trigonometric Hyperbolic Area Cosine /// /// /// The angle in radian angle. /// /// /// The inverse hyperbolic cosine of the radian angle. /// public static double InverseHyperbolicCosine(double radian) { return Math.Log(radian + (Math.Sqrt(radian - 1) * Math.Sqrt(radian + 1)), Math.E); } /// /// Trigonometric Hyperbolic Arc Cosine of this Complex number. /// /// /// The complex value. /// /// /// The hyperbolic arc cosine of a complex number. /// public static Complex InverseHyperbolicCosine(this Complex value) { return (value + ((value - 1).SquareRoot() * (value + 1).SquareRoot())).NaturalLogarithm(); } /// /// Trigonometric Hyperbolic Arc Cotangent /// /// /// The angle in radian angle. /// /// /// The inverse hyperbolic cotangent of the radian angle. /// public static double InverseHyperbolicCotangent(double radian) { return 0.5 * Math.Log((radian + 1) / (radian - 1), Math.E); } /// /// Trigonometric Hyperbolic Arc Cotangent of this Complex number. /// /// /// The complex value. /// /// /// The hyperbolic arc cotangent of a complex number. /// public static Complex InverseHyperbolicCotangent(this Complex value) { var inv = 1.0 / value; return 0.5 * ((1.0 + inv).NaturalLogarithm() - (1.0 - inv).NaturalLogarithm()); } /// /// Trigonometric Hyperbolic Area Secant /// /// /// The angle in radian angle. /// /// /// The inverse hyperbolic secant of the radian angle. /// public static double InverseHyperbolicSecant(double radian) { return InverseHyperbolicCosine(1 / radian); } /// /// Trigonometric Hyperbolic Arc Secant of this Complex number. /// /// /// The complex value. /// /// /// The hyperbolic arc secant of a complex number. /// public static Complex InverseHyperbolicSecant(this Complex value) { var inv = 1 / value; return (inv + ((inv - 1).SquareRoot() * (inv + 1).SquareRoot())).NaturalLogarithm(); } /// /// Trigonometric Hyperbolic Area Sine /// /// /// The angle in radian angle. /// /// /// The inverse hyperbolic sine of the radian angle. /// public static double InverseHyperbolicSine(double radian) { return Math.Log(radian + Math.Sqrt((radian * radian) + 1), Math.E); } /// /// Trigonometric Hyperbolic Arc Sine of this Complex number. /// /// /// The complex value. /// /// /// The hyperbolic arc sine of a complex number. /// public static Complex InverseHyperbolicSine(this Complex value) { return (value + (value.Square() + 1).SquareRoot()).NaturalLogarithm(); } /// /// Trigonometric Hyperbolic Area Tangent /// /// /// The angle in radian angle. /// /// /// The inverse hyperbolic tangent of the radian angle. /// public static double InverseHyperbolicTangent(double radian) { return 0.5 * Math.Log((1 + radian) / (1 - radian), Math.E); } /// /// Trigonometric Hyperbolic Arc Tangent of this Complex number. /// /// /// The complex value. /// /// /// The hyperbolic arc tangent of a complex number. /// public static Complex InverseHyperbolicTangent(this Complex value) { return 0.5 * ((1 + value).NaturalLogarithm() - (1 - value).NaturalLogarithm()); } /// /// Trigonometric Arc Secant in radian /// /// /// The angle in radian angle. /// /// /// The inverse secant of the radian angle. /// public static double InverseSecant(double radian) { return Math.Acos(1 / radian); } /// /// Trigonometric Arc Secant of this Complex number. /// /// /// The complex value. /// /// /// The arc secant of a complex number. /// public static Complex InverseSecant(this Complex value) { var inv = 1 / value; return -Complex.I * (inv + (Complex.I * (1 - inv.Square()).SquareRoot())).NaturalLogarithm(); } /// /// Trigonometric Arc Sine in radian /// /// /// The angle in radian angle. /// /// /// The inverse sine of the radian angle. /// public static double InverseSine(double radian) { return Math.Asin(radian); } /// /// Trigonometric Arc Sine of this Complex number. /// /// /// The complex value. /// /// /// The arc sine of a complex number. /// public static Complex InverseSine(this Complex value) { return -Complex.I * ((1 - value.Square()).SquareRoot() + (Complex.I * value)).NaturalLogarithm(); } /// /// Trigonometric Arc Tangent in radian /// /// /// The angle in radian angle. /// /// /// The inverse tangent of the radian angle. /// public static double InverseTangent(double radian) { return Math.Atan(radian); } /// /// Trigonometric Arc Tangent of this Complex number. /// /// /// The complex value. /// /// /// The arc tangent of a complex number. /// public static Complex InverseTangent(this Complex value) { var iz = new Complex(-value.Imaginary, value.Real); // I*this return new Complex(0, 0.5) * ((1 - iz).NaturalLogarithm() - (1 + iz).NaturalLogarithm()); } /// /// Converts a radian (2*Pi-periodic) angle to a degree (360-periodic) angle. /// /// /// The radian to convert. /// /// /// The converted degree. /// public static double RadianToDegree(double radian) { return radian / Constants.Degree; } /// /// Converts a radian (2*Pi-periodic) angle to a grad (400-periodic) angle. /// /// /// The radian to convert. /// /// /// The converted grad. /// public static double RadianToGrad(double radian) { return radian / Constants.Grad; } /// /// Trigonometric Secant of an angle in radian /// /// /// The angle in radian. /// /// /// The secant of the radian angle. /// public static double Secant(double radian) { return 1 / Math.Cos(radian); } /// /// Trigonometric Secant of a Complex number. /// /// /// The complex value. /// /// /// The secant of the complex number. /// public static Complex Secant(this Complex value) { if (value.IsReal) { return new Complex(Secant(value.Real), 0d); } var cosr = Cosine(value.Real); var sinhi = HyperbolicSine(value.Imaginary); var denom = (cosr * cosr) + (sinhi * sinhi); return new Complex(cosr * HyperbolicCosine(value.Imaginary) / denom, Sine(value.Real) * sinhi / denom); } /// /// Trigonometric Sine of an angle in radian /// /// /// The angle in radian. /// /// /// The sine of the radian angle. /// public static double Sine(double radian) { return Math.Sin(radian); } /// /// Trigonometric Sine of a Complex number. /// /// /// The complex value. /// /// /// The sine of the complex number. /// public static Complex Sine(this Complex value) { if (value.IsReal) { return new Complex(Sine(value.Real), 0.0); } return new Complex( Sine(value.Real) * HyperbolicCosine(value.Imaginary), Cosine(value.Real) * HyperbolicSine(value.Imaginary)); } /// /// Trigonometric Tangent of an angle in radian /// /// /// The angle in radian. /// /// /// The tangent of the radian angle. /// public static double Tangent(double radian) { return Math.Tan(radian); } /// /// Trigonometric Tangent of a Complex number. /// /// /// The complex value. /// /// /// The tangent of the complex number. /// public static Complex Tangent(this Complex value) { if (value.IsReal) { return new Complex(Tangent(value.Real), 0.0); } var cosr = Cosine(value.Real); var sinhi = HyperbolicSine(value.Imaginary); var denom = (cosr * cosr) + (sinhi * sinhi); return new Complex(Sine(value.Real) * cosr / denom, sinhi * HyperbolicCosine(value.Imaginary) / denom); } } }