Efficient matrix multiplications in Matlab - matlab

What's the best way to do the following (in Matlab) if I have two matrices A and B, let'say both of size m-by-n:
C = zeros(m,m);
for t=1:n
C=C+A(:,t)*B(:,t)';
end

This is nothing more than
C = A*B';
where A and B are each m-by-n. I'm not sure that you're going to get more efficient than that unless the matrices have special properties.
One place where you might get a benefit from using bsxfun for matrix multiplication is when the dimensions are sufficiently large (probably 100-by-100 or more) and one matrix is diagonal, e.g.:
A = rand(1e2);
B = diag(rand(1,1e2));
C = bsxfun(#times,A,diag(B).');
This occurs in many matrix transforms – see the code for sqrtm for example (edit sqrtm).

Related

Calculating covariance in Matlab for large dataset and different mean

So I'm trying to implement an EM-Algorithm to train a Gaussian Class Conditional model for classifying data. I'm stuck in the M-step at the moment because I can't figure out how to calculate the covariance matrix.
The problem is I have a big data set and using a for loop to go through each point would be way to slow. I also can't use the covariance function cov(), because I need to use a mean which I calculated using this formula(mu symbol one)
Is there a way to adjust cov() to use the mean I want? Or is there another way I could do this without for loops?
Edit: Forgot to explain what the data matrix is like. Its an nx3 where each row is a data point.
It technically needs to work for the general case nxm but n is usually really big(1000 or more) while m is relatively small.
You can calculate your covariance matrix manually. Let data be the matrix containing all your variables (for example, [x y]) and mu your custom mean, proceed as follows:
n = size(data,1);
data_dem = data - (ones(n,1) * mu);
cov_mat = (data_dem.' * data_dem) ./ (n - 1);
Notice that I used the Bessel's Correction (n-1 instead of n) because the Matlab cov function uses it, unless you specify the third argument as 1:
cov_mat = cov(x,y,1);
C = cov(___,w) specifies the normalization weight for any of the
previous syntaxes. When w = 0 (default), C is normalized by the number
of observations-1. When w = 1, it is normalized by the number of
observations.

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

Multiplying two 3d matrices in MATLAB

I have two matrices A and B with dimensions [a b c] and [b a c] respectively. I would like to do the following:
C = zeros([a a c]);
for i = 1 : c
C(:,:,i) = A(:,:,i) * B(:,:,i);
end
without using any for loop. In other words, via some in-built function, or maybe some kind of vector manipulation.
Is this possible?
I think your computation should already be reasonably fast. You could however try the mtimesx submission by James Tursa on the File Exchange, that is described as:
MTIMESX is a fast general purpose matrix and scalar multiply routine that has the following features:
Supports multi-dimensional (nD, n>2) arrays directly
[...]
Can meet or beat MATLAB for speed in most cases
If you are dealing with lots of matrices of small size, you might find that vectorizing different dimensions could also speed things up:
C = zeros(a,a,c);
for j = 1:size(A,2)
C = C + bsxfun(#times, A(:,j,:), B(j,:,:));
end

Sparse diagonal matrix solver

I want to solve, in MatLab, a linear system (corresponding to a PDE system of two equations written in finite difference scheme). The action of the system matrix (corresponding to one of the diffusive terms of the PDE system) reads, symbolically (u is one of the unknown fields, n is the time step, j is the grid point):
and fully:
The above matrix has to be intended as A, where A*U^n+1 = B is the system. U contains the 'u' and the 'v' (second unknown field of the PDE system) alternatively: U = [u_1,v_1,u_2,v_2,...,u_J,v_J].
So far I have been filling this matrix using spdiags and diag in the following expensive way:
E=zeros(2*J,1);
E(1:2:2*J) = 1;
E(2:2:2*J) = 0;
Dvec=zeros(2*J,1);
for i=3:2:2*J-3
Dvec(i)=D_11((i+1)/2);
end
for i=4:2:2*J-2
Dvec(i)=D_21(i/2);
end
A = diag(Dvec)*spdiags([-E,-E,2*E,2*E,-E,-E],[-3,-2,-1,0,1,2],2*J,2*J)/(dx^2);`
and for the solution
[L,U]=lu(A);
y = L\B;
U(:) =U\y;
where B is the right hand side vector.
This is obviously unreasonably expensive because it needs to build a JxJ matrix, do a JxJ matrix multiplication, etc.
Then comes my question: is there a way to solve the system without passing MatLab a matrix, e.g., by passing the vector Dvec or alternatively directly D_11 and D_22?
This would spare me a lot of memory and processing time!
Matlab doesn't store sparse matrices as JxJ arrays but as lists of size O(J). See
http://au.mathworks.com/help/matlab/math/constructing-sparse-matrices.html
Since you are using the spdiags function to construct A, Matlab should already recognize A as sparse and you should indeed see such a list if you display A in console view.
For a tridiagonal matrix like yours, the L and U matrices should already be sparse.
So you just need to ensure that the \ operator uses the appropriate sparse algorithm according to the rules in http://au.mathworks.com/help/matlab/ref/mldivide.html. It's not clear whether the vector B will already be considered sparse, but you could recast it as a diagonal matrix which should certainly be considered sparse.

Converting 'labels' of matrices to matrices in Matlab

I'm trying to write a short Matlab code to perform a certain mathematical function. The code generates a vector H which has entries of either 1, 2 or 3 (and size dependent on other factors). (In my mind), the numbers 1, 2 and 3 correspond to three particular matrices. Once my program has calculated H, I would like it to be able to multiply together all the matrices represented by its entries. To clarify, if H = [1 2 3 2], I'd like my code to calculate A*B*C*B. What is the simplest way of doing this? I thought about creating a vector with entries that are matrices, and using a function that gives the product of the entries of the vector, but I couldn't get that to work (and don't know if it can work - I'm very new to Matlab).
Ideally I'd rather not rewrite the rest of my code - if there's a way to get this to work with what I've done so far then that'd be great. I'm looking for functionality as opposed to slick coding - it doesn't matter if it's clumsy, as long as it works.
#zuloos answer might be problematic if the sizes of matrices are not the same - especially if number of rows are different. Should work if you put the matrices in cells.
matrices = {A,B,C,D};
result = matrices{H(1)};
for i=2:numel(H)
result = result * matrices{H(i)};
end
put all your matrices in another matice then you can use values of H as a the key to choose the right matrice matices = [A, B, C, D]. you would then go throug H one by one and multiply it with the result of the last operation. you will start with a diagonal matrice of the same dimensions as the other matrices and multiply this in each round of the loop with the matrice in matrices coreesponding to the value of H
matrices = [A, B, C, D]
// d is dimension of your matrices (i guess they are square)
erg = diag(d)
for i=length(H):1
// supposed your matices are 2d
erg = matrices(H(i),:,:)*init
end
i dont know if it makes sense here to multiply each step from left (like you would do in openGL) but i thought this allows you split up the operation in steps (like its done in openGL)