OpenWareLaboratory
ComplexShortArray.cpp
Go to the documentation of this file.
1 #include "ComplexShortArray.h"
2 #include "basicmaths.h"
3 #include "message.h"
4 #include "qint.h"
5 
7 #ifdef ARM_CORTEX
8  int16_t out;
9  int16_t in[2] = {re, im};
10  arm_cmplx_mag_q15(in, &out, 1);
11  // function above returns 2.14, so we shift it back to 1.15
12  // but first we check we do not lose data.
13  // TODO: make sure it saturates
14  out = out >> 1;
15  return out;
16 #else
17  float fre = Q15_TO_FLOAT(re);
18  float fim = Q15_TO_FLOAT(im);
19  return FLOAT_TO_Q15(sqrtf(fre*fre+fim*fim) + 0.5);
20 #endif
21 }
22 
24  return FLOAT_TO_Q15(atan2(Q15_TO_FLOAT(im), Q15_TO_FLOAT(re)));
25 }
26 
27 void ComplexShort::setPolar(int16_t magnitude, int16_t phase){
28  float fm = Q15_TO_FLOAT(magnitude);
29  float fp = Q15_TO_FLOAT(phase);
30  re = FLOAT_TO_Q15(fm*cosf(fp) + 0.5);
31  im = FLOAT_TO_Q15(fm*sinf(fp) + 0.5);
32 }
33 
34 int16_t ComplexShortArray::mag(const int i){
35  int16_t result;
37 #ifdef ARM_CORTEX
38  arm_cmplx_mag_q15((int16_t*)&(data[i]), &result,1);
39 #else
40  result = FLOAT_TO_Q15(sqrtf(Q15_TO_FLOAT(mag2(i))));
41 #endif
42  return result;
43 }
44 
47 #ifdef ARM_CORTEX
48  arm_cmplx_mag_q15((int16_t*)data, (int16_t*)destination, size);
49  // function above returns 2.14, so we shift it back to 1.15
50  destination.shift(1);
51 #else
52  for(size_t i=0; i<size; i++){
53  destination[i]=mag(i);
54  }
55 #endif
56 }
57 
58 int16_t ComplexShortArray::mag2(const int i){
59  int16_t result;
61 #ifdef ARM_CORTEX
62  arm_cmplx_mag_squared_q15((int16_t*)&(data[i]), &result, 1);
63  // function above returns 3.13, so we shift it back to 1.15
64  // this is saturating
65  arm_shift_q15((int16_t*)&result, 2, (int16_t*)&result, 1);
66 #else
67  float re=Q15_TO_FLOAT(data[i].re);
68  float im=Q15_TO_FLOAT(data[i].im);
69  result=FLOAT_TO_Q15(re*re+im*im);
70 #endif
71  return result;
72 }
73 
76 #ifdef ARM_CORTEX
77  arm_cmplx_mag_squared_q15((int16_t*)data, (int16_t*)destination, size);
78  // function above returns 3.13, so we shift it back to 1.15
79  // this is saturating
80  arm_shift_q15((int16_t*)destination, 2, (int16_t*)destination,
81  destination.getSize());
82 #else
83  for(size_t i=0; i<size; i++){
84  destination[i]=mag2(i);
85  }
86 #endif
87 }
88 
89 #if 0
92 #ifdef ARM_CORTEX
93  arm_cmplx_dot_prod_q15 ( (int16_t*)data, (int16_t*)operand2, size, &(result.re), &(result.im) );
94 #else
95  int16_t *pSrcA=(int16_t*)data;
96  int16_t *pSrcB=(int16_t*)operand2;
97  int16_t realResult=0;
98  int16_t imagResult=0;
99  for(size_t n=0; n<size; n++) {
100  realResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+0] - pSrcA[(2*n)+1]*pSrcB[(2*n)+1];
101  imagResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+1] + pSrcA[(2*n)+1]*pSrcB[(2*n)+0];
102  }
103  result.re=realResult;
104  result.im=imagResult;
105 #endif
106 }
107 #endif /* 0 */
108 
110  //ASSERT(operand2.size == size && result.getSize() >= size, "Arrays size mismatch");
112 #ifdef ARM_CORTEX
113  arm_cmplx_mult_cmplx_q15((int16_t*)getData(), (int16_t*)operand2.getData(), (int16_t*)result.getData(), size );
114 #else
115  int16_t* pSrcA = (int16_t*)data;
116  int16_t* pSrcB = (int16_t*)operand2.getData();
117  int16_t* pDst = (int16_t*)result.getData();
118  for(size_t n=0; n<size; n++) {
119  pDst[(2*n)+0] = Q15_MUL_Q15(pSrcA[(2*n)+0], pSrcB[(2*n)+0]) -
120  Q15_MUL_Q15(pSrcA[(2*n)+1], pSrcB[(2*n)+1]);
121  pDst[(2*n)+1] = Q15_MUL_Q15(pSrcA[(2*n)+0], pSrcB[(2*n)+1]) +
122  Q15_MUL_Q15(pSrcA[(2*n)+1], pSrcB[(2*n)+0]);
123  }
124 #endif
125 }
126 
127 void ComplexShortArray::setAll(int16_t value){
129 #ifdef ARM_CORTEX
130  arm_fill_q15(value, (int16_t*)data, size *2 ); //note the *2 multiplier which accounts for real and imaginary parts
131 #else
132  ComplexShort val;
133  val.re=value;
134  val.im=value;
135  setAll(val);
136 #endif /* ARM_CORTEX */
137 }
138 
140  for(size_t n=0; n<size; n++){
141  data[n].re=value.re;
142  data[n].im=value.im;
143  }
144 }
145 
146 void ComplexShortArray::setAll(int16_t valueRe, int16_t valueIm){
147  ComplexShort value = {valueRe, valueIm};
148  setAll(value);
149 }
150 
152  //ASSERT(operand2.size == size && destination.size >= size, "Arrays size mismatch");
153 #ifdef ARM_CORTEX
154  arm_add_q15((int16_t*)data, (int16_t*)operand2.data, (int16_t*)destination.data, size*2);
155 #else
156  for(size_t n=0; n<size; n++){
157  destination[n].re = data[n].re + operand2[n].re;
158  destination[n].im = data[n].im + operand2[n].im;
159  }
160 #endif /* ARM_CORTEX */
161 }
162 
165  obj.clear();
166  return obj;
167 }
168 
170  delete[] array.data;
171 }
int16_t mag(const int i)
The magnitude of an element of the array.
int16_t im(const int i)
The imaginary part of an element of the array.
void add(ComplexShortArray operand2, ComplexShortArray destination)
Element-wise sum between complex arrays.
void complexByComplexMultiplication(ComplexShortArray operand2, ComplexShortArray result)
Complex by complex multiplication between arrays.
static ComplexShortArray create(unsigned int size)
Creates a new ComplexShortArray.
void complexDotProduct(ComplexShortArray operand2, ComplexShort &result)
Complex dot product between arrays.
void getMagnitudeSquaredValues(ShortArray destination)
The squared magnitudes of the elements of the array.
int16_t mag2(const int i)
The magnitude squared of an element of the array.
static void destroy(ComplexShortArray)
Destroys a ComplexShortArray created with the create() method.
void getMagnitudeValues(ShortArray destination)
The magnitudes of the elements of the array.
int16_t re(const int i)
The real part of an element of the array.
void setAll(ComplexShort value)
Set all the elements in the array.
This class contains useful methods for manipulating arrays of int16_ts.
Definition: ShortArray.h:12
void shift(int shiftValue)
Bitshift the array values, saturating.
Definition: ShortArray.cpp:532
size_t getSize() const
Definition: SimpleArray.h:31
ComplexShort * getData()
Get the data stored in the Array.
Definition: SimpleArray.h:27
#define Q15_MUL_Q15(a, b)
Definition: qint.h:17
#define FLOAT_TO_Q15(a)
Definition: qint.h:20
#define Q15_TO_FLOAT(a)
Definition: qint.h:52
A structure defining a fixed point complex number as two members of type int16_t.
void setPolar(int16_t magnitude, int16_t phase)
Set magnitude and phase of the complex number.
int16_t re
The real part of the complex number.
int16_t getMagnitude()
Get the magnitude of the complex number.
int16_t getPhase()
Get the phase of the complex number.
int16_t im
The imaginary part of the complex number.