2011-05-04 4 views
1

Ceci est très étroitement lié à this other question, mais cette question voulait éviter en raison de problèmes de performances. Je suis plus préoccupé par le "unelegance" d'utiliser sub2ind. Supposons que je veuille créer une autre matrice MxN qui soit toute zéros sauf une entrée dans chaque colonne que je veux assigner à partir de l'entrée correspondante dans un vecteur, et le choix de la ligne dans chaque colonne est basé sur un autre vecteur. Par exemple:matlab: adressage d'un index sans sub2ind

z = zeros(10,4); 
rchoice = [3 1 8 7]; 
newvals = [123 456 789 10]; 
% ??? I would like to set z(3,1)=123, z(1,2)=456, z(8,3)=789, z(7,4)=10 

Je peux utiliser sub2ind pour ce faire (que je en an answer to a closely related question):

z(sub2ind(size(z),rchoice,1:4)) = newvals 

, mais est-il une autre alternative? On dirait que l'adressage logique pourrait être utilisé d'une certaine manière, mais je suis perplexe, car pour définir les éléments d'une matrice logique à 1, vous devez traiter les mêmes positions d'éléments que dans la matrice que vous voulez réellement traiter.

Répondre

2

Il y a beaucoup façon plus simple de le faire.

nCols=size(z,2); 
z(rchoice,1:nCols)=diag(newvals); 
+1

intelligent vous êtes, récompensé vous serez .... –

+0

cela crée-t-il réellement une matrice NxN, ou est-ce que MATLAB est assez intelligent pour savoir ce que je veux dire? Si j'ai 1000 valeurs, cela fonctionne-t-il ou manque-t-il de mémoire? –

+0

'diag' va créer une matrice' NxN'. Je n'ai pas pris la peine d'utiliser sparse, car c'était juste un exemple conceptuel. Si vous avez un grand nombre de valeurs, vous pouvez utiliser 'spdiags (newvals ', 0, N, N)'. Ceci n'utilise que des éléments 'N', donc ne manquera pas de mémoire. – abcd

2

Vous pouvez simplement ajouter le nombre de lignes dans les colonnes précédentes à rchoice pour obtenir directement l'index linéaire.

nRows = size(z,1); %# in case you don't know this already 
nCols2write = length(newvals); 
z(rchoice+[0:nRows:(nRows*(nCols2write-1)]) = newvals; 
+0

qui fonctionne pour 2D (et la réponse que je lié ou pensé que je lié à, mentionne cette approche comme une amélioration de la performance sur sub2ind), donc +1, mais semble difficile à obtenir le droit pour la 3D ou plus. –

+0

@Jason: Bien que pas aussi simple que le cas 2D, il est certainement possible de calculer les indices de façon simple pour les matrices ND ... Voir les réponses à [this] (http://stackoverflow.com/questions/5598900)/comment-je-index-les-diagonales-d'un-3-d-matrice-dans-matlab/5598991 # 5598991) question et [ceci] (http://stackoverflow.com/questions/5319178/how -can-i-assign-a-value-to-the-diagonals-of-a-4-d-matrix-using-linear-indexing-i/5319338 # 5319338) pour des exemples sur l'indexation linéaire dans les matrices 3D et 4D. – abcd