1

I wanted to know the reasoning behind a conflict ONLY in imaginary parts after IFFT.

For both my C/C++ implementation and Matlab implemenation I am doing the same following steps.

  1. My signal x is of dimension Mx1 and I perform an N-point FFT (where N = 2*M) on that signal to get N-point signal in frequency domain.
  2. Apply a customized filter on this frequency domain signal (both real and imaginary parts are changed in step).
  3. Perform in N-point inverse FFT.

Both C/C++ and Matlab implementations generate exactly the same result except the after the inverse IFFT step, imaginary parts do not match but real parts do match.

If I skip step 2 above, IFFT output of both implementation match without any problem. It is intended that my input signal to IFFT (i.e., after step2 filter) is not required to be conjugate symmetric. Infact this signal may even not be a Hermitian/symmetric.

Currently, I am using C-implementation of FFT/IFFT defined as a function smbFft available in this CPP-FILE.

Any clues, why this could be happening?

PS: It would be great, if someone can point me to an FFT implementation in C/C++, which is exactly aligned with corresponding Matlab implementation.

Thanks.

Edit: I just tested FFTW implementation instead of smbFfT (I mentioned above). FFTW implementation also has the same problem, which suggest that both of these tested C-implementations perform IFFT with hermitian symmetry setting. I need to perform the same IFFT in C as Matlab does with IFFT(..., 'nonsymmetric').

user1082170
  • 323
  • 2
  • 13
  • 3
    Post your code. Specially, beware of Matlab `'` operator, which applies a complex conjugation – Luis Mendo Nov 08 '13 at 16:04
  • 2
    try FFT -> IFFT *without* other changes with both codes too confirm the inverse operation in your C code is correct. The results should be equal to the input (taking into account numerical precison) – Sebastien Nov 08 '13 at 16:10
  • @Sebastien I just edited above, I skip step 2 above, the output of IFFT matches with Matlab's IFFT. – user1082170 Nov 08 '13 at 16:11
  • @LuisMendo Thanks for your pointer. I am aware of this operation. – user1082170 Nov 08 '13 at 16:11
  • Do you use the exact same filter in both cases? I used to use fftw for C code. very efficient and robust. – Sebastien Nov 08 '13 at 16:13
  • @LuisMendo Currently, I am using the FFT/IFFT implemenation from DSP-dimension, available as `smbFft(...)` in this file [link](http://downloads.dspdimension.com/smbPitchShift.cpp) – user1082170 Nov 08 '13 at 16:13
  • @Sebastien Yes, I used the same exact filter in both implementations. Infact, for both implementations, I have validated the output of step 2 (i.e., the input to IFFT) and they match. – user1082170 Nov 08 '13 at 16:16
  • What is the relative mismatch? Does your original function has an imaginary part? If you try the whole thing with a known analytic function, does it works? – Sebastien Nov 08 '13 at 16:21
  • @Sebastien: Imaginary parts differs significantly in their magnitudes as well as signs. Should I provide the output of step 2? – user1082170 Nov 08 '13 at 16:25
  • Try with an analytic function (a lorentizian or a gaussian). – Sebastien Nov 08 '13 at 16:26
  • @Sebastien Yes it does work. Note that, because of the filter in step2, IFFT should output non-zero imaginary parts (instead of zero magnitude of imaginary part). My guess is it may be that smbFft FFT/IFFT does not support some special case of FFT/IFFT, which is handled well in Matlab. But still no clue why its happening. – user1082170 Nov 08 '13 at 16:36
  • Is your filter Hermitian? Is the FFT result hermitian too? If so, the problem is most probably related to the code that applies it. The most frequent error that shows these symptoms is a damning offset in your array values (1 to n vs 0 to n-1). Beyond that, not sure I can help – Sebastien Nov 08 '13 at 16:44
  • @Sebastien Thanks for your help. Indexing the array is not the issue. Do you know any C implementation of FFT/IFFT, which claims to match with corresponding Matlab implementation. – user1082170 Nov 08 '13 at 16:54
  • The only thing I can recommend is fftw.org fast, reliable, and easy to add to a project. – Sebastien Nov 08 '13 at 17:04
  • OK thanks for your help. I just found out, in matlab if I run ifft(..., 'nonsymmetric') I get the same result as I was getting initially. In other words, Matlab somehow automatically selected 'nonosymmetric' when I did not give any. Running with ifft(..., 'symmetric') only output real part, no imaginary part. Have to dig a bit deeper why Matlab.ifft is working like this. – user1082170 Nov 08 '13 at 17:14
  • @Sebastien I tried fftw3 implementation of FFT/IFFT. The imaginary parts of fftw3.IFFT(p) also do not match to Matlab.IFFT(..., 'non-symmetric'). Since result of my filter is required not to be Hermitian. That's why I want to perform a IFFT with non-symmetry enabled. What I feel is most C-implementations perform IFFT with Hermitian/symmetric setting. – user1082170 Nov 10 '13 at 14:16
  • Well at that point I guess you should review matlab and fftw documentation relative to this. – Sebastien Nov 10 '13 at 19:40

1 Answers1

1

If you want a strictly real result (imaginary parts all equal to zero), then you need to make the vector be exactly conjugate symmetric (real parts mirrored, imaginary parts inversely mirrored) before the IFFT.

Matlab and C treat index 0 or 1 of arrays differently. Make sure your filter takes that into account as well.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • Thanks for your pointers. It is intended that my input signal to IFFT (i.e., after step2 filter) is not required to be conjugate symmetric. Hence, I know the after IFFT would not yield imaginary part as zero. That's not the problem. The problem is imaginary part is still important to me after IFFT. But the C-implementation (I mentioned above) computes different values of imaginary than in comparison to Matlab.IFFT implementation. In other words, these two IFFT implementations are in conflict while dealing with same input non-symmetric signal. – user1082170 Nov 10 '13 at 13:23