Question

J'ai une matrice de taille n par k, contenant des nombres k par ligne. Je veux utiliser ces chiffres k comme indices dans une matrice de dimension k. Est-il un moyen compact de le faire dans Matlab ou dois-je utiliser une boucle?

est ce que je veux faire (dans le code Matlab pseudo), mais d'une manière plus Matlab ish:

for row=1:1:n
    finalTable(row) = kDimensionalMatrix(indexmatrix(row, 1),...
          indexmatrix(row, 2),...,indexmatrix(row, k))
end
Était-ce utile?

La solution

Si vous voulez éviter d'avoir à utiliser une boucle, c'est probablement la plus propre façon de le faire:

indexCell = num2cell(indexmatrix, 1);
linearIndexMatrix = sub2ind(size(kDimensionalMatrix), indexCell{:});
finalTable = kDimensionalMatrix(linearIndexMatrix);

La première ligne met chaque colonne de indexmatrix dans des cellules séparées d'un réseau de cellules en utilisant num2cell . Cela nous permet de passer toutes les colonnes de k comme séparés par des virgules liste dans sub2ind , une fonction qui convertit indices indicées (ligne, colonne, etc.) dans indices linéaires (chaque élément de matrice est numérotée de 1 à N, N étant le nombre total d'éléments dans la matrice). La dernière ligne utilise ces indices linéaires pour remplacer votre boucle. Une bonne discussion sur l'indexation de la matrice (indice, linéaire et logique) se trouve .

plus de nourriture pour la pensée ...

La tendance à fuir pour les boucles en faveur de solutions vectorisés est quelque chose de nombreux utilisateurs (Matlab compris moi-même) sont devenus habitués. Cependant, les nouvelles versions de poignée en boucle Matlab beaucoup plus efficacement. Comme indiqué dans cette réponse à une autre question SO, en utilisant des boucles peut parfois aboutir à un code plus rapide en cours d'exécution que vous obtiendriez avec une solution vectorisé.

Je ne suis certainement pas que vous ne devriez pas essayer de vectoriser votre plus code, seulement que chaque problème est unique. Vectorisation sera souvent être plus efficace, mais pas toujours . Pour votre problème, sera probablement la vitesse d'exécution pour les boucles par rapport à un code vectorisé dépendent de la taille et les valeurs n k sont.

Autres conseils

Pour traiter les éléments du indexmatrix(row, :) vectoriel séparés indices, vous avez besoin des éléments comme une matrice de cellules. Donc, vous pourriez faire quelque chose comme ça

subsCell = num2cell( indexmatrix( row, : ) );
finalTable( row ) = kDimensionalMatrix( subsCell{:} );

Pour développer subsCell comme une liste séparée par des virgules, malheureusement, vous avez besoin des deux lignes distinctes. Cependant, ce code est indépendant de k.

Convertir vos sous-indices en indices linéaires de manière hacky

ksz = size(kDimensionalMatrix);
cksz = cumprod([ 1 ksz(1:end-1)] );
lidx = ( indexmatrix - 1 ) * cksz' + 1; #'
% lindx is now (n)x1 linear indices into kDimensionalMatrix, one index per row of indexmatrix
% access all n values:
selectedValues = kDimensionalMatrix( lindx );

Vive!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top