IT++ Logo

cfix.cpp

Go to the documentation of this file.
00001 
00030 #include <itpp/fixed/cfix.h>
00031 #include <itpp/base/itassert.h>
00032 #include <iostream>
00033 #include <cstdio>
00034 
00035 namespace itpp
00036 {
00037 
00038 CFix& CFix::operator=(const CFix &x)
00039 {
00040   shift = x.shift;
00041   re = apply_o_mode(x.re);
00042   im = apply_o_mode(x.im);
00043   return *this;
00044 }
00045 
00046 CFix& CFix::operator=(const Fix &x)
00047 {
00048   shift = x.shift;
00049   re = apply_o_mode(x.re);
00050   im = 0;
00051   return *this;
00052 }
00053 
00054 CFix& CFix::operator=(const std::complex<double> &x)
00055 {
00056   shift = 0;
00057   re = apply_o_mode(fixrep(std::real(x)));
00058   im = apply_o_mode(fixrep(std::imag(x)));
00059   return *this;
00060 }
00061 
00062 CFix& CFix::operator=(const int x)
00063 {
00064   shift = 0;
00065   re = apply_o_mode(x);
00066   im = 0;
00067   return *this;
00068 }
00069 
00070 CFix& CFix::operator+=(const CFix &x)
00071 {
00072   shift = assert_shifts(*this, x);
00073   re = apply_o_mode(re + x.re);
00074   im = apply_o_mode(im + x.im);
00075   return *this;
00076 }
00077 
00078 CFix& CFix::operator+=(const Fix &x)
00079 {
00080   shift = assert_shifts(*this, x);
00081   re = apply_o_mode(re + x.re);
00082   return *this;
00083 }
00084 
00085 CFix& CFix::operator+=(const int x)
00086 {
00087   assert_shifts(*this, x);
00088   re = apply_o_mode(re + x);
00089   return *this;
00090 }
00091 
00092 CFix& CFix::operator-=(const CFix &x)
00093 {
00094   shift = assert_shifts(*this, x);
00095   re = apply_o_mode(re - x.re);
00096   im = apply_o_mode(im - x.im);
00097   return *this;
00098 }
00099 
00100 CFix& CFix::operator-=(const Fix &x)
00101 {
00102   shift = assert_shifts(*this, x);
00103   re = apply_o_mode(re - x.re);
00104   return *this;
00105 }
00106 
00107 CFix& CFix::operator-=(const int x)
00108 {
00109   assert_shifts(*this, x);
00110   re = apply_o_mode(re - x);
00111   return *this;
00112 }
00113 
00114 CFix& CFix::operator*=(const CFix &x)
00115 {
00116   shift += x.shift;
00117   fixrep tmp_re = apply_o_mode(re * x.re - im * x.im);
00118   im = apply_o_mode(re * x.im + im * x.re);
00119   re = tmp_re;
00120   return *this;
00121 }
00122 
00123 CFix& CFix::operator*=(const Fix &x)
00124 {
00125   shift += x.shift;
00126   re = apply_o_mode(re * x.re);
00127   im = apply_o_mode(im * x.re);
00128   return *this;
00129 }
00130 
00131 CFix& CFix::operator*=(const int x)
00132 {
00133   re = apply_o_mode(re * x);
00134   im = apply_o_mode(im * x);
00135   return *this;
00136 }
00137 
00138 CFix& CFix::operator/=(const CFix &x)
00139 {
00140   shift -= x.shift;
00141   fixrep denominator = x.re * x.re + x.im * x.im;
00142   fixrep tmp_re = apply_o_mode((re * x.re + im * x.im) / denominator);
00143   im = apply_o_mode((im * x.re - re * x.im) / denominator);
00144   re = tmp_re;
00145   return *this;
00146 }
00147 
00148 CFix& CFix::operator/=(const Fix &x)
00149 {
00150   shift -= x.shift;
00151   re = apply_o_mode(re / x.re);
00152   im = apply_o_mode(im / x.re);
00153   return *this;
00154 }
00155 
00156 CFix& CFix::operator/=(const int x)
00157 {
00158   re = apply_o_mode(re / x);
00159   im = apply_o_mode(im / x);
00160   return *this;
00161 }
00162 
00163 CFix CFix::operator-() const
00164 {
00165   return CFix(-re, -im, shift, 0, 0);
00166 }
00167 
00168 CFix& CFix::operator<<=(const int n)
00169 {
00170   it_assert_debug(n >= 0, "CFix::operator<<=: n cannot be negative!");
00171   shift += n;
00172   re = apply_o_mode(re << n);
00173   im = apply_o_mode(im << n);
00174   return *this;
00175 }
00176 
00177 CFix& CFix::operator>>=(const int n)
00178 {
00179   shift -= n;
00180   re = rshift_and_apply_q_mode(re, n);
00181   im = rshift_and_apply_q_mode(im, n);
00182   return *this;
00183 }
00184 
00185 void CFix::set(double real, double imag, int n)
00186 {
00187   shift = n;
00188   re = scale_and_apply_modes(real);
00189   im = scale_and_apply_modes(imag);
00190 }
00191 
00192 void CFix::set(double real, double imag, int n, q_mode q)
00193 {
00194   shift = n;
00195   re = scale_and_apply_modes(real, q);
00196   im = scale_and_apply_modes(imag, q);
00197 }
00198 
00199 void CFix::set(const std::complex<double> &x, int n)
00200 {
00201   shift = n;
00202   re = scale_and_apply_modes(std::real(x));
00203   im = scale_and_apply_modes(std::imag(x));
00204 }
00205 
00206 void CFix::set(const std::complex<double> &x, int n, q_mode q)
00207 {
00208   shift = n;
00209   re = scale_and_apply_modes(std::real(x), q);
00210   im = scale_and_apply_modes(std::imag(x), q);
00211 }
00212 
00213 void CFix::lshift(int n)
00214 {
00215   it_assert_debug(n >= 0, "CFix::lshift: n cannot be negative!");
00216   shift += n;
00217   re = apply_o_mode(re << n);
00218   im = apply_o_mode(im << n);
00219 }
00220 
00221 void CFix::rshift(int n)
00222 {
00223   shift -= n;
00224   re = rshift_and_apply_q_mode(re, n);
00225   im = rshift_and_apply_q_mode(im, n);
00226 }
00227 
00228 void CFix::rshift(int n, q_mode q)
00229 {
00230   shift -= n;
00231   re = rshift_and_apply_q_mode(re, n, q);
00232   im = rshift_and_apply_q_mode(im, n, q);
00233 }
00234 
00235 std::complex<double> CFix::unfix() const
00236 {
00237   it_assert_debug(shift >= -63 && shift <= 64, "CFix::unfix: Illegal shift!");
00238   return std::complex<double>(double(re)*DOUBLE_POW2[64 - shift],
00239                               double(im)*DOUBLE_POW2[64 - shift]);
00240 }
00241 
00242 void CFix::print() const
00243 {
00244   Fix_Base::print();
00245   std::cout << "re = " << re << std::endl;
00246   std::cout << "im = " << im << std::endl;
00247 }
00248 
00249 int assert_shifts(const CFix &x, const CFix &y)
00250 {
00251   int ret = 0;
00252 
00253   if (x.shift == y.shift)
00254     ret = x.shift;
00255   else if (x.re == 0 && x.im == 0)
00256     ret = y.shift;
00257   else if (y.re == 0 && y.im == 0)
00258     ret = x.shift;
00259   else
00260     it_error("assert_shifts: Different shifts not allowed!");
00261 
00262   return ret;
00263 }
00264 
00265 int assert_shifts(const CFix &x, const Fix &y)
00266 {
00267   int ret = 0;
00268 
00269   if (x.shift == y.shift)
00270     ret = x.shift;
00271   else if (x.re == 0 && x.im == 0)
00272     ret = y.shift;
00273   else if (y.re == 0)
00274     ret = x.shift;
00275   else
00276     it_error("assert_shifts: Different shifts not allowed!");
00277 
00278   return ret;
00279 }
00280 
00281 int assert_shifts(const CFix &x, int y)
00282 {
00283   it_error_if((x.shift != 0) && !(x.re == 0 && x.im == 0)
00284               && (y != 0), "assert_shifts: Different shifts not allowed!");
00285   return x.shift;
00286 }
00287 
00288 std::istream &operator>>(std::istream &is, CFix &x)
00289 {
00290   std::complex<double> value;
00291   is >> value;
00292   if (!is.eof() && (is.peek() == '<')) {
00293     int shift;
00294     is.get();  // Swallow '<' sign
00295     if (is.peek() == '<') {
00296       is.get();  // Swallow '<' sign
00297       is >> shift;
00298       x.set(value, shift);
00299     }
00300     else {
00301       is >> shift;
00302       is.get();  // Swallow '>' sign
00303       x.set_re(fixrep(std::real(value)));
00304       x.set_im(fixrep(std::imag(value)));
00305       x.set_shift(shift);
00306     }
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 void 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 }
00377 
00378 // Specialization of template definition in mat.cpp
00379 template<>
00380 void cfixmat::set(const char *values)
00381 {
00382   std::istringstream buffer(values);
00383   int default_shift = 0, rows = 0, maxrows = 10, cols = 0, nocols = 0, maxcols = 10;
00384   if (datasize > 0) {
00385     // Assume that all elements have the same shift
00386     default_shift = data[0].get_shift();
00387   }
00388   alloc(maxrows, maxcols);
00389   while (buffer.peek() != EOF) {
00390     rows++;
00391     if (rows > maxrows) {
00392       maxrows = maxrows * 2;
00393       set_size(maxrows, maxcols, true);
00394     }
00395     cols = 0;
00396     while ((buffer.peek() != ';') && (buffer.peek() != EOF)) {
00397       if (buffer.peek() == ',') {
00398         buffer.get();
00399       }
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 }
00419 
00420 } // namespace itpp
SourceForge Logo

Generated on Thu Apr 23 20:07:46 2009 for IT++ by Doxygen 1.5.8