diff options
author | dburgess <dburgess@19bc5d8c-e614-43d4-8b26-e1612bc8e597> | 2011-10-12 07:44:40 +0000 |
---|---|---|
committer | dburgess <dburgess@19bc5d8c-e614-43d4-8b26-e1612bc8e597> | 2011-10-12 07:44:40 +0000 |
commit | b3a0ca42db0bd08c58b9370a1398528016e6953f (patch) | |
tree | 1e81558498b765f0faac4c8588c18fbc4bfc8dfb /Transceiver52M/Complex.h | |
parent | ec3d77d0eaa12c102893490766557dd4d4efd029 (diff) |
Adding in the missing Transceiver52M directory
git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@2307 19bc5d8c-e614-43d4-8b26-e1612bc8e597
Diffstat (limited to 'Transceiver52M/Complex.h')
-rw-r--r-- | Transceiver52M/Complex.h | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/Transceiver52M/Complex.h b/Transceiver52M/Complex.h new file mode 100644 index 0000000..32eb18f --- /dev/null +++ b/Transceiver52M/Complex.h @@ -0,0 +1,267 @@ +/**@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"; + os << "\n"; + return os; +} + +//@} + + +#endif |