/** \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 * * \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 */ class imcfloat { public: float real; ///< Real part. float imag; ///< Imaginary part. /// Default Constructor (0,0). imcfloat():real(0), imag(0) {} /// Constructor from (real, imag) imcfloat(const float& r, const float& i):real(r),imag(i) {} /// Constructor from (real) imcfloat(const float& r):real(r),imag(0) {} }; /** \addtogroup cpx * Complex numbers operators. * @{ */ inline int operator <= (const imcfloat& C1, const imcfloat& C2) { return ((C1.real <= C2.real) && (C1.imag <= C2.imag)); } inline int operator <= (const imcfloat& C, const float& F) { return ((F <= C.real) && (0 <= C.imag)); } inline int operator < (const imcfloat& C1, const imcfloat& C2) { return ((C1.real < C2.real) && (C1.imag < C2.imag)); } inline int operator < (const imcfloat& C, const float& F) { return ((F < C.real) && (0 < C.imag)); } inline int operator > (const imcfloat& C1, const imcfloat& C2) { return ((C1.real > C2.real) && (C1.imag > C2.imag)); } inline int operator > (const imcfloat& C, const float& F) { return ((F > C.real) && (0 > C.imag)); } inline imcfloat operator + (const imcfloat& C1, const imcfloat& C2) { return imcfloat(C1.real + C2.real, C1.imag + C2.imag); } inline imcfloat operator += (const imcfloat& C1, const imcfloat& C2) { return imcfloat(C1.real + C2.real, C1.imag + C2.imag); } inline imcfloat operator - (const imcfloat& C1, const imcfloat& C2) { return imcfloat(C1.real - C2.real, C1.imag - C2.imag); } inline imcfloat operator * (const imcfloat& C1, const imcfloat& C2) { return imcfloat(C1.real * C2.real - C1.imag * C2.imag, C1.imag * C2.real + C1.real * C2.imag); } inline imcfloat operator / (const imcfloat& C1, const imcfloat& C2) { float den = C2.real * C2.real - C2.imag * C2.imag; return imcfloat((C1.real * C2.real + C1.imag * C2.imag) / den, (C1.imag * C2.real - C1.real * C2.imag) / den); } inline imcfloat operator / (const imcfloat& C, const float& R) { return imcfloat(C.real / R, C.imag / R); } inline imcfloat operator /= (const imcfloat& C, const float& R) { return imcfloat(C.real / R, C.imag / R); } inline imcfloat operator * (const imcfloat& C, const float& R) { return imcfloat(C.real * R, C.imag * R); } inline int operator == (const imcfloat& C1, const imcfloat& C2) { return ((C1.real == C2.real) && (C1.imag == C2.imag)); } inline float cpxreal(const imcfloat& C) { return C.real; } inline float cpximag(const imcfloat& C) { return C.imag; } inline float cpxmag(const imcfloat& C) { return sqrtf(C.real*C.real + C.imag*C.imag); } inline float cpxphase(const imcfloat& C) { return atan2f(C.real, C.imag); } inline imcfloat cpxconj(const imcfloat& C) { return imcfloat(C.real, -C.imag); } inline imcfloat log(const imcfloat& C) { return imcfloat(logf(cpxmag(C)), atan2f(C.real, C.imag)); } inline imcfloat exp(const imcfloat& C) { float mag = expf(C.real); return imcfloat(mag * cosf(C.imag), mag * sinf(C.imag)); } inline imcfloat pow(const imcfloat& C1, const imcfloat& C2) { return exp(C1 * log(C2)); } inline imcfloat sqrt(const imcfloat& C) { float mag = sqrtf(sqrtf(C.real*C.real + C.imag*C.imag)); float phase = atan2f(C.real, C.imag) / 2; return imcfloat(mag * cosf(phase), mag * sinf(phase)); } inline imcfloat cpxpolar(const float& mag, const float& phase) { return imcfloat(mag * cosf(phase), mag * sinf(phase)); } /** @} */ #endif