OpenWareLaboratory
ComplexFloatArray.cpp
Go to the documentation of this file.
1 #include "ComplexFloatArray.h"
2 #include "basicmaths.h"
3 #include "message.h"
4 
5 float ComplexFloatArray::mag(const int i){
6  float result;
8 #ifdef ARM_CORTEX
9  arm_cmplx_mag_f32((float*)&(data[i]), &result,1);
10 #else
11  result=sqrtf(mag2(i));
12 #endif
13  return result;
14 }
15 
18 #ifdef ARM_CORTEX
19  arm_cmplx_mag_f32((float*)data, (float*)destination, size);
20 #else
21  for(size_t i=0; i<size; i++){
22  destination[i]=mag(i);
23  }
24 #endif
25 }
26 
27 float ComplexFloatArray::mag2(const int i){
28  float result;
30 #ifdef ARM_CORTEX
31  arm_cmplx_mag_squared_f32((float*)&(data[i]), &result, 1);
32 #else
33  float re=data[i].re;
34  float im=data[i].im;
35  result=re*re+im*im;
36 #endif
37  return result;
38 }
39 
41  ASSERT(destination.getSize()>=size, "Wrong array size");
43 #ifdef ARM_CORTEX
44  arm_cmplx_mag_squared_f32((float*)data, (float*)destination, size);
45 #else
46  for(size_t i=0; i<size; i++){
47  destination[i]=mag2(i);
48  }
49 #endif
50 }
51 
53  ASSERT(magnitude.getSize()>=size, "Wrong array size");
54  ASSERT(phase.getSize()>=size, "Wrong array size");
55  for(size_t i=0; i<size; i++){
56  magnitude[i] = data[i].getMagnitude();
57  phase[i] = data[i].getPhase();
58  }
59 }
60 
62  ASSERT(destination.getSize()>=size, "Wrong array size");
63  for(size_t i=0; i<size; i++)
64  destination[i] = data[i].getPhase();
65 }
66 
69 #ifdef ARM_CORTEX
70  arm_cmplx_dot_prod_f32 ( (float*)getData(), (float*)operand2.getData(), size, &(result.re), &(result.im) );
71 #else
72  float *pSrcA=(float*)getData();
73  float *pSrcB=(float*)operand2.getData();
74  float realResult=0;
75  float imagResult=0;
76  for(size_t n=0; n<size; n++) {
77  realResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+0] - pSrcA[(2*n)+1]*pSrcB[(2*n)+1];
78  imagResult += pSrcA[(2*n)+0]*pSrcB[(2*n)+1] + pSrcA[(2*n)+1]*pSrcB[(2*n)+0];
79  }
80  result.re=realResult;
81  result.im=imagResult;
82 #endif
83 }
84 
86  ASSERT(operand2.size == size && result.size >= size, "Arrays size mismatch");
88 #ifdef ARM_CORTEX
89  arm_cmplx_mult_cmplx_f32( (float*)getData(), (float*)operand2.getData(), (float*)result.getData(), size );
90 #else
91  float *pSrcA=(float*)getData();
92  float *pSrcB=(float*)operand2.getData();
93  float *pDst=(float*)result.getData();
94  for(size_t n=0; n<size; n++) {
95  pDst[(2*n)+0] = pSrcA[(2*n)+0] * pSrcB[(2*n)+0] - pSrcA[(2*n)+1] * pSrcB[(2*n)+1];
96  pDst[(2*n)+1] = pSrcA[(2*n)+0] * pSrcB[(2*n)+1] + pSrcA[(2*n)+1] * pSrcB[(2*n)+0];
97  }
98 #endif
99 }
100 
102  ASSERT(operand2.size == size && destination.size >= size, "Arrays size mismatch");
103 #ifdef ARM_CORTEX
104  arm_add_f32((float*)getData(), (float*)operand2.getData(), (float*)destination.getData(), size*2);
105 #else
106  for(size_t n=0; n<size; n++){
107  destination[n].re = data[n].re + operand2[n].re;
108  destination[n].im = data[n].im + operand2[n].im;
109  }
110 #endif /* ARM_CORTEX */
111 }
112 
114  add(operand2, *this);
115 }
116 
118  ASSERT(operand2.size == size && destination.size >= size, "Arrays size mismatch");
119 #ifdef ARM_CORTEX
120  arm_sub_f32((float*)data, (float*)operand2.data, (float*)destination.getData(), size*2);
121 #else
122  for(size_t n=0; n<size; n++){
123  destination[n].re = data[n].re - operand2[n].re;
124  destination[n].im = data[n].im - operand2[n].im;
125  }
126 #endif /* ARM_CORTEX */
127 }
128 
130  subtract(operand2, *this);
131 }
132 
134  ASSERT(size==destination.getSize(), "Wrong array size");
136 #ifdef ARM_CORTEX
137  arm_cmplx_conj_f32( (float*)getData(), (float*)destination.getData(), size );
138 #else
139  float *pSrc=(float*)getData();
140  float *pDst=(float *)destination.getData();
141  for(size_t n=0; n<size; n++) {
142  pDst[(2*n)+0] = pSrc[(2*n)+0]; // real part
143  pDst[(2*n)+1] = -pSrc[(2*n)+1]; // imag part
144 }
145 #endif
146 }
147 
149  ASSERT(size==operand2.getSize(), "Wrong size");
151 #ifdef ARM_CORTEX
152  arm_cmplx_mult_real_f32 ( (float*)getData(), (float*)operand2.getData(), (float*)result.getData(), size );
153 #else
154  float *pSrcCmplx=(float*)getData();
155  float *pSrcReal=(float*)operand2.getData();
156  float *pCmplxDst=(float*)result.getData();
157  for(size_t n=0; n<size; n++) {
158  pCmplxDst[(2*n)+0] = pSrcCmplx[(2*n)+0] * pSrcReal[n];
159  pCmplxDst[(2*n)+1] = pSrcCmplx[(2*n)+1] * pSrcReal[n];
160  }
161 #endif
162 }
163 
164 int ComplexFloatArray::getMaxMagnitudeIndex(){ //this is probably slower than getMagnitudeSquaredValues() and getMaxIndex() on it
165  float maxMag=-1;
166  int maxInd=-1;
167  for(size_t n=0; n<size; n++){
168  float magnitude=mag2(n); //uses mag2 which is faster
169  if(magnitude>maxMag){
170  maxMag=magnitude;
171  maxInd=n;
172  }
173  }
174  return maxInd;
175 }
176 
178  ASSERT(size >= offset+length, "Array too small");
179  return ComplexFloatArray(data+offset, length);
180 }
181 
182 float ComplexFloatArray::getMaxMagnitudeValue(){ //this is probably slower than getMagnitudeSquaredValues() and getMaxValue() on it
183  float maxMag=-1;
184  for(size_t n=0; n<size; n++){
185  float mag=this->mag2(n);
186  if(mag>maxMag){
187  maxMag=mag;
188  }
189  }
190  maxMag=sqrtf(maxMag);
191  return maxMag;
192 }
193 
195  for(size_t n=0; n<size; n++){
196  buf[n]=data[n].re;
197  }
198 }
199 
201  for(size_t n=0; n<size; n++){
202  buf[n]=data[n].im;
203  }
204 }
205 
206 void ComplexFloatArray::scale(float factor){
208 #ifdef ARM_CORTEX
209  arm_scale_f32((float*)data, factor, (float*)data, size*2); //the *2 accounts for the fact that both real and imaginary parts are scaled
210 #else
211  for(size_t n=0; n<size; n++){
212  data[n].re *= factor;
213  data[n].im *= factor;
214  }
215 #endif
216 }
217 
219  ASSERT(source.getSize() >= size, "Array too small");
220  for(size_t n=0; n<size; n++){
221  data[n].re = source[n];
222  data[n].im = 0;
223  }
224 }
225 
226 /* Copies real part to a FloatArray */
228  ASSERT(destination.getSize() >= size, "Array too small");
229  for(size_t n=0; n<size; n++){
230  destination[n] = data[n].re;
231  }
232 }
233 
234 
235 void ComplexFloatArray::setAll(float value){
237 #ifdef ARM_CORTEX
238  arm_fill_f32(value, (float *)data, size *2 ); //note the *2 multiplier which accounts for real and imaginary parts
239 #else
240  ComplexFloat val;
241  val.re=value;
242  val.im=value;
243  setAll(val);
244 #endif /* ARM_CORTEX */
245 }
246 
248  for(size_t n=0; n<size; n++){
249  data[n].re=value.re;
250  data[n].im=value.im;
251  }
252 }
253 
254 void ComplexFloatArray::setAll(float valueRe, float valueIm){
255  ComplexFloat value;
256  value.re=valueRe;
257  value.im=valueIm;
258  setAll(value);
259 }
260 
262  setPolar(magnitude, phase, 0, size);
263 }
264 void ComplexFloatArray::setPolar(FloatArray magnitude, FloatArray phase, int offset, size_t count){
265  for(size_t n=offset; n<count+offset; n++){
266  data[n].setPolar(magnitude[n], phase[n]);
267  }
268 }
269 
271  setPhase(phase, 0, size);
272 }
273 void ComplexFloatArray::setPhase(FloatArray phase, int offset, size_t count){
274  for(size_t n=offset; n<count+offset; n++){
275  data[n].setPhase(phase[n]);
276  }
277 }
279  setPhase(phase, 0, size, destination);
280 }
281 void ComplexFloatArray::setPhase(FloatArray phase, int offset, size_t count, ComplexFloatArray destination){
282  ASSERT(destination.getSize()>=count+offset, "Wrong size");
283  for(size_t n=offset; n<count+offset; n++){
284  destination.getData()[n].setPolar(getData()[n].getMagnitude(), phase[n]);
285  }
286 }
288  setMagnitude(magnitude, 0, size);
289 }
290 void ComplexFloatArray::setMagnitude(FloatArray magnitude, int offset, size_t count){
291  setMagnitude(magnitude, offset, count, *this);
292 }
294  setMagnitude(magnitude, 0, size, destination);
295 }
296 void ComplexFloatArray::setMagnitude(FloatArray magnitude, int offset, size_t count, ComplexFloatArray destination){
297  ASSERT(getSize()==magnitude.getSize(),"wrong size0");
298  ASSERT(getSize()==destination.getSize(),"wrong size1");
299  ASSERT(offset+count<=destination.getSize(), "Wrong size2");
300  ASSERT(offset+count<=getSize(), "Wrong size3");
301  for(size_t n=offset; n<count+offset; n++){
302  destination.getData()[n].setPolar(magnitude[n], getData()[n].getPhase());
303  }
304 }
305 
308  obj.clear();
309  return obj;
310 }
311 
313  delete[] array.data;
314 }
315 
317  for (size_t i = 0; i < getSize(); i++) {
318  data[i] = ComplexFloat(real[i], imag[i]);
319  }
320 }
321 
323  for (size_t i = 0; i < getSize(); i++) {
324  real[i] = data[i].re;
325  imag[i] = data[i].im;
326  }
327 }
void getPhaseValues(FloatArray destination)
The phases of the elements of the array.
float im(const int i)
Get the imaginary part of an element of the array.
void getImaginaryValues(FloatArray buf)
Get the imaginary part of the elements of the array.
void getComplexConjugateValues(ComplexFloatArray destination)
The complex conjugate values of the element of the array.
void setPolar(FloatArray magnitude, FloatArray phase)
Set all the elements in the array using polar coordinates.
void setPhase(FloatArray phase)
Set the phase of the elements of the array, leaving the magnitude unchanged.
void getMagnitudeSquaredValues(FloatArray destination)
The squared magnitudes of the elements of the array.
void getRealValues(FloatArray buf)
Get the real part of the elements of the array.
void add(ComplexFloatArray operand2, ComplexFloatArray destination)
Element-wise sum between complex arrays.
static void destroy(ComplexFloatArray)
Destroys a ComplexFloatArray created with the create() method.
void setMagnitude(FloatArray magnitude)
Set the magnitude of the elements of the array, leaving the phase unchanged.
void complexDotProduct(ComplexFloatArray operand2, ComplexFloat &result)
Complex dot product between arrays.
ComplexFloatArray subArray(int offset, size_t length)
A subset of the array.
void copyTo(FloatArray real, FloatArray imag)
Split complex data into two channels of audio containing real and imaginary axis data.
void complexByComplexMultiplication(ComplexFloatArray operand2, ComplexFloatArray result)
Complex by complex multiplication between arrays.
void getPolar(FloatArray magnitude, FloatArray phase)
Get polar coordinates for all the elements in the array.
void getMagnitudeValues(FloatArray destination)
The magnitudes of the elements of the array.
void setAll(ComplexFloat value)
Set all the elements in the array.
float mag2(const int i)
The magnitude squared of an element of the array.
void scale(float factor)
Array by scalar multiplication.
static ComplexFloatArray create(size_t size)
Creates a new ComplexFloatArray.
int getMaxMagnitudeIndex()
The index of the element with the maximum magnitude in the array.
void copyFrom(FloatArray real, FloatArray imag)
Merge two channels of audio containing real and imaginary axis data into this array.
float re(const int i)
Get the real part of an element of the array.
float getMaxMagnitudeValue()
The value of the element with the maximum magnitude in the array.
void subtract(ComplexFloatArray operand2, ComplexFloatArray destination)
Element-wise difference between complex arrays.
float mag(const int i)
Get the magnitude of an element of the array.
void toFloat(FloatArray destination)
Copies real and imaginary values of the ComplexFloatArray into a FloatArray.
void complexByRealMultiplication(FloatArray operand2, ComplexFloatArray result)
Complex by real multiplication between arrays.
void fromFloat(FloatArray source)
Copies real values from a FloatArray, sets imaginary values to 0.
This class contains useful methods for manipulating arrays of floats.
Definition: FloatArray.h:12
size_t getSize() const
Definition: SimpleArray.h:31
ComplexFloat * getData()
Get the data stored in the Array.
Definition: SimpleArray.h:27
#define ASSERT(cond, msg)
Definition: message.h:16
A structure defining a floating point complex number as two members of type float.
float im
The imaginary part of the complex number.
float re
The real part of the complex number.
float getMagnitude() const
Get the magnitude of the complex number.
float getPhase() const
Get the phase of the complex number.
void setPhase(float phase)
Set the phase of the complex number.
void setPolar(float magnitude, float phase)
Set magnitude and phase of the complex number.