Effacer les filtres
Effacer les filtres

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

2 vues (au cours des 30 derniers jours)
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 commentaire
SB
SB le 8 Avr 2020
Modifié(e) : SB le 9 Avr 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);

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 8 Avr 2020
Modifié(e) : Matt J le 8 Avr 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 commentaire
SB
SB le 9 Avr 2020
I edited my question to match your answer, since this solves my problem perfectly. Thank you so much.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Matrices and Arrays dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by