Simple way to multiply column elements by corresponding vector elements in MATLAB? - matlab

I want to multiply every column of a M × N matrix by corresponding element of a vector of size N.
I know it's possible using a for loop. But I'm seeking a more simple way of doing it.

I think this is what you want:
mat1=randi(10,[4 5]);
vec1=randi(10,[1 5]);
result=mat1.*repmat(vec1,[size(mat1,1),1]);
rempat will replicate vec1 along the rows of mat1. Then we can do element-wise multiplication (.*) to "multiply every column of a M × N matrix by corresponding element of a vector of size N".
Edit: Just to add to the computational aspect. There is an alternative to repmat that I would like you to know. Matrix indexing can achieve the same behavior as repmat and be faster. I have adopted this technique from here.
Observe that you can write the following statement
repmat(vec1,[size(mat1,1),1]);
as
vec1([1:size(vec1,1)]'*ones(1,size(mat1,1)),:);
If you see closely, the expression boils down to vec1([1]'*[1 1 1 1]),:); which is again:
vec1([1 1 1 1]),:);
thereby achieving the same behavior as repmat and be faster. I ran three solutions 100000 times, namely,
Solution using repmat : 0.824518 seconds
Solution using indexing technique explained above : 0.734435 seconds
Solution using bsxfun provided by #LuisMendo : 0.683331 seconds
You can observe that bsxfun is slightly faster.

Although you can do it with repmat (as in #Parag's answer), it's often more efficient to use bsxfun. It also has the advantage that the code (last line) is the same for a row and for a column vector.
%// Example data
M = 4;
N = 5;
matrix = rand(M,N);
vector = rand(1,N); %// or size M,1
%// Computation
result = bsxfun(#times, matrix, vector); %// bsxfun does an "implicit" repmat

Related

Matlab create matrix by iterating the same command several times without for loop

I have a code like this:
A = [sparse(round(rand(4,4)))];
B = [sparse(round(rand(1,4)))];
C = [bsxfun(#minus,A(1,:),B); bsxfun(#minus,A(2,:),B); bsxfun(#minus,A(3,:),B); bsxfun(#minus,A(4,:),B);]
Is is possible to somehow define C this way for a large amount rows (so that I cannot physically print the command this way) WITHOUT a loop (because a loop would take an excessively long time)?
One another options:
If you prefer to keep a sparse matrix:
C = A - repmat(B,size(A,1),1); %but slower than the bsxfun version.
If you pass a matrix and a row vector to bsxfun, it will automatically apply the vector to all rows of the matrix, so just use:
C = bsxfun(#minus, A, B);
This will substract the row vector B to all rows of matrix A, no matter how many rows you have.
EDIT: If you have two matrices instead of a Matrix and a Vector, you can either use permutations or arrayfun. Take a look at:
Multiply all columns of one matrix by another matrix with bsxfun

Dividing a matrix into sub matrices with same number of rows but different number of columns

If, for example, I have a 5000x30 matrix and I want to obtain 10 sub matrices having dimensions of 5000x3, how do I code this in Matlab. I have read several post on this issue,this one here for example, but none of them keep the number of rows in the submatrices the same as the main matrix.
As I will be handling very large matrices, I would prefer a code that is faster, like using Matlab's inbuilt functions such as mat2cell or any other vectorized method, but not with loops.
As per #beaker comment, using reshape(A, 5000, 3, 10) solved my problem.
A = rand(5000,30);
b = {}; % Somewhere to store sub-matrices
for k = 1:10
b{k} = A(:, (k*3-2):(k*3));
end

Matlab - Create N sparse matrices and sum them

I have N kx1 sparse vectors and I need to multiply each of them by their transpose, creating N square matrices, which I then have to sum over. The desired output is a k by k matrix. I have tried doing this in a loop and using arrayfun, but both solutions are too slow. Perhaps one of you can come up with something faster. Below are specific details about the best solution I've come up with.
mdev_big is k by N sparse matrix, containing each of the N vectors.
fun_sigma_i = #(i) mdev_big(:,i)*mdev_big(:,i)';
sigma_i = arrayfun(fun_sigma_i,1:N,'UniformOutput',false);
sigma = sum(reshape(full([sigma_i{:}]),k,k,N),3);
The slow part of this process is making sigma_i full, but I cannot reshape it into a 3d array otherwise. I've also tried cat instead of reshape (slower), ndSparse instead of full (way slower), and making fun_sigma_i return a full matrix rather than a sparse one (slower).
Thanks for the help! ,

Correlation coefficient between rows of two matrices

I have the following code, how will I be able to simplify it using the function as it currently runs pretty slow, assume X is 10x7 and Y is 4x7 and D is a matrix stores the correlation between each pair of vectors. If the solution is to use the xcorr2 function can someone show me how it is done?
for i = 1:4
for j = 1:10
D(j,i) = corr2(X(j,:),Y(i,:));
end
end
Use pdist2 (Statistics toolbox) with 'correlation' option. It's faster than your code (even with preallocation), and requires just one line:
D = 1-pdist2(X,Y,'correlation');
Here is how I would do it:
First of all, store/process your matrix transposed. This makes for easier use of the correlation function.
Now assuming you have matrices X and Y and want to get the correlations between combinations of columns, this is easily achieved with a single loop:
Take the first column of X
use corrcoef to determine the correlation with all columns of Y at once.
As long as there is one, take the next column of X
Alternate to this, you can check whether it helps to replace corr2 in your original code with corr, xcorr or corrcoef and see which one runs fastest.
With corrcoef you can do this without a loop, and without using a toolbox:
D = corrcoef([X', Y']);
D = D(1 : size(X, 1), end - size(Y, 1) + 1 : end);
A drawback is that more coefficients are computed than necessary.
The transpose is necessary because your matrices do not follow the Matlab convention to enumerate samples with the first index and variables with the second.

nonzero elements of sparse Matrix

let's say I have a big Matrix X with a lot of zeros, so of course I make it sparse in order to save on memory and CPU. After that I do some stuff and at some point I want to have the nonzero elements. My code looks something like this:
ind = M ~= 0; % Whereby M is the sparse Matrix
This looks however rather silly to me since the structure of the sparse Matrix should allow the direct extraction of the information.
To clarify: I do not look for a solution that works, but rather would like to avoid doing the same thing twice. A sparse Matrix should perdefinition already know it's nonzero values, so there should be no need to search for it.
yours magu_
The direct way to retrieve nonzero elements from a sparse matrix, is to call nonzeros().
The direct way is obviously the fastest method, however I performed some tests against logical indexing on the sparse and its full() counterparty, and the indexing on the former is faster (results depend on the sparsity pattern and dimension of the matrix).
The sum of times over 100 iterations is:
nonzeros: 0.02657 seconds
sparse idx: 0.52946 seconds
full idx: 2.27051 seconds
The testing suite:
N = 100;
t = zeros(N,3);
for ii = 1:N
s = sprand(10000,1000,0.01);
r = full(s);
% Direct call nonzeros
tic
nonzeros(s);
t(ii,1) = toc;
% Indexing sparse
tic
full(s(s ~= 0));
t(ii,2) = toc;
% Indexing full
tic
r(r~=0);
t(ii,3) = toc;
end
sum(t)
I'm not 100% sure what you're after but maybe [r c] = find(M) suits you better?
You can get to the values of M by going M(r,c) but the best method will surely be dictated by what you intend to do with the data next.
find function is recommended by MATLAB:
[row,col] = find(X, ...) returns the row and column indices of the nonzero entries in the matrix X. This syntax is especially useful when working with sparse matrices.
While find has been proposed before, I think this is an important addition:
[r,c,v] = find(M);
Gives you not only the indices r,c, but also the non-zero values v. Using the nonzeros command seems to be a bit faster, but find is in general very useful when dealing with sparse matrices because the [r,c,v] vectors describe the complete matrix (except matrix dimension).