设A
是一个大小为 的矩阵[n,n]
。如果我想提取它的对角线,我会这样做diag(A)
。
实际上,我想要相反的对角线,即[A(n,1),A(n-1,2),A(n-2,3),...]
.
一种方法是通过diag(flipud(A))
. 然而,flipud(A)
与找到通常的对角线相比,这是非常浪费的,并且将花费的时间乘以 10 倍。
我正在寻找一种快速获得对角线的方法。自然地,for
循环看起来非常缓慢。建议将不胜感激。
设A
是一个大小为 的矩阵[n,n]
。如果我想提取它的对角线,我会这样做diag(A)
。
实际上,我想要相反的对角线,即[A(n,1),A(n-1,2),A(n-2,3),...]
.
一种方法是通过diag(flipud(A))
. 然而,flipud(A)
与找到通常的对角线相比,这是非常浪费的,并且将花费的时间乘以 10 倍。
我正在寻找一种快速获得对角线的方法。自然地,for
循环看起来非常缓慢。建议将不胜感激。
这是我的矩阵,由 A = magic(5) 生成
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
s = size(A,1)
A(s:s-1:end-1)
ans =
11 12 13 14 15
下面是迄今为止提到的所有方法的比较,以及我能想到的其他一些变化。这是使用TIMEIT函数在 64 位 R2013a 上测试的。
function [t,v] = testAntiDiag()
% data and functions
A = magic(5000);
f = {
@() func0(A) ;
@() func1(A) ;
@() func2(A) ;
@() func3(A) ;
@() func4(A) ;
@() func5(A) ;
@() func6(A) ;
@() func7(A) ;
};
% timeit and check results
t = cellfun(@timeit, f, 'UniformOutput',true);
v = cellfun(@feval, f, 'UniformOutput',false);
assert( isequal(v{:}) )
end
function d = func0(A)
d = diag(A(end:-1:1,:));
end
function d = func1(A)
d = diag(flipud(A));
end
function d = func2(A)
d = flipud(diag(fliplr(A)));
end
function d = func3(A)
d = diag(rot90(A,3));
end
function d = func4(A)
n = size(A,1);
d = A(n:n-1:end-1).';
end
function d = func5(A)
n = size(A,1);
d = A(cumsum(n + [0,repmat(-1,1,n-1)])).';
end
function d = func6(A)
n = size(A,1);
d = A(sub2ind([n n], n:-1:1, 1:n)).';
end
function d = func7(A)
n = size(A,1);
d = zeros(n,1);
for i=1:n
d(i) = A(n-i+1,i);
end
end
时间安排(按照上面定义的相同顺序):
>> testAntiDiag
ans =
0.078635867152801
0.077895631970976 % @AlexR.
0.080368641824528
0.195832501156751
0.000074983294297 % @thefourtheye
0.000143019460665 % @woodchips
0.000174679680437
0.000152488508547 % for-loop
对我来说最令人惊讶的结果是最后一个。显然,JIT 编译在这种简单的 for 循环上非常有效。
您想要的元素很容易通过索引获得。例如,这应该可以解决问题。
n = 4;
A = magic(n)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
A(cumsum(n + [0,repmat(-1,1,n-1)]))
ans =
4 7 10 13
我也可以使用 sub2ind 来获取这些元素索引,但这会更干净一些,尽管它的工作方式不太明显。
A = 魔法(6)
一个=
35 1 6 26 19 24
3 32 7 21 23 25
31 9 2 22 27 20
8 28 33 17 10 15
30 5 34 12 14 16
4 36 29 13 18 11
b =诊断(A(1:长度(A),长度(A):-1:1))
b =
24
23
22
33
5
4