Хорошо, я провел несколько тестов и думаю, что "отсортировано" в цитате означает в линейном индексировании смысл. (Я использую R2013a, если это важно)
Чтобы понять, как accumarray
вызывает указанную функцию, я воспользуюсь приемом группировки значений в подвал, указав fun = @(x) {x}
в качестве применяемой функции.
1) 1D индексы
Сначала давайте создадим некоторые индексы и значения
N = 10; sz = 4;
subs = randi([1 sz], [N 1]);
vals = (1:N)'*100;
Теперь мы вызываем ACCUMARRAY для несортированных индексов (несколько раз)
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs, vals, [], @(x){x});
end
Порядок значений, передаваемых в функцию, произвольный, но все же согласованный для нескольких запусков:
>> assert(isequal(C{:}))
>> celldisp(C{1})
ans{1} =
800
900
700
ans{2} =
300
ans{3} =
1000
200
100
ans{4} =
400
600
500
Вот почему документация предупреждает вас, что fun
не должен зависеть от порядка передаваемых ему значений.
Теперь, если предварительно отсортировать индексы:
[~,ord] = sort(subs);
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs(ord), vals(ord), [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
мы увидим, что значения передаются в отсортированную функцию:
ans{1} =
700
800
900
ans{2} =
300
ans{3} =
100
200
1000
ans{4} =
400
500
600
2) 2D индексы
Я пробовал то же самое в случае индексов 2D-индекса. Сначала мы начнем со случайных данных:
%# some 2d subscripts and corresponding values
N = 10; sz = 2;
subs = randi([1 sz], [N 2]);
vals = (1:N)*100;
Вот случай с несортированными индексами:
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs, vals, [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
Вот когда я попробовал "сортировку по строкам":
[~,ord] = sortrows(subs, [1 2]);
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs(ord,:), vals(ord), [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
И, наконец, вот когда мы сортируем по "линейному индексу":
[~,ord] = sort(sub2ind([sz sz], subs(:,1), subs(:,2)));
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs(ord,:), vals(ord), [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
Я опущу длинный вывод и сообщу, что только в последнем случае, когда значения были переданы в функцию order. Итак, я прихожу к выводу, что «отсортированные» критерии основаны на линейных показателях.
ans{1,1} =
[]
ans{2,1} =
200
600
700
ans{1,2} =
100
300
400
500
1000
ans{2,2} =
800
900
Бонус:
Вместо этого попробуйте использовать следующую функцию:
function out = fun(x)
out = {x};
disp('[')
disp(x)
disp(']')
end
вы увидите, что функция вызывается непредсказуемым образом, даже с некоторым дублированием! Возможно, вам придется увеличить размер данных, чтобы увидеть такое поведение ...
Что касается обратной совместимости, документация упоминает это примечание полностью назад в MATLAB R14sp3, но не R14sp2 а>. Учитывая тот факт, что это было задокументировано с 2005, я бы сказал, что можно с уверенностью полагаться по этой функции (я сомневаюсь, что кто-то, использующий такие старые версии, ожидает, что новый код все равно будет работать!)
person
Amro
schedule
08.07.2013