块对角化J-by-2矩阵的行

Mat*_*tle 4 matlab

J例如,给定a -by-2矩阵

A = [1 2 ; 3 4 ; 5 6]
Run Code Online (Sandbox Code Playgroud)

我想阻止对角线化.也就是说,我想:

B = [1 2 0 0 0 0 ; 0 0 3 4 0 0 ; 0 0 0 0 5 6].
Run Code Online (Sandbox Code Playgroud)

执行此操作的一个命令是:

blkdiag(A(1,:),A(2,:),A(3,:))
Run Code Online (Sandbox Code Playgroud)

如果J很大,这将是缓慢而乏味的.是否有内置的Matlab功能可以做到这一点?

Div*_*kar 5

这是一个使用的阵列案例的hacky解决方案-J x 2linear indexing

%// Get number of rows
N = size(A,1);                   

%// Get linear indices of the first column elements positions in output array
idx = 1:2*N+1:(N-1)*(2*N+1)+1;   

%// Setup output array
out = zeros(N,N*2);

%// Put first and second column elements into idx and idx+N positions
out([idx(:) idx(:)+N]) = A
Run Code Online (Sandbox Code Playgroud)

只有一个函数调用(忽略,size因为它必须是最小的)开销,zeros甚至可以删除this undocumented zeros initialization trick-

out(N,N*2) = 0; %// Instead of out = zeros(N,N*2);
Run Code Online (Sandbox Code Playgroud)

样品运行 -

A =
     1     2
     3     4
     5     6
     7     8
out =
     1     2     0     0     0     0     0     0
     0     0     3     4     0     0     0     0
     0     0     0     0     5     6     0     0
     0     0     0     0     0     0     7     8
Run Code Online (Sandbox Code Playgroud)

这是迄今为止发布的解决方案的基准测试.

基准代码

%//Set up some random data
J = 7000;   A = rand(J,2);
%// Warm up tic/toc
for k = 1:100000
    tic(); elapsed = toc();
end   
disp('---------------------------------- With @mikkola solution')
tic
temp = mat2cell(A, ones(J,1), 2);
B = blkdiag(temp{:});
toc, clear B temp
disp('---------------------------------- With @Jeff Irwin solution')
tic
m = size(A, 1);
n = size(A, 2);
B = zeros(m, m * n);
for k = 1: n
    B(:, k: n: m * n) = diag(A(:, k));
end
toc, clear B k m n
disp('---------------------------------- With Hacky1 solution')
tic
N = size(A,1);                   
idx = 1:2*N+1:(N-1)*(2*N+1)+1;   
out = zeros(N,N*2);
out([idx(:) idx(:)+N]) = A;
toc, clear out idx N
disp('---------------------------------- With Hacky2 solution')
tic
N = size(A,1);                   
idx = 1:2*N+1:(N-1)*(2*N+1)+1;
out(N,N*2) = 0;
out([idx(:) idx(:)+N]) = A;
toc, clear out idx N
Run Code Online (Sandbox Code Playgroud)

运行时

---------------------------------- With @mikkola solution
Elapsed time is 0.546584 seconds.
---------------------------------- With @Jeff Irwin solution
Elapsed time is 1.330666 seconds.
---------------------------------- With Hacky1 solution
Elapsed time is 0.455735 seconds.
---------------------------------- With Hacky2 solution
Elapsed time is 0.364227 seconds.
Run Code Online (Sandbox Code Playgroud)