MATLAB Answers

How can I get all entries of the lower triangular (simplex) of a tensor with arbitrary dimension?

2 views (last 30 days)
SB
SB on 7 Apr 2020
Edited: SB on 9 Apr 2020
If you have an m-dimensional tensor A, how can you get all entries in a vector V that are in the lower simplex of A? The order in the output vector V does not matter to me. The matrix A is quadratic, so it has the same length in each dimension.
For 2D I want to get V from A like this:
A=[1 4 7;
2 5 8;
3 6 9];
Simplex=rot90(triu(true(size(A))));
V=A(Simplex)
%V =
%
% 1
% 2
% 3
% 5
% 6
% 9
For 3D the resulting V should look like this:
A=reshape(1:27,3,3,3)
%ans(:,:,1) =
% 1 4 7
% 2 5 8
% 3 6 9
%
%ans(:,:,2) =
% 10 13 16
% 11 14 17
% 12 15 18
%
%ans(:,:,3) =
% 19 22 25
% 20 23 26
% 21 24 27
V=[1 2 3 5 6 9 11 12 15 21];
The dimension of the Tensor A is really arbitrary.
Edit (thanks to the accepted answer):
Actually for my problem it is even better when the simplex lies in the origin of the matrix (the indices of each dimension are 0). I just noticed this, thanks to the accepted answer. The modified version of the answer than would simply be:
A=reshape(1:27,3,3,3);
N=size(A,1);
M=ndims(A);
%C(1:M)={0:N-1}; C{1}=N-(1:N);
%[C{1:M}]=ndgrid(C{:});
[C{1:M}]=ndgrid(0:N-1);
lowerSimplex=sum(cat(M+1,C{:}),M+1)<=(N-1);
V=A(lowerSimplex)
%V = 1 2 3 4 5 7 10 11 13 19

  1 Comment

SB
SB on 8 Apr 2020
An "indexing way" to get the triangle (simplex in 2D) lying in the origin of A could be
N = size(A,1);
X = mod(0:numel(A)-1,N)+1;
Y = ceil((1:numel(A))/N);
V = A(X+Y-2 <= N-1);
It basically uses the index i of A, with , and calculates the indices in each dimension: , . This lead me to an alternative version, directly generating the indices:
N = size(A,1);
M = ndims(A); %M=2 for 2D
X = repmat(repelem(1:N,N^0),1,N^(M-1)); %123123123
Y = repmat(repelem(1:N,N^1),1,N^(M-2)); %111222333
V = A(X+Y-2 <= N-1);
Or with IND2SUB for any dimension (thanks to the accepted answer of this question):
N = size(A,1);
M = ndims(A); %m=2 for 2D
X = cell(1,M);
[X{:}] = ind2sub(repelem(N,M),1:numel(A));
V = A(sum(vertcat(X{:}))-M <= N-1);

Sign in to comment.

Accepted Answer

Matt J
Matt J on 8 Apr 2020
Edited: Matt J on 8 Apr 2020
M=size(A,1);
N=ndims(A);
C(1:N)={0:M-1}; C{1}=M-(1:M);
[C{1:N}]=ndgrid(C{:});
lowerSimplex=sum(cat(N+1,C{:}),N+1)<=(M-1);
V=A(lowerSimplex)

  1 Comment

SB
SB on 9 Apr 2020
I edited my question to match your answer, since this solves my problem perfectly. Thank you so much.

Sign in to comment.

More Answers (0)

Sign in to answer this question.