2010-10-17 25 views
2

Il s'agit d'incrémenter une valeur d'une matrice MATLAB plusieurs fois dans la même instruction, sans avoir à utiliser une boucle for.Incrémentation d'une valeur d'une matrice MATLAB plusieurs fois dans une ligne

Je mis mon tableau comme:

>> A = [10 20 30]; 

Et puis exécutez:

>> A([1, 1]) = A([1, 1]) + [20 3] 

A = 

    13 20 30 

Il est clair que le 20 est ignoré. Cependant, je voudrais qu'il soit inclus, de sorte que:

>> A = [10 20 30]; 
>> A([1, 1]) = A([1, 1]) + [20, 3] 

donnerait:

A = 

    33 20 30 

Y at-il une fonction pour permettre que cela se fasse dans un joli mode vectorisé?

(En réalité, l'indexation au tableau comprendrait plusieurs index, il pourrait être [1 1 2 2 1 1 1 1 3 3 3] etc., avec un tableau de nombres à incrémenter par (le [20, 3] ci-dessus) de la même longueur.)

Répondre

11

Qu'est-ce que vous voulez faire peut être fait en utilisant la fonction ACCUMARRAY, comme ceci:

A = [10 20 30];   %# Starting array 
index = [1 2 2 1];   %# Indices for increments 
increment = [20 10 10 3]; %# Value of increments 
A = accumarray([1:numel(A) index].',[A increment]); %'# Accumulate starting 
                 %# values and increments 

Et la sortie de cet exemple doit être:

A = [33 40 30]; 


EDIT: Si A est un large éventail de valeurs, et il y a seulement quelques incréments pour ajouter, ce qui suit peut être plus efficace que le calcul ci-dessus:

B = accumarray(index.',increment); %'# Accumulate the increments 
nzIndex = (B ~= 0);    %# Find the indices of the non-zero increments 
A(nzIndex) = A(nzIndex)+B(nzIndex); %# Add the non-zero increments 
+0

aaargh, 30 secondes plus vite :) – Adrien

+1

Merci, j'ai ce premier travail un régal. Je crois qu'il y a un symbole de transposition manquant sur le SUBS - je pourrais seulement faire 'A = accumarray ([1: numel (A) index] ', [A incrément]);' travail. Je ferai quelques comparaisons de vitesse pour la deuxième suggestion une fois que mes données seront peuplées. –

+0

@Bill: Vous avez raison. J'ai oublié que la première entrée doit être un vecteur de colonne dans ce cas. En général, la première entrée doit être une matrice M-by-N où M est le nombre de valeurs accumulées et N le nombre d'indices (1 dans ce cas, mais plus pour l'indexation multidimensionnelle). – gnovice

1

Peut-être il y a quelque chose que je ne comprends pas ici, mais vous essayez en fait d'ajouter 23 au premier élément de A, n'est-ce pas? Vous pouvez donc écrire:

A([1, 1]) = A([1, 1]) + sum([20 3]) 

En outre, si vous avez un tableau d'index, vous pouvez écrire

indexArray = [1 2 2 3 1 1 2 1]; 
toAdd = [20 3]; 
A = [10 20 30]; 

A(indexArray) + sum(toAdd) 

ans = 
33 43 43 53 33 33 43 33 
+0

Cela ne résout pas son problème général. –

+0

@Oli Charlesworth: Je ne sais pas si c'est le cas maintenant, mais j'ai modifié la question pendant que vous écriviez le commentaire. – Jonas

+1

Je pense que le cas général a 'toAdd' la même longueur que' indexArray'. Donc si le contenu de 'indexArray' était unique, vous feriez juste' A (indexArray) + toAdd'. –