在MATLAB中将零的对角线添加到矩阵 [英] Add a diagonal of zeros to a matrix in MATLAB

查看:421
本文介绍了在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?

推荐答案

您可以对矩阵的上下三角形部分(triutril)进行此操作.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆