I am trying to compute the inverse FFT of a fft-output manually. I am using the following script, which first uses fft to compute the FFT of a data set. I then try to find the inverse FFT manually, but it doesn't resemble the result I get from ifft.
Can you spot my error? I am merely using the standard inverse formula of the FFT presented here, https://en.wikipedia.org/wiki/Fast_Fourier_transform#Definition_and_speed
data = [
-0.0005
-0.0004
-0.0003
-0.0002
-0.0001
-0.0000
0.0001
0.0001
0.0001
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0003
0.0004
0.0005
0.0006
0.0007
0.0009
0.0010
0.0011
0.0011
0.0012
0.0011
0.0011
0.0011
0.0010
0.0011];
delta = 0.0125;
fs = 1/delta;
x = (0:1:length(data)-1)/fs;
X=fft(data);
%find fft
N=length(data);
ws = 2*pi/N;
wnorm = -pi:ws:pi;
wnorm = wnorm(1:length(x));
w = wnorm*fs;
figure(2)
plot(w/(2*pi),abs(fftshift(X)))
%find inverse fft manually
for m=1:length(X)
for k=1:length(data)
X_real(m) = X(k)*exp(i*k*ws*(m-1));
end
end
figure(3)
plot(1:length(data), abs(X_real), 1:length(data), ifft(X))
Please, change your for loop like below.
for m=1:length(X)
for k=1:length(data)
temp(k) = X(k)*exp(i*(m-1)*ws*(k-1));
end
X_real(m)=(1/N)*sum(temp);
end
figure(3)
plot(1:length(data), real(X_real))
You can find the equation of ifft in matlab, here.
You missed two things.
One thing is normalization, another is summing.
I am trying to do an inverse FFT in Matlab, but I can't seem to get the inverse working correctly. Here is my code:
data = [-0.0005
-0.0004
-0.0003
-0.0002
-0.0001
-0.0000
0.0001
0.0001
0.0001
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0002
0.0003
0.0004
0.0005
0.0006
0.0007
0.0009
0.0010
0.0011
0.0011
0.0012
0.0011
0.0011
0.0011
0.0010 ];
%plot data
figure(1)
plot(data)
%FFT
N = 100;
X = fft(data, N);
F = [-N/2:N/2-1]/N;
F = F/0.0125;
X = fftshift(X);
figure(2)
plot(F, abs( X ) )
%inverse FFT
y = ifft(X);
figure(3)
plot(F,y)
Figure 1 and 3 should be identical, but are not in any way. I made sure not to take ifft of the absolute value of fft, so it's not clear to me what is wrong.
Since you shifted the spectrum using fftshift, you have to "unshift" the spectrum prior to taking the inverse Fourier transform
y = ifft(fftshift(X));
I am trying to classify vehicles in matlab. I need to reduce the dimensionality of the features to eliminate redundancy. Am using pca for this. Unfortunately, the the pca function is not returning the expected results. The output seems truncated and i don't understand why.
summary of this is as follows:
Components_matrix = [Areas_vector MajorAxisLengths_vector MinorAxisLengths_vector Perimeters_vector...
EquivDiameters_vector Extents_vector Orientations_vector Soliditys_vector]
The output is:
Components_matrix =
1.0e+03 *
1.4000 0.1042 0.0220 0.3352 0.0422 0.0003 0.0222 0.0006
2.7690 0.0998 0.0437 0.3973 0.0594 0.0005 0.0234 0.0007
1.7560 0.0853 0.0317 0.2610 0.0473 0.0005 0.0236 0.0008
1.0870 0.0920 0.0258 0.3939 0.0372 0.0003 0.0157 0.0005
0.7270 0.0583 0.0233 0.2451 0.0304 0.0004 0.0093 0.0006
1.2380 0.0624 0.0317 0.2436 0.0397 0.0004 0.0106 0.0007
Then i used the pca function as follows:
[COEFF, SCORE, LATENT] = pca(Components_matrix)
The displayed results are:
COEFF =
0.9984 -0.0533 -0.0057 -0.0177 0.0045
0.0162 0.1810 0.8788 0.0695 -0.3537
0.0099 -0.0218 -0.2809 0.8034 -0.2036
0.0514 0.9817 -0.1739 -0.0016 0.0468
0.0138 -0.0018 0.0616 0.4276 -0.3585
0.0001 -0.0008 -0.0025 0.0215 0.0210
0.0069 0.0158 0.3388 0.4070 0.8380
0.0001 -0.0011 0.0022 0.0198 0.0016
SCORE =
1.0e+03 *
-0.0946 0.0312 0.0184 -0.0014 -0.0009
1.2758 0.0179 -0.0086 -0.0008 0.0001
0.2569 -0.0642 0.0107 0.0016 0.0012
-0.4043 0.1031 -0.0043 0.0015 0.0003
-0.7721 -0.0299 -0.0079 -0.0017 0.0012
-0.2617 -0.0580 -0.0083 0.0008 -0.0020
LATENT =
1.0e+05 *
5.0614
0.0406
0.0014
0.0000
0.0000
I expected for instance COEFF and LATENT to be 8x8 and 8x1 matrices respectively. But that is not what i get. Why is this so and how can the situation be rectified. Kindly help.
Your usage of pca() and Matlab's output are correct. The issue is that you have more dimensions than you have samples, i.e., you only have 6 vehicles but 8 variables. If you have N samples and N or greater variables, the number of principal components there are is only N-1, because further components would not be unique. So COEFF are the eigenvectors of the covariance matrix of the input, and SCORE(:,1) is the first principal component, SCORE(:,2) is the second, etc., of which there are only N-1=5 in total, and LATENT are the eigenvalues of the covariance matrix, or the amount of variance explained by each successive principal component, of which there are, again, only N-1=5.
There is a more detailed discussion of this here.
I have sampled data in the interval [0,1] in an Array transitions=zeros(101,101) which I want to plot as a 3D-histogram. transitions is filled with data similar to the example data provided at the end of this thread.
The first columns refers to the first observed variable X, the second column to the second variable Y and the third column is the normalized frequency. I.e. for the first row: the observed normalized frequency of the variable pair (0,0) is 0.9459. The sum of the normalized frequencies for (0,Y)thus is 1.
I tried to make (sort of) a 3D histogram with the following code:
x_c = (transitions(:,1) * 100)+1;
y = (transitions(:,2) * 100)+1;
z = transitions(:,4);
%A = zeros(10,10);
A = zeros(max(x_c),max(y));
for i = 1:length(x_c)
try
if(z(i)>0)
A(int32(x_c(i)), int32(y(i))) = abs(log(z(i)));
else
% deal with exceptions regarding log(0)
A(int32(x_c(i)), int32(y(i))) = 0;
end
catch
disp('');
end
end
bar3(A);
However, since it is sampled data in a discrete space A the output looks like the plot below. This is somehow misleading as there are 'gaps' in the plot (z-value = 0 for coordinates where I have no sampled data). I rather would like to have the sampled data being assigned to their corresponding plots, thus resulting in a 'real' 3d histogram.
By the way, as a result of my 'hack' of creating A also the x-,y- and z-scale is not correct. The 3D histogram's axes (all three) should be in the interval of [0,1].
ans =
0 0 0.9459
0 0.0500 0.0256
0 0.1000 0.0098
0 0.1100 0.0004
0 0.1500 0.0055
0 0.1600 0.0002
0 0.2000 0.0034
0 0.2100 0.0001
0 0.2500 0.0024
0 0.2600 0.0001
0 0.3000 0.0018
0 0.3200 0.0000
0 0.3700 0.0000
0 0.4000 0.0010
0 0.4200 0.0000
0 0.4500 0.0007
0 0.5000 0.0007
0 0.5300 0.0000
0 0.5500 0.0005
0 0.6000 0.0005
0 0.6300 0.0000
0 0.7000 0.0002
0 0.7400 0
0 0.7500 0.0003
0 0.7900 0.0000
0 0.8000 0.0002
0 0.8400 0.0000
0 0.8500 0.0002
0 0.8900 0.0000
0 0.9000 0.0002
0 0.9500 0.0001
0 1.0000 0.0001
0.0500 0 0.0235
0.0500 0.0500 0.0086
0.0500 0.1000 0.0045
. . .
. . .
. . .
. . .
. . .
0.9500 0.9000 0.0035
0.9500 0.9500 0.0066
0.9500 1.0000 0.0180
1.0000 0 0.0001
1.0000 0.0500 0.0001
1.0000 0.1000 0.0001
1.0000 0.1100 0.0000
1.0000 0.1500 0.0001
1.0000 0.1600 0.0000
1.0000 0.2000 0.0001
1.0000 0.2100 0.0000
1.0000 0.2500 0.0001
1.0000 0.2600 0.0000
1.0000 0.3000 0.0001
1.0000 0.3200 0.0000
1.0000 0.3700 0.0000
1.0000 0.4000 0.0002
1.0000 0.4200 0
1.0000 0.4500 0.0002
1.0000 0.5000 0.0003
1.0000 0.5300 0.0000
1.0000 0.5500 0.0004
1.0000 0.6000 0.0004
1.0000 0.6300 0.0000
1.0000 0.7000 0.0007
1.0000 0.7400 0.0000
1.0000 0.7500 0.0010
1.0000 0.7900 0.0000
1.0000 0.8000 0.0015
1.0000 0.8400 0.0001
1.0000 0.8500 0.0024
1.0000 0.8900 0.0002
1.0000 0.9000 0.0042
1.0000 0.9500 0.0111
1.0000 1.0000 0.3998
I found a solution by working on the non-aggregated data. In particular each row of the data set transitions contains one observation of Xand Y. I used the code below to produce a normalized 3D histogram (and a 2D map) as folllows:
function createHistogram(transitions)
uniqueValues = unique(transitions(:,1));
biases = cell(numel(uniqueValues),1);
for i = 1:numel(uniqueValues)
start = min(find(transitions(:,1) == uniqueValues(i)));
stop = max(find(transitions(:,1) == uniqueValues(i)));
biases(i) = mat2cell(transitions(start:stop,2));
end
combinedBiases = padcat(biases{1},biases{2},biases{3},biases{4},...
biases{5},biases{6},biases{7},biases{8},biases{9},biases{10},...
biases{11},biases{12},biases{13},biases{14},biases{15},biases{16},...
biases{17},biases{18},biases{19});
bins = 0:0.1:1;
[f, x] = hist(combinedBiases, bins);
%
% normalize
%
for i = 1:numel(f(1,:))
for j = 1:numel(f(:,i))
f(j,i) = f(j,i)/numel(biases{i});
end
end
bHandle = bar3(x, f);
ylim([-0.04,1.04])
for k = 1:length(bHandle)
zdata = get(bHandle(k),'ZData');
set(bHandle(k),'CData',zdata, 'FaceColor','interp');
end
colormap('autumn');
hcol = colorbar();
axis('square');
cpos=get(hcol,'Position');
cpos(4)=cpos(4)/3; % Halve the thickness
cpos(2)=0.4; % Move it down outside the plot#
cpos(1)=0.82;
set(hcol, 'Position',cpos);
xlabel('Enrollment biases');
ylabel('Aging biases');
zlabel('Bias transition probability');
title(strcat('Probability mass function of bias transitions (', device,')'));
set(gca,'XTick',0:2:20);
set(gca,'XTickLabel',0:0.1:1);
print('-dpng','-r600',strcat('tau_PMF3D_enrollment-ageing-', device));
view(2);
cpos(1)=0.84;
set(hcol, 'Position',cpos);
print('-dpng','-r600',strcat('tau_PMF2D_enrollment-ageing-', device));
end
From the comment on the question it appears you have the values you want to represent each bin count. If so an alternative solution is to plot using hist3 with "junk" data using correct x and y scales and then update the zdata of the surface object created with your bin data (modified to be in the correct format).
This modification to the bin data is fairly simple and consists of reshaping into a matrix then replicating and padding all the elements, the method is included in the code below.
Based on the ans variable at the end of the question, assuming
ans(:,1) gives x values
ans(:,2) gives y values
ans(:,3) gives the normalised bin counts
code
%// Inputs
zdata=ans(:,3); %// zdata=rand(21*21,1); % for testing
xvalues = 0:0.05:1;
yvalues = 0:0.05:1;
%// plot with junk data, [0,0] in this case
nx = numel(xvalues); ny = numel(yvalues);
bincenters = { xvalues , yvalues };
hist3([0,0],bincenters);
Hsurface = get(gca,'children');
%// apply bin count format
pad = [0 0 0 0 0;0 1 1 0 0;0 1 1 0 0;0 0 0 0 0;0 0 0 0 0]; %// padding for each point
ztrans=kron(reshape(zdata,[nx,ny]),pad); %// apply padding to each point
%// update plot
set(Hsurface,'ZData',ztrans)
%// to set colour based on bar height
colormap('autumn');
set(Hsurface,'CData',ztrans,'FaceColor','interp')
output
I am a beginner in MATLAB, and I need to represent e(-t2).
I know that, for example, to represent ex I use exp(x), and I have tried the following
1) tp=t^2; / tp=t*t;
x=exp(-tp);
2) x=exp(-t^2);
3) x=exp(-(t*t));
4) x=exp(-t)*exp(-t);
What is the correct way to do it?
If t is a matrix, you need to use the element-wise multiplication or exponentiation. Note the dot.
x = exp( -t.^2 )
or
x = exp( -t.*t )
All the 3 first ways are identical. You have make sure that if t is a matrix you add . before using multiplication or the power.
for matrix:
t= [1 2 3;2 3 4;3 4 5];
tp=t.*t;
x=exp(-(t.^2));
y=exp(-(t.*t));
z=exp(-(tp));
gives the results:
x =
0.3679 0.0183 0.0001
0.0183 0.0001 0.0000
0.0001 0.0000 0.0000
y =
0.3679 0.0183 0.0001
0.0183 0.0001 0.0000
0.0001 0.0000 0.0000
z=
0.3679 0.0183 0.0001
0.0183 0.0001 0.0000
0.0001 0.0000 0.0000
And using a scalar:
p=3;
pp=p^2;
x=exp(-(p^2));
y=exp(-(p*p));
z=exp(-pp);
gives the results:
x =
1.2341e-004
y =
1.2341e-004
z =
1.2341e-004