Discussion and code
This may be one approach with , which makes it easier to function-encoded - bsxfun(@plus linear indexing
function out = bsxfun_linidx(A,a)
%
[A_nrows,A_ncols] = size(A);
N_a = numel(a);
%
off1 = A_nrows*N_a;
off2 = off1*A_ncols+A_nrows;
%
vals = bsxfun(@times,A,permute(a,[1 3 2])); %
%
block1_idx = bsxfun(@plus,[1:A_nrows]',[0:A_ncols-1]*off1); %//'
%
%
out(A_nrows*N_a,A_ncols*N_a) = 0;
%
out(bsxfun(@plus,block1_idx(:),(0:N_a-1)*off2)) = vals;
return;
How to use: To use the above function code, assume that you have a1, a2, a3, ...., anstored in a vector a, then do something like this out = bsxfun_linidx(A,a)to get the desired result out.
Benchmarking
This section compares or compares the approach specified in this answer compared to the other two approaches listed in the other answers for execution at runtime.
Other answers have been converted to function forms, for example:
function B = bsxfun_blkdiag(A,a)
B = bsxfun(@times, A, reshape(a,1,1,[])); %
B = mat2cell(B,size(A,1),size(A,2),ones(1,numel(a))); %
B = blkdiag(B{:}); %
and
function out = kron_diag(A,a_arr)
out = kron(diag(a_arr),A);
a a, <
a 500 x 500 a 1 x 10a 200 x 200 a 1 x 50a 100 x 100 a 1 x 100a 50 x 50 a 1 x 200
-
%// Datasizes
N_a = [10 50 100 200];
N_A = [500 200 100 50];
timeall = zeros(3,numel(N_a)); %// Array to store runtimes
for iter = 1:numel(N_a)
%// Create random inputs
a = randi(9,1,N_a(iter));
A = rand(N_A(iter),N_A(iter));
%// Time the approaches
func1 = @() kron_diag(A,a);
timeall(1,iter) = timeit(func1); clear func1
func2 = @() bsxfun_blkdiag(A,a);
timeall(2,iter) = timeit(func2); clear func2
func3 = @() bsxfun_linidx(A,a);
timeall(3,iter) = timeit(func3); clear func3
end
%// Plot runtimes against size of A
figure,hold on,grid on
plot(N_A,timeall(1,:),'-ro'),
plot(N_A,timeall(2,:),'-kx'),
plot(N_A,timeall(3,:),'-b+'),
legend('KRON + DIAG','BSXFUN + BLKDIAG','BSXFUN + LINEAR INDEXING'),
xlabel('Datasize (Size of A) ->'),ylabel('Runtimes (sec)'),title('Runtime Plot')
%// Plot runtimes against size of a
figure,hold on,grid on
plot(N_a,timeall(1,:),'-ro'),
plot(N_a,timeall(2,:),'-kx'),
plot(N_a,timeall(3,:),'-b+'),
legend('KRON + DIAG','BSXFUN + BLKDIAG','BSXFUN + LINEAR INDEXING'),
xlabel('Datasize (Size of a) ->'),ylabel('Runtimes (sec)'),title('Runtime Plot')
, ,


: , , bsxfun, , !