Понимание 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
По крайней мере, было бы видно, что это то, что говорится в документации.