I have 30x30 matrix and need to extrapolate lower triangle numbers

3 ビュー (過去 30 日間)
aet
aet 2019 年 6 月 7 日
編集済み: Jan 2019 年 6 月 10 日
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 件のコメント
Jan
Jan 2019 年 6 月 7 日
"Pull out values" and "extrapolate" is something different.

サインインしてコメントする。

採用された回答

John D'Errico
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
Jan 2019 年 6 月 8 日
V = A(tril(true(size(A))))
avoids the creation and conversion of the double matrix.
John D'Errico
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
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 件のコメント
aet
aet 2019 年 6 月 7 日
I'm not super experienced with this stuff so I apologize. I'm fine using tril as long as I can maintain any zeros in the lower triangle when I pull out the values for the lower triangle. This isn't working for my matrix. It is saying that the logical indices contain a true value outside of the array bounds.
Jan
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 ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by