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
35namespace 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
54CFix& CFix::operator=(const std::complex<double> &x)
55{
56 shift = 0;
57 re = apply_o_mode(fixrep(std::real(x)));
58 im = apply_o_mode(fixrep(std::imag(x)));
59 return *this;
60}
61
62CFix& 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
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
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
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
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
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
178{
179 shift -= n;
182 return *this;
183}
184
185void CFix::set(double real, double imag, int n)
186{
187 shift = n;
190}
191
192void CFix::set(double real, double imag, int n, q_mode q)
193{
194 shift = n;
197}
198
199void CFix::set(const std::complex<double> &x, int n)
200{
201 shift = n;
202 re = scale_and_apply_modes(std::real(x));
203 im = scale_and_apply_modes(std::imag(x));
204}
205
206void CFix::set(const std::complex<double> &x, int n, q_mode q)
207{
208 shift = n;
209 re = scale_and_apply_modes(std::real(x), q);
210 im = scale_and_apply_modes(std::imag(x), q);
211}
212
213void 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
221void CFix::rshift(int n)
222{
223 shift -= n;
226}
227
228void CFix::rshift(int n, q_mode q)
229{
230 shift -= n;
233}
234
235std::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
242void CFix::print() const
243{
245 std::cout << "re = " << re << std::endl;
246 std::cout << "im = " << im << std::endl;
247}
248
249int 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
265int 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
281int 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
288std::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
316std::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;
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
345template<>
346void 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
379template<>
380void 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
Definitions of a complex fixed-point data type CFix.
Complex fixed-point data type.
Definition cfix.h:52
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
CFix operator-() const
Unary negative of CFix.
Definition cfix.cpp:163
fixrep get_im() const
Get data representation for imaginary part (mainly for internal use since it reveals the representati...
Definition cfix.h:140
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
virtual void print() const
Print restrictions.
Definition cfix.cpp:242
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)
Multiplication with CFix. Temporary variables use the maximum word length (64 bits)
Definition cfix.cpp:114
void lshift(int n)
Left shift n bits.
Definition cfix.cpp:213
CFix & operator<<=(const int n)
Left shift n bits.
Definition cfix.cpp:168
CFix & operator-=(const CFix &x)
Subtraction of CFix.
Definition cfix.cpp:92
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 & operator+=(const CFix &x)
Addition of CFix.
Definition cfix.cpp:70
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
void set_im(fixrep x)
Set data representation for imaginary part (mainly for internal use since it reveals the representati...
Definition cfix.h:126
void rshift(int n)
Right shift n bits using quantization mode qmode (constructor argument)
Definition cfix.cpp:221
std::complex< double > unfix() const
Conversion to std::complex<double>
Definition cfix.cpp:235
CFix & operator>>=(const int n)
Right shift n bits using quantization mode qmode (constructor argument)
Definition cfix.cpp:177
CFix & operator=(const CFix &x)
Assignment from CFix.
Definition cfix.cpp:38
fixrep im
Imaginary data part.
Definition cfix.h:162
fixrep re
Real data part.
Definition cfix.h:161
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
virtual void print() const
Print restrictions.
Definition fix_base.cpp:54
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 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
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
output_mode get_output_mode() const
Get output mode.
Definition fix_base.h:1011
void set_shift(int s)
Set shift (without shifting)
Definition fix_base.h:994
int get_shift() const
Get shift.
Definition fix_base.h:1001
int shift
Accumulated bitshift (positive means left-shifted, negative means right-shifted)
Definition fix_base.h:1021
Fixed-point data type.
Definition fix.h:52
fixrep re
Data representation.
Definition fix.h:137
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
void set(const std::string &str)
Set matrix equal to values in the string str.
Definition mat.h:762
int rows() const
The number of rows.
Definition mat.h:237
Num_T * data
Protected data pointer.
Definition mat.h:457
int cols() const
The number of columns.
Definition mat.h:235
const Num_T & operator()(int r, int c) const
Get element (r,c) from matrix.
Definition mat.h:712
int datasize
Definition mat.h:454
void alloc(int rows, int cols)
Allocate memory for the matrix.
Definition mat.h:548
int datasize
The current number of elements in the vector.
Definition vec.h:503
Num_T * data
A pointer to the data area.
Definition vec.h:505
void set_size(int size, bool copy=false)
Set length of vector. if copy = true then keeping the old values.
Definition vec.h:663
void alloc(int size)
Allocate storage for a vector of length size.
Definition vec.h:593
#define it_error_if(t, s)
Abort if t is true.
Definition itassert.h:117
#define it_error(s)
Abort unconditionally.
Definition itassert.h:126
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition itassert.h:107
const double DOUBLE_POW2[128]
Table for fast multiplication by 2^(n-64)
Definition fix_base.h:906
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
void set(const char *str)
Set the vector equal to the values in the str string.
Definition vec.h:814
q_mode
Quantization modes (aligned with SystemC)
Definition fix_base.h:957
int64_t fixrep
Representation for fixed-point data types.
Definition fix_base.h:884
@ OUTPUT_FIX
Output fixed-point representation only.
Definition fix_base.h:970
@ OUTPUT_FLOAT
Output floating-point value.
Definition fix_base.h:972
@ OUTPUT_FIX_SHIFT
Output fixed-point representation followed by <shift> (default)
Definition fix_base.h:971
@ OUTPUT_FLOAT_SHIFT
Output floating-point value followed by <<shift.
Definition fix_base.h:973
vec imag(const cvec &data)
Imaginary part of complex values.
vec real(const cvec &data)
Real part of complex values.
Error handling functions - header file.
itpp namespace
Definition itmex.h:37
std::ostream & operator<<(std::ostream &output, const bin &inbin)
Output stream of bin.
Definition binary.cpp:36
std::istream & operator>>(std::istream &input, bin &outbin)
Input stream of bin.
Definition binary.cpp:42
SourceForge Logo

Generated on Tue Dec 10 2024 04:49:37 for IT++ by Doxygen 1.12.0