From owner-help-octave at bevo dot che dot wisc dot edu Thu Nov 14 17:18:12 1996 Subject: Re: Efficient multiplication by a diagonal matrix From: Mario Storti To: help-octave at bevo dot che dot wisc dot edu Date: Thu, 14 Nov 1996 20:18:26 -0300 >>>>> On Thu, 14 Nov 1996 17:43:56 -0400 (EDT), SANDS at VSDEC dot NL dot NUWC dot NAVY dot MIL said: > Mario Storti writes: > >I found myself repeatedly with the following problem. Given a matrix > >A(n,m) and a vector v(n), I have to multiply each row A(j,:) by > >v(j). This is equivalent to compute: > > > >B = diag(v) * A (1) > > > >Now, for large n, (1) is very inefficient ... > > Right, try using "Tony's Trick", it's been around for years. > > Assuming v is a column vector (if not do v=v(:);) try > > B=v(:,ones(length(v),1)) .* A; > > This is a kind-of MATLAB specific thing but I think > it works in octave o.k. > > Scott Sands (...) > Sorry about the previous post, the right answer is > > B=v(:,ones(1,m)) .*A; > > ss I tried, and it works also in Octave. Curiously enough, both work: >> octave:3> v=rand(5,1) >> v = >> >> 0.397911 >> 0.517248 >> 0.876939 >> 0.025083 >> 0.895795 >> >> octave:4> v(:,ones(5,1)) >> ans = >> >> 0.397911 0.397911 0.397911 0.397911 0.397911 >> 0.517248 0.517248 0.517248 0.517248 0.517248 >> 0.876939 0.876939 0.876939 0.876939 0.876939 >> 0.025083 0.025083 0.025083 0.025083 0.025083 >> 0.895795 0.895795 0.895795 0.895795 0.895795 >> >> octave:5> v(:,ones(1,5)) >> ans = >> >> 0.397911 0.397911 0.397911 0.397911 0.397911 >> 0.517248 0.517248 0.517248 0.517248 0.517248 >> 0.876939 0.876939 0.876939 0.876939 0.876939 >> 0.025083 0.025083 0.025083 0.025083 0.025083 >> 0.895795 0.895795 0.895795 0.895795 0.895795 >> But it is equivalent to kron(v,ones(1,m)) and it has the same problems of inefficiency as mentioned in the original post: > Now, for large n, (1) is very inefficient, because it requires > constructing the square matrix diag(v) which requires storage and many > redundant operations since most elements of diag(v) are null. If n>>m ^^^^^^^ > then: > > B= kron(v,ones(1,m)).*A (2) > > does the job and is better. But the more efficient way is computing ^^^^^^^^^^^^^^^^^^^^^^^^^^^ > row by row if m>>n and column by column if n>>m. However, I repeat, I > find this problem so many times and in so many areas that it seems to (...) Mario %%%%%%<>%%%%%%<>%%%%%%<>%%%%%%<>%%%%%%<>%%%%%%<>%%%%%%<>%%%%%%<>%%%%%%<>%%% Mario Alberto Storti | Fax: (54)(42) 55.09.44 | Grupo de Tecnologia Mecanica | Tel: (54)(42) 55.91.75 | INTEC, Guemes 3450 - 3000 Santa Fe | http://venus.unl.edu.ar/gtm-eng.html | Argentina | Home: Gob. Vera 3161 | Reply: mstorti at galileo dot unl dot edu dot ar| | (54)(42) 55 dot 00 dot 23 | (54)(42) 55.00.23 |