在MATLAB中将零的对角线添加到矩阵 [英] Add a diagonal of zeros to a matrix in MATLAB
问题描述
假设我在MATLAB中有一个尺寸为Nx(N-1)
的矩阵A
,例如
Suppose I have a matrix A
of dimension Nx(N-1)
in MATLAB, e.g.
N=5;
A=[1 2 3 4;
5 6 7 8;
9 10 11 12;
13 14 15 16;
17 18 19 20 ];
我想通过添加零对角线(即
I want to transform A
into an NxN
matrix B
, just by adding a zero diagonal, i.e.,
B=[ 0 1 2 3 4;
5 0 6 7 8;
9 10 0 11 12;
13 14 15 0 16;
17 18 19 20 0];
这段代码可以满足我的要求:
This code does what I want:
B_temp = zeros(N,N);
B_temp(1,:) = [0 A(1,:)];
B_temp(N,:) = [A(N,:) 0];
for j=2:N-1
B_temp(j,:)= [A(j,1:j-1) 0 A(j,j:end)];
end
B = B_temp;
您能建议一种有效的矢量化方法吗?
Could you suggest an efficient way to vectorise it?
推荐答案
您可以对矩阵的上下三角形部分(triu
和tril
)进行此操作.
You can do this with upper and lower triangular parts of the matrix (triu
and tril
).
那么这是1行解决方案:
Then it's a 1 line solution:
B = [tril(A,-1) zeros(N, 1)] + [zeros(N,1) triu(A)];
修改:基准测试
这是循环方法, Sardar的答案和我上面的方法中的2种方法的比较.
This is a comparison of the loop method, the 2 methods in Sardar's answer, and my method above.
基准代码,使用timeit
进行计时,并直接从问题和答案中提取代码:
Benchmark code, using timeit
for timing and directly lifting code from question and answers:
function benchie()
N = 1e4; A = rand(N,N-1); % Initialise large matrix
% Set up anonymous functions for input to timeit
s1 = @() sardar1(A,N); s2 = @() sardar2(A,N);
w = @() wolfie(A,N); u = @() user3285148(A,N);
% timings
timeit(s1), timeit(s2), timeit(w), timeit(u)
end
function sardar1(A, N) % using eye as an indexing matrix
B=double(~eye(N)); B(find(B))=A.'; B=B.';
end
function sardar2(A,N) % similar to sardar1, but avoiding slow operations
B=1-eye(N); B(logical(B))=A.'; B=B.';
end
function wolfie(A,N) % using triangular parts of the matrix
B = [tril(A,-1) zeros(N, 1)] + [zeros(N,1) triu(A)];
end
function user3285148(A, N) % original looping method
B = zeros(N,N); B(1,:) = [0 A(1,:)]; B(N,:) = [A(N,:) 0];
for j=2:N-1; B(j,:)= [A(j,1:j-1) 0 A(j,j:end)]; end
end
结果:
- Sardar方法1:2.83秒
- Sardar方法2:1.82秒
- 我的方法:1.45秒
- 循环方法:3.80秒(!)
结论:
- 您希望对此进行矢量化处理的理由很充分,循环比其他方法要慢得多.
- 避免大型矩阵的数据转换和
find
很重要,在Sardar方法之间可节省约35%的处理时间. - 通过避免一起编制索引,可以节省20%的处理时间.
- Your desire to vectorise this was well founded, looping is way slower than other methods.
- Avoiding data conversions and
find
for large matrices is important, saving ~35% processing time between Sardar's methods. - By avoiding indexing all together you can save a further 20% processing time.
这篇关于在MATLAB中将零的对角线添加到矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!