//
// 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;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Properties;
///
/// Complex numbers class.
///
///
///
/// The class Complex provides all elementary operations
/// on complex numbers. All the operators +, -,
/// *, /, ==, != are defined in the
/// canonical way. Additional complex trigonometric functions such
/// as , ...
/// are also provided. Note that the Complex structures
/// has two special constant values and
/// .
///
///
/// In order to avoid possible ambiguities resulting from a
/// Complex(double, double) constructor, the static methods
/// and
/// are provided instead.
///
///
///
/// Complex x = Complex.FromRealImaginary(1d, 2d);
/// Complex y = Complex.FromModulusArgument(1d, Math.Pi);
/// Complex z = (x + y) / (x - y);
///
///
///
/// For mathematical details about complex numbers, please
/// have a look at the
/// Wikipedia
///
///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Complex : IFormattable, IEquatable, IPrecisionSupport
{
#region fields
///
/// Represents imaginary unit number.
///
private static readonly Complex _i = new Complex(0, 1);
///
/// Represents a infinite complex number
///
private static readonly Complex _infinity = new Complex(double.PositiveInfinity, double.PositiveInfinity);
///
/// Represents not-a-number.
///
private static readonly Complex _nan = new Complex(Double.NaN, Double.NaN);
///
/// Representing the one value.
///
private static readonly Complex _one = new Complex(1.0, 0.0);
///
/// Representing the zero value.
///
private static readonly Complex _zero = new Complex(0.0, 0.0);
///
/// The real component of the complex number.
///
private readonly double _real;
///
/// The imaginary component of the complex number.
///
private readonly double _imag;
#endregion fields
#region Constructor
///
/// Initializes a new instance of the Complex structure with the given real
/// and imaginary parts.
///
///
/// The value for the real component.
///
///
/// The value for the imaginary component.
///
public Complex(double real, double imaginary)
{
_real = real;
_imag = imaginary;
}
#endregion
#region Properties
///
/// Gets a value representing the infinity value. This field is constant.
///
/// The infinity.
///
/// The semantic associated to this value is a Complex of
/// infinite real and imaginary part. If you need more formal complex
/// number handling (according to the Riemann Sphere and the extended
/// complex plane C*, or using directed infinity) please check out the
/// alternative Math.NET symbolics packages instead.
///
/// A value representing the infinity value.
public static Complex Infinity
{
get { return _infinity; }
}
///
/// Gets a value representing not-a-number. This field is constant.
///
/// A value representing not-a-number.
public static Complex NaN
{
get { return _nan; }
}
///
/// Gets a value representing the imaginary unit number. This field is constant.
///
/// A value representing the imaginary unit number.
public static Complex I
{
get { return _i; }
}
///
/// Gets a value representing the zero value. This field is constant.
///
/// A value representing the zero value.
public static Complex Zero
{
get { return new Complex(0.0, 0.0); }
}
///
/// Gets a value representing the 1 value. This field is constant.
///
/// A value representing the 1 value.
public static Complex One
{
get { return _one; }
}
#endregion Properties
///
/// Gets the real component of the complex number.
///
/// The real component of the complex number.
public double Real
{
get { return _real; }
}
///
/// Gets the real imaginary component of the complex number.
///
/// The real imaginary component of the complex number.
public double Imaginary
{
get { return _imag; }
}
///
/// Gets a value indicating whether whether the Complex is zero.
///
/// true if this instance is zero; otherwise, false.
public bool IsZero
{
get { return _real.AlmostZero() && _imag.AlmostZero(); }
}
///
/// Gets a value indicating whether the Complex is one.
///
/// true if this instance is one; otherwise, false.
public bool IsOne
{
get { return _real.AlmostEqual(1.0) && _imag.AlmostZero(); }
}
///
/// Gets a value indicating whether the Complex is the imaginary unit.
///
/// true if this instance is I; otherwise, false.
public bool IsI
{
get { return _real.AlmostZero() && _imag.AlmostEqual(1.0); }
}
///
/// Gets a value indicating whether the provided Complexevaluates
/// to a value that is not a number.
///
///
/// true if this instance is ; otherwise,
/// false.
///
public bool IsNaN
{
get { return double.IsNaN(_real) || double.IsNaN(_imag); }
}
///
/// Gets a value indicating whether the provided Complex 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
{
get { return double.IsInfinity(_real) || double.IsInfinity(_imag); }
}
///
/// Gets a value indicating whether the provided Complex is real.
///
/// true if this instance is a real number; otherwise, false.
public bool IsReal
{
get { return _imag.AlmostZero(); }
}
///
/// Gets a value indicating whether the provided Complex is real and not negative, that is >= 0.
///
///
/// true if this instance is real nonnegative number; otherwise, false.
///
public bool IsRealNonNegative
{
get { return _imag.AlmostZero() && _real >= 0; }
}
///
/// Gets the conjugate of this Complex.
///
///
/// The semantic of setting the conjugate is such that
///
/// // a, b of type Complex
/// a.Conjugate = b;
///
/// is equivalent to
///
/// // a, b of type Complex
/// a = b.Conjugate
///
///
public Complex Conjugate
{
get { return new Complex(_real, -_imag); }
}
///
/// Gets or modulus of this Complex.
///
///
public double Modulus
{
get { return Math.Sqrt((_real * _real) + (_imag * _imag)); }
}
///
/// Gets the squared modulus of this Complex.
///
///
public double ModulusSquared
{
get { return (_real * _real) + (_imag * _imag); }
}
///
/// Gets argument of this Complex.
///
///
/// Argument always returns a value bigger than negative Pi and
/// smaller or equal to Pi. If this Complex is zero, the Complex
/// is assumed to be positive real with an argument of zero.
///
public double Argument
{
get
{
if (IsReal && _real < 0)
{
return Math.PI;
}
return IsRealNonNegative ? 0 : Math.Atan2(_imag, _real);
}
}
///
/// Gets the unity of this complex (same argument, but on the unit circle; exp(I*arg))
///
public Complex Sign
{
get
{
if (double.IsPositiveInfinity(_real) && double.IsPositiveInfinity(_imag))
{
return new Complex(Constants.Sqrt1Over2, Constants.Sqrt1Over2);
}
if (double.IsPositiveInfinity(_real) && double.IsNegativeInfinity(_imag))
{
return new Complex(Constants.Sqrt1Over2, -Constants.Sqrt1Over2);
}
if (double.IsNegativeInfinity(_real) && double.IsPositiveInfinity(_imag))
{
return new Complex(-Constants.Sqrt1Over2, -Constants.Sqrt1Over2);
}
if (double.IsNegativeInfinity(_real) && double.IsNegativeInfinity(_imag))
{
return new Complex(-Constants.Sqrt1Over2, Constants.Sqrt1Over2);
}
// don't replace this with "Modulus"!
var mod = SpecialFunctions.Hypotenuse(_real, _imag);
if (mod.AlmostZero())
{
return Zero;
}
return new Complex(_real / mod, _imag / mod);
}
}
#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;
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
///
/// Constructs a Complex from its real
/// and imaginary parts.
///
///
/// The value for the real component.
///
///
/// The value for the imaginary component.
///
///
/// A new Complex with the given values.
///
public static Complex WithRealImaginary(double real, double imaginary)
{
return new Complex(real, imaginary);
}
///
/// Constructs a Complex from its modulus and
/// argument.
///
///
/// Must be non-negative.
///
///
/// Real number.
///
///
/// A new Complex from the given values.
///
public static Complex WithModulusArgument(double modulus, double argument)
{
if (modulus < 0.0)
{
throw new ArgumentOutOfRangeException("modulus", modulus, Resources.ArgumentNotNegative);
}
return new Complex(modulus * Math.Cos(argument), modulus * Math.Sin(argument));
}
#endregion
#region IFormattable Members
///
/// A string representation of this complex number.
///
///
/// The string representation of this complex number.
///
public override string ToString()
{
return ToString(null, null);
}
///
/// A string representation of this complex number.
///
///
/// The string representation of this complex number formatted as specified by the
/// format string.
///
///
/// A format specification.
///
public string ToString(string format)
{
return ToString(format, null);
}
///
/// A string representation of this complex number.
///
///
/// The string representation of this complex number formatted as specified by the
/// format provider.
///
///
/// An that supplies culture-specific formatting information.
///
public string ToString(IFormatProvider formatProvider)
{
return ToString(null, formatProvider);
}
///
/// A string representation of this complex number.
///
///
/// The string representation of this complex number formatted as specified by the
/// format string and format provider.
///
///
/// if the n, is not a number.
///
///
/// if s, is .
///
///
/// A format specification.
///
///
/// An that supplies culture-specific formatting information.
///
public string ToString(string format, IFormatProvider formatProvider)
{
var numberFormatInfo = formatProvider.GetNumberFormatInfo();
if (IsNaN)
{
return numberFormatInfo.NaNSymbol;
}
if (IsInfinity)
{
return numberFormatInfo.PositiveInfinitySymbol;
}
var ret = new StringBuilder();
if (!_real.AlmostZero())
{
ret.Append(_real.ToString(format, formatProvider));
}
if (!_imag.AlmostZero())
{
if (!_real.AlmostZero())
{
if (_imag < 0)
{
ret.Append(" ");
}
else
{
ret.Append(" + ");
}
}
ret.Append(_imag.ToString(format, formatProvider)).Append("i");
}
if (ret.Length == 0)
{
ret.Append((0.0).ToString(format, formatProvider));
}
return ret.ToString();
}
#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(Complex 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()
{
return _real.GetHashCode() ^ (-_imag.GetHashCode());
}
///
/// 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 Complex) && Equals((Complex)obj);
}
#endregion
#region Operators
///
/// 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 ==(Complex complex1, Complex 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 !=(Complex complex1, Complex complex2)
{
return !complex1.Equals(complex2);
}
///
/// Unary addition.
///
/// The complex number to operate on.
/// Returns the same complex number.
public static Complex operator +(Complex summand)
{
return summand;
}
///
/// Unary minus.
///
/// The complex number to operate on.
/// The negated value of the .
public static Complex operator -(Complex subtrahend)
{
return new Complex(-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 Complex operator +(Complex summand1, Complex summand2)
{
return new Complex(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 Complex operator -(Complex minuend, Complex subtrahend)
{
return new Complex(minuend._real - subtrahend._real, minuend._imag - subtrahend._imag);
}
/// Addition operator. Adds a complex number and double together.
/// The result of the addition.
/// The complex numbers to add.
/// The double value to add.
public static Complex operator +(Complex summand1, double summand2)
{
return new Complex(summand1._real + summand2, summand1._imag);
}
/// Subtraction operator. Subtracts double value from a complex value.
/// The result of the subtraction.
/// The complex number to subtract from.
/// The double value to subtract.
public static Complex operator -(Complex minuend, double subtrahend)
{
return new Complex(minuend._real - subtrahend, minuend._imag);
}
/// Addition operator. Adds a complex number and double together.
/// The result of the addition.
/// The double value to add.
/// The complex numbers to add.
public static Complex operator +(double summand1, Complex summand2)
{
return new Complex(summand2._real + summand1, summand2._imag);
}
/// Subtraction operator. Subtracts complex value from a double value.
/// The result of the subtraction.
/// The double vale to subtract from.
/// The complex value to subtract.
public static Complex operator -(double minuend, Complex subtrahend)
{
return new Complex(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 Complex operator *(Complex multiplicand, Complex multiplier)
{
return new Complex(
(multiplicand._real * multiplier._real) - (multiplicand._imag * multiplier._imag),
(multiplicand._real * multiplier._imag) + (multiplicand._imag * multiplier._real));
}
/// Multiplication operator. Multiplies a complex number with a double value.
/// The result of the multiplication.
/// The double value to multiply.
/// The complex number to multiply.
public static Complex operator *(double multiplicand, Complex multiplier)
{
return new Complex(multiplier._real * multiplicand, multiplier._imag * multiplicand);
}
/// Multiplication operator. Multiplies a complex number with a double value.
/// The result of the multiplication.
/// The complex number to multiply.
/// The double value to multiply.
public static Complex operator *(Complex multiplicand, double multiplier)
{
return new Complex(multiplicand._real * multiplier, multiplicand._imag * multiplier);
}
/// Division operator. Divides a complex number by another.
/// The result of the division.
/// The dividend.
/// The divisor.
public static Complex operator /(Complex dividend, Complex divisor)
{
if (divisor.IsZero)
{
return Infinity;
}
var modSquared = divisor.ModulusSquared;
return new Complex(
((dividend._real * divisor._real) + (dividend._imag * divisor._imag)) / modSquared,
((dividend._imag * divisor._real) - (dividend._real * divisor._imag)) / modSquared);
}
/// Division operator. Divides a double value by a complex number.
/// The result of the division.
/// The dividend.
/// The divisor.
public static Complex operator /(double dividend, Complex divisor)
{
if (divisor.IsZero)
{
return Infinity;
}
var zmod = divisor.ModulusSquared;
return new Complex(dividend * divisor._real / zmod, -dividend * divisor._imag / zmod);
}
/// Division operator. Divides a complex number by a double value.
/// The result of the division.
/// The dividend.
/// The divisor.
public static Complex operator /(Complex dividend, double divisor)
{
if (divisor.AlmostZero())
{
return Infinity;
}
return new Complex(dividend._real / divisor, dividend._imag / divisor);
}
///
/// Implicit conversion of a real double to a real Complex.
///
/// The double value to convert.
/// The result of the conversion.
public static implicit operator Complex(double number)
{
return new Complex(number, 0.0);
}
///
/// Unary addition.
///
///
/// Returns the same complex number.
///
public Complex Plus()
{
return this;
}
///
/// Unary minus.
///
///
/// The negated value of this complex number.
///
public Complex Negate()
{
return -this;
}
///
/// Adds a complex number to this one.
///
///
/// The result of the addition.
///
///
/// The other complex number to add.
///
public Complex Add(Complex other)
{
return this + other;
}
///
/// Subtracts a complex number from this one.
///
///
/// The result of the subtraction.
///
///
/// The other complex number to subtract from this one.
///
public Complex Subtract(Complex other)
{
return this - other;
}
///
/// Multiplies this complex number with this one.
///
///
/// The result of the multiplication.
///
///
/// The complex number to multiply.
///
public Complex Multiply(Complex multiplier)
{
return this * multiplier;
}
///
/// Divides this complex number by another.
///
///
/// The result of the division.
///
///
/// The divisor.
///
public Complex Divide(Complex divisor)
{
return this / divisor;
}
#endregion
#region IPrecisionSupport
///
/// Returns a Norm of a value of this type, which is appropriate for measuring how
/// close this value is to zero.
///
///
/// A norm of this value.
///
double IPrecisionSupport.Norm()
{
return ModulusSquared;
}
///
/// Returns a Norm of the difference of two values of this type, which is
/// appropriate for measuring how close together these two values are.
///
///
/// The value to compare with.
///
///
/// A norm of the difference between this and the other value.
///
double IPrecisionSupport.NormOfDifference(Complex otherValue)
{
return (this - otherValue).ModulusSquared;
}
#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 double.
///
///
/// A complex number containing the value specified by the given string.
///
///
/// The string to parse.
///
public static Complex Parse(string value)
{
return Parse(value, null);
}
///
/// 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 double.
///
///
/// A complex number containing the value specified by the given string.
///
///
/// the string to parse.
///
///
/// An that supplies culture-specific
/// formatting information.
///
public static Complex Parse(string value, IFormatProvider formatProvider)
{
if (value == null)
{
throw new ArgumentNullException(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;
double leftPart = ParsePart(ref token, out isLeftPartImaginary, formatProvider);
if (token == null)
{
return isLeftPartImaginary ? new Complex(0, leftPart) : new Complex(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;
double rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider);
return new Complex(leftPart, rightPart);
}
else
{
// format: real + imag
bool isRightPartImaginary;
double 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 Complex(rightPart, leftPart) : new Complex(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 double.
///
private static double 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();
}
}
bool 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;
}
}
double value = GlobalizationHelper.ParseDouble(ref token, format.GetCultureInfo());
// handle suffix imaginary symbol
if (token != null && String.Compare(token.Value, "i", 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 double-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 Complex result)
{
return TryParse(value, null, out result);
}
///
/// Converts the string representation of a complex number to double-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 Complex 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
}
}