IT++ Logo Newcom Logo

cfix.cpp

Go to the documentation of this file.
00001 
00033 #include <itpp/fixedpoint/cfix.h>
00034 #include <itpp/base/itassert.h>
00035 #include <iostream>
00036 
00037 
00038 namespace itpp {
00039 
00040   CFix& CFix::operator=(const CFix &x)
00041   {
00042     shift = x.shift;
00043     re = apply_o_mode(x.re);
00044     im = apply_o_mode(x.im);
00045     return *this;
00046   }
00047 
00048   CFix& CFix::operator=(const Fix &x)
00049   {
00050     shift = x.shift;
00051     re = apply_o_mode(x.re);
00052     im = 0;
00053     return *this;
00054   }
00055 
00056   CFix& CFix::operator=(const std::complex<double> &x)
00057   {
00058     shift = 0;
00059     re = apply_o_mode(fixrep(std::real(x)));
00060     im = apply_o_mode(fixrep(std::imag(x)));
00061     return *this;
00062   }
00063 
00064   CFix& CFix::operator=(const int x)
00065   {
00066     shift = 0;
00067     re = apply_o_mode(x);
00068     im = 0;
00069     return *this;
00070   }
00071 
00072   CFix& CFix::operator+=(const CFix &x)
00073   {
00074     shift = assert_shifts(*this, x);
00075     re = apply_o_mode(re + x.re);
00076     im = apply_o_mode(im + x.im);
00077     return *this;
00078   }
00079 
00080   CFix& CFix::operator+=(const Fix &x)
00081   {
00082     shift = assert_shifts(*this, x);
00083     re = apply_o_mode(re + x.re);
00084     return *this;
00085   }
00086 
00087   CFix& CFix::operator+=(const int x)
00088   {
00089     assert_shifts(*this, x);
00090     re = apply_o_mode(re + x);
00091     return *this;
00092   }
00093 
00094   CFix& CFix::operator-=(const CFix &x)
00095   {
00096     shift = assert_shifts(*this, x);
00097     re = apply_o_mode(re - x.re);
00098     im = apply_o_mode(im - x.im);
00099     return *this;
00100   }
00101 
00102   CFix& CFix::operator-=(const Fix &x)
00103   {
00104     shift = assert_shifts(*this, x);
00105     re = apply_o_mode(re - x.re);
00106     return *this;
00107   }
00108 
00109   CFix& CFix::operator-=(const int x)
00110   {
00111     assert_shifts(*this, x);
00112     re = apply_o_mode(re - x);
00113     return *this;
00114   }
00115 
00116   CFix& CFix::operator*=(const CFix &x)
00117   {
00118     shift += x.shift;
00119     fixrep tmp_re = apply_o_mode(re*x.re - im*x.im);
00120     im = apply_o_mode(re*x.im + im*x.re);
00121     re = tmp_re;
00122     return *this;
00123   }
00124 
00125   CFix& CFix::operator*=(const Fix &x)
00126   {
00127     shift += x.shift;
00128     re = apply_o_mode(re*x.re);
00129     im = apply_o_mode(im*x.re);
00130     return *this;
00131   }
00132 
00133   CFix& CFix::operator*=(const int x)
00134   {
00135     re = apply_o_mode(re*x);
00136     im = apply_o_mode(im*x);
00137     return *this;
00138   }
00139 
00140   CFix& CFix::operator/=(const CFix &x)
00141   {
00142     shift -= x.shift;
00143     fixrep denominator = x.re*x.re + x.im*x.im;
00144     fixrep tmp_re = apply_o_mode((re*x.re + im*x.im)/denominator);
00145     im = apply_o_mode((im*x.re - re*x.im)/denominator);
00146     re = tmp_re;
00147     return *this;
00148   }
00149 
00150   CFix& CFix::operator/=(const Fix &x)
00151   {
00152     shift -= x.shift;
00153     re = apply_o_mode(re/x.re);
00154     im = apply_o_mode(im/x.re);
00155     return *this;
00156   }
00157 
00158   CFix& CFix::operator/=(const int x)
00159   {
00160     re = apply_o_mode(re/x);
00161     im = apply_o_mode(im/x);
00162     return *this;
00163   }
00164 
00165   CFix CFix::operator-() const
00166   {
00167     return CFix(-re, -im, shift, 0, 0);
00168   }
00169 
00170   CFix& CFix::operator<<=(const int n)
00171   {
00172     it_assert1(n >= 0, "CFix::operator<<=: n cannot be negative!");
00173     shift += n;
00174     re = apply_o_mode(re << n);
00175     im = apply_o_mode(im << n);
00176     return *this;
00177   }
00178 
00179   CFix& CFix::operator>>=(const int n)
00180   {
00181     shift -= n;
00182     re = rshift_and_apply_q_mode(re, n);
00183     im = rshift_and_apply_q_mode(im, n);
00184     return *this;
00185   }
00186 
00187   void CFix::set(double real, double imag, int n)
00188   {
00189     shift = n;
00190     re = scale_and_apply_modes(real);
00191     im = scale_and_apply_modes(imag);
00192   }
00193 
00194   void CFix::set(double real, double imag, int n, q_mode q)
00195   {
00196     shift = n;
00197     re = scale_and_apply_modes(real, q);
00198     im = scale_and_apply_modes(imag, q);
00199   }
00200 
00201   void CFix::set(const std::complex<double> &x, int n)
00202   {
00203     shift = n;
00204     re = scale_and_apply_modes(std::real(x));
00205     im = scale_and_apply_modes(std::imag(x));
00206   }
00207 
00208   void CFix::set(const std::complex<double> &x, int n, q_mode q)
00209   {
00210     shift = n;
00211     re = scale_and_apply_modes(std::real(x), q);
00212     im = scale_and_apply_modes(std::imag(x), q);
00213   }
00214 
00215   void CFix::lshift(int n)
00216   {
00217     it_assert1(n >= 0, "CFix::lshift: n cannot be negative!");
00218     shift += n;
00219     re = apply_o_mode(re << n);
00220     im = apply_o_mode(im << n);
00221   }
00222 
00223   void CFix::rshift(int n)
00224   {
00225     shift -= n;
00226     re = rshift_and_apply_q_mode(re, n);
00227     im = rshift_and_apply_q_mode(im, n);
00228   }
00229 
00230   void CFix::rshift(int n, q_mode q)
00231   {
00232     shift -= n;
00233     re = rshift_and_apply_q_mode(re, n, q);
00234     im = rshift_and_apply_q_mode(im, n, q);
00235   }
00236 
00237   std::complex<double> CFix::unfix() const
00238   {
00239     it_assert1(shift>=-63 && shift<=64, "CFix::unfix: Illegal shift!");
00240     return std::complex<double>(double(re)*DOUBLE_POW2[64 - shift],
00241                            double(im)*DOUBLE_POW2[64 - shift]);
00242   }
00243 
00244   void CFix::print() const
00245   {
00246     Fix_Base::print();
00247     std::cout << "re = " << re << std::endl;
00248     std::cout << "im = " << im << std::endl;
00249   }
00250 
00251   int assert_shifts(const CFix &x, const CFix &y)
00252   {
00253     int ret = 0;
00254 
00255     if (x.shift == y.shift)
00256       ret = x.shift;
00257     else if (x.re == 0 && x.im == 0)
00258       ret = y.shift;
00259     else if (y.re == 0 && y.im == 0)
00260       ret = x.shift;
00261     else
00262       it_error("assert_shifts: Different shifts not allowed!");
00263 
00264     return ret;
00265   }
00266 
00267   int assert_shifts(const CFix &x, const Fix &y)
00268   {
00269     int ret = 0;
00270 
00271     if (x.shift == y.shift)
00272       ret = x.shift;
00273     else if (x.re == 0 && x.im == 0)
00274       ret = y.shift;
00275     else if (y.re == 0)
00276       ret = x.shift;
00277     else
00278       it_error("assert_shifts: Different shifts not allowed!");
00279 
00280     return ret;
00281   }
00282 
00283   int assert_shifts(const CFix &x, int y)
00284   {
00285     if ((x.shift != 0) && !(x.re==0 && x.im==0) && (y != 0))
00286       it_error("assert_shifts: Different shifts not allowed!");
00287     return x.shift;
00288   }
00289 
00290   std::istream &operator>>(std::istream &is, CFix &x)
00291   {
00292     std::complex<double> value;
00293     is >> value;
00294     if (!is.eof() && (is.peek() == '<')) {
00295       int shift;
00296       is.get();  // Swallow '<' sign
00297       if (is.peek() == '<') {
00298         is.get();  // Swallow '<' sign
00299         is >> shift;
00300         x.set(value, shift);
00301       } else {
00302         is >> shift;
00303         is.get();  // Swallow '>' sign
00304         x.set_re(fixrep(std::real(value)));
00305         x.set_im(fixrep(std::imag(value)));
00306         x.set_shift(shift);
00307       }
00308     } else {
00309       // Change data representation but keep shift
00310       x.set_re(fixrep(std::real(value)));
00311       x.set_im(fixrep(std::imag(value)));
00312     }
00313     return is;
00314   }
00315 
00316   std::ostream &operator<<(std::ostream &os, const CFix &x)
00317   {
00318     switch (x.get_output_mode()) {
00319     case OUTPUT_FIX:
00320       if (x.get_im() < 0)
00321         os << x.get_re() << x.get_im() << 'i';
00322       else
00323         os << x.get_re() << '+' << x.get_im() << 'i';
00324       break;
00325     case OUTPUT_FIX_SHIFT:
00326       if (x.get_im() < 0)
00327         os << x.get_re() << x.get_im() << 'i';
00328       else
00329         os << x.get_re() << '+' << x.get_im() << 'i';
00330       os << '<' << x.get_shift() << '>';
00331       break;
00332     case OUTPUT_FLOAT:
00333       os << std::complex<double>(x);
00334       break;
00335     case OUTPUT_FLOAT_SHIFT:
00336       os << std::complex<double>(x) << "<<" << x.get_shift();
00337       break;
00338     default:
00339       it_error("operator<<: Illegal output mode!");
00340     }
00341     return os;
00342   }
00343 
00344   // Specialization of template definition in vec.cpp
00345   template<>
00346   bool cfixvec::set(const char *values)
00347   {
00348     std::istringstream buffer(values);
00349     int default_shift=0, pos=0, maxpos=10;
00350     if (datasize > 0) {
00351       // Assume that all elements have the same shift
00352       default_shift = data[0].get_shift();
00353     }
00354     alloc(maxpos);
00355     while (buffer.peek()!=EOF) {
00356       switch (buffer.peek()) {
00357       case ':':
00358         it_error("set: expressions with ':' are not valid for cfixvec");
00359         break;
00360       case ',':
00361         buffer.get();
00362         break;
00363       default:
00364         pos++;
00365         if (pos > maxpos) {
00366           maxpos *= 2;
00367           set_size(maxpos, true);
00368         }
00369         data[pos-1].set_shift(default_shift);
00370         buffer >> data[pos-1];  // May override default_shift
00371         while (buffer.peek()==' ') { buffer.get(); }
00372         break;
00373       }
00374     }
00375     set_size(pos, true);
00376     return true;
00377   }
00378 
00379   // Specialization of template definition in mat.cpp
00380   template<>
00381   bool cfixmat::set(const char *values)
00382   {
00383     std::istringstream buffer(values);
00384     int default_shift=0, rows=0, maxrows=10, cols=0, nocols=0, maxcols=10;
00385     if (datasize > 0) {
00386       // Assume that all elements have the same shift
00387       default_shift = data[0].get_shift();
00388     }
00389     alloc(maxrows, maxcols);
00390     while (buffer.peek()!=EOF) {
00391       rows++;
00392       if (rows > maxrows) {
00393         maxrows=maxrows*2;
00394         set_size(maxrows, maxcols, true);
00395       }
00396       cols=0;
00397       while ( (buffer.peek() != ';') && (buffer.peek() != EOF) ) {
00398         if (buffer.peek()==',') {
00399           buffer.get();
00400         } else {
00401           cols++;
00402           if (cols > nocols) {
00403             nocols=cols;
00404             if (cols > maxcols) {
00405               maxcols=maxcols*2;
00406               set_size(maxrows, maxcols, true);
00407             }
00408           }
00409           this->operator()(rows-1,cols-1).set_shift(default_shift);
00410           buffer >> this->operator()(rows-1,cols-1);  // May override default_shift
00411           while (buffer.peek()==' ') { buffer.get(); }
00412         }
00413       }
00414       if (!buffer.eof())
00415         buffer.get();
00416     }
00417     set_size(rows, nocols, true);
00418     return true;
00419   }
00420 
00421 } // namespace itpp
SourceForge Logo

Generated on Fri Jun 8 00:37:34 2007 for IT++ by Doxygen 1.5.2