Storing output from each for loop iteration in MATLAB - matlab

Say I have 3 matrix data files in a folder..
I have a function (clustering_coef_bu) which calculates the clustering coefficient of a 2D matrix (data; has the dimensions 512x512) file. The output vector of the function creates a 512x1 Matrix (Clustering Coefficient), in double format.
With the for loop below, for each matrix (data) I'm calculating the clustering coefficient. However, I am having difficulties being able to store the output clustering coefficient for each run of the for loop. It would be ideal to output the clustering coefficient of each matrix into one singular structure. I.e a cell array, which has the dimensions 512x3.
for k = 1:3
ClusteringCoefficient=clustering_coef_bu(data)
end
Any help would be great. Thanks.

Something like this would probably help you:
widthArray = 3;
ClustingeringCoefficient = zeros(size(data, 1), widthArray);
for k = 1:widthArray
ClusteringCoefficient(:, k) = clustering_coef_bu(data); % a 512x3 double matrix
end

Related

Calculate fft for each column or row in matrix

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

How to raise a matrix to a vector of powers in matlab without for loop?

I have a 2x2 matrix that I want to multiply by itself 10 times while storing the result after each multiplication. This can easily be done with a for loop but I would like to vectorize it an eliminate the for loop. My approach was to have my 2x2 matrix a and raise it to a vector b with elements 1:10. The answer should be a 2x2x10 matrix that replicates typing
a^b(1)
a^b(2)
.
.
.
a^b(10)
To clarify I'm not doing this element wise I need actual matrix multiplication, and prefer not to use a for loop. Thanks for any help you can give me.
here is the code for you. I use the cellfun to do this and I have comments after each line of the code. It can compute and store from fisrt - nth order of the self-multiplication of an arbitrary matrix m. If you have any question, feel free to ask.
function m_powerCell = power_store(m, n) %m is your input matrix, n is the highest power you want to reach
n_mat = [1:n]; %set a vector for indexing each power result in cell
n_cell = mat2cell(n_mat,1,ones(1,n)); %set a cell for each of the power
m_powerCell = cellfun(#(x)power(m, x), n_cell, 'uni', 0); %compute the power of the matrix
end
%this code will return a cell to you, each element is a matrix, you can
%read each of the matrix by m_powerCell{x}, x represents the xth order

Extracting block diagonal from matrix

I have an njxnj matrix made up of nxn matrices. I want to extract the diagonal j blocks of nxn matrices. i.e. I want to extract the diagonal (for n = 2, j = 4):
What would be the most efficient way of doing this?
To index the elements you can use blkdiag to create a corresponding mask.
%your parameters
n=2
j=4
%some example matrix
M=magic(n*j);
%create the input for blkdiag, j matrices of size n
h=repmat({true(n)},j,1)
%use blkdiag to select the elements
M(logical(blkdiag(h{:})))
For large j, this answer of #Daniel becomes slow. I would instead recommend using linear indices of block diagonal.
n=2;
j=4;
%some example matrix
M=magic(n*j);
linIndices = (0:n*((n*j)+1):n*((n*j)+1)*(j-1))+reshape((1:n)'+n*j*(0:n-1),[],1);
newM = reshape(M(linIndices),n,n,[]);

Calculating the covariance of a 1000 5x5 matrices in matlab

I have a 1000 5x5 matrices (Xm) like this:
Each $(x_ij)m$ is a point estimate drawn from a distribution. I'd like to calculate the covariance cov of each $x{ij}$, where i=1..n, and j=1..n in the direction of the red arrow.
For example the variance of $X_m$ is `var(X,0,3) which gives a 5x5 matrix of variances. Can I calculate the covariance in the same way?
Attempt at answer
So far I've done this:
for m=1:1000
Xm_new(m,:)=reshape(Xm(:,:,m)',25,1);
end
cov(Xm_new)
spy(Xm_new) gives me this unusual looking sparse matrix:
If you look at cov (edit cov in the command window) you might see why it doesn't support multi-dimensional arrays. It perform a transpose and a matrix multiplication of the input matrices: xc' * xc. Both operations don't support multi-dimensional arrays and I guess whoever wrote the function decided not to do the work to generalize it (it still might be good to contact the Mathworks however and make a feature request).
In your case, if we take the basic code from cov and make a few assumptions, we can write a covariance function M-file the supports 3-D arrays:
function x = cov3d(x)
% Based on Matlab's cov, version 5.16.4.10
[m,n,p] = size(x);
if m == 1
x = zeros(n,n,p,class(x));
else
x = bsxfun(#minus,x,sum(x,1)/m);
for i = 1:p
xi = x(:,:,i);
x(:,:,i) = xi'*xi;
end
x = x/(m-1);
end
Note that this simple code assumes that x is a series of 2-D matrices stacked up along the third dimension. And the normalization flag is 0, the default in cov. It could be exapnded to multiple dimensions like var with a bit of work. In my timings, it's over 10 times faster than a function that calls cov(x(:,:,i)) in a for loop.
Yes, I used a for loop. There may or may not be faster ways to do this, but in this case for loops are going to be faster than most schemes, especially when the size of your array is not known a priori.
The answer below also works for a rectangular matrix xi=x(:,:,i)
function xy = cov3d(x)
[m,n,p] = size(x);
if m == 1
x = zeros(n,n,p,class(x));
else
xc = bsxfun(#minus,x,sum(x,1)/m);
for i = 1:p
xci = xc(:,:,i);
xy(:,:,i) = xci'*xci;
end
xy = xy/(m-1);
end
My answer is very similar to horchler, however horchler's code does not work with rectangular matrices xi (whose dimensions are different from xi'*xi dimensions).

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.