I have 30x30 matrix and need to extrapolate lower triangle numbers
3 ビュー (過去 30 日間)
古いコメントを表示
I need to pull out everything below the diagonal (the lower triagnle numbers), but I don't want to use tril and change the diagonal and upper triangle to zeros. I just want to pull out the lower triangle numbers so that I can make a vector out of its values.
Anything is helpful!! Thank you!
1 件のコメント
採用された回答
John D'Errico
2019 年 6 月 7 日
You just want to extract the lower triangle, whatever is in it? The result going into a vector?
A = magic(5) - 10
A =
7 14 -9 -2 5
13 -5 -3 4 6
-6 -4 3 10 12
0 2 9 11 -7
1 8 15 -8 -1
V = A(logical(tril(ones(size(A)))))
V =
7
13
-6
0
1
-5
-4
2
8
3
9
15
11
-8
-1
That includes the diagonal. But if you want the strictly lower triangle, just set a second argument for tril.
3 件のコメント
Jan
2019 年 6 月 8 日
V = A(tril(true(size(A))))
avoids the creation and conversion of the double matrix.
John D'Errico
2019 年 6 月 9 日
Yes. I knew I was being sloppy there, but I was too lazy to think of the better alternative suggested by Jan. True works better.
その他の回答 (1 件)
Jan
2019 年 6 月 7 日
編集済み: Jan
2019 年 6 月 8 日
x = rand(5, 5);
y = x(tril(true(size(x))))
What is the reason to avoid tril?
Maybe:
s = size(x);
y = x((1:s(1)).' >= (1:s2)) % lower left triangle
n = 1;
y = x((1+n:s(1)+n).' >= (1:s2)) % lower left triangle + n diagonals above
% or below, if n < 0
2 件のコメント
Jan
2019 年 6 月 8 日
編集済み: Jan
2019 年 6 月 10 日
@aet: Then you made a typo in your tests or used my example of "5", although your matrix is smaller. I've replaced the fix size 5 by the real size of the matrix. The 1st example is equivalent to John's suggestion, but
tril(true(size(A)))
creates the triangular index matrix in the logical type directly, while
logical(tril(ones(size(A)))
creates a double matrix at first, which is 8 times larger. For larger arrays, this needs more resources and an additional conversion.
With
n = 1;
y = x((1+n:s(1)+n).' >= (1:s2))
you can exclude e.g. the main diagonal also: n=-1.
Some timings:
x = rand(1000, 1000);
tic
for k = 1:1000
y = x(tril(true(size(x))));
end
toc
tic
for k = 1:1000
y = x(logical(tril(ones(size(x)))));
end
toc
tic
for k = 1:1000
s = size(x);
y = x((1:s(1)).' >= (1:s(2)));
end
toc
tic
for k = 1:1000
s = size(x);
y = x(bsxfun(@ge, (1:s(1)).', 1:s(2)));
end
toc
Elapsed time is 5.526872 seconds.
Elapsed time is 10.652150 seconds.
Elapsed time is 6.415982 seconds. % Auto-expanding
Elapsed time is 6.094049 seconds. % BSXFUN
I'm sureprised that tril(true()) is faster than the bsxfun approach.
参考
カテゴリ
Help Center および File Exchange で Matrix Indexing についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!