Понимание accmarray в Matlab

Мне нужно понять тарабар, чтобы написать код, который мне действительно нужен.

Я пытался понять http://www.mathworks.co.kr/kr/help/matlab/ref/accumarray.html

Большинство примеров были понятны.

Однако в первом примере примера 2 я подумал

(1,2) -й элемент B должен быть 1

так как

(1,2) = 1st, 2nd of subs
1st, 2nd of vals = 101, 102
sum(diff([101,102]))=1

Кроме того, во втором примере примера 2 я подумал

(1,2) -й элемент B1 должен быть 2 вместо -2

так как

(1,2) = 1st, 3rd of subs
1st, 3rd of vals = 101, 103
sum(diff([101,103]))=2

а также я думал

(4,1) элемент B1 должен быть 1 вместо -1

так как

(4,1) = 5,6th of subs
5,6th of vals = 105,106
sum(diff([105,106]))=1

Что мне не хватает?

Пожалуйста, исправьте, мне нужно глубоко понять accmarray, чтобы написать собственный код.

2 ответа

Я думаю, что неожиданные значения вызваны тем, что вы ожидаете, что значения будут переданы анонимной функции в том же порядке, в котором соответствующие индексы появляются в подпрограммах.

Тем не менее, документация для accmarray гласит:

Примечание. Если подписки в подпрограммах не сортируются, веселье не должно зависеть от порядка значений во входных данных.

Это означает, что запуск подпрограмм ( 1 2; 1 2;) может привести к тому, что 102 101 или 101 102 будут переданы анонимной функции (поскольку в документации сказано, что веселье не должно зависеть от порядка значений.

sum (diff ([102 101])) равно -1, что является значением, записанным в элемент 1,2 в примере

val = 101:106;
subs=[1 2; 1 2; 3 1; 4 1; 4 4; 4 1];
B = accumarray(subs,val,[],@(x)sum(diff(x)))

B =

     0    -1     0     0
     0     0     0     0
     0     0     0     0
     2     0     0     0

Я не уверен, почему Mathworks выбрал бы использование функции diff в примере, когда результат diff явно зависит от порядка значений, переданных ему.

Похоже, что упорядочение входных значений является причиной того, что другие выходные значения отличаются от ваших ожиданий.

Почему в ответе Гранта, вот как получить предсказуемое поведение.

Как говорится в документации: "Если подписчики в subs не отсортированы, fun не должно зависеть от порядка значений во входных данных."Таким образом, чтобы получить предсказуемое поведение из accumarray, подводные лодки должны быть отсортированы.

Для индексов, представляющих местоположения (строки, столбцы) в матрице, это означает, что элементы, на которые указывают индексы, должны быть упорядочены в соответствии с линейным индексом. Таким образом, для "сортировки" 2D подписок необходимо отсортировать эквивалентный линейный индекс. Затем вам нужно применить этот порядок к valsиначе вы зашифровали свои данные.

val = 101:106;
subs = [1 2; 1 2; 3 1; 4 1; 4 4; 4 1];

% convert the subscripts to linear inds and sort them
inds = sub2ind([4 4],subs(:,1),subs(:,2));
[indsSorted,sortingInds] = (sort(inds));

% apply the sorting to val
valsSorted = val(sortingInds);

% convert inds back to subs
[iiS jjS] = ind2sub([4 4],indsSorted);
subsSorted = [iiS jjS];

B = accumarray(subsSorted,valsSorted,[],@(x)sum(diff(x)))

B =

     0     1     0     0
     0     0     0     0
     0     0     0     0
     2     0     0     0

По крайней мере, было бы видно, что это то, что говорится в документации.

Другие вопросы по тегам