/** \file * \brief Complex Data Type. * * See Copyright Notice in im_lib.h */ #ifndef __IM_COMPLEX_H #define __IM_COMPLEX_H #include "im_math.h" /** \defgroup cpx Complex Numbers * \par * See \ref im_complex.h * \ingroup util */ /** \brief Complex Float Data Type Class * * \par * Complex class using two floats, one for real part, one for the imaginary part. * \par * It is not a complete complex class, we just implement constructors inside the class. * All the other operators and functions are external to the class. * \ingroup cpx */ template class imComplex { public: T real; ///< Real part. T imag; ///< Imaginary part. /// Default Constructor (0,0). imComplex():real(0), imag(0) {} /// Constructor from (real, imag) imComplex(const T& r, const T& i):real(r),imag(i) {} /// Constructor from (real) imComplex(const T& r):real(r),imag(0) {} }; /** \addtogroup cpx * Complex numbers operators. * @{ */ template inline int operator <= (const imComplex& C1, const imComplex& C2) { return ((C1.real <= C2.real) && (C1.imag <= C2.imag)); } template inline int operator <= (const imComplex& C, const float& R) { return ((C.real <= (T)R) && (C.imag <= 0)); } template inline int operator <= (const imComplex& C, const double& R) { return ((C.real <= (T)R) && (C.imag <= 0)); } template inline int operator < (const imComplex& C1, const imComplex& C2) { return ((C1.real < C2.real) && (C1.imag < C2.imag)); } template inline int operator < (const imComplex& C, const T& R) { return ((C.real < R) && (C.imag < 0)); } template inline int operator > (const imComplex& C1, const imComplex& C2) { return ((C1.real > C2.real) && (C1.imag > C2.imag)); } template inline int operator > (const imComplex& C, const T& R) { return ((C.real > R) && (C.imag > 0)); } template inline imComplex operator + (const imComplex& C1, const imComplex& C2) { return imComplex(C1.real + C2.real, C1.imag + C2.imag); } template inline imComplex operator + (const imComplex& C, const T& R) { return imComplex(C.real + R, C.imag); } template inline imComplex operator += (const imComplex& C1, const imComplex& C2) { return imComplex(C1.real + C2.real, C1.imag + C2.imag); } template inline imComplex operator - (const imComplex& C1, const imComplex& C2) { return imComplex(C1.real - C2.real, C1.imag - C2.imag); } template inline imComplex operator - (const imComplex& C, const T& R) { return imComplex(C.real - R, C.imag); } template inline imComplex operator * (const imComplex& C1, const imComplex& C2) { return imComplex(C1.real * C2.real - C1.imag * C2.imag, C1.imag * C2.real + C1.real * C2.imag); } template inline imComplex operator / (const imComplex& C1, const imComplex& C2) { T den = C2.real * C2.real - C2.imag * C2.imag; return imComplex((C1.real * C2.real + C1.imag * C2.imag) / den, (C1.imag * C2.real - C1.real * C2.imag) / den); } template inline imComplex operator / (const imComplex& C, const float& R) { return imComplex(C.real / (T)R, C.imag / (T)R); } template inline imComplex operator / (const imComplex& C, const double& R) { return imComplex(C.real / (T)R, C.imag / (T)R); } template inline imComplex operator /= (const imComplex& C, const float& R) { return imComplex(C.real / (T)R, C.imag / (T)R); } template inline imComplex operator /= (const imComplex& C, const double& R) { return imComplex(C.real / (T)R, C.imag / (T)R); } template inline imComplex operator * (const imComplex& C, const float& R) { return imComplex(C.real * (T)R, C.imag * (T)R); } template inline imComplex operator * (const imComplex& C, const double& R) { return imComplex(C.real * (T)R, C.imag * (T)R); } template inline int operator == (const imComplex& C1, const imComplex& C2) { return ((C1.real == C2.real) && (C1.imag == C2.imag)); } template inline T cpxreal(const imComplex& C) { return C.real; } template inline T cpximag(const imComplex& C) { return C.imag; } template inline T cpxmag(const imComplex& C) { return sqrt(C.real*C.real + C.imag*C.imag); } template inline T cpxphase(const imComplex& C) { return atan2(C.real, C.imag); } template inline imComplex cpxconj(const imComplex& C) { return imComplex(C.real, -C.imag); } template inline imComplex cpxpolar(const T& mag, const T& phase) { return imComplex(mag * cos(phase), mag * sin(phase)); } template inline imComplex log(const imComplex& C) { return imComplex(log(cpxmag(C)), atan2(C.real, C.imag)); } template inline imComplex exp(const imComplex& C) { T mag = exp(C.real); return imComplex(mag * cos(C.imag), mag * sin(C.imag)); } template inline imComplex pow(const imComplex& C1, const imComplex& C2) { return exp(C1 * log(C2)); } template inline imComplex pow(const imComplex& C1, const T& R) { imComplex C2(R); return pow(C1, C2); } template inline imComplex sqrt(const imComplex& C) { T mag = sqrt(sqrt(C.real*C.real + C.imag*C.imag)); T phase = atan2(C.real, C.imag) / 2; return imComplex(mag * cos(phase), mag * sin(phase)); } /** @} */ /** complex numbers usign 2 floats * \ingroup cpx */ typedef imComplex imcfloat; /** complex numbers usign 2 doubles * \ingroup cpx */ typedef imComplex imcdouble; #endif