예제 #1
0
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;
}
예제 #2
0
파일: fft.c 프로젝트: chlik/fft
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;
}
예제 #3
0
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;
}
예제 #4
0
파일: fft.c 프로젝트: chlik/fft
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;
}