gpt4 book ai didi

matlab - 乐趣取决于潜艇的顺序和 accumarray 中的值

转载 作者:太空宇宙 更新时间:2023-11-03 20:30:23 24 4
gpt4 key购买 nike

accumarray()关于“subs”的第一个注释,首先出现在 MATLAB R14sp3 docs , 说:

Note If the subscripts in subs are not sorted, fun should not depend on the order of the values in its input data.

我不清楚什么被认为是排序的。假设:

subs = [1 1
2 1
1 2
2 2];
  1. subs 是否应该按issorted(subs,'rows') 的方式排序,或者...
  2. linear indexing 意义,即 issorted(sub2ind([2 2],subs(:,1), subs(:,2)))

我想依靠:

accumarray(subs,val,[], @(x) x(end))

如果有人还可以提供旧版本的示例/测试(以检查向后兼容性),例如1) 是错误的,而 2) 是正确的,那就太好了。

附言。我主要对 accumarray 的替代品不感兴趣,除非非常简洁并且使用相同的 subsval

最佳答案

好的,我做了一些测试,我认为在 quote 中“排序”了是指 linear indexing 感觉。 (如果重要的话,我使用 R2013a)

要了解 accumarray 如何调用指定的函数,我将使用 trick通过将 fun = @(x) {x} 指定为要应用的函数,将值分组到一个 cellarray 中。

1) 一维索引

首先让我们创建一些下标和值

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 下标索引的情况下尝试了同样的事情。首先我们从随机数据开始:

%# 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})
  • 这是我尝试的时候 "sorting by rows" :

    [~,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})
  • 最后是我们按 "linear index" 排序的时候:

    [~,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})

我将省略长输出,并报告仅在最后一种情况下将值传递给函数 ordered。所以我得出结论,“排序”标准是基于线性索引的。

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 以来已被记录在案。 ,我会说依赖此功能是安全的(我怀疑任何使用此类旧版本的人都希望新代码无论如何都能正常工作!)

关于matlab - 乐趣取决于潜艇的顺序和 accumarray 中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17536558/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com