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
Generated on Thu Apr 19 14:43:44 2007 for IT++ by Doxygen 1.5.1