Elementwise multiplication of a matrix by a vector - matlab

Suppose I have a matrix A=rand(2,14,24) and a vector x=10*ones(1,14)
I want element wise multiplication of A and x, such that B(i,j,k)=A(i,j,k)*x(j) for all j=1,2,..14.
I want to be able to do this without running a loop. What is the most efficient way to do this in matlab?

If you're multiplying A by a vector of 10's element-wise, wouldn't it be easier to simply multiply by a scalar instead?
B = A * 10;
For a general case, there is no need for repmat logic here. bsxfun can do the trick (and it's faster). :
B = bsxfun(#times, A, x);

You first use repmat to tile x the right number of times, then do element-wise multiplication.
repX = repmat(x, [size(A, 1), 1, size(A, 3)]);
B = A.*repX;

Related

How to extend a column vector to a matrix in matlab

For a vector a = [1 2 3]', I want to extend it to matrix [1:1+n;2:2+n;3:3+n]. Just like extend a number x to a sequential vector by x:x+a.
You can use bsxfun to add 0:n to each element in a
b = bsxfun(#plus, a, 0:n)
Or if you're using MATLAB R2016b, you can replace the bsxfun approach with the following thanks to automatic broadcasting of dimensions.
b = a + 0:n

Multiply two matrices in Matlab to obtain 3-dimensional matrix

I have two sparse matrices in Matlab, A and B,
and I want to compute a three-dimensional matrix C such that
C(i,j,k) = A(i,j) * B(j,k)
can I do this without a loop?
(Side question: Is there a name for this operation?)
Edit:
Seems my question has already been asked (just for full matrices):
Create a 3-dim matrix from two 2-dim matrices
For full matrices:
You can do it using bsxfun and shiftdim:
C = bsxfun(#times, A, shiftdim(B,-1))
Explanation: Let A be of size M x N and B of size N x P. Applying shiftdim(B,-1) gives a 1 x N x P array. bsxfun implicitly replicates A along the third dimension and shiftdim(B,-1) along the first to compute the desired element-wise product.
Another possibility, usually less efficient than bsxfun, is to repeat the arrays explicity along the desired dimensions, using repmat:
C = repmat(A, [1 1 size(B,2)]) .* repmat(shiftdim(B,-1), [size(A,1) 1 1])
For sparse matrices:
The result cannot be sparse, as sparse ND-arrays are not supported.. But you can do the computations with sparse A and B using linear indexing:
ind1 = repmat(1:numel(A),1,size(B,2));
ind2 = repmat(1:numel(B),size(A,1),1);
ind2 = ind2(:).';
C = NaN([size(A,1),size(A,2),size(B,2)]); %// preallocate with appropriate shape
C(:) = full(A(ind1).*B(ind2)); %// need to use full if C is to be 3D
Answer to your side question: the name for this operation is a hash join.

Comparing two sets of vectors

I've got matrices A and B
size(A) = [n x]; size(B) = [n y];
Now I need to compare euclidian distance of each column vector of A from each column vector of B. I'm using dist method right now
Q = dist([A B]); Q = Q(1:x, x:end);
But it does also lot of needless work (like calculating distances between vectors of A and B separately).
What is the best way to calculate this?
You are looking for pdist2.
% Compute the ordinary Euclidean distance
D = pdist2(A.',B.','euclidean'); % euclidean distance
You should take the transpose of the matrices since pdist2 assumes the observations are in rows, not in columns.
An alternative solution to pdist2, if you don't have the Statistics Toolbox, is to compute this manually. For example, one way to do it is:
[X, Y] = meshgrid(1:size(A, 2), 1:size(B, 2)); %// or meshgrid(1:x, 1:y)
Q = sqrt(sum((A(:, X(:)) - B(:, Y(:))) .^ 2, 1));
The indices of the columns from A and B for each value in vector Q can be obtained by computing:
[X(:), Y(:)]
where each row contains a pair of indices: the first is the column index in matrix A, and the second is the column index in matrix B.
Another solution if you don't have pdist2 and which may also be faster for very large matrices is to vectorize the following mathematical fact:
||x-y||^2 = ||x||^2 + ||y||^2 - 2*dot(x,y)
where ||a|| is the L2-norm (euclidean norm) of a.
Comments:
C=-2*A'*B (this is a x by y matrix) is the vectorization of the dot products.
||x-y||^2 is the square of the euclidean distance which you are looking for.
Is that enough or do you need the explicit code?
The reason this may be faster asymptotically is that you avoid doing the metric calculation for all x*y comparisons, since you are instead making the bottleneck a matrix multiplication (matrix multiplication is highly optimized in matlab). You are taking advantage of the fact that this is the euclidean distance and not just some unknown metric.

Multiply each column of a matrix by another matrix

I have a M x N matrix. I want to multiply each of the N columns by a M x M matrix. The following does this in a loop, but I have no idea how to vectorize it.
u=repmat(sin(2*pi*f*t),[n 1]);
W = rand(n);
answer = size(u);
for i=1:size(u,2)
answer(:,i) = W*u(:,i);
end
You simply need to multiply the two matrices:
answer = W*u;
Think about it: in every iteration of your loop you multiply a matrix by a vector. The result of that operation is a vector, which you save into your answer in column i. Matrix multiplication is a similar thing: you can understand it as multiplication of a matrix (W) by a set of vectors, which form your matrix u.
So your code is good, just remove the loop :)

Multiplying matrices in a cell array

Suppose you have an N x 1 cell array where each constituent cell is an m x m matrix. I would like the matrix product (i.e. not entry-by-entry multiplication) of these matrices, so if E_i is the ith matrix in the cell array. I would like to compute E_1 * E_2 * ... * E_N. Any ideas for a vectorized approach to this?
The most direct way is to do this (where p is your answer and cellarray is your cell array). * is the matrix multiplication while .* is the element-by-element multiplication you wish to avoid.
p = 1;
for i = 1:N,
p = p*cellarray{i};
end
I don't think this can be vectorized since the iterations aren't independent of each other. A multiplication at some step is dependent on all the multiplications prior to it.