I'm trying to use the FFTW for my large project, so I wrote a basic program to check if the FFT is working or not. I am trying to send sine values to the FFT and back. After using the FFT forwards and FFT backwards I get exactly the same results, but I get a NaN value at the first element of the array. I read in some of the questions here that the issue is the data type, I need to use long double and fftwl to maintain accuracy of the results.
Where is the problem? Is it in the data type and how can I solve it?
#include <fftw3.h>
#include <math.h>
#include <stdio.h>
#include <complex.h>
#include <stdlib.h>
#include <inttypes.h>
#include <assert.h>
int Ypt=128;
long double PI=3.14159265358979323846;
void complex2FFT( complex long double *U)
{
long double normalizing_factor= 2.0/Ypt;
fftwl_plan plan_f;
fftwl_complex *in;
fftwl_complex *out;
in = (fftwl_complex *) fftwl_malloc(sizeof(fftwl_complex) * Ypt);
out = (fftwl_complex *) fftwl_malloc(sizeof(fftwl_complex) * Ypt);
for (int i = 0; i < Ypt; ++i){
in[i ][0]= creal(U[i]);
in[i ][1]= cimag(U[i]);
}
plan_f = fftwl_plan_dft_1d(Ypt, in, out, FFTW_FORWARD , FFTW_ESTIMATE);
fftwl_execute(plan_f);
for (int i = 0; i < Ypt; ++i){
U[i] = normalizing_factor*out[i][0] + normalizing_factor*out[i][1]*I;
}
fftwl_destroy_plan(plan_f);
fftwl_free(in);
fftwl_free(out);
fftwl_cleanup();
}
void FFT2complex( complex long double *U)
{
long double normalizing_factor= 1.0;
fftwl_plan plan_b;
fftwl_complex *in;
fftwl_complex *out;
in = (fftwl_complex *) fftwl_malloc(sizeof(fftwl_complex) * Ypt);
out = (fftwl_complex *) fftwl_malloc(sizeof(fftwl_complex) * Ypt);
for (int i = 0; i < Ypt; ++i){
out[i ][0]= creal(U[i]);
out[i ][1]= cimag(U[i]);
}
plan_b = fftwl_plan_dft_1d(Ypt, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
for (int i = 0; i < Ypt; ++i){
U[i] = normalizing_factor*in[i ][0] + normalizing_factor*in[i ][1]*I;
}
fftwl_execute(plan_b);
fftwl_destroy_plan(plan_b);
fftwl_free(in);
fftwl_free(out);
fftwl_cleanup();
}
int main(int argc, char **argv){
long double dy=( (long double)1) / ( (long double)Ypt);
complex long double *U = malloc(Ypt * sizeof(*U));
complex long double *V = malloc(Ypt * sizeof(*V));
for (int i = 0; i < Ypt; ++i){
U[i] = sin( (double) (2.0*PI* (double)i * dy)) ;
V[i] = sin( (double) (2.0*PI* (double)i * dy)) ;
}
char name[45];
FILE *stream;
sprintf(name, "V%d.txt", 0);
stream= fopen(name,"w");
for (int i = 0; i < Ypt; ++i){
fprintf(stream, "%Lf %2.5f %2.5f \n", (long double)i*dy,creal(U[i]),cimag(U[i]));
}
complex2FFT(U);
FFT2complex(U);
for (int i = 0; i < Ypt; ++i){
fprintf(stream, "%Lf %2.5f %2.5f \n", (long double)i*dy,creal(U[i]),cimag(U[i]) );
}
free(U);
free(V);
}
As noticed by #Dietrich Epp , fftwl_execute(plan_b) runs after the output is copied, therefore the output is left unchanged. In addition, FFTW_BACKWARD performs the backward DFT, but it does not mean that the argument in is used as output. Even with flag FFTW_BACKWARD, the input argument of fftw_plan_dft_1d() is in and the output is out.
See for instance that example of forward then backward transform : FFTW forward and back ward yield in different results why?
for (int i = 0; i < Ypt; ++i){
out[i ][0]= creal(U[i]);
out[i ][1]= cimag(U[i]);
}
plan_b = fftwl_plan_dft_1d(Ypt, out, in, FFTW_BACKWARD, FFTW_ESTIMATE);
fftwl_execute(plan_b);
for (int i = 0; i < Ypt; ++i){
U[i] = normalizing_factor*in[i ][0] + normalizing_factor*in[i ][1]*I;
}
Related
I am doing a convolution of two integer signals with the help of FFT, but somehow I can't get it right. I am not sure if my implementation of FFT is correct. Especially the math part.
big edit:
I posted all the code now. My apologies for not starting with it. I was sure the error was only in FFT part, but there might be more problems I overlooked. I know the code is messy and not clean. Everything is a bit fragmented and can be programmed in a simpler and cleaner way, but I was testing bit by bit. As for input it reads two signals from the command line. build up as a number indicating how big the signal is and the signal presented as an integer array e.q 2: [1,-1] and 10: [0,0,0,1,1,1,1,0,0,0]. It should then do a convolution on the signals by performing a FFT on both of them then do bit wise multiplication. With a inverse FFT on the resulting signal. Printing it again with the length and then the array consiting of integers. The printing itself is correct, but the values in the resulting array is not correct. I hope it is all a bit clearer now again my apologies and thank you for your help so far.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
double PI;
int *readSignal(int *len) { //reads the signal
int *x;
char c;
scanf("%d:", len);
x = calloc(*len, sizeof(int));
do c = getchar(); while (c != '[');
if (len > 0) {
scanf("%d", &x[0]);
for (int i=1; i < *len; i++) scanf(",%d", &x[i]);
}
do c = getchar(); while (c != ']');
return x;
}
void printSignal(int len, int *x) { //prints the signal
printf("%d: [", len);
if (len > 0) {
printf("%d", x[0]);
for (int i=1; i < len; i++)
printf(",%d", x[i]);
}
printf("]\n");
}
void *padSignal(int len, int lenSig, int *x) { //ensures that the signal is of size 2^n by padding it with 0's
int *padded;
padded = calloc(len, sizeof(int));
for (int i=0; i < lenSig; i++) {
padded[i] = x[i];
}
return padded;
}
void fft(double complex signal[], int length, int power) {
if (length == 1) {
return;
}
double complex *signalODD = calloc((length/2+1), sizeof(double complex));
double complex *signalEVEN = calloc((length/2+1), sizeof(double complex));
int index1 = 0;
int index2 = 0;
for(int i = 0; i < length; i++) {
if(i % 2 ==0) {
signalEVEN[index1] = signal[i];
index1++;
}
else {
signalODD[index2] = signal[i];
index2++;
}
}
fft(signalEVEN,length/2, power+1);
fft(signalODD,length/2, power+1);
for(int i = 0; i<length/2-1; i++) {
signal[i] = signalEVEN[i] + cexp((I*2*PI*i)/length)*signalODD[i];
signal[i+length/2] = signalEVEN[i]-cexp((I*2*PI*i)/length)*signalODD[i];
}
free(signalODD);
free(signalEVEN);
}
void ifft(double complex signal[], int length, int power) {
if (length == 1) {
return;
}
double complex *signalODD = calloc((length/2+1), sizeof(double complex));
double complex *signalEVEN = calloc((length/2+1), sizeof(double complex));
int index1 = 0;
int index2 = 0;
for(int i = 0; i < length; i++) {
if(i % 2 ==0) {
signalEVEN[index1] = signal[i];
index1++;
}
else {
signalODD[index2] = signal[i];
index2++;
}
}
fft(signalEVEN,length/2, power+1);
ifft(signalODD,length/2, power+1);
for(int i = 0; i<length/2-1; i++) {
signal[i] = signalEVEN[i] + cexp((I*-2*PI*i)/length)*signalODD[i];
signal[i+length/2] = signalEVEN[i]-cexp((I*-2*PI*i)/length)*signalODD[i];
}
free(signalODD);
free(signalEVEN);
}
int checkPowerofTwo(double len) { //checks for the closed power of 2
double x = 1;
while(len > pow(2,x)) {
x++;
}
return pow(2,x);
}
int main(int argc, char *argv[]) {
int lenH, *H;
int lenX, *X;
int *paddedX;
int *paddedH;
double length;
H=readSignal(&lenH); //reads in the signal H
X=readSignal(&lenX); //reads in signal X
length = lenH+lenX-1;
paddedH=padSignal((length),lenH,H); //pads the signal to the length
paddedX=padSignal((length),lenX,X); // pads the signal to the length
double complex *signalX = calloc(length, sizeof(double complex)); //creats a complex signal X and fills it with paddedX
for (int i = 0; i<length; i++) {
signalX[i] = paddedX[i];
}
double complex *signalH = calloc(length, sizeof(double complex)); // same for H
for (int i = 0; i<length; i++) {
signalH[i] = paddedH[i];
}
fft(signalX, length, 1); //performs the fast fourier transform on X
fft(signalH,length, 1); // performs the fast fourier transfom on H
double complex *signalY = calloc(length, sizeof(double complex)); //makes complex signal Y
for (int i = 0; i<length; i++) { //performs the convolution
signalY[i] = signalX[i]*signalH[i];
}
ifft(signalY, length,1);
int *output = calloc(length, sizeof(int)); //creates the final output signal
for (int i = 0; i<length; i++) {
output[i] = creal(signalY[i]);
}
printSignal(length,output);
free(signalX);
free(signalH);
free(signalY);
free(H);
free(X);
free(paddedH);
free(paddedX);
free(output);
return 0;
}
In:
if(i % 2 ==0 && i != 0)
Why do you exclude i == 0? Change that to if(i % 2 ==0) in both fft and ifft.
In both fft and ifft, the line:
for(int i = 0; i<lenght/2-1; i++) {
should be:
for(int i = 0; i<lenght/2; i++) {
In ifft, the recursion accidentally uses fft:
fft(signalEVEN,lenght/2, power+1);
fft(signalODD,lenght/2, power+1);
Change those to ifft.
The calloc calls do not need this much space:
calloc((lenght/2 + 1), sizeof(double complex));
That can be:
calloc((lenght/2), sizeof(double complex));
Also, the proper spelling of is “length”.
With those fixed, the fft and ifft routines appear to work for some superficial cases.
I implemented the aforementioned algorithm (https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm).
Here' s the full working code.
I receive streaming input from microphone in a non interleaved stereo Callback.
Then i fill a buffer with input samples and process this buffer into fft and ifft
functions.
Finally i use a pointer to send the processed buffer to output.
I use Asio4all V2.
I really can' t understand where is the problem because it does work properly but i can' t go beyound N=16 or the output sounds highly intermittent.
Thanks a lot in advance.
Callback + Main:
#include <stdio.h>
#include <stdlib.h>
#include "portaudio.h"
#include "FFT.h"
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#define NUM_SECONDS (10)
typedef struct
{
}
paTestData;
static int patestCallback( void *INbuffers[2], void *OUTbuffers[2],
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *inL = (float *) INbuffers [0];
float *inR = (float *) INbuffers [1];
float *outL = (float *) OUTbuffers[0];
float *outR = (float *) OUTbuffers[1];
unsigned long i;
(void) timeInfo;
(void) statusFlags;
for( i=0; i<framesPerBuffer; i++ )
{
for(int i=0; i<N; i++)
{
Y[i] = *inL + 0*I;
}
*inL++;
fft(Y, N);
ifft(Y, N);
for(int i=0; i<N; i++)
{
p_out=&Y[i];
}
*outL++ = *p_out++;
*outR++ = *p_out++;
}
return paContinue;
}
int main()
{
PaStreamParameters inputParameters;
PaStreamParameters outputParameters;
PaStream *stream;
paTestData data;
Pa_Initialize();
inputParameters.device = Pa_GetDefaultInputDevice();
inputParameters.channelCount = 2;
inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
inputParameters.suggestedLatency = 0;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice();
outputParameters.channelCount = 2;
outputParameters.sampleFormat = paFloat32 | paNonInterleaved;
outputParameters.suggestedLatency = 0;
outputParameters.hostApiSpecificStreamInfo = NULL;
Pa_OpenStream( &stream,
&inputParameters,
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
patestCallback,
&data );
Pa_StartStream( stream );
Pa_Sleep( NUM_SECONDS * 1000);
Pa_StopStream( stream );
Pa_CloseStream( stream );
}
Header:
#ifndef FFT_H_INCLUDED
#define FFT_H_INCLUDED
#include <stdio.h>
#include <math.h>
#include <complex.h>
#define N (16)
complex Y[N];
complex *p_out;
void separate (complex *a, int n)
{
complex b[N/2];
for(int i=0; i<n/2; i++) // copy all odd elements to b
b[i] = a[i*2+1];
for(int i=0; i<n/2; i++) // copy all even elements to lower-half of a[]
a[i] = a[i*2];
for(int i=0; i<n/2; i++) // copy all odd (from heap) to upper-half of a[]
a[i+n/2] = b[i];
}
complex fft(complex *X, int m) // forward fft
{
if(m < 2) {
// bottom of recursion.
// Do nothing here, because already X[0] = x[0]
} else {
separate(X, m); // all evens to lower half, all odds to upper half
fft(X, m/2); // recurse even items
fft(X+m/2, m/2); // recurse odd items
for(int k=0; k<m/2; k++) // combine results of two half recursions
{
complex e = X[k ]; // even
complex o = X[k+m/2]; // odd
complex w = cexp( 0 + (-2.*M_PI*k/m)*I ); // w is the twiddle-factor
X[k ] = e + w * o;
X[k+m/2] = e - w * o;
}
}
}
float ifft(complex *X, int m) // inverse fft
{
for (int i=0; i<m; i++)
{
X[i]=conj(X[i]); // conjugate the complex array
}
fft(X, m); // forward fft
for (int i=0; i<m; i++)
{
X[i]=conj(X[i]); // conjugate the complex array again
}
for (int i=0; i<m; i++)
{
X[i] /= m; // scale the numbers
}
}
#endif // FFT_H_INCLUDED
So i'm trying to multiply a constant with short int a[101] with intel intrinsics. I have done it with addition but i can't seem to figure why it wont work with multiplication. Also before we used ints of 32 bits and now we use 16 bit short so we can have double as many values in the intrinsics to fill the 128 bit as far as i understand?
naive example of what im trying to do:
int main(int argc, char **argv){
short int a[101];
int len = sizeof(a)/sizeof(short);
/*Populating array a with values 1 to 101*/
mult(len, a);
return 0;
}
int mult(int len, short int *a){
int result = 0;
for(int i=0; i<len; i++){
result += a[i]*20;
}
return result;
}
And my code trying to do the same in intrinsics
/*Same main as before with a short int a[101] containing values 1 to 101*/
int SIMD(int len, short int *a){
int res;
int val[4];
/*Setting constant value to mulitply with*/
__m128i sum = _mm_set1_epi16(20);
__m128i s = _mm_setzero_si128( );
for(int i=0; i<len/4*4; i += 4){
__m128i vec = _mm_loadu_si128((__m128i *)(a+i));
s += _mm_mul_epu32(vec,sum);
}
_mm_storeu_si128((__m128i*) val, s);
res += val[0] + val[1] + val[2] + val[3];
/*Haldeling tail*/
for(int i=len/4*4; i<len; i++){
res += a[i];
}
return res;
}
So i do get a number out as result, but the number does not match the naive method, i have tried other intrinsics and changing numbers to see if it makes any noticable difference but nothing comes close to the output i expect. The computation time is almost the same as the naive at the moment aswell.
There are 8 short in one __m128i. So:
for(int i=0; i<len/4*4; i += 4)
should be
for(int i=0; i<len/8*8; i += 8)`
and:
res += val[0] + val[1] + val[2] + val[3];
should be:
res += val[0] + val[1] + val[2] + val[3] + val[4] + val[5] + val[6] + val[7];
and:
for(int i=len/4*4; i<len; i++)
should be:
for(int i=len/8*8; i<len; i++)
In:
s += _mm_mul_epu32(vec,sum);
_mm_mul_epu32 operates on 32-bit elements. It should be:
s += _mm_mullo_epi16(vec, sum);
The object res is not initialized; it should be:
int res = 0;
Here is working code:
#include <stdio.h>
#include <stdlib.h>
#include <immintrin.h>
// Number of elements in an array.
#define NumberOf(x) (sizeof (x) / sizeof *(x))
// Compute the result with scalar arithmetic.
static int mult(int len, short int *a)
{
int result = 0;
for (size_t i=0; i<len; i++)
{
result += a[i]*20;
}
return result;
}
// Compute the result with SIMD arithmetic.
static int SIMD(int len, short int *a)
{
// Initialize the multiplier and the sum.
__m128i multiplier = _mm_set1_epi16(20);
__m128i s = _mm_setzero_si128( );
// Process blocks of 8 short.
for (int i=0; i<len/8*8; i += 8)
{
__m128i vec = _mm_loadu_si128((__m128i *)(a+i));
// Multtiply by multiplier and add to sum.
s = _mm_add_epi16(s, _mm_mullo_epi16(vec, multiplier));
}
// Store the sum so far so its individual elements can be manipulated.
short val[8];
_mm_storeu_si128((__m128i*) val, s);
// Add the individual elements.
int res = 0;
for (size_t i = 0; i < 8; ++i)
res += val[i];
// Add the elements in the tail.
for (size_t i = len/8*8; i < len; ++i)
{
res += a[i];
}
return res;
}
int main(int argc, char **argv)
{
short int a[96];
int len = NumberOf(a);
// Initiailize a.
for (size_t i = 0; i < len; ++i)
a[i] = i+1;
printf("sum by scalar arithmetic is %d.\n", mult(len, a));
printf("sum by SIMD arithmetic is %d.\n", SIMD(len, a));
return 0;
}
I'm making a program which dynamically creating 2d array.but it's showing the error which I mentioned on the title. I'm using Visual Studio 2015.
// last.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <time.h>
#include "stdlib.h"
double selectionSort(int * number, int number_count);
void print2d(int ** array, int rows, int cols);
void twodarray();
void main(int argc, char* argv[])
{
int num_count = 10000;
int num[10000];
for (int i = 0; i < num_count; i++)
{
num[i] = rand();
}
double sortTime = selectionSort(num, num_count);
printf("Total Runtime is: %.0f milliseconds. \n", sortTime * 1000);
twodarray();
getchar();
}
double selectionSort(int * number, int number_count)
{
clock_t start, end;
double duration;
int min;
start = clock();
for (int i = 0; i < number_count - 1; i++)
{
min = i;
for (int j = i + 1; j < number_count; j++)
{
if (number[min] > number[j])
{
min = j;
}
}
if (min != i)
{
int temp = number[min];
number[min] = number[i];
number[i] = temp;
}
}
end = clock();
return duration = (double)(end - start) / CLOCKS_PER_SEC;
}
void print2d(int ** array, int rows, int cols)
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0, j < cols; j++;)
{
printf("%10d ", array[i][j]);
}
puts("");
}
}
void twodarray()
{
int **twod;
int rows = 10;
twod = malloc(rows * sizeof(int));
int i,cols = 10;
for (i = 0; i < rows; i++)
{
twod[i] = malloc(cols*sizeof(int));
print2d(twod, rows, cols);
}
for (i = 0; rows; i++)
{
free(twod[i]);
free(twod);
}
}
In c++ you need to cast when assigining a void * pointer to another type of pointer. But in c++ you should not use malloc(), instead use
int **twod = new int *[rows];
If you didn't mean to write a c++ program, rename the file. Change the extension from .cpp to .c.
Your allocation is wrong too, as pointed out by #KeineLust here.
This is wrong:
int **twod;
int rows = 10;
twod = malloc(rows * sizeof(int));
You need to reserve space for n pointers to int, not for n ints, change to
twod = malloc(rows * sizeof(int *));
And here:
for (j = 0, j < cols; j++;)
^ ^
Use a semicolon instead of a comma and also remove the last semicolon.
Another problem:
for (i = 0; rows; i++)
{
free(twod[i]);
free(twod); /* Don't free twod in the loop, one malloc -> one free */
}
And as pointed out by Nicat and Iharob, it seems that you are mixing C and C++, use the proper extension (.c)
I'm trying to get monochrome image from .bmp image with using bitmap_image.hpp library. But in one place (Pic[i][j] = 0.3 * r + 0.59 * g + 0.11 * b;) i receive that error: Unhandled exception at 0x0019BD8F in PicCircle.exe: 0xC0000005: Access violation writing location 0x011CF000. . So, that's wrong with it?
code:
#define _SCL_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "bitmap_image.hpp"
#define C 0.01
double** ArrayCreate ( int M, int N )
{
int i;
double** ArrayRoot;
ArrayRoot = (double **)malloc(sizeof(double*) * M);
for (i = 0; i < M; i++)
ArrayRoot[i] = (double *)malloc(sizeof(double) * N);
return ArrayRoot;
}
void ArrayDestroy ( double** Array , int M)
{
int i;
for (i = 0; i < M; i++){
Array[i] = (double *)realloc(Array[i], 0);
};
Array = (double **)realloc(Array, 0);
}
void main ( void )
{
double** Pic;
unsigned char r, g, b;
int H, W, i, j;
bitmap_image image("m1.bmp");
H = image.height();
W = image.width();
Pic = ArrayCreate(H, W);
for (i = 0; i < W; i++)
for (j = 0; j < H; j++)
{
image.get_pixel(i, j, r, g, b);
Pic[i][j] = 0.3 * r + 0.59 * g + 0.11 * b;
}
for (i = 0; i < W; i++)
for (j = 0; j < H; j++)
{
if (abs(sqrt(pow(Pic[i + 1][j] - Pic[i][j], 2) + pow(Pic[i][j + 1] - Pic[i][j], 2))) >= C)
Pic[i][j] = 1;
else
Pic[i][j] = 0;
}
ArrayDestroy(Pic, H);
}
In your first loop you access the Pic array as Pic[width][height], but in the second loop you access it as Pic[height][width].
One of those two is incorrect, probably the first one.
Fixing your for loop should correct the issue.
This:
ArrayRoot = (double **)malloc(sizeof(int*) * M);
looks super-broken; it assumes sizeof (int *) to be the same as (sizeof double *) which is probably true, but still a very broken thing to write.
The follow-up is worse:
ArrayRoot[i] = (double *)malloc(sizeof(int) * N);
since sizeof (int) is very probably smaller than sizeof (double) this is going to lead to horror.
The way to avoid this category of error is to never write the type name in the malloc() argument: dereference the pointer being assigned to, instead. The latter would then become:
ArrayRoot[i] = malloc(N * sizeof *ArrayRoot[i]);
^^^^^^^^^^^^^
this part is to
the left of the =
This also drops the cast of course.