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;
190 }
191 
192 void CFix::set(double real, double imag, int n, q_mode q)
193 {
194  shift = n;
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
#define it_error_if(t, s)
Abort if t is true.
Definition: itassert.h:117
output_mode get_output_mode() const
Get output mode.
Definition: fix_base.h:1011
void alloc(int rows, int cols)
Allocate memory for the matrix.
Definition: mat.h:548
void set_size(int rows, int cols, bool copy=false)
Set size of matrix. If copy = true then keep the data before resizing.
Definition: mat.h:647
Num_T * data
Protected data pointer.
Definition: mat.h:457
CFix operator-() const
Unary negative of CFix.
Definition: cfix.cpp:163
CFix & operator*=(const CFix &x)
Multiplication with CFix. Temporary variables use the maximum word length (64 bits) ...
Definition: cfix.cpp:114
int datasize
Definition: mat.h:454
fixrep scale_and_apply_modes(double x) const
Convert from double to fixrep using shift and quantization mode qmode, then call limit() ...
Definition: fix_base.h:1044
void rshift(int n)
Right shift n bits using quantization mode qmode (constructor argument)
Definition: cfix.cpp:221
const Num_T & operator()(int r, int c) const
Get element (r,c) from matrix.
Definition: mat.h:712
vec imag(const cvec &data)
Imaginary part of complex values.
Definition: elem_math.cpp:180
CFix & operator-=(const CFix &x)
Subtraction of CFix.
Definition: cfix.cpp:92
CFix & operator/=(const CFix &x)
Division with CFix using quantization mode TRN. Temporary variables use the maximum word length (64 b...
Definition: cfix.cpp:138
void set(const char *str)
Set the vector equal to the values in the str string.
Definition: vec.h:814
friend ITPP_EXPORT int assert_shifts(const CFix &x, const CFix &y)
Check that x.shift==y.shift OR x==0 OR y==0 and return the shift (for the non-zero argument) ...
Definition: cfix.cpp:249
CFix & operator+=(const CFix &x)
Addition of CFix.
Definition: cfix.cpp:70
Output floating-point value.
Definition: fix_base.h:972
std::ostream & operator<<(std::ostream &output, const bin &inbin)
Output stream of bin.
Definition: binary.cpp:36
Num_T * data
A pointer to the data area.
Definition: vec.h:505
CFix & operator>>=(const int n)
Right shift n bits using quantization mode qmode (constructor argument)
Definition: cfix.cpp:177
void set_shift(int s)
Set shift (without shifting)
Definition: fix_base.h:994
fixrep apply_o_mode(fixrep x) const
Handle overflows using overflow mode omode and make call to statistics object (if any) ...
Definition: fix_base.cpp:88
fixrep re
Real data part.
Definition: cfix.h:161
void set(const std::string &str)
Set matrix equal to values in the string str.
Definition: mat.h:762
fixrep rshift_and_apply_q_mode(fixrep x, int n) const
Right shift n bits using quantization mode qmode and make call to statistics object (if any) ...
Definition: fix_base.h:1048
fixrep re
Data representation.
Definition: fix.h:137
void set_size(int size, bool copy=false)
Set length of vector. if copy = true then keeping the old values.
Definition: vec.h:663
int datasize
The current number of elements in the vector.
Definition: vec.h:503
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition: itassert.h:107
std::complex< double > unfix() const
Conversion to std::complex<double>
Definition: cfix.cpp:235
int cols() const
The number of columns.
Definition: mat.h:235
const double DOUBLE_POW2[128]
Table for fast multiplication by 2^(n-64)
Definition: fix_base.h:906
CFix & operator<<=(const int n)
Left shift n bits.
Definition: cfix.cpp:168
Complex fixed-point data type.
Definition: cfix.h:51
virtual void print() const
Print restrictions.
Definition: cfix.cpp:242
Output fixed-point representation only.
Definition: fix_base.h:970
void set_im(fixrep x)
Set data representation for imaginary part (mainly for internal use since it reveals the representati...
Definition: cfix.h:126
itpp namespace
Definition: itmex.h:36
void lshift(int n)
Left shift n bits.
Definition: cfix.cpp:213
int shift
Accumulated bitshift (positive means left-shifted, negative means right-shifted)
Definition: fix_base.h:1021
Error handling functions - header file.
void set(double real, double imag, int n)
Set to (real + i*imag) * pow2(n) using quantization mode qmode (constructor argument) ...
Definition: cfix.cpp:185
CFix & operator=(const CFix &x)
Assignment from CFix.
Definition: cfix.cpp:38
void set_re(fixrep x)
Set data representation for real part (mainly for internal use since it reveals the representation ty...
Definition: cfix.h:124
fixrep im
Imaginary data part.
Definition: cfix.h:162
Output floating-point value followed by <<shift.
Definition: fix_base.h:973
Fixed-point data type.
Definition: fix.h:51
fixrep get_im() const
Get data representation for imaginary part (mainly for internal use since it reveals the representati...
Definition: cfix.h:140
int assert_shifts(const CFix &x, const CFix &y)
Check that x.shift==y.shift OR x==0 OR y==0 and return the shift (for the non-zero argument) ...
Definition: cfix.cpp:249
#define it_error(s)
Abort unconditionally.
Definition: itassert.h:126
int rows() const
The number of rows.
Definition: mat.h:237
void alloc(int size)
Allocate storage for a vector of length size.
Definition: vec.h:593
fixrep get_re() const
Get data representation for real part (mainly for internal use since it reveals the representation ty...
Definition: cfix.h:138
CFix(double r=0.0, double i=0.0, int s=0, int w=MAX_WORDLEN, e_mode e=TC, o_mode o=WRAP, q_mode q=TRN, Stat *ptr=0)
Default constructor.
Definition: cfix.h:56
int64_t fixrep
Representation for fixed-point data types.
Definition: fix_base.h:884
Output fixed-point representation followed by <shift> (default)
Definition: fix_base.h:971
std::istream & operator>>(std::istream &input, bin &outbin)
Input stream of bin.
Definition: binary.cpp:42
vec real(const cvec &data)
Real part of complex values.
Definition: elem_math.cpp:157
q_mode
Quantization modes (aligned with SystemC)
Definition: fix_base.h:957
int get_shift() const
Get shift.
Definition: fix_base.h:1001
virtual void print() const
Print restrictions.
Definition: fix_base.cpp:54
Definitions of a complex fixed-point data type CFix.
SourceForge Logo

Generated on Sun Apr 10 2022 12:00:00 for IT++ by Doxygen 1.8.14