views:

2570

answers:

6

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.

+4  A: 

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
Steve
+5  A: 

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).

gnovice
Why does the bottom expression produce different results than the top expression? It would seem like C = C(:). There is something subtle that's going on here I don't understand.
NoMoreZealots
@Pete: I'll add an explanation to the answer to make it clearer.
gnovice
I read your explantion and thought, if what your saying is correct THEN C'*S should work and lo and behold it does. So the real issue is just the order which the column vector is multiplied with the row vector. Sweet. Thanks.
NoMoreZealots
Glad to help. C and S must have both been row vectors to start with, in which case C'*S and C(:)*S do the same thing. The more general C(:)*S(:)' is really only necessary if you have no idea whether C and S are row or column vectors, but still want to perform an outer product with them.
gnovice
I always thought of the parenthesis as an "Indexing operator" and the C(:,x) as shorthand for C(1:length(C),x). The subtleties of the operation aren't really highlighted in the documentation. It's kinda funny, they document the libraries better than the language itself.
NoMoreZealots
Parentheses are one type of indexing operator, and the arguments between the parentheses can involve expressions and other operators. The colon operator, when used inside the parentheses, can wear many hats. It can be used to make vectors like "C(1:length(C),x)", it can index an entire dimension like "C(:,x)", or it can access all elements in a column-wise fashion like "C(:)". Truthfully, I've found the documentation for MATLAB to be very good and often clearer than other languages.
gnovice
A: 

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.

+1  A: 

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.

Tim Whitcomb
+2  A: 

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(:)'
Vebjorn Ljosa
+1  A: 

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

Loren

related questions