2010-10-17 2 views
2

Это вопрос об увеличении одного значения массива MATLAB несколько раз в одном и том же операторе без использования цикла for.Увеличение одного значения массива MATLAB несколько раз в одной строке

Я установил мой массив как:

>> A = [10 20 30]; 

А затем запустить:

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

A = 

    13 20 30 

Очевидно, что 20 игнорируется. Тем не менее, я хотел бы, чтобы это было включено, так что:

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

даст:

A = 

    33 20 30 

Есть ли функция, чтобы это сделать в хорошем, vectorised моды?

(В действительности, индексация в массив будет включать в себя несколько индексов, так что это может быть [1 1 2 2 1 1 1 1 3 3 3] и т.д., с массивом чисел, чтобы увеличить путем (на [20, 3] выше) той же длины.)

ответ

11

То, что вы хотите сделать, может быть сделано с помощью функции ACCUMARRAY, например, так:

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 

И выход из этого примера должно быть:

A = [33 40 30]; 


EDIT: Если A большой массив значений, и есть всего лишь несколько приращений, чтобы добавить следующее может быть вычислительно более эффективным, чем выше:

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 секунд быстрее :) – Adrien

+1

Спасибо, у меня есть тот первый, кто работает с удовольствием. Я считаю, что в SUBS отсутствует символ транспонирования, хотя я могу только сделать «A = accumarray ([1: numel (A) index] ', [A increment]);' work. Я сделаю некоторые сравнения скорости для второго предложения, как только мои данные будут заполнены. –

+0

@Bill: Вы правы. Я забыл, что первый вход должен быть вектором столбца в этом случае. В общем случае первый вход должен быть матрицей M-by-N, где M - количество накопленных значений, а N - количество индексов (в этом случае 1, но больше для многомерного индексации). – gnovice

1

Может быть есть что-то, чего я не совсем понимаю, но вы в основном пытаетесь добавить 23 к первому элементу A, правильно? Таким образом, вы можете написать:

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

Кроме того, если у вас есть массив индексов, вы можете написать

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

Это не решает его общая проблема. –

+0

@ Oli Charlesworth: Не уверен, что это происходит сейчас, но я отредактировал вопрос, когда вы писали комментарий. – Jonas

+1

Я думаю, что общий случай имеет 'toAdd' ту же длину, что и' indexArray'. Поэтому, если содержимое 'indexArray' было уникальным, вы просто выполните' A (indexArray) + toAdd'. –

Смежные вопросы