Beispiel #1
0
        //---------------------------------------------------------------------------------------------------
        /// <summary>
        /// Calculate the power of a complex number
        /// </summary>
        /// <param name="c"></param>
        /// <param name="exponent"></param>
        /// <returns></returns>
        public static ComplexF Pow( ComplexF 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		= (float)( modulus * System.Math.Cos( argument ) );
            c.Im = (float)( modulus * System.Math.Sin( argument ) );

            return	c;
        }
Beispiel #2
0
 //-----------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------
 /// <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>
 public static bool IsEqual( ComplexF a, ComplexF b, float tolerance )
 {
     return
         ( Math.Abs( a.Re - b.Re ) < tolerance ) &&
         ( Math.Abs( a.Im - b.Im ) < tolerance );
 }
Beispiel #3
0
 /// <summary>
 /// Swap two complex numbers
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 public static void Swap( ref ComplexF a, ref ComplexF b )
 {
     ComplexF temp = a;
     a = b;
     b = temp;
 }
Beispiel #4
0
 private static void UnlockWorkspaceF( ref ComplexF[] workspace )
 {
     Debug.Assert( _workspaceF == workspace );
     Debug.Assert( _workspaceFLocked == true );
     _workspaceFLocked = false;
     workspace = null;
 }
Beispiel #5
0
        /// <summary>
        /// Shift (offset) the elements in the array
        /// </summary>
        /// <param name="array"></param>
        /// <param name="offset"></param>
        public static void Shift( ComplexF[] array, int offset )
        {
            Debug.Assert( array != null );
            Debug.Assert( offset >= 0 );
            Debug.Assert( offset < array.Length );

            if( offset == 0 ) {
                return;
            }

            int			length		= array.Length;
            ComplexF[]	workspace	= null;
            ComplexArray.LockWorkspaceF( length, ref workspace );

            for( int i = 0; i < length; i ++ ) {
                workspace[ ( i + offset ) % length ] = array[ i ];
            }
            for( int i = 0; i < length; i ++ ) {
                array[ i ] = workspace[ i ];
            }

            ComplexArray.UnlockWorkspaceF( ref workspace );
        }
Beispiel #6
0
        /// <summary>
        /// Multiply each element in the array by a specific value
        /// </summary>
        /// <param name="array"></param>
        /// <param name="scale"></param>
        public static void Scale( ComplexF[] array, ComplexF scale )
        {
            Debug.Assert( array != null );

            int length = array.Length;
            for( int i = 0; i < length; i ++ ) {
                array[i] *= scale;
            }
        }
Beispiel #7
0
 /// <summary>
 /// Scale and offset the elements in the array so that the
 /// overall range is [0, 1]
 /// </summary>
 /// <param name="array"></param>
 public static void Normalize( ComplexF[] array )
 {
     float min = 0, max = 0;
     GetLengthRange( array, ref min, ref max );
     Scale( array, ( 1 / ( max - min ) ) );
     Offset( array, ( - min / ( max - min ) ) );
 }
Beispiel #8
0
 /// <summary>
 /// Multiply each element in target array with corresponding element in rhs array
 /// </summary>
 /// <param name="target"></param>
 /// <param name="rhs"></param>
 public static void Multiply( ComplexF[] target, ComplexF[] rhs )
 {
     ComplexArray.Multiply( target, rhs, target );
 }
Beispiel #9
0
        private static ComplexF SumRecursion( ComplexF[] 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 ) {
                ComplexF sum = ComplexF.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 );
            }
        }
Beispiel #10
0
        private static float SumOfSquaredErrorRecursion( ComplexF[] alpha, ComplexF[] 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 ) {
                float sumOfSquaredError = 0;
                for( int i = start; i < end; i ++ ) {
                    ComplexF 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 );
            }
        }
Beispiel #11
0
 /// <summary>
 /// Calculate the variance
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public static ComplexF Variance( ComplexF[] data )
 {
     Debug.Assert( data != null );
     if( data.Length == 0 ) {
         throw new DivideByZeroException( "length of data is zero" );
     }
     return	ComplexStats.SumOfSquares( data ) / data.Length - ComplexStats.Sum( data );
 }
Beispiel #12
0
 //--------------------------------------------------------------------------------------------
 //--------------------------------------------------------------------------------------------
 /// <summary>
 /// Calculate the sum of squares
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public static ComplexF SumOfSquares( ComplexF[] data )
 {
     Debug.Assert( data != null );
     return	SumOfSquaresRecursion( data, 0, data.Length );
 }
Beispiel #13
0
 /// <summary>
 /// Calculate the standard deviation
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public static ComplexF StdDev( ComplexF[] data )
 {
     Debug.Assert( data != null );
     if( data.Length == 0 ) {
         throw new DivideByZeroException( "length of data is zero" );
     }
     return	ComplexMath.Sqrt( ComplexStats.Variance( data ) );
 }
Beispiel #14
0
 /// <summary>
 /// Create a complex number based on an existing complex number
 /// </summary>
 /// <param name="c"></param>
 public ComplexF(ComplexF c)
 {
     this.Re = c.Re;
     this.Im = c.Im;
 }
Beispiel #15
0
        //-----------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------

        /// <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(ComplexF a, ComplexF b, float tolerance)
        {
            return
                ((Math.Abs(a.Re - b.Re) < tolerance) &&
                 (Math.Abs(a.Im - b.Im) < tolerance));
        }
Beispiel #16
0
        private static void LinearFFT( ComplexF[] data, int start, int inc, int length, FourierDirection direction )
        {
            Debug.Assert( data != null );
            Debug.Assert( start >= 0 );
            Debug.Assert( inc >= 1 );
            Debug.Assert( length >= 1 );
            Debug.Assert( ( start + inc * ( length - 1 ) ) < data.Length );

            // copy to buffer
            ComplexF[]	buffer = null;
            LockBufferCF( length, ref buffer );
            int j = start;
            for( int i = 0; i < length; i ++ ) {
                buffer[ i ] = data[ j ];
                j += inc;
            }

            FFT( buffer, length, direction );

            // copy from buffer
            j = start;
            for( int i = 0; i < length; i ++ ) {
                data[ j ] = buffer[ i ];
                j += inc;
            }
            UnlockBufferCF( ref buffer );
        }
Beispiel #17
0
 /// <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>
 public static bool IsEqual( ComplexF[] array1, ComplexF[] array2, float tolerance )
 {
     if ( array1.Length != array2.Length ) {
         return false;
     }
     for( int i = 0; i < array1.Length; i ++ ) {
         if( ComplexF.IsEqual( array1[i], array2[i], tolerance ) == false ) {
             return false;
         }
     }
     return true;
 }
Beispiel #18
0
 //--------------------------------------------------------------------------------------------
 //--------------------------------------------------------------------------------------------
 /// <summary>
 /// Calculate the mean (average)
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public static ComplexF Mean( ComplexF[] data )
 {
     return	ComplexStats.Sum( data ) / data.Length;
 }
Beispiel #19
0
        /// <summary>
        /// Multiply each element in lhs array with corresponding element in rhs array and
        /// put product in result array
        /// </summary>
        /// <param name="lhs"></param>
        /// <param name="rhs"></param>
        /// <param name="result"></param>
        public static void Multiply( ComplexF[] lhs, ComplexF[] rhs, ComplexF[] result )
        {
            Debug.Assert( lhs != null );
            Debug.Assert( rhs != null );
            Debug.Assert( result != null );
            Debug.Assert( lhs.Length == rhs.Length );
            Debug.Assert( lhs.Length == result.Length );

            int length = lhs.Length;
            for( int i = 0; i < length; i ++ ) {
                result[i] = lhs[i] * rhs[i];
            }
        }
Beispiel #20
0
        //--------------------------------------------------------------------------------------------
        //--------------------------------------------------------------------------------------------
        /// <summary>
        /// Calculate the root mean squared (RMS) error between two sets of data.
        /// </summary>
        /// <param name="alpha"></param>
        /// <param name="beta"></param>
        /// <returns></returns>
        public static float RMSError( ComplexF[] alpha, ComplexF[] beta )
        {
            Debug.Assert( alpha != null );
            Debug.Assert( beta != null );
            Debug.Assert( beta.Length == alpha.Length );

            return (float) Math.Sqrt( SumOfSquaredErrorRecursion( alpha, beta, 0, alpha.Length ) );
        }
Beispiel #21
0
 /// <summary>
 /// Add a specific value to each element in the array
 /// </summary>
 /// <param name="array"></param>
 /// <param name="offset"></param>
 public static void Offset( ComplexF[] array, ComplexF offset )
 {
     int length = array.Length;
     for( int i = 0; i < length; i ++ ) {
         array[i] += offset;
     }
 }
        public int GetMandelbrotDepth( ComplexF c )
        {
            int depth = 0;
            ComplexF a = ComplexF.Zero;

            // iterate until either the limit is reached or it is
            // certain that a(k+1) = a(k)^2 + c goes to infinity.
            do {
                a = a*a + c;
                depth += 8;
            } while ( ( depth < 512 ) && ( a.GetModulusSquared() < 4.0f ) );

            if( a.GetModulusSquared() < 4.0f ) {
                return	255;
            }

            return	( depth % 256 );
        }
Beispiel #23
0
        /// <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>
        public static void Scale( ComplexF[] array, ComplexF 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;
            }
        }
Beispiel #24
0
 /// <summary>
 /// Copy an array
 /// </summary>
 /// <param name="dest"></param>
 /// <param name="source"></param>
 public static void Copy( ComplexF[] dest, ComplexF[] source )
 {
     Debug.Assert( dest != null );
     Debug.Assert( source != null );
     Debug.Assert( dest.Length == source.Length );
     for( int i = 0; i < dest.Length; i ++ ) {
         dest[i] = source[i];
     }
 }
Beispiel #25
0
 private static void LockWorkspaceF( int length, ref ComplexF[] workspace )
 {
     Debug.Assert( _workspaceFLocked == false );
     _workspaceFLocked = true;
     if( length >= _workspaceF.Length ) {
         _workspaceF	= new ComplexF[ length ];
     }
     workspace =	_workspaceF;
 }
Beispiel #26
0
 /// <summary>
 /// Divide each element in target array with corresponding element in rhs array
 /// </summary>
 /// <param name="target"></param>
 /// <param name="rhs"></param>
 public static void Divide( ComplexF[] target, ComplexF[] rhs )
 {
     ComplexArray.Divide( target, rhs, target );
 }
Beispiel #27
0
        /// <summary>
        /// Calculate the square root of a complex number
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public static ComplexF Sqrt( ComplexF 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		= (float)( _halfOfRoot2 * Math.Sqrt( modulus + x ) );
            c.Im	= (float)( _halfOfRoot2 * sign * Math.Sqrt( modulus - x ) );

            return	c;
        }
Beispiel #28
0
        /// <summary>
        /// Divide each element in lhs array with corresponding element in rhs array and
        /// put product in result array
        /// </summary>
        /// <param name="lhs"></param>
        /// <param name="rhs"></param>
        /// <param name="result"></param>
        public static void Divide( ComplexF[] lhs, ComplexF[] rhs, ComplexF[] result )
        {
            Debug.Assert( lhs != null );
            Debug.Assert( rhs != null );
            Debug.Assert( result != null );
            Debug.Assert( lhs.Length == rhs.Length );
            Debug.Assert( lhs.Length == result.Length );

            ComplexF zero = ComplexF.Zero;
            int length = lhs.Length;
            for( int i = 0; i < length; i ++ ) {
                if( rhs[i] != zero ) {
                    result[i] = lhs[i] / rhs[i];
                }
                else {
                    result[i] = zero;
                }
            }
        }
Beispiel #29
0
 /// <summary>
 /// Get the range of element lengths
 /// </summary>
 /// <param name="array"></param>
 /// <param name="minimum"></param>
 /// <param name="maximum"></param>
 public static void GetLengthRange( ComplexF[] array, ref float minimum, ref float maximum )
 {
     minimum = +float.MaxValue;
     maximum = -float.MaxValue;
     for( int i = 0; i < array.Length; i ++ ) {
         float temp = array[i].GetModulus();
         minimum = Math.Min( temp, minimum );
         maximum = Math.Max( temp, maximum );
     }
 }
Beispiel #30
0
 /// <summary>
 /// Invert each element in the array
 /// </summary>
 /// <param name="array"></param>
 public static void Invert( ComplexF[] array )
 {
     for( int i = 0; i < array.Length; i ++ ) {
         array[i] = ((ComplexF) 1 ) / array[i];
     }
 }
Beispiel #31
0
 /// <summary>
 /// Create a complex number based on an existing complex number
 /// </summary>
 /// <param name="c"></param>
 public ComplexF( ComplexF c )
 {
     this.Re		= c.Re;
     this.Im	= c.Im;
 }
Beispiel #32
0
        /// <summary>
        /// Compute a 1D fast Fourier transform of a dataset of complex numbers.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <param name="direction"></param>
        public static void FFT_Quick( ComplexF[] data, int length, FourierDirection direction )
        {
            /*if( data == null ) {
                throw new ArgumentNullException( "data" );
            }
            if( data.Length < length ) {
                throw new ArgumentOutOfRangeException( "length", length, "must be at least as large as 'data.Length' parameter" );
            }
            if( Fourier.IsPowerOf2( length ) == false ) {
                throw new ArgumentOutOfRangeException( "length", length, "must be a power of 2" );
            }

            Fourier.SyncLookupTableLength( length );*/

            int ln = Fourier.Log2( length );

            // reorder array
            Fourier.ReorderArray( data );

            // successive doubling
            int N = 1;
            int signIndex = ( direction == FourierDirection.Forward ) ? 0 : 1;

            for( int level = 1; level <= ln; level ++ ) {
                int M = N;
                N <<= 1;

                float[] uRLookup = _uRLookupF[ level, signIndex ];
                float[] uILookup = _uILookupF[ level, signIndex ];

                for( int j = 0; j < M; j ++ ) {
                    float uR = uRLookup[j];
                    float uI = uILookup[j];

                    for( int even = j; even < length; even += N ) {
                        int odd	 = even + M;

                        float	r = data[ odd ].Re;
                        float	i = data[ odd ].Im;

                        float	odduR = r * uR - i * uI;
                        float	odduI = r * uI + i * uR;

                        r = data[ even ].Re;
                        i = data[ even ].Im;

                        data[ even ].Re	= r + odduR;
                        data[ even ].Im	= i + odduI;

                        data[ odd ].Re	= r - odduR;
                        data[ odd ].Im	= i - odduI;
                    }
                }
            }
        }