IT++ Logo
cfix.cpp
Go to the documentation of this file.
1 
29 #include <itpp/fixed/cfix.h>
30 #include <itpp/base/itassert.h>
31 #include <cstdio>
32 #include <iostream>
33 
34 
35 namespace itpp
36 {
37 
39 {
40  shift = x.shift;
41  re = apply_o_mode(x.re);
42  im = apply_o_mode(x.im);
43  return *this;
44 }
45 
47 {
48  shift = x.shift;
49  re = apply_o_mode(x.re);
50  im = 0;
51  return *this;
52 }
53 
54 CFix& CFix::operator=(const std::complex<double> &x)
55 {
56  shift = 0;
59  return *this;
60 }
61 
62 CFix& CFix::operator=(const int x)
63 {
64  shift = 0;
65  re = apply_o_mode(x);
66  im = 0;
67  return *this;
68 }
69 
71 {
72  shift = assert_shifts(*this, x);
73  re = apply_o_mode(re + x.re);
74  im = apply_o_mode(im + x.im);
75  return *this;
76 }
77 
79 {
80  shift = assert_shifts(*this, x);
81  re = apply_o_mode(re + x.re);
82  return *this;
83 }
84 
85 CFix& CFix::operator+=(const int x)
86 {
87  assert_shifts(*this, x);
88  re = apply_o_mode(re + x);
89  return *this;
90 }
91 
93 {
94  shift = assert_shifts(*this, x);
95  re = apply_o_mode(re - x.re);
96  im = apply_o_mode(im - x.im);
97  return *this;
98 }
99 
101 {
102  shift = assert_shifts(*this, x);
103  re = apply_o_mode(re - x.re);
104  return *this;
105 }
106 
107 CFix& CFix::operator-=(const int x)
108 {
109  assert_shifts(*this, x);
110  re = apply_o_mode(re - x);
111  return *this;
112 }
113 
115 {
116  shift += x.shift;
117  fixrep tmp_re = apply_o_mode(re * x.re - im * x.im);
118  im = apply_o_mode(re * x.im + im * x.re);
119  re = tmp_re;
120  return *this;
121 }
122 
124 {
125  shift += x.shift;
126  re = apply_o_mode(re * x.re);
127  im = apply_o_mode(im * x.re);
128  return *this;
129 }
130 
131 CFix& CFix::operator*=(const int x)
132 {
133  re = apply_o_mode(re * x);
134  im = apply_o_mode(im * x);
135  return *this;
136 }
137 
139 {
140  shift -= x.shift;
141  fixrep denominator = x.re * x.re + x.im * x.im;
142  fixrep tmp_re = apply_o_mode((re * x.re + im * x.im) / denominator);
143  im = apply_o_mode((im * x.re - re * x.im) / denominator);
144  re = tmp_re;
145  return *this;
146 }
147 
149 {
150  shift -= x.shift;
151  re = apply_o_mode(re / x.re);
152  im = apply_o_mode(im / x.re);
153  return *this;
154 }
155 
156 CFix& CFix::operator/=(const int x)
157 {
158  re = apply_o_mode(re / x);
159  im = apply_o_mode(im / x);
160  return *this;
161 }
162 
164 {
165  return CFix(-re, -im, shift, 0, 0);
166 }
167 
168 CFix& CFix::operator<<=(const int n)
169 {
170  it_assert_debug(n >= 0, "CFix::operator<<=: n cannot be negative!");
171  shift += n;
172  re = apply_o_mode(re << n);
173  im = apply_o_mode(im << n);
174  return *this;
175 }
176 
177 CFix& CFix::operator>>=(const int n)
178 {
179  shift -= n;
182  return *this;
183 }
184 
185 void CFix::set(double real, double imag, int n)
186 {
187  shift = n;
188  re = scale_and_apply_modes(real);
189  im = scale_and_apply_modes(imag);
190 }
191 
192 void CFix::set(double real, double imag, int n, q_mode q)
193 {
194  shift = n;
195  re = scale_and_apply_modes(real, q);
196  im = scale_and_apply_modes(imag, q);
197 }
198 
199 void CFix::set(const std::complex<double> &x, int n)
200 {
201  shift = n;
204 }
205 
206 void CFix::set(const std::complex<double> &x, int n, q_mode q)
207 {
208  shift = n;
211 }
212 
213 void CFix::lshift(int n)
214 {
215  it_assert_debug(n >= 0, "CFix::lshift: n cannot be negative!");
216  shift += n;
217  re = apply_o_mode(re << n);
218  im = apply_o_mode(im << n);
219 }
220 
221 void CFix::rshift(int n)
222 {
223  shift -= n;
226 }
227 
228 void CFix::rshift(int n, q_mode q)
229 {
230  shift -= n;
231  re = rshift_and_apply_q_mode(re, n, q);
232  im = rshift_and_apply_q_mode(im, n, q);
233 }
234 
235 std::complex<double> CFix::unfix() const
236 {
237  it_assert_debug(shift >= -63 && shift <= 64, "CFix::unfix: Illegal shift!");
238  return std::complex<double>(double(re)*DOUBLE_POW2[64 - shift],
239  double(im)*DOUBLE_POW2[64 - shift]);
240 }
241 
242 void CFix::print() const
243 {
244  Fix_Base::print();
245  std::cout << "re = " << re << std::endl;
246  std::cout << "im = " << im << std::endl;
247 }
248 
249 int assert_shifts(const CFix &x, const CFix &y)
250 {
251  int ret = 0;
252 
253  if (x.shift == y.shift)
254  ret = x.shift;
255  else if (x.re == 0 && x.im == 0)
256  ret = y.shift;
257  else if (y.re == 0 && y.im == 0)
258  ret = x.shift;
259  else
260  it_error("assert_shifts: Different shifts not allowed!");
261 
262  return ret;
263 }
264 
265 int assert_shifts(const CFix &x, const Fix &y)
266 {
267  int ret = 0;
268 
269  if (x.shift == y.shift)
270  ret = x.shift;
271  else if (x.re == 0 && x.im == 0)
272  ret = y.shift;
273  else if (y.re == 0)
274  ret = x.shift;
275  else
276  it_error("assert_shifts: Different shifts not allowed!");
277 
278  return ret;
279 }
280 
281 int assert_shifts(const CFix &x, int y)
282 {
283  it_error_if((x.shift != 0) && !(x.re == 0 && x.im == 0)
284  && (y != 0), "assert_shifts: Different shifts not allowed!");
285  return x.shift;
286 }
287 
288 std::istream &operator>>(std::istream &is, CFix &x)
289 {
290  std::complex<double> value;
291  is >> value;
292  if (!is.eof() && (is.peek() == '<')) {
293  int shift;
294  is.get(); // Swallow '<' sign
295  if (is.peek() == '<') {
296  is.get(); // Swallow '<' sign
297  is >> shift;
298  x.set(value, shift);
299  }
300  else {
301  is >> shift;
302  is.get(); // Swallow '>' sign
303  x.set_re(fixrep(std::real(value)));
304  x.set_im(fixrep(std::imag(value)));
305  x.set_shift(shift);
306  }
307  }
308  else {
309  // Change data representation but keep shift
310  x.set_re(fixrep(std::real(value)));
311  x.set_im(fixrep(std::imag(value)));
312  }
313  return is;
314 }
315 
316 std::ostream &operator<<(std::ostream &os, const CFix &x)
317 {
318  switch (x.get_output_mode()) {
319  case OUTPUT_FIX:
320  if (x.get_im() < 0)
321  os << x.get_re() << x.get_im() << 'i';
322  else
323  os << x.get_re() << '+' << x.get_im() << 'i';
324  break;
325  case OUTPUT_FIX_SHIFT:
326  if (x.get_im() < 0)
327  os << x.get_re() << x.get_im() << 'i';
328  else
329  os << x.get_re() << '+' << x.get_im() << 'i';
330  os << '<' << x.get_shift() << '>';
331  break;
332  case OUTPUT_FLOAT:
333  os << std::complex<double>(x);
334  break;
335  case OUTPUT_FLOAT_SHIFT:
336  os << std::complex<double>(x) << "<<" << x.get_shift();
337  break;
338  default:
339  it_error("operator<<: Illegal output mode!");
340  }
341  return os;
342 }
343 
344 // Specialization of template definition in vec.cpp
345 template<>
346 void cfixvec::set(const char *values)
347 {
348  std::istringstream buffer(values);
349  int default_shift = 0, pos = 0, maxpos = 10;
350  if (datasize > 0) {
351  // Assume that all elements have the same shift
352  default_shift = data[0].get_shift();
353  }
354  alloc(maxpos);
355  while (buffer.peek() != EOF) {
356  switch (buffer.peek()) {
357  case ':':
358  it_error("set: expressions with ':' are not valid for cfixvec");
359  break;
360  case ',':
361  buffer.get();
362  break;
363  default:
364  pos++;
365  if (pos > maxpos) {
366  maxpos *= 2;
367  set_size(maxpos, true);
368  }
369  data[pos-1].set_shift(default_shift);
370  buffer >> data[pos-1]; // May override default_shift
371  while (buffer.peek() == ' ') { buffer.get(); }
372  break;
373  }
374  }
375  set_size(pos, true);
376 }
377 
378 // Specialization of template definition in mat.cpp
379 template<>
380 void cfixmat::set(const char *values)
381 {
382  std::istringstream buffer(values);
383  int default_shift = 0, rows = 0, maxrows = 10, cols = 0, nocols = 0, maxcols = 10;
384  if (datasize > 0) {
385  // Assume that all elements have the same shift
386  default_shift = data[0].get_shift();
387  }
388  alloc(maxrows, maxcols);
389  while (buffer.peek() != EOF) {
390  rows++;
391  if (rows > maxrows) {
392  maxrows = maxrows * 2;
393  set_size(maxrows, maxcols, true);
394  }
395  cols = 0;
396  while ((buffer.peek() != ';') && (buffer.peek() != EOF)) {
397  if (buffer.peek() == ',') {
398  buffer.get();
399  }
400  else {
401  cols++;
402  if (cols > nocols) {
403  nocols = cols;
404  if (cols > maxcols) {
405  maxcols = maxcols * 2;
406  set_size(maxrows, maxcols, true);
407  }
408  }
409  this->operator()(rows-1, cols - 1).set_shift(default_shift);
410  buffer >> this->operator()(rows-1, cols - 1); // May override default_shift
411  while (buffer.peek() == ' ') { buffer.get(); }
412  }
413  }
414  if (!buffer.eof())
415  buffer.get();
416  }
417  set_size(rows, nocols, true);
418 }
419 
420 } // namespace itpp
SourceForge Logo

Generated on Sat May 25 2013 16:32:22 for IT++ by Doxygen 1.8.2