summaryrefslogtreecommitdiff
path: root/include/im_complex.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/im_complex.h')
-rw-r--r--include/im_complex.h160
1 files changed, 160 insertions, 0 deletions
diff --git a/include/im_complex.h b/include/im_complex.h
new file mode 100644
index 0000000..2ac4d92
--- /dev/null
+++ b/include/im_complex.h
@@ -0,0 +1,160 @@
+/** \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 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