/*---------------------------------------------------------------------------* * IT++ * *---------------------------------------------------------------------------* * Copyright (c) 2004 by Johan Bergman. * * * * Permission to use, copy, modify, and distribute this software and its * * documentation under the terms of the GNU General Public License is hereby * * granted. No representations are made about the suitability of this * * software for any purpose. It is provided "as is" without expressed or * * implied warranty. See the GNU General Public License for more details. * *---------------------------------------------------------------------------*/ /*! \file \brief Complex fixed-point data type CFix \author Johan Bergman 1.10 2004/09/28 20:19:48 */ #ifndef __cfix_h #define __cfix_h #include "base/fix_base.h" #include "base/fix_factory.h" #include "base/fix.h" namespace itpp { // Forward declarations template class Vec; template class Mat; //! \addtogroup fixtypes //!@{ /*! \brief Complex fixed-point data type. See the Detailed Description in the \ref fixtypes module. */ class CFix : public Fix_Base { template friend class CFixed; public: //! Default constructor CFix(double r=0.0, double i=0.0, int s=0, int w=MAX_WORDLEN, e_mode e=TC, o_mode o=WRAP, q_mode q=TRN, Stat *ptr=0) : Fix_Base(s, w, e, o, q, ptr), re(scale_and_apply_modes(r)), im(scale_and_apply_modes(i)) {} //! Constructor CFix(std::complex x, double dummy=0.0, int s=0, int w=MAX_WORDLEN, e_mode e=TC, o_mode o=WRAP, q_mode q=TRN, Stat *ptr=0) : Fix_Base(s, w, e, o, q, ptr), re(scale_and_apply_modes(std::real(x))), im(scale_and_apply_modes(std::imag(x))) {} //! Constructor explicit CFix(const Fix_Factory &f) : Fix_Base(0, f.wordlen, f.emode, f.omode, f.qmode, f.stat_ptr), re(0), im(0) {} //! Constructor for internal use. No restrictions are applied. The dummies help to avoid ambiguities CFix(fixrep r, fixrep i, int s, int dummy1, int dummy2) : Fix_Base(s), re(r), im(i) {} //! Constructor CFix(const Fix &r, const Fix &i=0.0, int w=MAX_WORDLEN, e_mode e=TC, o_mode o=WRAP, q_mode q=TRN, Stat *ptr=0) : Fix_Base(assert_shifts(r, i), w, e, o, q, ptr), re(r.re), im(i.re) {} //! Copy constructor CFix(const CFix &x, double dummy=0.0, int w=MAX_WORDLEN, e_mode e=TC, o_mode o=WRAP, q_mode q=TRN, Stat *ptr=0) : Fix_Base(x.shift, w, e, o, q, ptr), re(x.re), im(x.im) {} //! Destructor virtual ~CFix() {} //! Assignment from CFix CFix& operator=(const CFix &x); //! Assignment from Fix CFix& operator=(const Fix &x); //! Assignment from complex. Fractional part is truncated CFix& operator=(const std::complex &x); //! Assignment from int CFix& operator=(const int x); //! Addition of CFix CFix& operator+=(const CFix &x); //! Addition of Fix CFix& operator+=(const Fix &x); //! Addition of int CFix& operator+=(const int x); //! Subtraction of CFix CFix& operator-=(const CFix &x); //! Subtraction of Fix CFix& operator-=(const Fix &x); //! Subtraction of int CFix& operator-=(const int x); //! Multiplication with CFix. Temporary variables use the maximum word length (64 bits) CFix& operator*=(const CFix &x); //! Multiplication with Fix. Temporary variables use the maximum word length (64 bits) CFix& operator*=(const Fix &x); //! Multiplication with int. Temporary variables use the maximum word length (64 bits) CFix& operator*=(const int x); //! Division with CFix using quantization mode \c TRN. Temporary variables use the maximum word length (64 bits) CFix& operator/=(const CFix &x); //! Division with Fix using quantization mode \c TRN. Temporary variables use the maximum word length (64 bits) CFix& operator/=(const Fix &x); //! Division with int using quantization mode \c TRN. Temporary variables use the maximum word length (64 bits) CFix& operator/=(const int x); //! Unary negative of CFix CFix operator-() const; //! Left shift \c n bits CFix& operator<<=(const int n); //! Right shift \c n bits using quantization mode \c qmode (constructor argument) CFix& operator>>=(const int n); //! Set to (real + i*imag) * pow2(n) using quantization mode \c qmode (constructor argument) void set(double real, double imag, int n); //! Set to (real + i*imag) * pow2(n) using quantization mode \c q (function argument) void set(double real, double imag, int n, q_mode q); //! Set to x * pow2(n) using quantization mode \c qmode (constructor argument) void set(const complex &x, int n); //! Set to x * pow2(n) using quantization mode \c q (function argument) void set(const complex &x, int n, q_mode q); //! Set data representation for real part (mainly for internal use since it reveals the representation type) void set_re(fixrep x) {re = apply_o_mode(x);} //! Set data representation for imaginary part (mainly for internal use since it reveals the representation type) void set_im(fixrep x) {im = apply_o_mode(x);} //! Left shift \c n bits void lshift(int n); //! Right shift \c n bits using quantization mode \c qmode (constructor argument) void rshift(int n); //! Right shift \c n bits using quantization mode \c q (function argument) void rshift(int n, q_mode q); //! Print restrictions virtual void print() const; //! Get data representation for real part (mainly for internal use since it reveals the representation type) fixrep get_re() const {return re;} //! Get data representation for imaginary part (mainly for internal use since it reveals the representation type) fixrep get_im() const {return im;} //! Conversion to complex std::complex unfix() const; #ifndef NO_IMPLICIT_FIX_CONVERSION //! Conversion to complex operator std::complex() const { it_assert1(shift>=-63 && shift<=64, "CFix::operator complex: Illegal shift!"); return complex(double(re)*DOUBLE_POW2[64 - shift], double(im)*DOUBLE_POW2[64 - shift]); } #endif //! Check that x.shift==y.shift OR x==0 OR y==0 and return the shift (for the non-zero argument) friend int assert_shifts(const CFix &x, const CFix &y); //! Check that x.shift==y.shift OR x==0 OR y==0 and return the shift (for the non-zero argument) friend int assert_shifts(const CFix &x, const Fix &y); //! Check that x.shift==0 OR x==0 OR y==0 and return x.shift friend int assert_shifts(const CFix &x, int y); protected: //! Data representation fixrep re, im; }; //! Input bit representation and, optionally, the shift std::istream &operator>>(std::istream &is, CFix &x); //! Output bit representation and, optionally, the shift std::ostream &operator<<(std::ostream &os, const CFix &x); //! Typedef for complex fixed-point vector type typedef Vec cfixvec; //! Typedef for complex fixed-point matrix type typedef Mat cfixmat; //!@} } //namespace itpp #endif // __cfix_h