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
Generated on Thu Apr 24 13:39:00 2008 for IT++ by Doxygen 1.5.5