// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // // Copyright (c) 2009-2010 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. // using System; using System.Collections.Generic; using System.Globalization; using System.Runtime.InteropServices; using System.Runtime.Serialization; using Complex = System.Numerics.Complex; using BigInteger = System.Numerics.BigInteger; #if !NETSTANDARD1_3 using System.Runtime; #endif namespace IStation.Numerics { /// /// 32-bit single precision complex numbers class. /// /// /// /// The class Complex32 provides all elementary operations /// on complex numbers. All the operators +, -, /// *, /, ==, != are defined in the /// canonical way. Additional complex trigonometric functions /// are also provided. Note that the Complex32 structures /// has two special constant values and /// . /// /// /// /// Complex32 x = new Complex32(1f,2f); /// Complex32 y = Complex32.FromPolarCoordinates(1f, Math.Pi); /// Complex32 z = (x + y) / (x - y); /// /// /// /// For mathematical details about complex numbers, please /// have a look at the /// Wikipedia /// /// [Serializable] [StructLayout(LayoutKind.Sequential)] [DataContract(Namespace = "urn:IStation/Numerics")] public readonly struct Complex32 : IFormattable, IEquatable { /// /// The real component of the complex number. /// [DataMember(Order = 1)] private readonly float _real; /// /// The imaginary component of the complex number. /// [DataMember(Order = 2)] private readonly float _imag; /// /// Initializes a new instance of the Complex32 structure with the given real /// and imaginary parts. /// /// The value for the real component. /// The value for the imaginary component. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public Complex32(float real, float imaginary) { _real = real; _imag = imaginary; } /// /// Creates a complex number from a point's polar coordinates. /// /// A complex number. /// The magnitude, which is the distance from the origin (the intersection of the x-axis and the y-axis) to the number. /// The phase, which is the angle from the line to the horizontal axis, measured in radians. public static Complex32 FromPolarCoordinates(float magnitude, float phase) { return new Complex32(magnitude * (float)Math.Cos(phase), magnitude * (float)Math.Sin(phase)); } /// /// Returns a new instance /// with a real number equal to zero and an imaginary number equal to zero. /// public static readonly Complex32 Zero = new Complex32(0.0f, 0.0f); /// /// Returns a new instance /// with a real number equal to one and an imaginary number equal to zero. /// public static readonly Complex32 One = new Complex32(1.0f, 0.0f); /// /// Returns a new instance /// with a real number equal to zero and an imaginary number equal to one. /// public static readonly Complex32 ImaginaryOne = new Complex32(0, 1); /// /// Returns a new instance /// with real and imaginary numbers positive infinite. /// public static readonly Complex32 PositiveInfinity = new Complex32(float.PositiveInfinity, float.PositiveInfinity); /// /// Returns a new instance /// with real and imaginary numbers not a number. /// public static readonly Complex32 NaN = new Complex32(float.NaN, float.NaN); /// /// Gets the real component of the complex number. /// /// The real component of the complex number. public float Real { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get => _real; } /// /// Gets the real imaginary component of the complex number. /// /// The real imaginary component of the complex number. public float Imaginary { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get => _imag; } /// /// Gets the phase or argument of this Complex32. /// /// /// Phase always returns a value bigger than negative Pi and /// smaller or equal to Pi. If this Complex32 is zero, the Complex32 /// is assumed to be positive real with an argument of zero. /// /// The phase or argument of this Complex32 public float Phase { // NOTE: the special case for negative real numbers fixes negative-zero value behavior. Do not remove. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get => _imag == 0f && _real < 0f ? (float)Constants.Pi : (float)Math.Atan2(_imag, _real); } /// /// Gets the magnitude (or absolute value) of a complex number. /// /// Assuming that magnitude of (inf,a) and (a,inf) and (inf,inf) is inf and (NaN,a), (a,NaN) and (NaN,NaN) is NaN /// The magnitude of the current instance. public float Magnitude { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { if (float.IsNaN(_real) || float.IsNaN(_imag)) return float.NaN; if (float.IsInfinity(_real) || float.IsInfinity(_imag)) return float.PositiveInfinity; float a = Math.Abs(_real); float b = Math.Abs(_imag); if (a > b) { double tmp = b / a; return a * (float)Math.Sqrt(1.0f + tmp * tmp); } if (a == 0.0f) // one can write a >= float.Epsilon here { return b; } else { double tmp = a / b; return b * (float)Math.Sqrt(1.0f + tmp * tmp); } } } /// /// Gets the squared magnitude (or squared absolute value) of a complex number. /// /// The squared magnitude of the current instance. public float MagnitudeSquared => _real * _real + _imag * _imag; /// /// Gets the unity of this complex (same argument, but on the unit circle; exp(I*arg)) /// /// The unity of this Complex32. public Complex32 Sign { get { if (float.IsPositiveInfinity(_real) && float.IsPositiveInfinity(_imag)) { return new Complex32((float)Constants.Sqrt1Over2, (float)Constants.Sqrt1Over2); } if (float.IsPositiveInfinity(_real) && float.IsNegativeInfinity(_imag)) { return new Complex32((float)Constants.Sqrt1Over2, -(float)Constants.Sqrt1Over2); } if (float.IsNegativeInfinity(_real) && float.IsPositiveInfinity(_imag)) { return new Complex32(-(float)Constants.Sqrt1Over2, -(float)Constants.Sqrt1Over2); } if (float.IsNegativeInfinity(_real) && float.IsNegativeInfinity(_imag)) { return new Complex32(-(float)Constants.Sqrt1Over2, (float)Constants.Sqrt1Over2); } // don't replace this with "Magnitude"! var mod = SpecialFunctions.Hypotenuse(_real, _imag); if (mod == 0.0f) { return Zero; } return new Complex32(_real / mod, _imag / mod); } } /// /// Gets a value indicating whether the Complex32 is zero. /// /// true if this instance is zero; otherwise, false. public bool IsZero() { return _real == 0.0f && _imag == 0.0f; } /// /// Gets a value indicating whether the Complex32 is one. /// /// true if this instance is one; otherwise, false. public bool IsOne() { return _real == 1.0f && _imag == 0.0f; } /// /// Gets a value indicating whether the Complex32 is the imaginary unit. /// /// true if this instance is ImaginaryOne; otherwise, false. public bool IsImaginaryOne() { return _real == 0.0f && _imag == 1.0f; } /// /// Gets a value indicating whether the provided Complex32evaluates /// to a value that is not a number. /// /// /// true if this instance is ; otherwise, /// false. /// public bool IsNaN() { return float.IsNaN(_real) || float.IsNaN(_imag); } /// /// Gets a value indicating whether the provided Complex32 evaluates to an /// infinite value. /// /// /// true if this instance is infinite; otherwise, false. /// /// /// True if it either evaluates to a complex infinity /// or to a directed infinity. /// public bool IsInfinity() { return float.IsInfinity(_real) || float.IsInfinity(_imag); } /// /// Gets a value indicating whether the provided Complex32 is real. /// /// true if this instance is a real number; otherwise, false. public bool IsReal() { return _imag == 0.0f; } /// /// Gets a value indicating whether the provided Complex32 is real and not negative, that is >= 0. /// /// /// true if this instance is real nonnegative number; otherwise, false. /// public bool IsRealNonNegative() { return _imag == 0.0f && _real >= 0; } /// /// Exponential of this Complex32 (exp(x), E^x). /// /// /// The exponential of this complex number. /// public Complex32 Exponential() { var exp = (float)Math.Exp(_real); if (IsReal()) { return new Complex32(exp, 0.0f); } return new Complex32(exp * (float)Math.Cos(_imag), exp * (float)Math.Sin(_imag)); } /// /// Natural Logarithm of this Complex32 (Base E). /// /// The natural logarithm of this complex number. public Complex32 NaturalLogarithm() { if (IsRealNonNegative()) { return new Complex32((float)Math.Log(_real), 0.0f); } return new Complex32(0.5f * (float)Math.Log(MagnitudeSquared), Phase); } /// /// Common Logarithm of this Complex32 (Base 10). /// /// The common logarithm of this complex number. public Complex32 CommonLogarithm() { return NaturalLogarithm() / (float)Constants.Ln10; } /// /// Logarithm of this Complex32 with custom base. /// /// The logarithm of this complex number. public Complex32 Logarithm(float baseValue) { return NaturalLogarithm() / (float)Math.Log(baseValue); } /// /// Raise this Complex32 to the given value. /// /// /// The exponent. /// /// /// The complex number raised to the given exponent. /// public Complex32 Power(Complex32 exponent) { if (IsZero()) { if (exponent.IsZero()) { return One; } if (exponent.Real > 0f) { return Zero; } if (exponent.Real < 0f) { return exponent.Imaginary == 0f ? new Complex32(float.PositiveInfinity, 0f) : new Complex32(float.PositiveInfinity, float.PositiveInfinity); } return NaN; } return (exponent * NaturalLogarithm()).Exponential(); } /// /// Raise this Complex32 to the inverse of the given value. /// /// /// The root exponent. /// /// /// The complex raised to the inverse of the given exponent. /// public Complex32 Root(Complex32 rootExponent) { return Power(1 / rootExponent); } /// /// The Square (power 2) of this Complex32 /// /// /// The square of this complex number. /// public Complex32 Square() { if (IsReal()) { return new Complex32(_real * _real, 0.0f); } return new Complex32((_real * _real) - (_imag * _imag), 2 * _real * _imag); } /// /// The Square Root (power 1/2) of this Complex32 /// /// /// The square root of this complex number. /// public Complex32 SquareRoot() { if (IsRealNonNegative()) { return new Complex32((float)Math.Sqrt(_real), 0.0f); } Complex32 result; 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.0f + Math.Sqrt(1.0f + (ratio * ratio)))); } else { var ratio = Real / Imaginary; w = Math.Sqrt(absImag) * Math.Sqrt(0.5 * (Math.Abs(ratio) + Math.Sqrt(1.0f + (ratio * ratio)))); } if (Real >= 0.0f) { result = new Complex32((float)w, (float)(Imaginary / (2.0f * w))); } else if (Imaginary >= 0.0f) { result = new Complex32((float)(absImag / (2.0 * w)), (float)w); } else { result = new Complex32((float)(absImag / (2.0 * w)), (float)-w); } return result; } /// /// Evaluate all square roots of this Complex32. /// public Tuple SquareRoots() { var principal = SquareRoot(); return new Tuple(principal, -principal); } /// /// Evaluate all cubic roots of this Complex32. /// public Tuple CubicRoots() { float r = (float)Math.Pow(Magnitude, 1d / 3d); float theta = Phase / 3; const float shift = (float)Constants.Pi2 / 3; return new Tuple( FromPolarCoordinates(r, theta), FromPolarCoordinates(r, theta + shift), FromPolarCoordinates(r, theta - shift)); } /// /// Equality test. /// /// One of complex numbers to compare. /// The other complex numbers to compare. /// true if the real and imaginary components of the two complex numbers are equal; false otherwise. public static bool operator ==(Complex32 complex1, Complex32 complex2) { return complex1.Equals(complex2); } /// /// Inequality test. /// /// One of complex numbers to compare. /// The other complex numbers to compare. /// true if the real or imaginary components of the two complex numbers are not equal; false otherwise. public static bool operator !=(Complex32 complex1, Complex32 complex2) { return !complex1.Equals(complex2); } /// /// Unary addition. /// /// The complex number to operate on. /// Returns the same complex number. public static Complex32 operator +(Complex32 summand) { return summand; } /// /// Unary minus. /// /// The complex number to operate on. /// The negated value of the . public static Complex32 operator -(Complex32 subtrahend) { return new Complex32(-subtrahend._real, -subtrahend._imag); } /// Addition operator. Adds two complex numbers together. /// The result of the addition. /// One of the complex numbers to add. /// The other complex numbers to add. public static Complex32 operator +(Complex32 summand1, Complex32 summand2) { return new Complex32(summand1._real + summand2._real, summand1._imag + summand2._imag); } /// Subtraction operator. Subtracts two complex numbers. /// The result of the subtraction. /// The complex number to subtract from. /// The complex number to subtract. public static Complex32 operator -(Complex32 minuend, Complex32 subtrahend) { return new Complex32(minuend._real - subtrahend._real, minuend._imag - subtrahend._imag); } /// Addition operator. Adds a complex number and float together. /// The result of the addition. /// The complex numbers to add. /// The float value to add. public static Complex32 operator +(Complex32 summand1, float summand2) { return new Complex32(summand1._real + summand2, summand1._imag); } /// Subtraction operator. Subtracts float value from a complex value. /// The result of the subtraction. /// The complex number to subtract from. /// The float value to subtract. public static Complex32 operator -(Complex32 minuend, float subtrahend) { return new Complex32(minuend._real - subtrahend, minuend._imag); } /// Addition operator. Adds a complex number and float together. /// The result of the addition. /// The float value to add. /// The complex numbers to add. public static Complex32 operator +(float summand1, Complex32 summand2) { return new Complex32(summand2._real + summand1, summand2._imag); } /// Subtraction operator. Subtracts complex value from a float value. /// The result of the subtraction. /// The float vale to subtract from. /// The complex value to subtract. public static Complex32 operator -(float minuend, Complex32 subtrahend) { return new Complex32(minuend - subtrahend._real, -subtrahend._imag); } /// Multiplication operator. Multiplies two complex numbers. /// The result of the multiplication. /// One of the complex numbers to multiply. /// The other complex number to multiply. public static Complex32 operator *(Complex32 multiplicand, Complex32 multiplier) { return new Complex32( (multiplicand._real * multiplier._real) - (multiplicand._imag * multiplier._imag), (multiplicand._real * multiplier._imag) + (multiplicand._imag * multiplier._real)); } /// Multiplication operator. Multiplies a complex number with a float value. /// The result of the multiplication. /// The float value to multiply. /// The complex number to multiply. public static Complex32 operator *(float multiplicand, Complex32 multiplier) { return new Complex32(multiplier._real * multiplicand, multiplier._imag * multiplicand); } /// Multiplication operator. Multiplies a complex number with a float value. /// The result of the multiplication. /// The complex number to multiply. /// The float value to multiply. public static Complex32 operator *(Complex32 multiplicand, float multiplier) { return new Complex32(multiplicand._real * multiplier, multiplicand._imag * multiplier); } /// Division operator. Divides a complex number by another. /// Enhanced Smith's algorithm for dividing two complex numbers /// /// The result of the division. /// The dividend. /// The divisor. public static Complex32 operator /(Complex32 dividend, Complex32 divisor) { if (dividend.IsZero() && divisor.IsZero()) { return NaN; } if (divisor.IsZero()) { return PositiveInfinity; } float a = dividend.Real; float b = dividend.Imaginary; float c = divisor.Real; float d = divisor.Imaginary; if (Math.Abs(d) <= Math.Abs(c)) return InternalDiv(a, b, c, d, false); return InternalDiv(b, a, d, c, true); } /// /// Helper method for dividing. /// /// Re first /// Im first /// Re second /// Im second /// /// private static Complex32 InternalDiv(float a, float b, float c, float d, bool swapped) { float r = d / c; float t = 1 / (c + d * r); float e, f; if (r != 0.0f) // one can use r >= float.Epsilon || r <= float.Epsilon instead { e = (a + b * r) * t; f = (b - a * r) * t; } else { e = (a + d * (b / c)) * t; f = (b - d * (a / c)) * t; } if (swapped) f = -f; return new Complex32(e, f); } /// Division operator. Divides a float value by a complex number. /// Algorithm based on Smith's algorithm /// /// The result of the division. /// The dividend. /// The divisor. public static Complex32 operator /(float dividend, Complex32 divisor) { if (dividend == 0.0f && divisor.IsZero()) { return NaN; } if (divisor.IsZero()) { return PositiveInfinity; } float c = divisor.Real; float d = divisor.Imaginary; if (Math.Abs(d) <= Math.Abs(c)) return InternalDiv(dividend, 0, c, d, false); return InternalDiv(0, dividend, d, c, true); } /// Division operator. Divides a complex number by a float value. /// The result of the division. /// The dividend. /// The divisor. public static Complex32 operator /(Complex32 dividend, float divisor) { if (dividend.IsZero() && divisor == 0.0f) { return NaN; } if (divisor == 0.0f) { return PositiveInfinity; } return new Complex32(dividend._real / divisor, dividend._imag / divisor); } /// /// Computes the conjugate of a complex number and returns the result. /// public Complex32 Conjugate() { return new Complex32(_real, -_imag); } /// /// Returns the multiplicative inverse of a complex number. /// public Complex32 Reciprocal() { if (IsZero()) { return Zero; } return 1.0f / this; } #region IFormattable Members /// /// Converts the value of the current complex number to its equivalent string representation in Cartesian form. /// /// The string representation of the current instance in Cartesian form. public override string ToString() { return string.Format(CultureInfo.CurrentCulture, "({0}, {1})", _real, _imag); } /// /// Converts the value of the current complex number to its equivalent string representation /// in Cartesian form by using the specified format for its real and imaginary parts. /// /// The string representation of the current instance in Cartesian form. /// A standard or custom numeric format string. /// /// is not a valid format string. public string ToString(string format) { return string.Format(CultureInfo.CurrentCulture, "({0}, {1})", _real.ToString(format, CultureInfo.CurrentCulture), _imag.ToString(format, CultureInfo.CurrentCulture)); } /// /// Converts the value of the current complex number to its equivalent string representation /// in Cartesian form by using the specified culture-specific formatting information. /// /// The string representation of the current instance in Cartesian form, as specified by . /// An object that supplies culture-specific formatting information. public string ToString(IFormatProvider provider) { return string.Format(provider, "({0}, {1})", _real, _imag); } /// Converts the value of the current complex number to its equivalent string representation /// in Cartesian form by using the specified format and culture-specific format information for its real and imaginary parts. /// The string representation of the current instance in Cartesian form, as specified by and . /// A standard or custom numeric format string. /// An object that supplies culture-specific formatting information. /// /// is not a valid format string. public string ToString(string format, IFormatProvider provider) { return string.Format(provider, "({0}, {1})", _real.ToString(format, provider), _imag.ToString(format, provider)); } #endregion #region IEquatable Members /// /// Checks if two complex numbers are equal. Two complex numbers are equal if their /// corresponding real and imaginary components are equal. /// /// /// Returns true if the two objects are the same object, or if their corresponding /// real and imaginary components are equal, false otherwise. /// /// /// The complex number to compare to with. /// public bool Equals(Complex32 other) { if (IsNaN() || other.IsNaN()) { return false; } if (IsInfinity() && other.IsInfinity()) { return true; } return _real.AlmostEqual(other._real) && _imag.AlmostEqual(other._imag); } /// /// The hash code for the complex number. /// /// /// The hash code of the complex number. /// /// /// The hash code is calculated as /// System.Math.Exp(ComplexMath.Absolute(complexNumber)). /// public override int GetHashCode() { int hash = 27; hash = (13 * hash) + _real.GetHashCode(); hash = (13 * hash) + _imag.GetHashCode(); return hash; } /// /// Checks if two complex numbers are equal. Two complex numbers are equal if their /// corresponding real and imaginary components are equal. /// /// /// Returns true if the two objects are the same object, or if their corresponding /// real and imaginary components are equal, false otherwise. /// /// /// The complex number to compare to with. /// public override bool Equals(object obj) { return (obj is Complex32) && Equals((Complex32)obj); } #endregion #region Parse Functions /// /// Creates a complex number based on a string. The string can be in the /// following formats (without the quotes): 'n', 'ni', 'n +/- ni', /// 'ni +/- n', 'n,n', 'n,ni,' '(n,n)', or '(n,ni)', where n is a float. /// /// /// A complex number containing the value specified by the given string. /// /// /// the string to parse. /// /// /// An that supplies culture-specific /// formatting information. /// public static Complex32 Parse(string value, IFormatProvider formatProvider = null) { if (value == null) { throw new ArgumentNullException(nameof(value)); } value = value.Trim(); if (value.Length == 0) { throw new FormatException(); } // strip out parens if (value.StartsWith("(", StringComparison.Ordinal)) { if (!value.EndsWith(")", StringComparison.Ordinal)) { throw new FormatException(); } value = value.Substring(1, value.Length - 2).Trim(); } // keywords var numberFormatInfo = formatProvider.GetNumberFormatInfo(); var textInfo = formatProvider.GetTextInfo(); var keywords = new[] { textInfo.ListSeparator, numberFormatInfo.NaNSymbol, numberFormatInfo.NegativeInfinitySymbol, numberFormatInfo.PositiveInfinitySymbol, "+", "-", "i", "j" }; // lexing var tokens = new LinkedList(); GlobalizationHelper.Tokenize(tokens.AddFirst(value), keywords, 0); var token = tokens.First; // parse the left part bool isLeftPartImaginary; var leftPart = ParsePart(ref token, out isLeftPartImaginary, formatProvider); if (token == null) { return isLeftPartImaginary ? new Complex32(0, leftPart) : new Complex32(leftPart, 0); } // parse the right part if (token.Value == textInfo.ListSeparator) { // format: real,imag token = token.Next; if (isLeftPartImaginary) { // left must not contain 'i', right doesn't matter. throw new FormatException(); } bool isRightPartImaginary; var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider); return new Complex32(leftPart, rightPart); } else { // format: real + imag bool isRightPartImaginary; var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider); if (!(isLeftPartImaginary ^ isRightPartImaginary)) { // either left or right part must contain 'i', but not both. throw new FormatException(); } return isLeftPartImaginary ? new Complex32(rightPart, leftPart) : new Complex32(leftPart, rightPart); } } /// /// Parse a part (real or complex) from a complex number. /// /// Start Token. /// Is set to true if the part identified itself as being imaginary. /// /// An that supplies culture-specific /// formatting information. /// /// Resulting part as float. /// private static float ParsePart(ref LinkedListNode token, out bool imaginary, IFormatProvider format) { imaginary = false; if (token == null) { throw new FormatException(); } // handle prefix modifiers if (token.Value == "+") { token = token.Next; if (token == null) { throw new FormatException(); } } var negative = false; if (token.Value == "-") { negative = true; token = token.Next; if (token == null) { throw new FormatException(); } } // handle prefix imaginary symbol if (String.Compare(token.Value, "i", StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(token.Value, "j", StringComparison.OrdinalIgnoreCase) == 0) { imaginary = true; token = token.Next; if (token == null) { return negative ? -1 : 1; } } #if NETSTANDARD1_3 var value = GlobalizationHelper.ParseSingle(ref token); #else var value = GlobalizationHelper.ParseSingle(ref token, format.GetCultureInfo()); #endif // handle suffix imaginary symbol if (token != null && (String.Compare(token.Value, "i", StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(token.Value, "j", StringComparison.OrdinalIgnoreCase) == 0)) { if (imaginary) { // only one time allowed: either prefix or suffix, or neither. throw new FormatException(); } imaginary = true; token = token.Next; } return negative ? -value : value; } /// /// Converts the string representation of a complex number to a single-precision complex number equivalent. /// A return value indicates whether the conversion succeeded or failed. /// /// /// A string containing a complex number to convert. /// /// /// The parsed value. /// /// /// If the conversion succeeds, the result will contain a complex number equivalent to value. /// Otherwise the result will contain complex32.Zero. This parameter is passed uninitialized /// public static bool TryParse(string value, out Complex32 result) { return TryParse(value, null, out result); } /// /// Converts the string representation of a complex number to single-precision complex number equivalent. /// A return value indicates whether the conversion succeeded or failed. /// /// /// A string containing a complex number to convert. /// /// /// An that supplies culture-specific formatting information about value. /// /// /// The parsed value. /// /// /// If the conversion succeeds, the result will contain a complex number equivalent to value. /// Otherwise the result will contain complex32.Zero. This parameter is passed uninitialized /// public static bool TryParse(string value, IFormatProvider formatProvider, out Complex32 result) { bool ret; try { result = Parse(value, formatProvider); ret = true; } catch (ArgumentNullException) { result = Zero; ret = false; } catch (FormatException) { result = Zero; ret = false; } return ret; } #endregion #region Conversion /// /// Explicit conversion of a real decimal to a Complex32. /// /// The decimal value to convert. /// The result of the conversion. public static explicit operator Complex32(decimal value) { return new Complex32((float)value, 0.0f); } /// /// Explicit conversion of a Complex to a Complex32. /// /// The decimal value to convert. /// The result of the conversion. public static explicit operator Complex32(Complex value) { return new Complex32((float)value.Real, (float)value.Imaginary); } /// /// Implicit conversion of a real byte to a Complex32. /// /// The byte value to convert. /// The result of the conversion. public static implicit operator Complex32(byte value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a real short to a Complex32. /// /// The short value to convert. /// The result of the conversion. public static implicit operator Complex32(short value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a signed byte to a Complex32. /// /// The signed byte value to convert. /// The result of the conversion. [CLSCompliant(false)] public static implicit operator Complex32(sbyte value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a unsigned real short to a Complex32. /// /// The unsigned short value to convert. /// The result of the conversion. [CLSCompliant(false)] public static implicit operator Complex32(ushort value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a real int to a Complex32. /// /// The int value to convert. /// The result of the conversion. public static implicit operator Complex32(int value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a BigInteger int to a Complex32. /// /// The BigInteger value to convert. /// The result of the conversion. public static implicit operator Complex32(BigInteger value) { return new Complex32((long)value, 0.0f); } /// /// Implicit conversion of a real long to a Complex32. /// /// The long value to convert. /// The result of the conversion. public static implicit operator Complex32(long value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a real uint to a Complex32. /// /// The uint value to convert. /// The result of the conversion. [CLSCompliant(false)] public static implicit operator Complex32(uint value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a real ulong to a Complex32. /// /// The ulong value to convert. /// The result of the conversion. [CLSCompliant(false)] public static implicit operator Complex32(ulong value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a real float to a Complex32. /// /// The float value to convert. /// The result of the conversion. public static implicit operator Complex32(float value) { return new Complex32(value, 0.0f); } /// /// Implicit conversion of a real double to a Complex32. /// /// The double value to convert. /// The result of the conversion. public static explicit operator Complex32(double value) { return new Complex32((float)value, 0.0f); } /// /// Converts this Complex32 to a . /// /// A with the same values as this Complex32. public Complex ToComplex() { return new Complex(_real, _imag); } #endregion /// /// Returns the additive inverse of a specified complex number. /// /// The result of the real and imaginary components of the value parameter multiplied by -1. /// A complex number. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Negate(Complex32 value) { return -value; } /// /// Computes the conjugate of a complex number and returns the result. /// /// The conjugate of . /// A complex number. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Conjugate(Complex32 value) { return value.Conjugate(); } /// /// Adds two complex numbers and returns the result. /// /// The sum of and . /// The first complex number to add. /// The second complex number to add. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Add(Complex32 left, Complex32 right) { return left + right; } /// /// Subtracts one complex number from another and returns the result. /// /// The result of subtracting from . /// The value to subtract from (the minuend). /// The value to subtract (the subtrahend). [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Subtract(Complex32 left, Complex32 right) { return left - right; } /// /// Returns the product of two complex numbers. /// /// The product of the and parameters. /// The first complex number to multiply. /// The second complex number to multiply. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Multiply(Complex32 left, Complex32 right) { return left * right; } /// /// Divides one complex number by another and returns the result. /// /// The quotient of the division. /// The complex number to be divided. /// The complex number to divide by. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Divide(Complex32 dividend, Complex32 divisor) { return dividend / divisor; } /// /// Returns the multiplicative inverse of a complex number. /// /// The reciprocal of . /// A complex number. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Reciprocal(Complex32 value) { return value.Reciprocal(); } /// /// Returns the square root of a specified complex number. /// /// The square root of . /// A complex number. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Sqrt(Complex32 value) { return value.SquareRoot(); } /// /// Gets the absolute value (or magnitude) of a complex number. /// /// The absolute value of . /// A complex number. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static double Abs(Complex32 value) { return value.Magnitude; } /// /// Returns e raised to the power specified by a complex number. /// /// The number e raised to the power . /// A complex number that specifies a power. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Exp(Complex32 value) { return value.Exponential(); } /// /// Returns a specified complex number raised to a power specified by a complex number. /// /// The complex number raised to the power . /// A complex number to be raised to a power. /// A complex number that specifies a power. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Pow(Complex32 value, Complex32 power) { return value.Power(power); } /// /// Returns a specified complex number raised to a power specified by a single-precision floating-point number. /// /// The complex number raised to the power . /// A complex number to be raised to a power. /// A single-precision floating-point number that specifies a power. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Pow(Complex32 value, float power) { return value.Power(power); } /// /// Returns the natural (base e) logarithm of a specified complex number. /// /// The natural (base e) logarithm of . /// A complex number. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Log(Complex32 value) { return value.NaturalLogarithm(); } /// /// Returns the logarithm of a specified complex number in a specified base. /// /// The logarithm of in base . /// A complex number. /// The base of the logarithm. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Log(Complex32 value, float baseValue) { return value.Logarithm(baseValue); } /// /// Returns the base-10 logarithm of a specified complex number. /// /// The base-10 logarithm of . /// A complex number. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static Complex32 Log10(Complex32 value) { return value.CommonLogarithm(); } /// /// Returns the sine of the specified complex number. /// /// The sine of . /// A complex number. public static Complex32 Sin(Complex32 value) { return (Complex32)Trig.Sin(value.ToComplex()); } /// /// Returns the cosine of the specified complex number. /// /// The cosine of . /// A complex number. public static Complex32 Cos(Complex32 value) { return (Complex32)Trig.Cos(value.ToComplex()); } /// /// Returns the tangent of the specified complex number. /// /// The tangent of . /// A complex number. public static Complex32 Tan(Complex32 value) { return (Complex32)Trig.Tan(value.ToComplex()); } /// /// Returns the angle that is the arc sine of the specified complex number. /// /// The angle which is the arc sine of . /// A complex number. public static Complex32 Asin(Complex32 value) { return (Complex32)Trig.Asin(value.ToComplex()); } /// /// Returns the angle that is the arc cosine of the specified complex number. /// /// The angle, measured in radians, which is the arc cosine of . /// A complex number that represents a cosine. public static Complex32 Acos(Complex32 value) { return (Complex32)Trig.Acos(value.ToComplex()); } /// /// Returns the angle that is the arc tangent of the specified complex number. /// /// The angle that is the arc tangent of . /// A complex number. public static Complex32 Atan(Complex32 value) { return (Complex32)Trig.Atan(value.ToComplex()); } /// /// Returns the hyperbolic sine of the specified complex number. /// /// The hyperbolic sine of . /// A complex number. public static Complex32 Sinh(Complex32 value) { return (Complex32)Trig.Sinh(value.ToComplex()); } /// /// Returns the hyperbolic cosine of the specified complex number. /// /// The hyperbolic cosine of . /// A complex number. public static Complex32 Cosh(Complex32 value) { return (Complex32)Trig.Cosh(value.ToComplex()); } /// /// Returns the hyperbolic tangent of the specified complex number. /// /// The hyperbolic tangent of . /// A complex number. public static Complex32 Tanh(Complex32 value) { return (Complex32)Trig.Tanh(value.ToComplex()); } } }