- exocortex.dsp.zip
- DSP
- bin
- Exocortex.DSP.dll
- ImageFilterDemo.exe
- MandelbrotDemo.exe
- doc
- DSPClassLibrary.chm
- src
- DSP.sln
- DSP.suo
- DSPExamplesSetup
- DSPExamplesSetup.vdproj
- ImageFilterExample
- MandelbrotExample
- Libraries
- Exocortex.DSP
- dsplibrarydemos.zip
- DSPLibraryDemos.msi
|
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Exocortex.DSP {
/// <summary>
/// <p>A single-precision complex number representation.</p>
/// <p>Comments? Questions? Bugs? Tell Ben Houston at ben@exocortex.org</p>
/// <p>Version: March 22, 2002</p>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ComplexF : IComparable, ICloneable {
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <summary>
/// The real component of the complex number
/// </summary>
public float Re;
/// <summary>
/// The imaginary component of the complex number
/// </summary>
public float Im;
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <summary>
/// Create a complex number from a real and an imaginary component
/// </summary>
/// <param name="real"></param>
/// <param name="imaginary"></param>
public ComplexF( float real, float imaginary ) {
this.Re = (float) real;
this.Im = (float) imaginary;
}
/// <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;
}
/// <summary>
/// Create a complex number from a real and an imaginary component
/// </summary>
/// <param name="real"></param>
/// <param name="imaginary"></param>
/// <returns></returns>
static public ComplexF FromRealImaginary( float real, float imaginary ) {
ComplexF c;
c.Re = (float) real;
c.Im = (float) imaginary;
return c;
}
/// <summary>
/// Create a complex number from a modulus (length) and an argument (radian)
/// </summary>
/// <param name="modulus"></param>
/// <param name="argument"></param>
/// <returns></returns>
static public ComplexF FromModulusArgument( float modulus, float argument ) {
ComplexF c;
c.Re = (float)( modulus * System.Math.Cos( argument ) );
c.Im = (float)( modulus * System.Math.Sin( argument ) );
return c;
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
object ICloneable.Clone() {
return new ComplexF( this );
}
/// <summary>
/// Clone the complex number
/// </summary>
/// <returns></returns>
public ComplexF Clone() {
return new ComplexF( this );
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <summary>
/// The modulus (length) of the complex number
/// </summary>
/// <returns></returns>
public float GetModulus() {
float x = this.Re;
float y = this.Im;
return (float) Math.Sqrt( x*x + y*y );
}
/// <summary>
/// The squared modulus (length^2) of the complex number
/// </summary>
/// <returns></returns>
public float GetModulusSquared() {
float x = this.Re;
float y = this.Im;
return (float) x*x + y*y;
}
/// <summary>
/// The argument (radians) of the complex number
/// </summary>
/// <returns></returns>
public float GetArgument() {
return (float) Math.Atan2( this.Im, this.Re );
}
//-----------------------------------------------------------------------------------
/// <summary>
/// Get the conjugate of the complex number
/// </summary>
/// <returns></returns>
public ComplexF GetConjugate() {
return FromRealImaginary( this.Re, -this.Im );
}
//-----------------------------------------------------------------------------------
/// <summary>
/// Scale the complex number to 1.
/// </summary>
public void Normalize() {
double modulus = this.GetModulus();
if( modulus == 0 ) {
throw new DivideByZeroException( "Can not normalize a complex number that is zero." );
}
this.Re = (float)( this.Re / modulus );
this.Im = (float)( this.Im / modulus );
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <summary>
/// Convert to a from double precision complex number to a single precison complex number
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public static explicit operator ComplexF ( Complex c ) {
ComplexF cF;
cF.Re = (float) c.Re;
cF.Im = (float) c.Im;
return cF;
}
/// <summary>
/// Convert from a single precision real number to a complex number
/// </summary>
/// <param name="f"></param>
/// <returns></returns>
public static explicit operator ComplexF ( float f ) {
ComplexF c;
c.Re = (float) f;
c.Im = (float) 0;
return c;
}
/// <summary>
/// Convert from a single precision complex to a real number
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public static explicit operator float ( ComplexF c ) {
return (float) c.Re;
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <summary>
/// Are these two complex numbers equivalent?
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static bool operator==( ComplexF a, ComplexF b ) {
return ( a.Re == b.Re ) && ( a.Im == b.Im );
}
/// <summary>
/// Are these two complex numbers different?
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static bool operator!=( ComplexF a, ComplexF b ) {
return ( a.Re != b.Re ) || ( a.Im != b.Im );
}
/// <summary>
/// Get the hash code of the complex number
/// </summary>
/// <returns></returns>
public override int GetHashCode() {
return ( this.Re.GetHashCode() ^ this.Im.GetHashCode() );
}
/// <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 ComplexF ) {
ComplexF c = (ComplexF) o;
return ( this == c );
}
return false;
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <summary>
/// Compare to other complex numbers or real numbers
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public int CompareTo( object o ) {
if( o is ComplexF ) {
return this.GetModulus().CompareTo( ((ComplexF)o).GetModulus() );
}
if( o is float ) {
return this.GetModulus().CompareTo( (float)o );
}
if( o is Complex ) {
return this.GetModulus().CompareTo( ((Complex)o).GetModulus() );
}
if( o is double ) {
return this.GetModulus().CompareTo( (double)o );
}
return 0;
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <summary>
/// This operator doesn't do much. :-)
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static ComplexF operator+( ComplexF a ) {
return a;
}
/// <summary>
/// Negate the complex number
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static ComplexF operator-( ComplexF a ) {
a.Re = -a.Re;
a.Im = -a.Im;
return a;
}
/// <summary>
/// Add a complex number to a real
/// </summary>
/// <param name="a"></param>
/// <param name="f"></param>
/// <returns></returns>
public static ComplexF operator+( ComplexF a, float f ) {
a.Re = (float)( a.Re + f );
return a;
}
/// <summary>
/// Add a real to a complex number
/// </summary>
/// <param name="f"></param>
/// <param name="a"></param>
/// <returns></returns>
public static ComplexF operator+( float f, ComplexF a ) {
a.Re = (float)( a.Re + f );
return a;
}
/// <summary>
/// Add to complex numbers
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static ComplexF operator+( ComplexF a, ComplexF b ) {
a.Re = a.Re + b.Re;
a.Im = a.Im + b.Im;
return a;
}
/// <summary>
/// Subtract a real from a complex number
/// </summary>
/// <param name="a"></param>
/// <param name="f"></param>
/// <returns></returns>
public static ComplexF operator-( ComplexF a, float f ) {
a.Re = (float)( a.Re - f );
return a;
}
/// <summary>
/// Subtract a complex number from a real
/// </summary>
/// <param name="f"></param>
/// <param name="a"></param>
/// <returns></returns>
public static ComplexF operator-( float f, ComplexF a ) {
a.Re = (float)( a.Re - f );
return a;
}
/// <summary>
/// Subtract two complex numbers
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static ComplexF operator-( ComplexF a, ComplexF b ) {
a.Re = a.Re - b.Re;
a.Im = a.Im - b.Im;
return a;
}
/// <summary>
/// Multiply a complex number by a real
/// </summary>
/// <param name="a"></param>
/// <param name="f"></param>
/// <returns></returns>
public static ComplexF operator*( ComplexF a, float f ) {
a.Re = (float)( a.Re * f );
a.Im = (float)( a.Im * f );
return a;
}
/// <summary>
/// Multiply a real by a complex number
/// </summary>
/// <param name="f"></param>
/// <param name="a"></param>
/// <returns></returns>
public static ComplexF operator*( float f, ComplexF a ) {
a.Re = (float)( a.Re * f );
a.Im = (float)( a.Im * f );
return a;
}
/// <summary>
/// Multiply two complex numbers together
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static ComplexF operator*( ComplexF a, ComplexF b ) {
// (x + yi)(u + vi) = (xu � yv) + (xv + yu)i.
double x = a.Re, y = a.Im;
double u = b.Re, v = b.Im;
a.Re = (float)( x*u - y*v );
a.Im = (float)( x*v + y*u );
return a;
}
/// <summary>
/// Divide a complex number by a real number
/// </summary>
/// <param name="a"></param>
/// <param name="f"></param>
/// <returns></returns>
public static ComplexF operator/( ComplexF a, float f ) {
if( f == 0 ) {
throw new DivideByZeroException();
}
a.Re = (float)( a.Re / f );
a.Im = (float)( a.Im / f );
return a;
}
/// <summary>
/// Divide a complex number by a complex number
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static ComplexF operator/( ComplexF a, ComplexF b ) {
double x = a.Re, y = a.Im;
double u = b.Re, v = b.Im;
double denom = u*u + v*v;
if( denom == 0 ) {
throw new DivideByZeroException();
}
a.Re = (float)( ( x*u + y*v ) / denom );
a.Im = (float)( ( y*u - x*u ) / denom );
return a;
}
/// <summary>
/// Parse a complex representation in this fashion: "( %f, %f )"
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
static public ComplexF Parse( string s ) {
throw new NotImplementedException( "ComplexF ComplexF.Parse( string s ) is not implemented." );
}
/// <summary>
/// Get the string representation
/// </summary>
/// <returns></returns>
public override string ToString() {
return String.Format( "( {0}, {1}i )", this.Re, this.Im );
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
/// <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 );
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
/// <summary>
/// Represents zero
/// </summary>
static public ComplexF Zero {
get { return ComplexF.FromRealImaginary( 0, 0 ); }
}
/// <summary>
/// Represents the result of sqrt( -1 )
/// </summary>
static public ComplexF I {
get { return ComplexF.FromRealImaginary( 0, 1 ); }
}
/// <summary>
/// Represents the largest possible value of ComplexF.
/// </summary>
static public ComplexF MaxValue {
get { return ComplexF.FromRealImaginary( float.MaxValue, float.MaxValue ); }
}
/// <summary>
/// Represents the smallest possible value of ComplexF.
/// </summary>
static public ComplexF MinValue {
get { return ComplexF.FromRealImaginary( float.MinValue, float.MinValue ); }
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.