Convert FFT to IFFT: Steps to Get Right Values Back

  • Thread starter Thread starter btb4198
  • Start date Start date
  • Tags Tags
    Fft
Click For Summary

Discussion Overview

The discussion revolves around the conversion of a Fast Fourier Transform (FFT) implementation into its Inverse Fast Fourier Transform (IFFT) counterpart. Participants explore the necessary modifications to the existing FFT code to achieve correct IFFT results, focusing on theoretical and practical aspects of the transformation process.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant inquires about the steps needed to convert their working FFT code into an IFFT, noting that they have not achieved the expected results.
  • Another participant suggests that an integer parameter should be passed to the FFT routine to indicate the direction of transformation, implying that this could be relevant for the IFFT.
  • A different participant references the concept of expressing the inverse Discrete Fourier Transform (DFT) in terms of the DFT, hinting at a theoretical approach to the problem.
  • One participant proposes a modification to the Complex1 function, suggesting that the exponent should be positive instead of negative to facilitate the IFFT conversion.
  • Another participant shares a FORTRAN implementation of FFT, expressing a need for a C, C#, or C++ version and questioning how to adapt it for IFFT use.
  • There is a discussion about which specific parts of the FFT code need to be changed to derive the IFFT, with one participant indicating uncertainty about the necessary modifications.

Areas of Agreement / Disagreement

Participants express differing views on how to effectively convert the FFT to IFFT, with no consensus reached on the exact modifications required. Some propose changes to the exponent in the Complex1 function, while others suggest looking at the overall structure of the FFT algorithm.

Contextual Notes

There are unresolved questions regarding the specific changes needed in the FFT code to achieve correct IFFT results, as well as the implications of the integer parameter for directionality in the transformation.

  • #61
I don't quite understand the last part. If he is passing in N points and receiving N FFT bins then how can the indexing be spread over N-1 frequencies?
 
Engineering news on Phys.org
  • #62
Because DC is zero frequency in bin zero.
 
  • #63
If you have N bins and divide by (N-1), then don't you get two bins with the same normalized frequency?

I think what you want is N bins with normalized frequency [0:N-1]/N, right?
 
  • #64
when you say DC do you mean Direct current?
 
  • #65
Yes, that's why he said DC is zero frequency.
 
  • #66
ok i just did this:
Code:
1.0
-0.41614683654714241
-0.65364362086361194
0.960170286650366
-0.14550003380861354
-0.83907152907645244
0.84385395873249214
0.13673721820783361

those 8 number from
Cos(2 * n);
and that go into my fft and I get :
Code:
{(0.886399443294871, 0)}
{(0.862297845278363, 0.616189555028432)}
{(0.664289628322506, 2.35212587048179)}
{(1.42870222233886, -2.37880560416378)}
{(1.20302116482566, 0)}
{(1.42870222233886, 2.37880560416378)}
{(0.664289628322506, -2.35212587048179)}
{(0.862297845278363, -0.616189555028432)}
then I reverse and send it back to the fft and dived by N
and I get this :
Code:
0.99999999999999989
0.41614683654714235
0.65364362086361194
0.96017028665036586
0.14550003380861354
0.83907152907645233
0.84385395873249214
0.13673721820783363
I lost my - value , will they all are + now... but it is because I am taking the
Magnitude
I am doing
Code:
double[] returntemp = new double[R];
           for (int v = 0; v < R; v++)
           {
               F[v] = F[v].Magnitude / N;
               returntemp[v] = F[v].Magnitude;
           }
           return returntemp;
I did not know if I should use the real or imaginary numbers, so I just used the
Magnitude
is that ok ?
 
  • #67
If you want to verify that your FFT and IFFT are working correctly, you need to output both the real and imaginary parts. There will probably be a small imaginary part due to numerical errors but it should be negligible.

Your magnitudes look good.
 
  • #68
ok this is my real:
Code:
0.99999999999999989
-0.41614683654714235
-0.65364362086361194
0.96017028665036586
-0.14550003380861354
-0.83907152907645233
0.84385395873249214
0.13673721820783363
so I should use my real and not the Magnitude?
 
  • #69
my img is all like 0 and 0.00000000000000017478323165292
which is 0
 
  • #70
here are some video i make




see my fft does work for that site with the
(bin index/N) * fs * 2

also I did test it again with the new version of this site and it still work
 
Last edited by a moderator:
  • #71
Then that's good. Your original signal was all real, so it makes sense that any imaginary part that you get after your IFFT is just numerical error. The real part is the part you want to keep.
 
  • #72
btb4198 said:
here are some video i make




see my fft does work for that site with the
(bin index/N) * fs * 2

also I did test it again with the new version of this site and it still work

Did you ever figure out if your samples contain interleaved L+R stereo channels?
 
Last edited by a moderator:
  • #73
yes it is Stereo Channels.
I am read in Stereo data from the sound card

so my FFT and IFFT it working now...
thanks for all the help

but question about the *2

as you can see in the youtube video my fft is working the * 2

you think this has something to do with the fact I am using Stereo data ?
 
  • #74
I don't know how your library is extracting the stereo data, but sure it could explain the 2* factor. Interleaving the L+R channels would mean you have twice as many samples per second as you might think. If the signals look more or less the same, the interleaved data could look similar to a (noisy) sine wave of half the frequency.
 
  • #75
yes I think that is what it is doing and that is how it plays that will... that is why I can add 2*PI to play it.

ok I make a low pass filter:
Code:
       public void lowpass_filter( int frequency)
        {
 for (int i = 0; i < R; i++)
 {      
     if((i / N) * Fs >= frequency)
     {
         F[i] = 0D;
     }

 }  }

and it is working good from what I have been testing ...
but my high pass is not working?

Code:
public void hightpass_filter(int frequency)
        {
            for (int i = 0; i < R; i++)
            {
                if ((i / N) * Fs <= frequency)
                {
                    F[i] = 0D;
                }

            }

I still get both frequencies back
high and low
frequencies back


the lowpass filter is working so good
why it the high pass filter not?
 
  • #76
The problem is what I mentioned to you earlier — the frequencies in an FFT output appear in pairs. So instead of thinking of the frequencies as [0, 1, 2, …, N-1]/N, you need to think of them as [0, 1, …, N/2-1, -N/2, -N/2+1, …, -2, -1]/N. You always need to filter positive and negative frequency bins in pairs.

The lowpass kind of works because you are zeroing out all the bins higher than a certain number. However, you won't get back a pure real signal because all you have left are unpaired (low numbered) bins. The high pass doesn't work at all because you are removing a few low numbered bins, but the corresponding negative frequency bins are untouched.

Also, if you are dealing with stereo channels, what you really need to do is de-interleave the stream and then FFT/filter the two channels separately.
 
  • #77
ok how do I find the negative frequency bins?
I tried to google it, but I do not see anything ...
can you show me an example ?
I get that there are two part of a signal way, one - and +. but what I do not get is how with the high pass filter I can till getting the low Frequency.
I mean you use bin Index to get the frequencies right and and every bin is different so no two bins should get you the same Frequency right?
 
  • #78
look carefully at the [0, 1, 2, …, N-1]/N I posted above.

Let's say you have 8 samples at sampling rate fs = 8 Hz. The "normal" way you'd label your frequency bins is
[0, 1, 2, …, N-1]/N * fs = [0, 1, 2, …, 7]/8 * 8 Hz = [0, 1, 2, …, 7] Hz.

Since the frequencies wrap around the 8 Hz sampling frequency, these are exactly the same as
[0, 1, 2, …, N/2-1, -N/2, …,-2, -1,]/N * fs = [0, 1, 2, 3, -4, -3, -2, -1]/8 * 8 Hz = [0, 1, 2, 3, -4, -3, -2, -1] Hz.

If you do a quick test, you'll notice that the Fourier coefficients contained in the 1 and -1 Hz bins are just complex conjugates of each other. Similarly for 3, -3 Hz and every other pair of bins. This is because you have a real-valued signal. If you want to so something to your signal but keep it real-valued, you have to maintain this symmetry.

For example, to high pass keeping >= 2 Hz signals, you can zero the 0 Hz and +1, -1 Hz bins and then inverse transform.
 
  • #79
ok based off your last post I make this function :

Code:
 public void hightpass_filter(int frequency)
        {
          int i = 0;
          int t = 0;
            for (; i < R/2; i++)
            {
                if ((i / N) * Fs <= frequency)
                {
                    F[i] = 0D;
                }

            }
            for (; i < R; i++)
            {
                if ((t / N) * Fs <= frequency)
                {
                    F[i] = 0D;
                }

                t++;
            }
      
      }

but it is this not working...
I still see both Frequencies
so what did I do wrong ?
from 0 to N/2 is positive
and from N/2 to (N-1) is negative
right?
or did I not understand that right ?
 
  • #80
Try running the example from my post through this function. Just use double F[] = {0, 1, 2, 3, -4, -3, -2, -1} or something easily identifiable to fill the bins. I think you'll discover the issue.
 
  • #81
what Fs should i use?
because I am using 44100 and that is too high for only 8 points
after 1/N * 44100 is too high...

(never mind)
 
  • #82
Use any Fs for your test. You're just testing with synthetic data that you fully understand so that you can verify your code. I think my example above used 8 points at 8 Hz.
 
  • #83
ok I did what you said, but I am not see why it is now working:
ok I am using:
double[] list = { 0, 1, 2, 3, -4, -3, -2, -1 };
and
and I set the high pass filter to 2
and after doing it

I get
{(0, 0)}
{(0, 0)}
{(0, 0)}
{(4, -1.65685424949238)}
{(0, 0)}
{(0, 0)}
{(0, 0)}
{(4, 9.65685424949238)}

oh I am using fs = 8;

this is what I get before the filter:
1 10.452503719011
2 5.65685424949238
3 4.32956880116958

and this is what I get after the filter:
1 5.22625185950551
3 2.16478440058479

the 2 is done, but the 1 is this there
how 1 hz is bin 1 and bin 6 right?
are am I wrong about this ?

I also tried with Fs = 44100
I tried to filter out anything lower then 11000
i got:
{(0, 0)}
{(0, 0)}
{(-4, 4)}
{(4, -1.65685424949238)}
{(0, 0)}
{(0, 0)}
{(-4, -4)}
{(4, 9.65685424949238)}
this is before the filter:

5512.5 10.452503719011
11025 5.65685424949238
16537.5 4.32956880116958

and after the filter:
5512.5 5.22625185950551
11025 5.65685424949238
16537.5 2.16478440058479

5512.5 is divide by half
...
what i am missing here ?
 
  • #84
Look carefully. If your FFT output is { 0, 1, 2, 3, -4, -3, -2, -1 } and your frequencies are [ 0, 1, 2, 3, -4, -3, -2, -1 ] Hz, then a high pass that keeps only frequencies greater than 2 Hz should leave you with { 0, 0, 0, 3, -4, -3, 0, 0 }, which you then pass to your IFFT.
 
  • #85
hey,
i think it is working!
thanks,
 
  • #86
Great!
You're welcome.
 

Similar threads

  • · Replies 16 ·
Replies
16
Views
3K
  • · Replies 11 ·
Replies
11
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
23
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
1K
  • · Replies 2 ·
Replies
2
Views
2K