aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/Complex.h
diff options
context:
space:
mode:
Diffstat (limited to 'Transceiver52M/Complex.h')
-rw-r--r--Transceiver52M/Complex.h266
1 files changed, 266 insertions, 0 deletions
diff --git a/Transceiver52M/Complex.h b/Transceiver52M/Complex.h
new file mode 100644
index 0000000..d02944b
--- /dev/null
+++ b/Transceiver52M/Complex.h
@@ -0,0 +1,266 @@
+/**@file templates for Complex classes
+unlike the built-in complex<> templates, these inline most operations for speed
+*/
+
+/*
+* Copyright 2008 Free Software Foundation, Inc.
+*
+* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
+*
+* This use of this software may be subject to additional restrictions.
+* See the LEGAL file in the main directory for details.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+*/
+
+
+
+
+#ifndef COMPLEXCPP_H
+#define COMPLEXCPP_H
+
+#include <math.h>
+#include <ostream>
+
+
+template<class Real> class Complex {
+
+public:
+
+ Real r, i;
+
+ /**@name constructors */
+ //@{
+ /**@name from real */
+ //@{
+ Complex(Real real, Real imag) {r=real; i=imag;} // x=complex(a,b)
+ Complex(Real real) {r=real; i=0;} // x=complex(a)
+ //@}
+ /**@name from nothing */
+ //@{
+ Complex() {r=(Real)0; i=(Real)0;} // x=complex()
+ //@}
+ /**@name from other complex */
+ //@{
+ Complex(const Complex<float>& z) {r=z.r; i=z.i;} // x=complex(z)
+ Complex(const Complex<double>& z) {r=z.r; i=z.i;} // x=complex(z)
+ Complex(const Complex<long double>& z) {r=z.r; i=z.i;} // x=complex(z)
+ //@}
+ //@}
+
+ /**@name casting up from basic numeric types */
+ //@{
+ Complex& operator=(char a) { r=(Real)a; i=(Real)0; return *this; }
+ Complex& operator=(int a) { r=(Real)a; i=(Real)0; return *this; }
+ Complex& operator=(long int a) { r=(Real)a; i=(Real)0; return *this; }
+ Complex& operator=(short a) { r=(Real)a; i=(Real)0; return *this; }
+ Complex& operator=(float a) { r=(Real)a; i=(Real)0; return *this; }
+ Complex& operator=(double a) { r=(Real)a; i=(Real)0; return *this; }
+ Complex& operator=(long double a) { r=(Real)a; i=(Real)0; return *this; }
+ //@}
+
+ /**@name arithmetic */
+ //@{
+ /**@ binary operators */
+ //@{
+ Complex operator+(const Complex<Real>& a) const { return Complex<Real>(r+a.r, i+a.i); }
+ Complex operator+(Real a) const { return Complex<Real>(r+a,i); }
+ Complex operator-(const Complex<Real>& a) const { return Complex<Real>(r-a.r, i-a.i); }
+ Complex operator-(Real a) const { return Complex<Real>(r-a,i); }
+ Complex operator*(const Complex<Real>& a) const { return Complex<Real>(r*a.r-i*a.i, r*a.i+i*a.r); }
+ Complex operator*(Real a) const { return Complex<Real>(r*a, i*a); }
+ Complex operator/(const Complex<Real>& a) const { return operator*(a.inv()); }
+ Complex operator/(Real a) const { return Complex<Real>(r/a, i/a); }
+ //@}
+ /*@name component-wise product */
+ //@{
+ Complex operator&(const Complex<Real>& a) const { return Complex<Real>(r*a.r, i*a.i); }
+ //@}
+ /*@name inplace operations */
+ //@{
+ Complex& operator+=(const Complex<Real>&);
+ Complex& operator-=(const Complex<Real>&);
+ Complex& operator*=(const Complex<Real>&);
+ Complex& operator/=(const Complex<Real>&);
+ Complex& operator+=(Real);
+ Complex& operator-=(Real);
+ Complex& operator*=(Real);
+ Complex& operator/=(Real);
+ //@}
+ //@}
+
+ /**@name comparisons */
+ //@{
+ bool operator==(const Complex<Real>& a) const { return ((i==a.i)&&(r==a.r)); }
+ bool operator!=(const Complex<Real>& a) const { return ((i!=a.i)||(r!=a.r)); }
+ bool operator<(const Complex<Real>& a) const { return norm2()<a.norm2(); }
+ bool operator>(const Complex<Real>& a) const { return norm2()>a.norm2(); }
+ //@}
+
+ /// reciprocation
+ Complex inv() const;
+
+ // unary functions -- inlined
+ /**@name unary functions */
+ //@{
+ /**@name inlined */
+ //@{
+ Complex conj() const { return Complex<Real>(r,-i); }
+ Real norm2() const { return i*i+r*r; }
+ Complex flip() const { return Complex<Real>(i,r); }
+ Real real() const { return r;}
+ Real imag() const { return i;}
+ Complex neg() const { return Complex<Real>(-r, -i); }
+ bool isZero() const { return ((r==(Real)0) && (i==(Real)0)); }
+ //@}
+ /**@name not inlined due to outside calls */
+ //@{
+ Real abs() const { return ::sqrt(norm2()); }
+ Real arg() const { return ::atan2(i,r); }
+ float dB() const { return 10.0*log10(norm2()); }
+ Complex exp() const { return expj(i)*(::exp(r)); }
+ Complex unit() const; ///< unit phasor with same angle
+ Complex log() const { return Complex(::log(abs()),arg()); }
+ Complex pow(double n) const { return expj(arg()*n)*(::pow(abs(),n)); }
+ Complex sqrt() const { return pow(0.5); }
+ //@}
+ //@}
+
+};
+
+
+/**@name standard Complex manifestations */
+//@{
+typedef Complex<float> complex;
+typedef Complex<double> dcomplex;
+typedef Complex<short> complex16;
+typedef Complex<long> complex32;
+//@}
+
+
+template<class Real> inline Complex<Real> Complex<Real>::inv() const
+{
+ Real nVal;
+
+ nVal = norm2();
+ return Complex<Real>(r/nVal, -i/nVal);
+}
+
+template<class Real> Complex<Real>& Complex<Real>::operator+=(const Complex<Real>& a)
+{
+ r += a.r;
+ i += a.i;
+ return *this;
+}
+
+template<class Real> Complex<Real>& Complex<Real>::operator*=(const Complex<Real>& a)
+{
+ operator*(a);
+ return *this;
+}
+
+template<class Real> Complex<Real>& Complex<Real>::operator-=(const Complex<Real>& a)
+{
+ r -= a.r;
+ i -= a.i;
+ return *this;
+}
+
+template<class Real> Complex<Real>& Complex<Real>::operator/=(const Complex<Real>& a)
+{
+ operator/(a);
+ return *this;
+}
+
+
+/* op= style operations with reals */
+
+template<class Real> Complex<Real>& Complex<Real>::operator+=(Real a)
+{
+ r += a;
+ return *this;
+}
+
+template<class Real> Complex<Real>& Complex<Real>::operator*=(Real a)
+{
+ r *=a;
+ i *=a;
+ return *this;
+}
+
+template<class Real> Complex<Real>& Complex<Real>::operator-=(Real a)
+{
+ r -= a;
+ return *this;
+}
+
+template<class Real> Complex<Real>& Complex<Real>::operator/=(Real a)
+{
+ r /= a;
+ i /= a;
+ return *this;
+}
+
+
+template<class Real> Complex<Real> Complex<Real>::unit() const
+{
+ Real absVal = abs();
+ return (Complex<Real>(r/absVal, i/absVal));
+}
+
+
+
+/**@name complex functions outside of the Complex<> class. */
+//@{
+
+/** this allows type-commutative multiplication */
+template<class Real> Complex<Real> operator*(Real a, const Complex<Real>& z)
+{
+ return Complex<Real>(z.r*a, z.i*a);
+}
+
+
+/** this allows type-commutative addition */
+template<class Real> Complex<Real> operator+(Real a, const Complex<Real>& z)
+{
+ return Complex<Real>(z.r+a, z.i);
+}
+
+
+/** this allows type-commutative subtraction */
+template<class Real> Complex<Real> operator-(Real a, const Complex<Real>& z)
+{
+ return Complex<Real>(z.r-a, z.i);
+}
+
+
+
+/// e^jphi
+template<class Real> Complex<Real> expj(Real phi)
+{
+ return Complex<Real>(cos(phi),sin(phi));
+}
+
+/// phasor expression of a complex number
+template<class Real> Complex<Real> phasor(Real C, Real phi)
+{
+ return (expj(phi)*C);
+}
+
+/// formatted stream output
+template<class Real> std::ostream& operator<<(std::ostream& os, const Complex<Real>& z)
+{
+ os << z.r << ' ';
+ //os << z.r << ", ";
+ //if (z.i>=0) { os << "+"; }
+ os << z.i << "j";
+ return os;
+}
+
+//@}
+
+
+#endif