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
Generated on Sun Jul 26 08:36:49 2009 for IT++ by Doxygen 1.5.9