MATLAB Answers

aet
0

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

Asked by aet
on 7 Jun 2019
Latest activity Edited by Jan
on 10 Jun 2019
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 Comment

"Pull out values" and "extrapolate" is something different.

Sign in to comment.

2 Answers

Answer by John D'Errico
on 7 Jun 2019
 Accepted Answer

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 Comments

Thank you so much! This worked for me!
V = A(tril(true(size(A))))
avoids the creation and conversion of the double matrix.
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.

Sign in to comment.


Answer by Jan
on 7 Jun 2019
Edited by Jan
on 8 Jun 2019

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 Comments

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.
@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.

Sign in to comment.