Vector Optimized Library of Kernels 3.2.0
Architecture-tuned implementations of math kernels
Loading...
Searching...
No Matches
volk_32fc_x2_divide_32fc

Overview

Divide first vector of complexes element-wise by second.

Dispatcher Prototype

void volk_32fc_x2_divide_32fc(lv_32fc_t* cVector, const lv_32fc_t* numeratorVector,
const lv_32fc_t* denumeratorVector, unsigned int num_points);
float complex lv_32fc_t
Definition volk_complex.h:74

Inputs

  • numeratorVector: The numerator complex values.
  • numeratorVector: The denumerator complex values.
  • num_points: The number of data points.

Outputs

  • outputVector: The output vector complex floats.

Example divide a complex vector by itself, demonstrating the result should be pretty close to 1+0j.

int N = 10;
unsigned int alignment = volk_get_alignment();
lv_32fc_t* input_vector = (lv_32fc_t*)volk_malloc(sizeof(lv_32fc_t)*N, alignment);
lv_32fc_t* out = (lv_32fc_t*)volk_malloc(sizeof(lv_32fc_t)*N, alignment);
float delta = 2.f*M_PI / (float)N;
for(unsigned int ii = 0; ii < N; ++ii){
float real_1 = std::cos(0.3f * (float)ii);
float imag_1 = std::sin(0.3f * (float)ii);
input_vector[ii] = lv_cmake(real_1, imag_1);
}
volk_32fc_x2_divide_32fc(out, input_vector, input_vector, N);
for(unsigned int ii = 0; ii < N; ++ii){
printf("%1.4f%+1.4fj,", lv_creal(out[ii]), lv_cimag(out[ii]));
}
printf("\n");
volk_free(input_vector);
volk_free(out);
size_t volk_get_alignment(void)
Get the machine alignment in bytes.
Definition volk.tmpl.c:90
#define lv_cimag(x)
Definition volk_complex.h:98
#define lv_cmake(r, i)
Definition volk_complex.h:77
#define lv_creal(x)
Definition volk_complex.h:96
__VOLK_DECL_BEGIN VOLK_API void * volk_malloc(size_t size, size_t alignment)
Allocate size bytes of data aligned to alignment.
Definition volk_malloc.c:38
VOLK_API void volk_free(void *aptr)
Free's memory allocated by volk_malloc.
Definition volk_malloc.c:70

Numerical accuracy

The division of complex numbers (a + bj)/(c + dj) is calculated as (a*c + b*d)/(c*c + d*d) + (b*c - a*d)/(c*c + d*d) j.

Since Volk is built using unsafe math optimizations (-fcx-limited-range -funsafe-math-optimizations with gcc), after computing the two numerators and the denominator in the above formula, the compiler can either:

a) compute the two divisions; b) compute the inverse of the denominator, 1.0/(c*c + d*d), and then multiply this number by each of the numerators.

Under gcc, b) is allowed by -freciprocal-math, which is included in -funsafe-math-optimizations.

Depending on the architecture and the estimated cost of multiply and divide instructions, the compiler can perform a) or b). gcc performs a) under x86_64 and armv7, and b) under aarch64.

To avoid obtaining inf or nan in some architectures, care should be taken that c*c + d*d is not too small. In particular, if c*c + d*d < FLT_MAX, then the calculation of 1.0/(c*c + d*d) will yield inf.

For more information about numerical accuracy of complex division, see the following: