int convolve_real(const float x[], const float y[], float out[], size_t n) { float *ximag, *yimag, *zimag; int status = 0; ximag = calloc(n, sizeof(float)); yimag = calloc(n, sizeof(float)); zimag = calloc(n, sizeof(float)); if (ximag == NULL || yimag == NULL || zimag == NULL) goto cleanup; status = convolve_complex(x, ximag, y, yimag, out, zimag, n); cleanup: free(zimag); free(yimag); free(ximag); return status; }
int convolve_real(const double x[], const double y[], double out[], size_t n) { double *ximag, *yimag, *zimag; int status = 0; ximag = calloc(n, sizeof(double)); yimag = calloc(n, sizeof(double)); zimag = calloc(n, sizeof(double)); if (ximag == NULL || yimag == NULL || zimag == NULL) goto cleanup; status = convolve_complex(x, ximag, y, yimag, out, zimag, n); cleanup: free(zimag); free(yimag); free(ximag); return status; }
int transform_bluestein(float real[], float imag[], size_t n) { // Variables int status = 0; //float *cos_table, *sin_table; float *areal, *aimag; float *breal, *bimag; float *creal, *cimag; size_t m; size_t size_n, size_m; size_t i; // Find a power-of-2 convolution length m such that m >= n * 2 + 1 { size_t target; if (n > (N_MAX - 1) / 2) return 0; target = n * 2 + 1; for (m = 1; m < target; m *= 2) { if (N_MAX / 2 < m) return 0; } } // Allocate memory if (N_MAX / sizeof(float) < n || N_MAX / sizeof(float) < m) return 0; size_n = n * sizeof(float); size_m = m * sizeof(float); //cos_table = malloc(size_n); //sin_table = malloc(size_n); areal = calloc(m, sizeof(float)); aimag = calloc(m, sizeof(float)); breal = calloc(m, sizeof(float)); bimag = calloc(m, sizeof(float)); creal = malloc(size_m); cimag = malloc(size_m); if (areal == NULL || aimag == NULL || breal == NULL || bimag == NULL || creal == NULL || cimag == NULL) goto cleanup; // Trignometric tables /*for (i = 0; i < n; i++) { //float temp = M_PI * (size_t)((unsigned long long)i * i % ((unsigned long long)n * 2)) / n; // Less accurate version if long long is unavailable: float temp = M_PI * i * i / n; cos_table[i] = cos(temp); sin_table[i] = sin(temp); }*/ // Temporary vectors and preprocessing for (i = 0; i < n; i++) { areal[i] = sum_acc(mul_acc(real[i], cos_mod(i,n)), mul_acc(imag[i], sin_mod(i,n))); aimag[i] = sum_acc(mul_acc(-real[i], sin_mod(i,n)), mul_acc(imag[i], cos_mod(i,n))); } breal[0] = cos_mod(0,n); bimag[0] = sin_mod(0,n); for (i = 1; i < n; i++) { breal[i] = breal[m - i] = cos_mod(i,n); bimag[i] = bimag[m - i] = sin_mod(i,n); } // Convolution if (!convolve_complex(areal, aimag, breal, bimag, creal, cimag, m)) goto cleanup; // Postprocessing for (i = 0; i < n; i++) { real[i] = sum_acc(mul_acc(creal[i], cos_mod(i,n)), mul_acc(cimag[i], sin_mod(i,n))); imag[i] = sum_acc(mul_acc(-creal[i], sin_mod(i,n)), mul_acc(cimag[i], cos_mod(i,n))); } status = 1; // Deallocation cleanup: free(cimag); free(creal); free(bimag); free(breal); free(aimag); free(areal); //free(sin_table); //free(cos_table); return status; }
int transform_bluestein(double real[], double imag[], size_t n) { // Variables int status = 0; double *cos_table, *sin_table; double *areal, *aimag; double *breal, *bimag; double *creal, *cimag; size_t m; size_t size_n, size_m; size_t i; // Find a power-of-2 convolution length m such that m >= n * 2 + 1 { size_t target; if (n > (SIZE_MAX - 1) / 2) return 0; target = n * 2 + 1; for (m = 1; m < target; m *= 2) { if (SIZE_MAX / 2 < m) return 0; } } // Allocate memory if (SIZE_MAX / sizeof(double) < n || SIZE_MAX / sizeof(double) < m) return 0; size_n = n * sizeof(double); size_m = m * sizeof(double); cos_table = malloc(size_n); sin_table = malloc(size_n); areal = calloc(m, sizeof(double)); aimag = calloc(m, sizeof(double)); breal = calloc(m, sizeof(double)); bimag = calloc(m, sizeof(double)); creal = malloc(size_m); cimag = malloc(size_m); if (cos_table == NULL || sin_table == NULL || areal == NULL || aimag == NULL || breal == NULL || bimag == NULL || creal == NULL || cimag == NULL) goto cleanup; // Trignometric tables for (i = 0; i < n; i++) { double temp = M_PI * (size_t)((unsigned long long)i * i % ((unsigned long long)n * 2)) / n; // Less accurate version if long long is unavailable: double temp = M_PI * i * i / n; cos_table[i] = cos(temp); sin_table[i] = sin(temp); } // Temporary vectors and preprocessing for (i = 0; i < n; i++) { areal[i] = real[i] * cos_table[i] + imag[i] * sin_table[i]; aimag[i] = -real[i] * sin_table[i] + imag[i] * cos_table[i]; } breal[0] = cos_table[0]; bimag[0] = sin_table[0]; for (i = 1; i < n; i++) { breal[i] = breal[m - i] = cos_table[i]; bimag[i] = bimag[m - i] = sin_table[i]; } // Convolution if (!convolve_complex(areal, aimag, breal, bimag, creal, cimag, m)) goto cleanup; // Postprocessing for (i = 0; i < n; i++) { real[i] = creal[i] * cos_table[i] + cimag[i] * sin_table[i]; imag[i] = -creal[i] * sin_table[i] + cimag[i] * cos_table[i]; } status = 1; // Deallocation cleanup: free(cimag); free(creal); free(bimag); free(breal); free(aimag); free(areal); free(sin_table); free(cos_table); return status; }