Hello,
I have been assigned the task of converting a matlab script to C++, and am currently working on the FFT part.
Given this input:
octave:67> r57
r57 =0.00000 0.20000 0.30000 0.30000 0.40000
0.30000 0.30000 0.40000 0.40000 0.50000
0.10000 0.30000 0.20000 0.40000 0.10000
0.50000 0.50000 0.40000 0.30000 0.20000
0.20000 0.20000 0.20000 0.20000 0.20000
0.30000 0.20000 0.30000 0.20000 0.30000
0.50000 0.50000 0.50000 0.50000 0.50000
I get this output:
octave:68> fft2(r57)
ans =10.90000 + 0.00000i -0.46180 - 0.00000i -0.23820 - 0.00000i -0.23820 + 0.00000i -0.46180 + 0.00000i
0.79650 + 0.27359i -0.55720 + 0.94400i -0.89353 + 0.39737i -0.10671 - 0.19919i -0.34353 - 0.30982i
-0.13330 + 1.20183i 0.50836 + 0.04556i 0.18356 + 0.35590i -0.57328 - 0.00290i -0.49515 + 0.11341i
-1.91320 - 0.77347i -0.54307 - 0.27387i 0.09683 - 0.23803i -0.56867 - 0.10558i -0.20760 - 0.41938i
-1.91320 + 0.77347i -0.20760 + 0.41938i -0.56867 + 0.10558i 0.09683 + 0.23803i -0.54307 + 0.27387i
-0.13330 - 1.20183i -0.49515 - 0.11341i -0.57328 + 0.00290i 0.18356 - 0.35590i 0.50836 - 0.04556i
0.79650 - 0.27359i -0.34353 + 0.30982i -0.10671 + 0.19919i -0.89353 - 0.39737i -0.55720 - 0.94400i
And now I am confused. The first column is as expected, with the second half computable from the 1st half. However, this is not the case for the remaining columns. The C++ code follows, but it doesn't work, among other things it assumes that the second half of the columns can be computed from the first half.
Not sure how to proceed, Is the octave (matlab clone) output correct/expected/common ? If not, if there is a problem with the test data, what would be more reasonable to test with ?
Any advice on how to handle this situation would be much appreciated. Any comments on the code also, I am not really sure that it is correct
Kind Regards,
MKL_LONG mklNumSamples [2] = { 5 /* columns */, 7 /* rows */}; MKL_LONG mklInputStrides [3] = { 0, mklNumSamples[1] + 2, 1}; MKL_LONG mklOutputStrides[3] = { 0, mklNumSamples[1] + 2, 1}; float mklBuffer [(5+2)*(7+2)] = { 0 }; DFTI_DESCRIPTOR_HANDLE dftiHandle = DFTI_DESCRIPTOR_HANDLE();DftiCreateDescriptor(&dftiHandle, DFTI_SINGLE, DFTI_REAL, 2, mklNumSamples);
DftiSetValue(dftiHandle, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
DftiSetValue(dftiHandle, DFTI_INPUT_STRIDES, mklInputStrides);
DftiSetValue(dftiHandle, DFTI_OUTPUT_STRIDES, mklOutputStrides);
DftiCommitDescriptor(dftiHandle);
{
/* Input is f, accessed as: f.size(), f[index] */size_t index[2] = { 0, 0 };
for(index[0] = 0; index[0] < f.size()[0]; ++index[0]) /* column */
{
for(index[1] = 0; index[1] < f.size()[1]; ++index[1]) /* row */
{
mklBuffer[ index[0] * (f.size()[1]+2) + index[1]] = f[index]; /* fetches, f with column = index[0] and row = index[1]
}
}
}DftiComputeForward(dftiHandle, &mkliBuffer[0]);
{
size_t index[2] = {0, 0 };
for(index[0] = 0; index[0] < f.size()[0]; ++index[0])
{
for(index[1] = 0; index[1] < (f.size()[1] + 1)/2; ++index[1])
{
const PUVec2st index0(index[0], index[1]);
const PUVec2st index1(index[0], f.size()[1] - index[1]);const float real =
mklBuffer[ index[0] * (f.size()[1] + 2) + index[1]*2+0];
const float imag =
mklBuffer[ index[0] * (f.size()[1] + 2) + index[1]*2+1];if (index[1] == 0)
{
result[index0] = std::complex<float>(real, imag);
}
else
{
result[index0] = std::complex<float>(real, imag);
result[index1] = std::complex<float>(real, -imag);
}
}
}
}