Matlab: Operations along the first dimension of a 3D array - matlab

I have a 3D array M(d*d,m,n). For each d*d vector of M (i.e. vectors of the first dimension), I split it into d parts and take the sum of each part to form a new vector (of size d).
For example, if u is a vector along the first dimension of M, then it will be replaced by the vector v, computed by:
v = sum(reshape(u,d,d))';
For the moment I use a loop as following, but I think there should be a much faster way to do it.
N = zeros(d,m,n)
for i=1:m
for j=1:n
N(:,i,j) = sum(reshape(M(:,i,j),d,d))'; %//'
end
end
Thank you so much for any suggestions!

Try this -
N = reshape(sum(reshape(M,d,[])),d,m,n)

I may not be understanding the question correctly but is this what you are looking for?
N=squeeze(sum(reshape(M,[d,d,size(M,2),size(M,3)])))

Related

Constructing lower triangular matrix

I'm trying to construct a lower triangular matrix of a particular form, and as of right now, I'm using the following for loop:
M = sparse(eye(DIM));
for k = 1 : DIM - 1
ak = -z*(1-z)^(k-1);
M = M + sparse(diag(ak * ones(1, DIM - k), -k));
end
Basically, each diagonal from the main diagonal down is constant. I didn't include my definitions for DIM and z since they're not relevant to the construction of the matrix.
Does anyone know a faster way to do this? Maybe a vectorized version?
As Andras mentioned in a comment, you can use toeplitz to help you generate this without the need for a loop. You can use the two-input form (supplying the first column and row contents) to create a non-symmetric matrix like so:
M = toeplitz([1 -z.*(1-z).^(0:DIM-2)], [1 zeros(1, DIM-1)]);
This will be a full matrix, so you'll have to convert it to sparse if you need it in that form (although it may not save you anything memory-wise, since your matrix will be half-full).

matlab - ith element of vector is the sum of the first i elements of a different vector

I'm trying to compute a vector A for which the ith element is the sum of the first i elements of a different vector B (this vector is given).
I couldn't work out how to do this and the internet wasn't much help either.
I am very new to matlab so an easy solution would be preferred :)
Use MATLAB's cumsum function.
code example:
%generates random vector b
b = rand(5,1);
%calculates accomulative sum
a = cumsum(b);
Result:
b = [0.4319 0.9616 0.5671 0.8731 0.5730]
a = [0.4319 1.3935 1.9606 2.8338 3.4068]

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

matlab try to write the max function

I'm trying to write the max function of matlab:
B = max(A,B);
Is it correct?
for i=1:size(A,1)
for j=1:size(A,2)
if A(i,j) > B(i,j)
B(i,j) = A(i,j);
end
end
end
thank you!
if you mean that B = max(A,B) should output a matrix containing at each index (i,j) the largest of either A(i,j) or B(i,j), then yes, it is correct (if you supply it with two-dimensional matrices A and B with size(A)>=size(B) )
The standard max function however does not exactly work like that. For example it can also handle higher dimensional matrix input, you can specify along which dimension you want to calculate maximum,...

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))