I have a1 a2 a3. They are constants. I have a matrix A. What I want to do is to get a1*A, a2*A, a3*A three matrices. Then I want transfer them into a diagonal block matrix. For three constants case, this is easy. I can let b1 = a1*A, b2=a2*A, b3=a3*A, then use blkdiag(b1, b2, b3) in matlab.
What if I have n constants, a1 ... an. How could I do this without any looping?I know this can be done by kronecker product but this is very time-consuming and you need do a lot of unnecessary 0 * constant.
Thank you.
Discussion and code
This could be one approach with
bsxfun(@plus
that facilitates inlinear indexing
as coded in a function format -How to use: To use the above listed function code, let's suppose you have the
a1
,a2
,a3
, ....,an
stored in a vectora
, then do something like thisout = bsxfun_linidx(A,a)
to have the desired output inout
.Benchmarking
This section compares or benchmarks the approach listed in this answer against the other two approaches listed in the other answers for runtime performances.
Other answers were converted to function forms, like so -
and,
For the comparison, four combinations of sizes of
A
anda
were tested, which are -A
as500 x 500
anda
as1 x 10
A
as200 x 200
anda
as1 x 50
A
as100 x 100
anda
as1 x 100
A
as50 x 50
anda
as1 x 200
The benchmarking code used is listed next -
Runtime plots thus obtained at my end were -
Conclusions: As you can see, either one of the
bsxfun
based methods could be looked into, depending on what kind of datasizes you are dealing with!Here's a method using
kron
which seems to be faster and more memory efficient than Divakar'sbsxfun
based solution. I'm not sure if this is different to your method, but the timing seems pretty good. It might be worth doing some testing between the different methods to work out which is more efficient for you problem.Here's another approach:
bsxfun
;blkdiag
with a comma-separated list generated from the cell array.Let
A
denote your matrix, anda
denote a vector with your constants. Then the desired resultB
is obtained as