例如,给定一个J
-by-2矩阵
A = [1 2 ; 3 4 ; 5 6]
我想阻止它对角化也就是说,我想要:
B = [1 2 0 0 0 0 ; 0 0 3 4 0 0 ; 0 0 0 0 5 6].
执行此操作的一个命令是:
blkdiag(A(1,:),A(2,:),A(3,:))
如果
J
很大,这将是一个缓慢而乏味的过程有没有内置的Matlab函数来实现这一点? 最佳答案
下面是一个使用J x 2
的linear 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
只有一个函数调用(忽略
size
,因为它必须是最小的)开销zeros
,甚至可以用this undocumented zeros initialization trick
移除-out(N,N*2) = 0; %// Instead of out = zeros(N,N*2);
样本运行-
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
以下是迄今为止发布的解决方案的基准测试。
基准代码
%//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
运行时
---------------------------------- 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.