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

Generated on Sat Apr 19 10:57:52 2008 for IT++ by Doxygen 1.5.5