Multiplication of each slice of a 3D matrix with 2D matrix [duplicate] - matlab

This question already has answers here:
Multiply a 3D matrix with a 2D matrix
(10 answers)
Closed 5 years ago.
I try to use svd in my work which will return the vector as below.
A=rand(10,5);
b=rand(10,5,100);
[U, S , V]=svd(A);
What I'm trying to do is to multiply each slice of b with U. With one specific slice, this operation is valid:
c=U'*b(:,:,1);
However when I try to use a vectorized method as below, it return array dimensions mismatch error.
Utran=U.';
c = cellfun(#(x) x.*b,num2cell(Utran,[1 2]),'UniformOutput',false);
I could probably use loop for the first method, but it's not efficient if I have a large matrix. Any idea what's my mistake here?

The following is a vectorized solution.
Not sure if it's faster than using loops; and even if it is, note that it uses more memorry for intermediate computations:
result = permute(sum(permute(conj(U), [1 3 4 2]).*b), [4 2 3 1]);

Related

How to speed up column wise operation in MATLAB using bsxfun? [duplicate]

This question already has answers here:
Fast Algorithms for Finding Pairwise Euclidean Distance (Distance Matrix)
(3 answers)
Closed 5 years ago.
I am trying to calculate the Square Euclidean Distance between each column from two matrices and store in matrix D.
im_patches is 81*60840 double
codebook is 81*456 double
SquareEuclidean = #(x, y) x'*x+y'*y-2*x'*y;
% Get N*K distance matrix D between the N patches extracted
% from the image (im patches) and the K prototypes in the codebook
D=zeros(size(im_patches,2),size(codebook, 2));
for i=1:size(im_patches,2)
for j=1:size(codebook, 2)
D(i,j)=SquareEuclidean(im_patches(:,i),codebook(:,j));
end
end
However, this is very inefficient that cost more than 10 minutes in my laptop.
I am wondering is there a better way of using bsxfun. So I tried:
D2 = bsxfun(#(x,y) x'.*x+y'.*y-2.*x'.*y,im_patches,codebook);
which gives an error:
Error using bsxfun: Non-singleton dimensions of the two input arrays must match each other.
I think bsxfun or arrayfun would be a nice way of dealing such problem. But don't know the correct way of doing this.
Thank you in advance.
Your loop can be reduced to:
bsxfun(#plus,sum(im_patches.'.^2,2),sum(codebook.^2)-2*im_patches.'*codebook)
In MATLAB r2016b there is no need to bsxfun:
sum(im_patches.'.^2,2)+sum(codebook.^2)-2*im_patches.'*codebook

How to get Matrix from row-major vector in Matlab? [duplicate]

This question already has answers here:
Reshaping of Array in MATLAB
(3 answers)
Closed 7 years ago.
I have the following matrix:
50,60,55,67,70
62,65,70,70,81
72,66,77,80,69
I turn now the matrix into a vector but in row-major. This gives the following vector:
50,60,55,67,70,62,65,70,70,81,72,66,77,80,69
Now I would like to turn this vector into the same matrix as above. The problem is that reshape(matrix,[3,5]) does not work because Matlab operates column-major.
How can this be done efficiently (for large matrices)?
To solve this, use
reshape(matrix,[5,3]).'
First using reshape with row and column dimension swapped, you get a matrix with the right order but transposed, then using transpose you get the right output.
Having the control systems toolbox, you could also use vec2mat

Matrix indexing using vectors in Matlab [duplicate]

This question already has an answer here:
MATLAB one liner for batch assignment in 2D matrix?
(1 answer)
Closed 7 years ago.
So I'm a beginner in MATLAB so this question might be trivial.
Suppose x=[1 2 3 4 5] and y=[3 4 2 5 1] and img = zeros(5,5). I want to set img(1,3),(2,4),(3,2),(4,5),(5,1) to 1. How do I do this? When I simply try img(x,y), it takes all the combinations of indices like (1,3),(1,4),(1,2) etc. which is not what I want.
As you have experienced, MATLABs indexing doesn't work that way. To get a feeling for the ways indexing works in MATLAB, please have a look at this nice article from Mathworks.
Now how to tackle your problem: The solution is to use linear indexing. You can always index a 2-dimensional matrix either by (i,j) or with a linear index k which increases column-wise. You can convert between matrix-indexes and linear indexes using the sub2ind function. To get the correct indexes for your questions, use
img = zeros(5,5)
x = [1 2 3 4 5];
y = [3 4 2 5 1];
ind = sub2ind(size(img),x,y);
img(ind) = 1;

Calculating the norm of each row in a matrix [duplicate]

This question already has answers here:
applying norm function to rows of matrix - Matlab [duplicate]
(3 answers)
Closed 9 years ago.
I have a Nx3 matrix (A) the columns are X,Y,Z respectively. I want to calculate the norm that is sqrt(X^2+Y^2+Z^2) for each row. I did a for loop for that:
for i = 1:length(A)
Result(i) = norm(A(i,:))
end
is there any other way to do it avoiding for loop?
Thanks
You can do it like this:
sqrt(sum(A.^2, 2))
Your method returns a 1x3 where this returns a 3x1. So if you want you can transpose it but I doubt you really need to.

Quick question about MATLAB elementwise division [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
How do I divide the rows of a matrix by different values in MATLAB (array division)
I have a matrix A (size MxN) in Matlab and a Vector b with M rows and now I want to divide all elemtens in the i-th row of A by the i-th entry in b like a(i,:)/b(i) but I really don't want to use this sort since I than use a for-loop and I definitly need a FAST solution!
Could anybody help out? Thanks!
Edit: Somehow I just came up with it after posting... My solution is bsxfun(#rdivide, [1 1; 2 2; 3 3], [2 2 6]'), do you think that's a good and fast one?
You want to use bsxfunc :
bsxfun(#rdivide,A,B)
http://www.mathworks.com/help/techdoc/ref/bsxfun.html