//--------------------------------------------------------------------------------------------- /// <summary> /// Clamp length (modulus) of the elements in the complex array /// </summary> /// <param name="array"></param> /// <param name="fMinimum"></param> /// <param name="fMaximum"></param> static public void ClampLength(ComplexD[] array, double fMinimum, double fMaximum) { for (int i = 0; i < array.Length; i++) { array[i] = ComplexD.FromModulusArgument(Math.Max(fMinimum, Math.Min(fMaximum, array[i].GetModulus())), array[i].GetArgument()); } }
//--------------------------------------------------------------------------------------------------- /// <summary> /// Swap two complex numbers /// </summary> /// <param name="a"></param> /// <param name="b"></param> static public void Swap(ref ComplexD a, ref ComplexD b) { ComplexD temp = a; a = b; b = temp; }
/// <summary> /// Clamp elements in the complex array to range [minimum,maximum] /// </summary> /// <param name="array"></param> /// <param name="minimum"></param> /// <param name="maximum"></param> static public void Clamp(ComplexD[] array, ComplexD minimum, ComplexD maximum) { for (int i = 0; i < array.Length; i++) { array[i].Re = Math.Min(Math.Max(array[i].Re, minimum.Re), maximum.Re); array[i].Im = Math.Min(Math.Max(array[i].Re, minimum.Im), maximum.Im); } }
/// <summary> /// Add a specific value to each element in the array /// </summary> /// <param name="array"></param> /// <param name="offset"></param> static public void Offset(ComplexD[] array, ComplexD offset) { int length = array.Length; for (int i = 0; i < length; i++) { array[i] += offset; } }
/// <summary> /// Is this complex number equivalent to another object? /// </summary> /// <param name="o"></param> /// <returns></returns> public override bool Equals(object o) { if (o is ComplexD || o is double) { ComplexD c = (ComplexD)o; return(this == c); } return(false); }
/// <summary> /// Creates a complex array from an array of doubles /// </summary> /// <param name="RealArray">Real parts, the imaginary parts presumed zero</param> /// <returns></returns> static public ComplexD[] CreateFromReal(double[] RealArray) { Debug.Assert(RealArray != null); Debug.Assert(RealArray.Length >= 0); ComplexD[] tmp = new ComplexD[RealArray.Length]; for (int i = 0; i < tmp.Length; i++) { tmp[i].Re = (double)RealArray[i]; } return(tmp); }
/// <summary> /// Multiply each element in the array by a specific value /// </summary> /// <param name="array"></param> /// <param name="scale"></param> static public void Scale(ComplexD[] array, ComplexD scale) { Debug.Assert(array != null); int length = array.Length; for (int i = 0; i < length; i++) { array[i] *= scale; } }
/// <summary> /// Multiply each element in the array by a specific value /// </summary> /// <param name="array"></param> /// <param name="scale"></param> /// <param name="start"></param> /// <param name="length"></param> static public void Scale(ComplexD[] array, ComplexD scale, int start, int length) { Debug.Assert(array != null); Debug.Assert(start >= 0); Debug.Assert(length >= 0); Debug.Assert((start + length) < array.Length); for (int i = 0; i < length; i++) { array[i + start] *= scale; } }
/// <summary> /// Calculate the square root of a complex number /// </summary> /// <param name="c"></param> /// <returns></returns> static public ComplexD Sqrt(ComplexD c) { double x = c.Re; double y = c.Im; double modulus = Math.Sqrt(x * x + y * y); int sign = (y < 0) ? -1 : 1; c.Re = (double)(_halfOfRoot2 * Math.Sqrt(modulus + x)); c.Im = (double)(_halfOfRoot2 * sign * Math.Sqrt(modulus - x)); return(c); }
/// <summary> /// Calculate the power of a complex number /// </summary> /// <param name="c"></param> /// <param name="exponent"></param> /// <returns></returns> static public ComplexD Pow(ComplexD c, double exponent) { double x = c.Re; double y = c.Im; double modulus = Math.Pow(x * x + y * y, exponent * 0.5); double argument = Math.Atan2(y, x) * exponent; c.Re = (double)(modulus * System.Math.Cos(argument)); c.Im = (double)(modulus * System.Math.Sin(argument)); return(c); }
// // <summary> // // Conver the complex array to a double array // // </summary> // // <param name="array"></param> // // <param name="style"></param> // // <returns></returns> /* static public double[] ConvertToDoubleArray( ComplexD[] array, ConversionStyle style ) { * double[] newArray = new double[ array.Length ]; * switch( style ) { * case ConversionStyle.Length: * for( int i = 0; i < array.Length; i ++ ) { * newArray[i] = (double) array[i].GetModulus(); * } * break; * case ConversionStyle.Real: * for( int i = 0; i < array.Length; i ++ ) { * newArray[i] = (double) array[i].Re; * } * break; * case ConversionStyle.Imaginary: * for( int i = 0; i < array.Length; i ++ ) { * newArray[i] = (double) array[i].Im; * } * break; * default: * Debug.Assert( false ); * break; * } * return newArray; * } */ //--------------------------------------------------------------------------------------------- /// <summary> /// Determine whether the elements in the two arrays are the same /// </summary> /// <param name="array1"></param> /// <param name="array2"></param> /// <param name="tolerance"></param> /// <returns></returns> static public bool IsEqual(ComplexD[] array1, ComplexD[] array2, double tolerance) { if (array1.Length != array2.Length) { return(false); } for (int i = 0; i < array1.Length; i++) { if (ComplexD.IsEqual(array1[i], array2[i], tolerance) == false) { return(false); } } return(true); }
/// <summary> /// Parse a complex representation in this fashion: "( %f, %f )" /// </summary> /// <param name="s"></param> /// <returns></returns> static public ComplexD Parse(string s) { char[] sep = { '(', ',', 'i', ' ' }; string[] ss = s.Split(sep, StringSplitOptions.RemoveEmptyEntries); ComplexD c = FromReal(0.0); if (ss.Length >= 1) { c.Re = Convert.ToDouble(ss[0]); } if (ss.Length >= 2) { c.Im = Convert.ToDouble(ss[1]); } return(c); }
static private ComplexD SumRecursion( ComplexD[] data, int start, int end ) { Debug.Assert( 0 <= start, "start = " + start ); Debug.Assert( start < end, "start = " + start + " and end = " + end ); Debug.Assert( end <= data.Length, "end = " + end + " and data.Length = " + data.Length ); if( ( end - start ) <= 1000 ) { ComplexD sum = ComplexD.Zero; for( int i = start; i < end; i ++ ) { sum += data[ i ]; } return sum; } else { int middle = ( start + end ) >> 1; return SumRecursion( data, start, middle ) + SumRecursion( data, middle, end ); } }
static private double SumOfSquaredErrorRecursion( ComplexD[] alpha, ComplexD[] beta, int start, int end ) { Debug.Assert( 0 <= start, "start = " + start ); Debug.Assert( start < end, "start = " + start + " and end = " + end ); Debug.Assert( end <= alpha.Length, "end = " + end + " and alpha.Length = " + alpha.Length ); Debug.Assert( beta.Length == alpha.Length ); if( ( end - start ) <= 1000 ) { double sumOfSquaredError = 0; for( int i = start; i < end; i ++ ) { ComplexD delta = beta[ i ] - alpha[ i ]; sumOfSquaredError += ( delta.Re * delta.Re ) + ( delta.Im * delta.Im ); } return sumOfSquaredError; } else { int middle = ( start + end ) >> 1; return SumOfSquaredErrorRecursion( alpha, beta, start, middle ) + SumOfSquaredErrorRecursion( alpha, beta, middle, end ); } }
//--------------------------------------------------------------------------------------------- /// <summary> /// Shift (offset) the elements in the array /// </summary> /// <param name="array"></param> /// <param name="offset"></param> static public void Shift(ComplexD[] array, int offset) { Debug.Assert(array != null); Debug.Assert(offset >= 0); Debug.Assert(offset < array.Length); if (offset == 0) { return; } int length = array.Length; ComplexD[] temp = new ComplexD[length]; for (int i = 0; i < length; i++) { temp[(i + offset) % length] = array[i]; } for (int i = 0; i < length; i++) { array[i] = temp[i]; } }
//----------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- /// <summary> /// Determine whether two complex numbers are almost (i.e. within the tolerance) equivalent. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="tolerance"></param> /// <returns></returns> static public bool IsEqual(ComplexD a, ComplexD b, double tolerance) { return ((Math.Abs(a.Re - b.Re) < tolerance) && (Math.Abs(a.Im - b.Im) < tolerance)); }
/// <summary> /// Create a complex number based on an existing complex number /// </summary> /// <param name="c"></param> public ComplexD(ComplexD c) { this.Re = c.Re; this.Im = c.Im; }