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

Generated on Wed Jan 20 23:03:05 2010 for IT++ by Doxygen 1.6.2