1

I have a signal x[n], transformed it using fft and extracted the dominant frequency by sorting the amplitude response. Calculated average as avg = mean(xn) , where xn is a 1x3142 matrix containing the signal data.

How do I use this information to plot an approximation of the original signal? I honestly don't know how to do this. Thought of using ifft but I don't know how the average value and dominant frequency are supposed to help me then.

Original Signal:

enter image description here

Amplitude Response:

enter image description here

rayryeng
  • 102,964
  • 22
  • 184
  • 193
Lightvvind
  • 155
  • 1
  • 8
  • The best you're going to get with this approach is a sinusoid whose frequency has the largest amplitude response. This will not reconstruct properly with complex varying data. Do you have an example signal that we can see? I seriously don't see how just using the average value (which is actually the DC offset in this case), and the dominant frequency will help in faithfully reconstructing the original signal. – rayryeng Nov 09 '15 at 20:07
  • @rayryeng Added plots of the original signal aswell as the amplitude response in the question. I don't see how I'm supposed to approximate the original signal either which is why I'm asking. – Lightvvind Nov 09 '15 at 20:18
  • BTW, if you have complex varying data, the component with the strongest response will most likely be 0 Hz / DC. You may want to search for the two largest components... or perhaps take the first component, and find the average of the next 10 top components... or something like that. But yes, I can't see this how this can be done by just using the dominant frequency and average value. The best thing you're going to get is a sinusoid at this dominant frequency, vertically offset by the average value, unless that's the point. Does this make sense to you? If it does, I'll write an answer. – rayryeng Nov 09 '15 at 20:19
  • @rayryeng Alright, I guess I'll generate a sinusoid and hope that it's good enogh. Thank you for the help. – Lightvvind Nov 09 '15 at 20:22
  • For sure. BTW, would it be possible to get the data of the signal itself? I'd love to be able to upload a plot to show you that it's working... and mainly to see if what I produce makes sense. – rayryeng Nov 09 '15 at 20:23
  • @rayryeng Sure! Here's a link to the dataset. Column 1 represents time and column 2 represents number of sunspots. Just run the file and it will generate a variable called ssd. https://dl.dropboxusercontent.com/u/15991564/sunspots.m – Lightvvind Nov 09 '15 at 20:29
  • Cool. I'll have a look. I have a question for you. What was the sampling frequency of this data you got? What the FFT returns is a set of normalized frequencies from `-1 <= f < 1`, but this isn't meaningful unless we know what the sampling frequency of your data was... and this will give more meaning to the horizontal axis of the FFT. – rayryeng Nov 09 '15 at 20:32
  • @rayryeng "Monthly data on the number of sunspots from 1750 to 2010" is the only thing I know about the data that's even remotely similar to sampling frequency. – Lightvvind Nov 09 '15 at 20:36
  • Yeah the reason why I asked is because the time interval in between points isn't constant. I'll have to fudge this and see how it goes lol. – rayryeng Nov 09 '15 at 20:38
  • @rayryeng I know, that was one of the first things I noticed... they are almost constant though... – Lightvvind Nov 09 '15 at 20:41

1 Answers1

3

OK, so here's my botched attempt at doing this. What you'll need to do is plot the spectrum and determine the largest peak - which is the average value as well as the second largest peak, which will give you the dominant frequency. I've noticed that the sampling times between points isn't constant, but let's hope that doesn't interfere with things and this should give us a nice signal.

BTW, I've increased the point size for the FFT to increase the resolution of the spectrum so we can get a better approximation of where the peaks are. As such, let's plot the spectrum and make sure we shift the spectrum so that the centre frequency is in the middle, rather than on the left:

N = 4096; %// FFT point size
F = fft(ssd(:,2), N);
Fs = fftshift(F);
mag = abs(Fs); %// Magnitude spectrum shifted
plot(1:N, abs(mag)); %// Plot the spectrum

This is what we get and I've added in some data cursors to help exemplify my point:

enter image description here

Note that I've manually inspected where the peaks are because sorting them and choosing the largest component isn't the best way to do things. The largest peak is obviously the DC value, but the larger values that follow the largest peak may not necessarily give you the right results as you can see here. Therefore, you could run it through a peak detection algorithm to get the dominant peak, but I'm going to avoid that to give you a result.

As you can see, in the shifted spectrum the points at locations 2018 and 2080 correspond to our dominant peaks while the point at 2049 is the DC offset / average value. As such, create a new signal where we only copy these three locations in the frequency domain, undo the shift, take the inverse, and also cap off any residual imaginary components.

You'll also note that the output length is the FFT point size. You'll want to remove out the extra output and only show up to as long as the original signal contains:

%// Create blank array
out_reconstruct = zeros(N,1);

%// Copy values over from shifted spectrum
out_reconstruct([2018 2049 2080]) = Fs([2018 2049 2080]);

%// Reconstruct in time domain and cap
out_reconstruct = real(ifft(ifftshift(out_reconstruct)));
out_reconstruct = out_reconstruct(1:size(ssd,1));

%// Plot
plot(ssd(:,1), ssd(:,2), ssd(:,1), out_reconstruct);

We get this:

enter image description here

As you can see, this isn't a good reconstruction. There is high variability in your data, and that's why only one dominant sinusoid isn't enough to reconstruct this data. However, the average value more or less is OK, and the oscillations between the original and reconstructed is the same.... so the dominant stuff does work, but the high variability isn't modelled here.

rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • Wow. Thank you, this is really helpful. – Lightvvind Nov 09 '15 at 21:11
  • No problem. Not sure if this is answer you're looking for! – rayryeng Nov 09 '15 at 21:13
  • Well, I can't think of anything else and I've been stuck on this for about 1 day. So I'll use this and see how it goes! – Lightvvind Nov 09 '15 at 21:16
  • Sure! If it does work, consider accepting my answer so that the community knows you no longer need help...whenever you're ready of course. Good luck! – rayryeng Nov 09 '15 at 21:17
  • @Lightvvind OK fixed. It didn't change the results at first sight, but the code is more correct. I had to sample from the actual FFT of the signal, not just the magnitude...and so once I got the phase information too, the reconstructed sinusoid is now more in phase with the original signal. – rayryeng Nov 09 '15 at 21:22
  • 1
    Cool! Thank you, you've been very helpful! – Lightvvind Nov 09 '15 at 21:40