/*---------------------------------------------------------------------------*
* 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 Num_T> class Vec;
template<class Num_T> 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<int, e_mode, o_mode, q_mode> 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<double> 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<double>. Fractional part is truncated
CFix& operator=(const std::complex<double> &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 <tt>(real + i*imag) * pow2(n)</tt> using quantization mode \c qmode (constructor argument)
void set(double real, double imag, int n);
//! Set to <tt>(real + i*imag) * pow2(n)</tt> using quantization mode \c q (function argument)
void set(double real, double imag, int n, q_mode q);
//! Set to <tt>x * pow2(n)</tt> using quantization mode \c qmode (constructor argument)
void set(const complex<double> &x, int n);
//! Set to <tt>x * pow2(n)</tt> using quantization mode \c q (function argument)
void set(const complex<double> &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<double>
std::complex<double> unfix() const;
#ifndef NO_IMPLICIT_FIX_CONVERSION
//! Conversion to complex<double>
operator std::complex<double>() const
{
it_assert1(shift>=-63 && shift<=64, "CFix::operator complex<double>: Illegal shift!");
return complex<double>(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<CFix> cfixvec;
//! Typedef for complex fixed-point matrix type
typedef Mat<CFix> cfixmat;
//!@}
} //namespace itpp
#endif // __cfix_h
syntax highlighted by Code2HTML, v. 0.9.1