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

1 view (last 30 days)
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
Edited: SB on 9 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)

More Answers (0)

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!