Taking IFFT2 of data set and what is means - matlab

I am dealing with a data set collected from a bistatic radar system which has electric field amplitude vs frequency points. I am trying to take the inverse fourier transform of the data set, converting from the frequency domain into the time domain. I have read in the data in the code below, created two different arrays, one for freq and one for amplitude. I correctly plot the data, but when I take the IFFT of the data I do not get what i expect.
Can someone tell me how to properly take the 2 dimensional fast fourier transform of the data set in matlab, and what exactly the IFFT in this case scenario is showing?
waves = csvread('10cm.txt');
A = waves(:,1);
B = abs(waves(:,2));
Matrix = [A B];
waves_transform = abs(ifft2(Matrix));
figure, plot(A,B), title('Frequency Domain'), xlabel('Frequency'),ylabel('amplitude');
figure, plot(waves_transform),title('Time Domain'), xlabel('Frequency'),ylabel('amplitude');
%axis([0 5 0 17*10^9]);
10cm.txt DATA FILE HERE: http://pastebin.com/0t0TwVvC
code output

Related

Different plot shape for fft depending on time sample spacing

I am having the following issue. I am trying to analyse the input and output signal of my filter using fft. However, I am not sure if my fft is correct. My input signal is the product of a sawtooth and sine waveforms both with frequencies 6kHz and 32kHz, respectively. Both individual signals have an amplitude of 1 before being multiplied.
Depending on my time values I get different result for my fft plots. If I use values of time spaced out by the period of my sampling frequency, I get a "nice" looking graph with clear peaks as you would expect in a Fourier Transform (see Fig.1). However, if I use values of time spaced out by the period of the signal being sampled, the graph has more frequency components (see Fig. 2). I really don't know which graph is correctly displays my FFT. Also I have the problem that I used an online tutorial to achieve my FFT but I do not understand why the guy did what he did in his code which I do not understand. However, if I plot the absolute values of FFT, I get graphs with similar shapes but the amplitudes jump up to 30 or 40 more (see Fig. 3 and 4). Also for Fig.2 why is there a small wiggle at the start of the filtered signal (time domain) vs time ? Please your help in performing FFT accurately would be of great help. Thanks.
Figures are in Google Drive since website won't allow me to upload more than 1 file:
Fig. 1: https://drive.google.com/file/d/1XHc4jJfMudVOd2E8cluDB4Z8PvfKGsbt/view
Fig. 2: https://drive.google.com/file/d/1pOUhSTSFRwwrKVrwYEa-jYoahqGiYxMA/view
Fig. 3: https://drive.google.com/file/d/10346ttMYZN_Ur_WuwqvbGchYbqmQ6l1F/view
Fig. 4: https://drive.google.com/file/d/17G_FgZznGPNimwgBmGIvqvvcuRvOh80F/view
%Time values using sampling frequency period.
fsampling = 80000;
tsampling = 0:1/fsampling:5000000*Tsampling;
%Time values using sawtooth frequency period.
fsampling = 80000;
fsawtooth = 6000;
Tsawtooth = (1/fsawtooth);
tsawtooth = 0:1/fssampling:20*Tsawtooth;
%Piece of code to use FFT that I don't understand.
L0 = length(product);
NFFT0 = 2^nextpow2(L0);
Y0 = fft(product,NFFT0)/L0;
FreqDom0 = fs/2*linspace(0,1,NFFT0/2+1);
plot(FreqDom0, 2*abs(Y0(1:NFFT0/2+1)));
%Performing FFT using just abs.
IPFFT = abs(fft(product));
plot(t, IPFFT);

FFT on accelerometer data spike at 0

I have some accelerometer data in MATLAB and I was told to try FFT and try to use FFT features on classification. However, I am confused about the plot after FFT. It seems that there is a large spike only in the beginning of the plot and I am not sure what to make of it. I tried using some code from other posts such as this one: Accelerometer with FFT - strange output, and also some examples on the Mathworks website, but it did not help.
data = acc_data_x(1:300);
fs = 1/(1/12);
m = length(data);
nfft = 2^nextpow2(m);
y = fft(data,nfft)/m;
f = fs/2 * linspace(0,1,nfft/2+1);
power = abs(y);
plot(f,power(1:nfft/2+1))
t = (0 : m-1)/fs;
figure
plot(t,data);
I attached the plot of the accelerometer data in x and the result of the FFT. Is there some other step I am missing? I apologize for any ignorance since this is my first time trying FFT and working with this type of data.
Accelerometer Data in X plot:
After FFT:
Edit: I have tried Gareth's suggestion and used detrend function in MATLAB
After Detrend and FFT:
Also here is the full data with FFT (in the first example I only used up to 300 data points).
I'm now confused if this tells me any information?
You should first detrend your data. FFT inputs that have an uncorrected DC bias (ie, sits positive or negative) have a strong 0 Hz component.
Try data = detrend(data) after your first line. It'll skew some of the other things you do, but might help with showing the issue in the FFT. You can more carefully manage your data so that you can both clean it for FFT and also plot the original raw data once you feel happy with the issue being mostly fixed.
The amplitude of the first "zero-frequency" component in FFT is exactly the mean value of your data. If you fft(x-mean(x)), the first component will be zero. Other components nearby can be related with slow trend.

Convert frequency Domain data of transducer to time Domain Transfer Function

I have a few .mat files that denote the characteristics of a transducer (transmitter); I want to use the data for my Matlab code, in order to observe the response it will have on my transmit signal.
The first file contains Magnitude of the transducer as follows: Each row contains the frequency response for one angle. Each column contains the angular response at one frequency.
Similarly, I have another .mat file that contains corresponding phase (in degrees) of the transmit voltage response
The frequencies (in Hz) (corresponding to the rows) are in another matrix given by a third .mat file
and similarly, The angles (in deg) (corresponding to the columns) are in another matrix given by a 4th file.
Can someone help me translate these into a Time Domain representation for a specific angle (using the Magnitude and phase information for a specific angle) and construct a Transfer Function to be used???
Any help will be appreciated.
In order to convert responses from the frequency domain into the time domain, you need to perform an inverse Fourier transformation. In matlab, this is done with the function ifft.
Lets consider that you load the data from the first file into the variable magnitude and from the second file into variable phase. You have to first merge these two variables into a single complex valued matrix
f_response = complex(magnitude.*cosd(phase),magnitude.*sind(phase));
The f_response is the actual response of your transducer, and can be supplied to ifft in order to get the time domain response. However there is a complication, the assumed frequency order implied by ifft. Although matlab does not provide much details about this, if you check out the fft docs, you will see that there are two frequency branches returned by fft. The frequency responses must be ordered in a way that corresponds to matlab's expected order. If you take, for instance, the first example in the docs
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1000; % Length of signal
t = (0:L-1)*T; % Time vector
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
X = S + 2*randn(size(t));
Y = fft(X);
The frequency array that corresponds to each of the Fourier transform output Y entries is:
f = Fs/L*[0:(L/2-1),-L/2:-1];
In order to correctly apply the Fourier inverse transformation, you have to check if the order in your frequencies file (lets assume you loaded its contents to the variable frequencies) has to be ordered exactly like f. Note that f has a regular increasing first branch and then makes a discontinuous jump to negative frequencies. The sign of the frequencies is used to represent the propagation direction of travelling waves. If your data only holds positive frequencies, that would be excellent because you would be able to construct the negative frequency branch easily as:
[frequencies,ix] = sort(frequencies);
f_response = f_response(:,ix);
f_response = 0.5*[f_response(:,1:end-1),f_response(:,end:-1:2)];
and then invert it by doing
t_response = ifft(f_response,[],1);
Note that, as you want the response for each angle, each row must be inverse transformed. This is achieved with the third input to ifft.
If your frequencies data file has negative frequencies, then you have to order it correctly and then re-order the f_response columns accordingly. You would need to upload some sample data for me to be able to help more with that.

Difficulty plotting correct IFFT of 2D function from given data

I am trying to read in a 2D data set into a matrix, plot the matrix, as well as plot the IFFT of the matrix. The data is 128x2 data set, with frequency in the first column (A) vs amplitude in the second column (B)
Unfortunately, plotting the matrix of the data is not plotting the correct waveform. Also, the IFFT seems to be incorrect as well.
waves = csvread('10cm.txt');
A = waves(:,1);
B = abs(waves(:,2));
Matrix = [A B];
waves_transform = abs(ifft2(waves));
figure, plot(waves);
figure, plot(waves_transform)
When I read in each column of the data and plot A vs B, the waveform of the data is correct but the ifft2 of the data is incorrect. I need to properly take the inverse Fourier transform of the two dimensional data that I have read in.
waves = csvread('10cm.txt');
A = waves(:,1);
B = abs(waves(:,2));
Matrix = [A B];
waves_transform = abs(ifft2(Matrix));
figure, plot(A,B);
figure, plot(waves_transform)
waves & waves_transform
Does anyone know why reading in the data and plotting it is different than reading in each of the columns and plotting it results in different graphs? Also, can anyone help me take the IFFT of the 2D data correctly?
10cm.txt DATA FILE HERE: http://pastebin.com/0t0TwVvC
According to MATLAB documentation, if you do plot(Y) and Y is a matrix, then the plot function plots the columns of Y versus their row number. The x-axis scale ranges from 1 to the number of rows in Y.
So, in your case you have to do:
plot(waves(:,1), waves(:,2))
Might I also suggest a free and IMO better numpy package for python

Fast fourier transform for deasonalizing data in MATLAB

I'm very much a novice at signal processing techniques, but I am trying to apply the fast fourier transform to a daily time series to remove the seasonality present in the data. The example I am working with is from here:
http://www.mathworks.com/help/signal/ug/frequency-domain-linear-regression.html
While I understand how to implement the code as it is written in the example, I am having a hard time adapting it to my specific application. What I am trying to do is create a preprocessing function which deseasonalizes the training data using similar code to the above example. Then, using the same estimated coefficients from the in-sample data, deseasonalize the out-of-sample data to preserve its independence from the in-sample data. Basically, once the coefficients are estimated, I will normalize each new data point using the same coefficients. I suspect this is akin to estimating a linear trend, then removing it from the in-sample data, and then using the same linear model on unseen data to detrend it i the same manner.
Obviously, when I estimate the fourier coefficients, the vector I get out is equal to the length of the in-sample data. The out-of-sample data is comprised of much fewer observations, so directly applying them is impossible.
Is this sort of analysis possible using this technique or am I going down a dead end road? How should I approach that using the code in the example above?
What you want to do is certainly possible, you are on the right track, but you seem to misunderstand a few points in the example. First, it is shown in the example that the technique is the equivalent of linear regression in the time domain, exploiting the FFT to perform in the frequency domain an operation with the same effect. Second, the trend that is removed is not linear, it is equal to a sum of sinusoids, which is why FFT is used to identify particular frequency components in a relatively tidy way.
In your case it seems you are interested in the residuals. The initial approach is therefore to proceed as in the example as follows:
(1) Perform a rough "detrending" by removing the DC component (the mean of the time-domain data)
(2) FFT and inspect the data, choose frequency channels that contain most of the signal.
You can then use those channels to generate a trend in the time domain and subtract that from the original data to obtain the residuals. You need not proceed by using IFFT, however. Instead you can explicitly sum over the cosine and sine components. You do this in a way similar to the last step of the example, which explains how to find the amplitudes via time-domain regression, but substituting the amplitudes obtained from the FFT.
The following code shows how you can do this:
tim = (time - time0)/timestep; % <-- acquisition times for your *new* data, normalized
NFpick = [2 7 13]; % <-- channels you picked to build the detrending baseline
% Compute the trend
mu = mean(ts);
tsdft = fft(ts-mu);
Nchannels = length(ts); % <-- size of time domain data
Mpick = 2*length(NFpick);
X(:,1:2:Mpick) = cos(2*pi*(NFpick-1)'/Nchannels*tim)';
X(:,2:2:Mpick) = sin(-2*pi*(NFpick-1)'/Nchannels*tim)';
% Generate beta vector "bet" containing scaled amplitudes from the spectrum
bet = 2*tsdft(NFpick)/Nchannels;
bet = reshape([real(bet) imag(bet)].', numel(bet)*2,1)
trend = X*bet + mu;
To remove the trend just do
detrended = dat - trend;
where dat is your new data acquired at times tim. Make sure you define the time origin consistently. In addition this assumes the data is real (not complex), as in the example linked to. You'll have to examine the code to make it work for complex data.