Calculate fft for each column or row in matrix - matlab

I have a problem with calculating fft for a signal which is stored in a matrix using matlab. I am trying to calculate fft for each column.
I am trying to do this like this:
for k = 1: ncol
y1(k)= fft(y(:,k));
end
where y is my matrix and and ncol is number of columns in matrix but I'm still getting the following error:
In an assignment A(:) = B, the number of elements in A and B must be the same.

Just do this
y1 = fft(y);
It computes each column separately and it does it much faster than using a for loop.
In response to your original question, you would have to do it like this:
for k = 1: ncol
y1(:,k)= fft(y(:,k));
end
You were trying to put an entire column into a single index which is why you were getting that error message. You need to allocate more room so that the entire column can be stored.

y1 should also be in matrix form. fft of a signal is an array of coefficients

Related

How to sum 3d Matrix row by interval in Matlab?

I have a 36x256x2232 3d matrix in Matlab created by M = ones(36,256,2232) and I want to reduce the size of the matrix by sum rows by interval 3. The result matrix should be 12x256x2232 and each cell should have the value 3.
I tried using reshape and sum function but I get 1x256x2232 matrix.
How can I do this without using the for-loop ?
This should do it:
M = ones(36,256,2232)
reduced = reshape(sum(reshape(M, 3,[], 256,2232), 1),[], 256, 2232);
reshape makes a 4d matrix with the given intervals
sum reduce it
second reshape transform it to 3d again
you can use also squeeze, which removes singleton dimensions:
reduced = squeeze(sum(reshape(M, 3,[], 256,2232), 1));
You can use the new-ish splitapply function (which is similar to accumarray but can handle data with multiple dimensions). This approach works even if the number of rows is not a multiple of the group size:
M = ones(4,5,2); % example data
n = 3; % group size
result = splitapply(#(x)sum(x,1), M, floor((0:size(M,1)-1).'/n)+1);

storing and accessing with matrices of more than two dimensions

I am using ode45 to solve a system with 4 variables. For each time I execute the code:
[t y] = ode45(#func, tspan, y0);
t will be a one dimensional matrix, while y will be a 2 dimensional matrix, with 4 columns, each of which is the solution for one of the variables in question.
I want to run multiple trials of this, and keep them in a 3D matrix my_y_results and my_t_results. I want to be able to, for example, plot the final value of a certain variable for a particular initial condition, as I change the initial condition. How would I do this?
So, on each iteration of the loop below, I want to place the new values in a new matrix.
for i = 1:1:10
y0 = **some value**
[t_temp, y_temp] = ode45(#func, tspan, y0);
my_t_results = **something**
my_y_results = *something* //your code here
end
Also, how would I access the different values after setting them? For example, to get the last value of the variable y(1) for each of the 10 trials, what code would I use?
Higher dimensions can be accessed similar to the usual row and column dimensions. Let's assume t is Nx1 and y is Nx4, and that we are running M trials (note that each trial will have to have the same number of points, N, in order to store the data in a 3-dimensional array).
Your array my_t_results doesn't have to be 3-dimensional and can simply be NxM, where each column is the time vector for a different trial.
The array my_y_results would be Nx4xM and can be defined in MATLAB with:
my_y_results = zeros(N,4,M);
At the end of each i'th trial you would store the results like this:
my_y_results(:,:,i) = y;
And of course accessing the data is similar:
y_i = my_y_results(:,:,i);

MatLab - Obtain histogram by column of matrix

Simply put I have an N x M matrix and I would like to obtain a 256 bin histogram for each column of the matrix. I know how to do this with a for loop, but I need to do it in matrix notation to save valuable computation time.
Also, I would like to use imhist rather than hist.
For loop method:
data = randint(100,100,10);
for n = 1:100
k(:,n) = imhist(data(n,:));
end
hist operates on the column of the input matrix by default. So
>> k = hist( data, 0:255 );
should do the trick for you.

How to select values with the higher occurences from several matrices having the same size in matlab?

I would like to have a program that makes the following actions:
Read several matrices having the same size (1126x1440 double)
Select the most occuring value in each cell (same i,j of the matrices)
write this value in an output matrix having the same size 1126x1440 in the corresponding i,j position, so that this output matrix will have in each cell the most occurent value from the same position of all the input matrices.
Building on #angainor 's answer, I think there is a simpler method using the mode function.
nmatrices - number of matrices
n, m - dimensions of a single matrix
maxval - maximum value of an entry (99)
First organize data into a 3-D matrix with dimensions [n X m X nmatrices]. As an example, we can just generate the following random data in a 3-D form:
CC = round(rand(n, m, nmatrices)*maxval);
and then the computation of the most frequent values is one line:
B = mode(CC,3); %compute the mode along the 3rd dimension
Here is the code you need. I have introduced a number of constants:
nmatrices - number of matrices
n, m - dimensions of a single matrix
maxval - maximum value of an entry (99)
I first generate example matrices with rand. Matrices are changed to vectors and concatenated in the CC matrix. Hence, the dimensions of CC are [m*n, nmatrices]. Every row of CC holds individual (i,j) values for all matrices - those you want to analyze.
CC = [];
% concatenate all matrices into CC
for i=1:nmatrices
% generate some example matrices
% A = round(rand(m, n)*maxval);
A = eval(['neurone' num2str(i)]);
% flatten matrix to a vector, concatenate vectors
CC = [CC A(:)];
end
Now we do the real work. I have to transpose CC, because matlab works on column-based matrices, so I want to analyze individual columns of CC, not rows. Next, using histc I find the most frequently occuring values in every column of CC, i.e. in (i,j) entries of all matrices. histc counts the values that fall into given bins (in your case - 1:maxval) in every column of CC.
% CC is of dimension [nmatrices, m*n]
% transpose it for better histc and sort performance
CC = CC';
% count values from 1 to maxval in every column of CC
counts = histc(CC, 1:maxval);
counts have dimensions [maxval, m*n] - for every (i,j) of your original matrices you know the number of times a given value from 1:maxval is represented. The last thing to do now is to sort the counts and find out, which is the most frequently occuring one. I do not need the sorted counts, I need the permutation that will tell me, which entry from counts has the highest value. That is exactly what you want to find out.
% sort the counts. Last row of the permutation will tell us,
% which entry is most frequently found in columns of CC
[~,perm] = sort(counts);
% the result is a reshaped last row of the permutation
B = reshape(perm(end,:)', m, n);
B is what you want.

How do I create a simliarity matrix in MATLAB?

I am working towards comparing multiple images. I have these image data as column vectors of a matrix called "images." I want to assess the similarity of images by first computing their Eucledian distance. I then want to create a matrix over which I can execute multiple random walks. Right now, my code is as follows:
% clear
% clc
% close all
%
% load tea.mat;
images = Input.X;
M = zeros(size(images, 2), size (images, 2));
for i = 1:size(images, 2)
for j = 1:size(images, 2)
normImageTemp = sqrt((sum((images(:, i) - images(:, j))./256).^2));
%Need to accurately select the value of gamma_i
gamma_i = 1/10;
M(i, j) = exp(-gamma_i.*normImageTemp);
end
end
My matrix M however, ends up having a value of 1 along its main diagonal and zeros elsewhere. I'm expecting "large" values for the first few elements of each row and "small" values for elements with column index > 4. Could someone please explain what is wrong? Any advice is appreciated.
Since you're trying to compute a Euclidean distance, it looks like you have an error in where your parentheses are placed when you compute normImageTemp. You have this:
normImageTemp = sqrt((sum((...)./256).^2));
%# ^--- Note that this parenthesis...
But you actually want to do this:
normImageTemp = sqrt(sum(((...)./256).^2));
%# ^--- ...should be here
In other words, you need to perform the element-wise squaring, then the summation, then the square root. What you are doing now is summing elements first, then squaring and taking the square root of the summation, which essentially cancel each other out (or are actually the equivalent of just taking the absolute value).
Incidentally, you can actually use the function NORM to perform this operation for you, like so:
normImageTemp = norm((images(:, i) - images(:, j))./256);
The results you're getting seem reasonable. Recall the behavior of the exp(-x). When x is zero, exp(-x) is 1. When x is large exp(-x) is zero.
Perhaps if you make M(i,j) = normImageTemp; you'd see what you expect to see.
Consider this solution:
I = Input.X;
D = squareform( pdist(I') ); %'# euclidean distance between columns of I
M = exp(-(1/10) * D); %# similarity matrix between columns of I
PDIST and SQUAREFORM are functions from the Statistics Toolbox.
Otherwise consider this equivalent vectorized code (using only built-in functions):
%# we know that: ||u-v||^2 = ||u||^2 + ||v||^2 - 2*u.v
X = sum(I.^2,1);
D = real( sqrt(bsxfun(#plus,X,X')-2*(I'*I)) );
M = exp(-(1/10) * D);
As was explained in the other answers, D is the distance matrix, while exp(-D) is the similarity matrix (which is why you get ones on the diagonal)
there is an already implemented function pdist, if you have a matrix A, you can directly do
Sim= squareform(pdist(A))