@ -1,7 +1,9 @@
// <copyright file="Complex.cs" company="Math.NET">
// 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
@ -10,8 +12,10 @@
// 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
@ -28,8 +32,7 @@ namespace MathNet.Numerics
using System.Runtime.InteropServices ;
using System.Text ;
using System.Text.RegularExpressions ;
using MathNet.Numerics.Properties ;
using Properties ;
/// <summary>
/// Complex numbers class.
@ -40,7 +43,7 @@ namespace MathNet.Numerics
/// on complex numbers. All the operators <c>+</c>, <c>-</c>,
/// <c>*</c>, <c>/</c>, <c>==</c>, <c>!=</c> are defined in the
/// canonical way. Additional complex trigonometric functions such
/// as <see cref="Complex.Cosine "/>, ...
/// as <see cref="Trig.Cosine(Complex) "/>, ...
/// are also provided. Note that the <c>Complex</c> structures
/// has two special constant values <see cref="Complex.NaN"/> and
/// <see cref="Complex.Infinity"/>.
@ -73,35 +76,35 @@ namespace MathNet.Numerics
/// <summary>
/// Regular expression used to parse strings into complex numbers.
/// </summary>
private static readonly Regex P arseExpression =
private static readonly Regex _ p arseExpression =
new Regex (
@"^((?<r>(([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|(NaN)|([-+]?Infinity)))|(?<i>(([-+]?((\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|(NaN)|([-+]?Infinity))?[i]))|(?<r>(([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|(NaN)|([-+]?Infinity)))(?<i>(([-+]((\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|[-+](NaN)|([-+]Infinity))?[i])))$" ,
@"^((?<r>(([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|(NaN)|([-+]?Infinity)))|(?<i>(([-+]?((\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|(NaN)|([-+]?Infinity))?[i]))|(?<r>(([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|(NaN)|([-+]?Infinity)))(?<i>(([-+]((\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-9]+)?)|[-+](NaN)|([-+]Infinity))?[i])))$" ,
RegexOptions . Singleline | RegexOptions . IgnoreCase | RegexOptions . IgnorePatternWhitespace ) ;
/// <summary>
/// Represents imaginary unit number.
/// </summary>
private static readonly Complex i = new Complex ( 0 , 1 ) ;
private static readonly Complex _ i = new Complex ( 0 , 1 ) ;
/// <summary>
/// Represents a infinite complex number
/// </summary>
private static readonly Complex infinity = new Complex ( double . PositiveInfinity , double . PositiveInfinity ) ;
private static readonly Complex _ infinity = new Complex ( double . PositiveInfinity , double . PositiveInfinity ) ;
/// <summary>
/// Represents not-a-number.
/// </summary>
private static readonly Complex nan = new Complex ( Double . NaN , Double . NaN ) ;
private static readonly Complex _ nan = new Complex ( Double . NaN , Double . NaN ) ;
/// <summary>
/// Representing the one value.
/// </summary>
private static readonly Complex one = new Complex ( 1.0 , 0.0 ) ;
private static readonly Complex _ one = new Complex ( 1.0 , 0.0 ) ;
/// <summary>
/// Representing the zero value.
/// </summary>
private static readonly Complex zero = new Complex ( 0.0 , 0.0 ) ;
private static readonly Complex _ zero = new Complex ( 0.0 , 0.0 ) ;
/// <summary>
/// The real component of the complex number.
@ -129,8 +132,8 @@ namespace MathNet.Numerics
/// </param>
public Complex ( double real , double imaginary )
{
this . _ real = real ;
this . _ imag = imaginary ;
_ real = real ;
_ imag = imaginary ;
}
#endregion
@ -152,10 +155,7 @@ namespace MathNet.Numerics
/// <value>A value representing the infinity value.</value>
public static Complex Infinity
{
get
{
return infinity ;
}
get { return _ infinity ; }
}
/// <summary>
@ -164,10 +164,7 @@ namespace MathNet.Numerics
/// <value>A value representing not-a-number.</value>
public static Complex NaN
{
get
{
return nan ;
}
get { return _ nan ; }
}
/// <summary>
@ -176,10 +173,7 @@ namespace MathNet.Numerics
/// <value>A value representing the imaginary unit number.</value>
public static Complex I
{
get
{
return i ;
}
get { return _ i ; }
}
/// <summary>
@ -188,10 +182,7 @@ namespace MathNet.Numerics
/// <value>A value representing the zero value.</value>
public static Complex Zero
{
get
{
return new Complex ( 0.0 , 0.0 ) ;
}
get { return new Complex ( 0.0 , 0.0 ) ; }
}
/// <summary>
@ -200,10 +191,7 @@ namespace MathNet.Numerics
/// <value>A value representing the <c>1</c> value.</value>
public static Complex One
{
get
{
return one ;
}
get { return _ one ; }
}
#endregion Properties
@ -214,10 +202,7 @@ namespace MathNet.Numerics
/// <value>The real component of the complex number.</value>
public double Real
{
get
{
return this . _ real ;
}
get { return _ real ; }
}
/// <summary>
@ -226,10 +211,7 @@ namespace MathNet.Numerics
/// <value>The real imaginary component of the complex number.</value>
public double Imaginary
{
get
{
return this . _ imag ;
}
get { return _ imag ; }
}
/// <summary>
@ -238,10 +220,7 @@ namespace MathNet.Numerics
/// <value><c>true</c> if this instance is zero; otherwise, <c>false</c>.</value>
public bool IsZero
{
get
{
return this . _ real . AlmostZero ( ) & & this . _ imag . AlmostZero ( ) ;
}
get { return _ real . AlmostZero ( ) & & _ imag . AlmostZero ( ) ; }
}
/// <summary>
@ -250,10 +229,7 @@ namespace MathNet.Numerics
/// <value><c>true</c> if this instance is one; otherwise, <c>false</c>.</value>
public bool IsOne
{
get
{
return this . _ real . AlmostEqual ( 1.0 ) & & this . _ imag . AlmostZero ( ) ;
}
get { return _ real . AlmostEqual ( 1.0 ) & & _ imag . AlmostZero ( ) ; }
}
/// <summary>
@ -262,10 +238,7 @@ namespace MathNet.Numerics
/// <value><c>true</c> if this instance is I; otherwise, <c>false</c>.</value>
public bool IsI
{
get
{
return this . _ real . AlmostZero ( ) & & this . _ imag . AlmostEqual ( 1.0 ) ;
}
get { return _ real . AlmostZero ( ) & & _ imag . AlmostEqual ( 1.0 ) ; }
}
/// <summary>
@ -275,10 +248,7 @@ namespace MathNet.Numerics
/// <value><c>true</c> if this instance is NaN; otherwise, <c>false</c>.</value>
public bool IsNaN
{
get
{
return double . IsNaN ( this . _ real ) | | double . IsNaN ( this . _ imag ) ;
}
get { return double . IsNaN ( _ real ) | | double . IsNaN ( _ imag ) ; }
}
/// <summary>
@ -294,10 +264,7 @@ namespace MathNet.Numerics
/// </remarks>
public bool IsInfinity
{
get
{
return double . IsInfinity ( this . _ real ) | | double . IsInfinity ( this . _ imag ) ;
}
get { return double . IsInfinity ( _ real ) | | double . IsInfinity ( _ imag ) ; }
}
/// <summary>
@ -306,10 +273,7 @@ namespace MathNet.Numerics
/// <value><c>true</c> if this instance is a real number; otherwise, <c>false</c>.</value>
public bool IsReal
{
get
{
return this . _ imag . AlmostZero ( ) ;
}
get { return _ imag . AlmostZero ( ) ; }
}
/// <summary>
@ -320,10 +284,7 @@ namespace MathNet.Numerics
/// </value>
public bool IsRealNonNegative
{
get
{
return this . _ imag . AlmostZero ( ) & & this . _ real > = 0 ;
}
get { return _ imag . AlmostZero ( ) & & _ real > = 0 ; }
}
/// <summary>
@ -343,10 +304,7 @@ namespace MathNet.Numerics
/// </remarks>
public Complex Conjugate
{
get
{
return new Complex ( this . _ real , - this . _ imag ) ;
}
get { return new Complex ( _ real , - _ imag ) ; }
}
/// <summary>
@ -355,10 +313,7 @@ namespace MathNet.Numerics
/// <seealso cref="Argument"/>
public double Modulus
{
get
{
return Math . Sqrt ( ( this . _ real * this . _ real ) + ( this . _ imag * this . _ imag ) ) ;
}
get { return Math . Sqrt ( ( _ real * _ real ) + ( _ imag * _ imag ) ) ; }
}
/// <summary>
@ -367,10 +322,7 @@ namespace MathNet.Numerics
/// <seealso cref="Argument"/>
public double ModulusSquared
{
get
{
return ( this . _ real * this . _ real ) + ( this . _ imag * this . _ imag ) ;
}
get { return ( _ real * _ real ) + ( _ imag * _ imag ) ; }
}
/// <summary>
@ -379,18 +331,18 @@ namespace MathNet.Numerics
/// <remarks>
/// Argument always returns a value bigger than negative Pi and
/// smaller or equal to Pi. If this <c>Complex</c> is zero, the Complex
/// is assumed to be positive _ real with an argument of zero.
/// is assumed to be positive real with an argument of zero.
/// </remarks>
public double Argument
{
get
{
if ( this . IsReal & & this . _ real < 0 )
if ( IsReal & & _ real < 0 )
{
return Math . PI ;
}
return this . IsRealNonNegative ? 0 : Math . Atan2 ( this . _ imag , this . _ real ) ;
return IsRealNonNegative ? 0 : Math . Atan2 ( _ imag , _ real ) ;
}
}
@ -401,34 +353,34 @@ namespace MathNet.Numerics
{
get
{
if ( double . IsPositiveInfinity ( this . _ real ) & & double . IsPositiveInfinity ( this . _ imag ) )
if ( double . IsPositiveInfinity ( _ real ) & & double . IsPositiveInfinity ( _ imag ) )
{
return new Complex ( Constants . Sqrt1Over2 , Constants . Sqrt1Over2 ) ;
}
if ( double . IsPositiveInfinity ( this . _ real ) & & double . IsNegativeInfinity ( this . _ imag ) )
if ( double . IsPositiveInfinity ( _ real ) & & double . IsNegativeInfinity ( _ imag ) )
{
return new Complex ( Constants . Sqrt1Over2 , - Constants . Sqrt1Over2 ) ;
}
if ( double . IsNegativeInfinity ( this . _ real ) & & double . IsPositiveInfinity ( this . _ imag ) )
if ( double . IsNegativeInfinity ( _ real ) & & double . IsPositiveInfinity ( _ imag ) )
{
return new Complex ( - Constants . Sqrt1Over2 , - Constants . Sqrt1Over2 ) ;
}
if ( double . IsNegativeInfinity ( this . _ real ) & & double . IsNegativeInfinity ( this . _ imag ) )
if ( double . IsNegativeInfinity ( _ real ) & & double . IsNegativeInfinity ( _ imag ) )
{
return new Complex ( - Constants . Sqrt1Over2 , Constants . Sqrt1Over2 ) ;
}
// don't replace this with "Modulus"!
var mod = SpecialFunctions . Hypotenuse ( this . _ real , this . _ imag ) ;
var mod = SpecialFunctions . Hypotenuse ( _ real , _ imag ) ;
if ( mod . AlmostZero ( ) )
{
return Zero ;
}
return new Complex ( this . _ real / mod , this . _ imag / mod ) ;
return new Complex ( _ real / mod , _ imag / mod ) ;
}
}
@ -509,15 +461,15 @@ namespace MathNet.Numerics
/// <summary>
/// Raise this <c>Complex</c> to the inverse of the given value.
/// </summary>
/// <param name="roote xponent">
/// <param name="rootE xponent">
/// The root exponent.
/// </param>
/// <returns>
/// The complex raised to the inverse of the given exponent.
/// </returns>
public Complex Root ( Complex roote xponent )
public Complex Root ( Complex rootE xponent )
{
return Power ( 1 / roote xponent ) ;
return Power ( 1 / rootE xponent ) ;
}
/// <summary>
@ -638,7 +590,7 @@ namespace MathNet.Numerics
/// </returns>
public override string ToString ( )
{
return this . ToString ( null , null ) ;
return ToString ( null , null ) ;
}
/// <summary>
@ -653,7 +605,7 @@ namespace MathNet.Numerics
/// </param>
public string ToString ( string format )
{
return this . ToString ( format , null ) ;
return ToString ( format , null ) ;
}
/// <summary>
@ -664,11 +616,11 @@ namespace MathNet.Numerics
/// format provider.
/// </returns>
/// <param name="formatProvider">
/// An IFormatProvider that supplies culture-specific formatting information.
/// An <see cref=" IFormatProvider"/> that supplies culture-specific formatting information.
/// </param>
public string ToString ( IFormatProvider formatProvider )
{
return this . ToString ( null , formatProvider ) ;
return ToString ( null , formatProvider ) ;
}
/// <summary>
@ -688,32 +640,32 @@ namespace MathNet.Numerics
/// A format specification.
/// </param>
/// <param name="formatProvider">
/// An IFormatProvider that supplies culture-specific formatting information.
/// An <see cref=" IFormatProvider"/> that supplies culture-specific formatting information.
/// </param>
public string ToString ( string format , IFormatProvider formatProvider )
{
if ( this . IsNaN )
if ( IsNaN )
{
return "NaN" ;
}
if ( this . IsInfinity )
if ( IsInfinity )
{
return "Infinity" ;
}
var ret = new StringBuilder ( ) ;
if ( ! this . _ real . AlmostZero ( ) )
if ( ! _ real . AlmostZero ( ) )
{
ret . Append ( this . _ real . ToString ( format , formatProvider ) ) ;
ret . Append ( _ real . ToString ( format , formatProvider ) ) ;
}
if ( ! this . _ imag . AlmostZero ( ) )
if ( ! _ imag . AlmostZero ( ) )
{
if ( ! this . _ real . AlmostZero ( ) )
if ( ! _ real . AlmostZero ( ) )
{
if ( this . _ imag < 0 )
if ( _ imag < 0 )
{
ret . Append ( " " ) ;
}
@ -723,7 +675,7 @@ namespace MathNet.Numerics
}
}
ret . Append ( this . _ imag . ToString ( format , formatProvider ) ) . Append ( "i" ) ;
ret . Append ( _ imag . ToString ( format , formatProvider ) ) . Append ( "i" ) ;
}
return ret . ToString ( ) ;
@ -738,25 +690,25 @@ namespace MathNet.Numerics
/// corresponding real and imaginary components are equal.
/// </summary>
/// <returns>
/// Returns true if the two objects are the same object, or if their corresponding
/// real and imaginary components are equal, false otherwise.
/// Returns <c> true</c> if the two objects are the same object, or if their corresponding
/// real and imaginary components are equal, <c> false</c> otherwise.
/// </returns>
/// <param name="other">
/// The complex number to compare to with.
/// </param>
public bool Equals ( Complex other )
{
if ( this . IsNaN | | other . IsNaN )
if ( IsNaN | | other . IsNaN )
{
return false ;
}
if ( this . IsInfinity & & other . IsInfinity )
if ( IsInfinity & & other . IsInfinity )
{
return true ;
}
return this . _ real . AlmostEqual ( other . _ real ) & & this . _ imag . AlmostEqual ( other . _ imag ) ;
return _ real . AlmostEqual ( other . _ real ) & & _ imag . AlmostEqual ( other . _ imag ) ;
}
/// <summary>
@ -771,7 +723,7 @@ namespace MathNet.Numerics
/// </remarks>
public override int GetHashCode ( )
{
return this . _ real . GetHashCode ( ) ^ ( - this . _ imag . GetHashCode ( ) ) ;
return _ real . GetHashCode ( ) ^ ( - _ imag . GetHashCode ( ) ) ;
}
/// <summary>
@ -779,15 +731,15 @@ namespace MathNet.Numerics
/// corresponding real and imaginary components are equal.
/// </summary>
/// <returns>
/// Returns true if the two objects are the same object, or if their corresponding
/// real and imaginary components are equal, false otherwise.
/// Returns <c> true</c> if the two objects are the same object, or if their corresponding
/// real and imaginary components are equal, <c> false</c> otherwise.
/// </returns>
/// <param name="obj">
/// The complex number to compare to with.
/// </param>
public override bool Equals ( object obj )
{
return ( obj is Complex ) & & this . Equals ( ( Complex ) obj ) ;
return ( obj is Complex ) & & Equals ( ( Complex ) obj ) ;
}
#endregion
@ -799,7 +751,7 @@ namespace MathNet.Numerics
/// </summary>
/// <param name="complex1">One of complex numbers to compare.</param>
/// <param name="complex2">The other complex numbers to compare.</param>
/// <returns>true if the real and imaginary components of the two complex numbers are equal; false otherwise.</returns>
/// <returns><c> true</c> if the real and imaginary components of the two complex numbers are equal; <c> false</c> otherwise.</returns>
public static bool operator = = ( Complex complex1 , Complex complex2 )
{
return complex1 . Equals ( complex2 ) ;
@ -810,7 +762,7 @@ namespace MathNet.Numerics
/// </summary>
/// <param name="complex1">One of complex numbers to compare.</param>
/// <param name="complex2">The other complex numbers to compare.</param>
/// <returns>true if the real or imaginary components of the two complex numbers are not equal; false otherwise.</returns>
/// <returns><c> true</c> if the real or imaginary components of the two complex numbers are not equal; <c> false</c> otherwise.</returns>
public static bool operator ! = ( Complex complex1 , Complex complex2 )
{
return ! complex1 . Equals ( complex2 ) ;
@ -897,7 +849,7 @@ namespace MathNet.Numerics
public static Complex operator * ( Complex multiplicand , Complex multiplier )
{
return new Complex (
( multiplicand . _ real * multiplier . _ real ) - ( multiplicand . _ imag * multiplier . _ imag ) ,
( multiplicand . _ real * multiplier . _ real ) - ( multiplicand . _ imag * multiplier . _ imag ) ,
( multiplicand . _ real * multiplier . _ imag ) + ( multiplicand . _ imag * multiplier . _ real ) ) ;
}
@ -932,7 +884,7 @@ namespace MathNet.Numerics
var modSquared = divisor . ModulusSquared ;
return new Complex (
( ( dividend . _ real * divisor . _ real ) + ( dividend . _ imag * divisor . _ imag ) ) / modSquared ,
( ( dividend . _ real * divisor . _ real ) + ( dividend . _ imag * divisor . _ imag ) ) / modSquared ,
( ( dividend . _ imag * divisor . _ real ) - ( dividend . _ real * divisor . _ imag ) ) / modSquared ) ;
}
@ -1116,7 +1068,7 @@ namespace MathNet.Numerics
/// the string to parse.
/// </param>
/// <param name="formatProvider">
/// An IFormatProvider that supplies culture-specific formatting information.
/// An <see cref=" IFormatProvider"/> that supplies culture-specific formatting information.
/// </param>
public static Complex Parse ( string value , IFormatProvider formatProvider )
{
@ -1178,7 +1130,7 @@ namespace MathNet.Numerics
}
else
{
var matchResult = P arseExpression. Match ( value ) ;
var matchResult = _ p arseExpression. Match ( value ) ;
if ( matchResult . Success )
{
var realStr = matchResult . Groups [ "r" ] . Value ;
@ -1241,7 +1193,7 @@ namespace MathNet.Numerics
/// A string containing a complex number to convert.
/// </param>
/// <param name="formatProvider">
/// An IFormatProvider that supplies culture-specific formatting information about value.
/// An <see cref=" IFormatProvider"/> that supplies culture-specific formatting information about value.
/// </param>
/// <param name="result">
/// The parsed value.
@ -1260,12 +1212,12 @@ namespace MathNet.Numerics
}
catch ( ArgumentNullException )
{
result = zero ;
result = _ zero ;
ret = false ;
}
catch ( FormatException )
{
result = zero ;
result = _ zero ;
ret = false ;
}
@ -1274,4 +1226,4 @@ namespace MathNet.Numerics
#endregion
}
}
}