Dot product of matrix and vector without a loop - matlab

Suppose we have a Mx3 matrix and a 1x3 vector. How can I compute the dot product of each column and the vector without using a loop?

If I understood your question correctly,
M = rand(8,3); V = 1:3;
P = sum( M .* V, 2 ); % or in older MATLAB versions: sum( bsxfun(#times, M, V), 2 );
If you're dealing with complex numbers, you might have to conjugate one of the inputs.

Using Dev-iL’s example data:
M = rand(8,3);
V = 1:3;
the dot product of each row of M with V is simply the matrix product with a transposed V:
M * V'
Note that ' returns the conjugate transpose, which you need for the dot product.
Computing the dot product with the columns of M, as stated in the question, is nonsensical because the dimensions don’t match, hence I presume you meant rows (as the other answers did).

Related

How can I generalize this function to `n` terms?

I'd like to create a function that adds several gaussian terms of various width over some specified region:
G(a,b,x) = a_1 exp(- b_1 x^2) + a_2 exp(- b_2 x^2) + ... a_N exp(-b_N x^2)
I'd like this function to output an array of length x, summing over the terms of parameters a,b provided, something like:
x = linspace(-2,2,1000);
N_gauss = #(a,b) a(:).*exp(-b(:)*x.^2);
This example actually works if a,b have only a single value, but when they become vectors it no longer works (I suppose Matlab doesn't know what should be added, multiplied or remain a vector). Is this even possible?
You can do this purely by matrix multiplication. Let's tackle the problem slowly and work our way up. You first need to form products of the elements of the vector b and scalar values stored in x. First create a 2D matrix of values where each row corresponds to the product-wise values between an element in b and an element in x. The element (i,j) in this matrix corresponds to the product of the ith element in x with the jth element in b.
You can achieve this by using the outer product. Make x a column vector and b a row vector, then perform the multiplication. Also, make sure you square each of the x terms as seen in your equation.
term1 = (x(:).^2)*b(:).';
Now you can apply the exponential operator and ensure you place a negative in the exponent so you can build the right side of each term (i.e. exp(- b_i x^2)):
term2 = exp(-term1);
The last thing you need to do is multiply each of the values in the 2D matrix with the right coefficient from the a vector. You can do this by enforcing that a be a column vector and performing matrix-vector multiplication.
out = term2*a(:);
Matrix-vector multiplication is the dot product between the column vector a with each row in the 2D matrix we created before. This exactly corresponds to the summation of your equation for each value in x. As such, this achieves the Gaussian summation for each value in x and places this into a n x 1 vector where n is the total number of elements in x. Putting this all together gives us:
out = exp(-(x(:).^2)*b(:).')*a(:);
To finally abstract this into an anonymous function, do:
N_gauss = #(a,b,x) exp(-(x(:).^2)*b(:).')*a(:);
This function takes in the vectors a, b and x as per your problem.

Matrix representation for point-wise operation

I have the following expression to implement in MATLAB:
(A*u).*(B*v)
Where A and B are matrices N x N and u and v column vectors N x 1.
For some reason, not really important at the moment, I want to represent it in the form C(A,u,b)*v for some matrix N x N originated by A,u and B.
How can I do that?
I tried to do something like using the following matrix
C = spdiags( A*u,0,N,N)*B
But it seems that the result is not really what I need.
How about
C1 = bsxfun(#times, A*u,B) * v

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.

MATLAB - resizing matrix using matrix multiplication and not the RESIZE command

For a specific problem, I need to design the resizing of a matrix process using multiplication of matrices alone.
Given a matrix of A of dimensions (a*b,1) where a and b are integers, I need to find a way to resize A to dimensions (a,b) like this:
M*A*N = resize(A,a,b)
where dim(M) = (a,a*b) and dim(N) = (1,b). It doesn't have to be two matrices but I don't think it is possible any other way.
If you can't use reshape or vec2mat, you need to do your manipulation for each element of A separately.
There is no such M and N that you are searching for.
Suppose:
resh_A = M*A*N;
Let's study one row of this equation. Assume one row of M*A :
temp_i = M(i, :) * A;
Since M(i, :) is 1 x a*b and A is a*b x 1; temp_i whould be a 1 x 1 matrix.
Now temp_i * N should result in the ith row of your result (or resh_A).
Thus resh_A will look like:
(note N is 1 x b)
temp_1 * N % row1
temp_2 * N % row2
temp_3 * N % row3
...
which is not a general matrix (it's a matrix with rank 1).

Vector to Matrix syntax in MATLAB

Is there a way to combine 2 vectors in MATLAB such that:
mat = zeros(length(C),length(S));
for j=1:length(C)
mat(j,:)=C(j)*S;
end
Using normal MATLAB syntax similar to:
mat = C * S(1:length(S))
This gives a "Inner matrix dimensions must agree error" because it's trying to do normal matrix operations. This is not a standard Linear Algebra operation so I'm not sure how to correctly express it in MATLAB, but it seems like it should be possible without requiring a loop, which is excessively slow in MATLAB.
From your description, it sounds like a simple matrix operation. You just have to make sure you have the right dimensions for C and S. C should be a column vector (length(C)-by-1) and S should be a row vector (1-by-length(S)). Assuming they are the right dimensions, just do the following:
mat = C*S;
If you're not sure of their dimensions, this should work:
mat = (C(:))*(S(:)');
EDIT: Actually, I went a little crazy with the parentheses. Some of them are unnecessary, since there are no order-of-operation concerns. Here's a cleaner version:
mat = C(:)*S(:)';
EXPLANATION:
The matrix multiplication operator in MATLAB will produce either an inner product (resulting in a scalar value) or an outer product (resulting in a matrix) depending on the dimensions of the vectors it is applied to.
The last equation above produces an outer product because of the use of the colon operator to reshape the dimensions of the vector arguments. The syntax C(:) reshapes the contents of C into a single column vector. The syntax S(:)' reshapes the contents of S into a column vector, then transposes it into a row vector. When multiplied, this results in a matrix of size (length(C)-by-length(S)).
Note: This use of the colon operator is applicable to vectors and matrices of any dimension, allowing you to reshape their contents into a single column vector (which makes some operations easier, as shown by this other SO question).
Try executing this in MATLAB:
mat = C*S'
As In:
C = [1; 2; 3];
S = [2; 2; 9; 1];
mat = zeros(length(C),length(S));
for j=1:length(C)
mat(j,:)=C(j)*S;
end
% Equivalent code:
mat2 = C*S';
myDiff = mat - mat2
Do you mean the following?
mat = zeros(length(C),length(S));
for j=1:length(C)
mat(j,:)=C(j)*S;
end
If so, it's simply matrix multiplication:
C' * S % if C and S are row vectors
C * S' % if C and S are column vectors
If you don't know whether C and S are row vectors or column vectors, you can use a trick to turn them into column vectors, then transpose S before multiplying them:
C(:) * S(:)'
I'm not entirely clear on what you're doing - it looks like your resulting matrix will consist of length(C) rows, where the ith row is the vector S scaled by the ith entry of C (since subscripting a vector gives a scalar). In this case, you can do something like
mat = repmat(C,[1 length(S)]) .* repmat(S, [length(C) 1])
where you tile C across columns, and S down rows.
Try this:
C = 1:3
S = 1:5
mat1 = C'*S
mat2 = bsxfun(#times, C',S)
(esp. good when the function you need isn't simpler MATLAB notation)
--Loren
Try using meshgrid:
[Cm, Sm] = meshgrid(C, S);
mat = Cm .* Sm;
edit: nevermind, matrix multiplication will do too. You just need one column vector C and one row vector S. Then do C * S.