0
$\begingroup$

I am sampling at $30 Hz$.

I have a sample of $N=150$.

Here is an example of how my sample looks like, which starts at 54 and ends on 203 on the X Axisenter image description here

I am interested in observing frequencies between 15 and 20 per minute. ( Cycles per minute ) Hence, I would derive the cycles per second ( Hz ) like this.

$15*0.0166666666667=0.25 \ Hz$

$20*0.0166666666667=0.33 \ Hz$

When I take the FFT, my data looks as follows. ( X axis are the bins to N / 2, not frequency )

enter image description here

To derive the frequency for each bin, I am using this stack answer to construct this logic:

Frequency = ( bin * sampleRate ) / dft.Points

So I might have some output as follows:

Frequency = 0 * 30/300
Frequency = 1 * 30/300
Frequency = 2 * 30/300
Frequency = 3 * 30/300

If I re-plot the same data, where the X axis now represents frequency, this is what I get :

enter image description here

Here is where my question kicks in: ( Note, if something above is wrong in my logic, please point it out, as it could be the reason why I am getting weird results )

I now want to take the IFFT of the dataset, given that the frequency of the bin is less than . Here is some java code to help illustrate how I am doing this with JTransforms:

final double[] ifft = new double[fft.length];
for (int idx = 0; idx < fft.length; idx++) {
    final double fftPoint = fft[idx];
    final Double sampleCount = Double.valueOf(idx * 30);
    final Double binToFrequency = Double.valueOf(sampleCount / fft.length);
    ifft[idx] = binToFrequency <= 0.33333334 ? fftPoint : 0;
}

analyzer.realInverseFull(ifft, false);

Variable fft above is the DFT/FFT array data points. Since I have 150 samples. fft.length should equate to 300. I am then checking the frequency of the bin, and if it is less than 0.33333334 I am using it, otherwise, it is getting zeroed out.

When I plot my graph, the odd part is that I get two waves:enter image description here

If I zoom in on the top one, here is what I see:enter image description here

I also notice that the numbers on the x axis are increments of 2. For example, the wave where the amplitude is around 400K on the Y axis starts at 1, and has points at 3,5,7,9, etc. The lower one starts at 0, and has points 2,4,6,8,etc.

Question:

Should I be seeing two waves? If yes, how do I combine it into one? If no, what step might have I destroyed?

From my cloudy knowledge, the only thing I can think of that can explain this is the notion of imaginary and real numbers. But, I do not see why they should be shown in a time domain, after an iFFT occurs.

$\endgroup$
3
  • $\begingroup$ 1. If the data foes from 54 to 254, that is 151 samples actually. 2. When you plot the FFT, is it only the real part? imaginary part? I bet it is the real part only. 3. You are not seeing two waves, it is the same at very high frequency. $\endgroup$
    – Fusho
    May 31, 2017 at 15:58
  • $\begingroup$ Sorry, from 54 to 204 (both included) there are 151 samples. $\endgroup$
    – Fusho
    May 31, 2017 at 16:05
  • $\begingroup$ @oxuf wrt to #1, my mistake, 54 to 203. wrt to #2, that is correct, it is only the real wrt to #3, I am not sure i understand what you mean. Are you saying that it is normal to see two identical waves, just one all the way up top and the other on the bottom? $\endgroup$
    – angryip
    May 31, 2017 at 18:56

2 Answers 2

3
$\begingroup$

FloatFFT has a funny array layout. Real and Imaginary components of each datapoint/bin have to be interleaved in the data array you provide. The FFT plot you show it is not a common FFT plot: is the real and imaginary part of the FFT interleaved: $[ Re\{X[0]\}, Im\{X[0]\}, Re\{X[1]\}, Im\{X[1]\}, ... ]$.

Handle two consecutive points everywhere accordingly. For example: $bin[0] = abs( sqrt( a[0]*a[0] + a[1]*a[1] )$ and so on... Also, follow that layout when you perform the inverse.

Documentation is not the best and you will have to read it carefully.

Bonus: the reason you have to provide a $2 \cdot n$ array to some functions is not that the FFT has to double the data set length, it is because each bin is stored in two consecutive array positions.

$\endgroup$
9
  • $\begingroup$ The formula you provide in the second paragraph. Is this what you are using to merge the two inverse waves into one? $\endgroup$
    – angryip
    May 31, 2017 at 22:31
  • $\begingroup$ Are you familiar with the concept of a function that takes an integer value (in this case an index) and returns a complex value (a+i*b)?, signal data and FFT are of this type in general, but in your particular case the signal data happens to have the imaginary part set to zero (it is a pure real sequence). If you plot real and imaginary part against index you need a 3D plot. A way to plot it in 2D is either plot only the real part or only the imaginary part or its absolute value (magnitude or module), etc... $\endgroup$
    – Fusho
    Jun 1, 2017 at 8:29
  • $\begingroup$ that formula computes the magnitude of the first bin (index==0) of the FFT given its real and imaginary values at that index (a[0] and a[1]) $\endgroup$
    – Fusho
    Jun 1, 2017 at 8:29
  • $\begingroup$ got it, i understand the purpose of the formula now. your solution helps me generate the correct fft plot. however, is there something similar i should be doing when creating the ifft to eliminate seeing two waves? ( seems to be im and re , but from the sounds of things i should be combining them $\endgroup$
    – angryip
    Jun 1, 2017 at 10:41
  • $\begingroup$ Well, they are not two distinct waves, it is just one wave but of the highest frequency possible (aprox.), imagine a line that goes from $x[0]$ to $x[1]$, another from $x[1]$ to $x[2]$ and so on and you will realize which is its shape: oscillating quickly. I suggest you use complexInverse instead of realInverseFull since you now have complex values (FFT you get has real and imaginary parts). $\endgroup$
    – Fusho
    Jun 1, 2017 at 11:41
0
$\begingroup$

The first problem might be that you need to sample more than twice the rate of the highest frequency in your signal. Otherwise your samples will be contaminated by aliasing.

The second problem in plotting your spectrum is that the lowest bins of an FFT or DFT of strictly real data can be mixed (contaminated) by the nearby complex conjugate negative frequency image. This can be solved by sampling longer (more samples covering more time), which will move the spectrum of interest to higher numbered FFT result bins.

Third, attempting to filter a signal by zeroing FFT bins does not work well. See this answer for details: Why is it a bad idea to filter by zeroing out FFT bins?

$\endgroup$
2
  • $\begingroup$ wrt to the third comment: I think I visited this post a few times before. However, while I understand what is discussed, I must admit I do not understand what the alternative is. Might you have some references / material that I can take a look that can tell me the appropriate way to filter out unwanted frequencies? $\endgroup$
    – angryip
    May 31, 2017 at 19:15
  • $\begingroup$ Find (or ask for) some filtering software specific to your computer/platform? (Not just an FFT. FIR or IIR maybe.) $\endgroup$
    – hotpaw2
    May 31, 2017 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.