How to multiply a vector of scalars with a vector of vectors in Matlab?

6.2k Views Asked by At

This sounds a bit strange, I'll explain it further. Assume we have a row vector $c = (c_1,c_2,\dots,c_n)$ and we have $n$ column vectors $v_i\in\mathbb R^4$ for $i\in\{1,\dots,n\}$. The $c$ is stored in Matlab as as vector c = [c1 c2 c3 ... cn] and the vectors $v_i$ are stored in a matrix V = [v1 v2 v3 ... vn].

I want now to calculate the matrix $(c_1 v_1, c_2 v_2, \dots, c_n v_n)$ in Matlab. This can be done easily by

for i = 1:n
   prod(1:4,i) = c(i)*V(:,i);
end

But I want it to do without any for loop and without any repmat-command as its rather slow this way.

5

There are 5 best solutions below

0
On BEST ANSWER

I just figured out an even faster way (with a little help from my friends) and I think this might be the fastest way to do this in Matlab:

prod = c(ones(4,1),:).*V;

Despite c beeing a vector, it can be treated as a matrix, also. The code c(ones(4,1),:) produces the same output as repmat(c,4,1), only faster.

4
On

Daryl's comment is mostly correct, except instead of transpose you need the diagonal operator on $c$. In MATLAB notation, prod = V*diag(c); for c being defined as a row vector. I will elaborate why.

$$V = \begin{pmatrix} v_{11} & v_{12} & \cdots & v_{1n} \\ v_{21} & v_{22} & \cdots & v_{2n} \\ \vdots & & \ddots & \vdots \\ v_{m1} & v_{m2} & \cdots & v_{mn}\end{pmatrix}$$ $$ c = \begin{pmatrix} c_1 & c_2 & \cdots & c_n\end{pmatrix} $$

Then,

$$V*\mathrm{diag}(c) = \begin{pmatrix} v_{11} & v_{12} & \cdots & v_{1n} \\ v_{21} & v_{22} & \cdots & v_{2n} \\ \vdots & & \ddots & \vdots \\ v_{m1} & v_{m2} & \cdots & v_{mn}\end{pmatrix} \begin{pmatrix} c_1 & 0 & 0 & 0\\ 0 & c_2 & 0 & 0 \\ 0 & 0 & \ddots & 0 \\ 0 & 0 & 0 &c_n\end{pmatrix} = \begin{pmatrix} c_1v_{11} & c_2v_{12} & \cdots & c_nv_{1n} \\ c_1v_{21} & c_2v_{22} & \cdots & c_nv_{2n} \\ \vdots & & \ddots & \vdots \\ c_1v_{m1} & c_2v_{m2} & \cdots & c_nv_{mn} \end{pmatrix}$$

Which is exactly what you want.

5
On

I'm not sure whether this is on-topic for this site, but the command you want is:

bsxfun(@times,V,c)
2
On

A more "algebraic" way is to use:

prod=V*diag(c)

where diag(c) creates a diagonal matrix with c on its diagonal

0
On

I just figured out a faster way (with a little help from my friends):

prod = (ones(4,1)*c).*V;