Reputation: 8118
Testing the following code I get the right answers:
#include <fftw3.h>
void dump_vector(float *a, int size)
{
int i;
for (i = 0; i < size; i++) {
printf("%f\t", a[i]);
}
printf("\n");
}
int main()
{
float a[] = {1, 2, 3, 4};
dump_vector(a, 4);
fftw_plan plan = fftw_plan_r2r_1d(2 * 2, a, a, FFTW_REDFT10, FFTW_ESTIMATE);
fftw_execute(plan);
dump_vector(a, 4);
}
Result:
./main
1.000000 2.000000 3.000000 4.000000
3.992188 4.501953 -334878449985782808576.000000 3.886292
But I want make a naive wrap for dct so:
#include <fftw3.h>
void dump_vector(float *a, int size)
{
int i;
for (i = 0; i < size; i++) {
printf("%f\t", a[i]);
}
printf("\n");
}
void dct(float * array, int xsize, int ysize)
{
fftw_plan plan = fftw_plan_r2r_1d(xsize * ysize, array, array, FFTW_REDFT10, FFTW_ESTIMATE);
fftw_execute(plan);
}
int main()
{
float a[] = {1, 2, 3, 4};
dump_vector(a, 4);
dct(a, 2, 2);
dump_vector(a, 4);
}
Result:
./main
1.000000 2.000000 3.000000 4.000000
3.992188 4.501953 -334878449985782808576.000000 3.886292
[1] 10880 segmentation fault ./main
Is there something that I am missing?
I need to do this because then I want to generate a .so
file for using it in another app.
Upvotes: 1
Views: 527
Reputation: 9817
The problem is much simplier than expected: fftw_plan_r2r_1d
perform DCTs/DSTs on arrays of double
.
As is, the array float a[]
is too small: 4 float
are stored in 4x4=16 bytes, while fftw_plan_r2r_1d
expects 4 double
(32 bytes). Hence, fftw_plan_r2r_1d
will attempt to read pass the end of the actual array. This triggers undefined behaviors such as segmentation fault or wrong results.
Two solutions:
float a[]
for double a[]
and dump_vector(float *a,...
for dump_vector(double *a,...
fftwf_plan_r2r_1d()
to build a fftwf_plan
for arrays of float
. See http://www.fftw.org/doc/Precision.html : the library libfftw3f.a
must be linked by adding -lfftw3f
to the compiler command.Upvotes: 1