有趣的是,取决于accumarray中子和值的顺序 [英] Fun depending on order of subs and values in accumarray

查看:100
本文介绍了有趣的是,取决于accumarray中子和值的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

accumarray() 中,有关'subs ",最早出现在MATLAB R14sp3文档中,说:

注意:如果未对sub中的下标进行排序,则乐趣不应取决于其输入数据中值的顺序.

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

对我来说不清楚是什么被分类.假设:

It is not clear to me what is considered to be sorted. Suppose:

subs = [1 1
        2 1
        1 2
        2 2];

  1. 应按issorted(subs,'rows')的含义对subs进行排序,或者...
  2. 线性索引中 意义,即issorted(sub2ind([2 2],subs(:,1), subs(:,2)))
  1. shall subs be sorted in the sense issorted(subs,'rows'), or ...
  2. in the linear indexing sense, i.e. issorted(sub2ind([2 2],subs(:,1), subs(:,2)))

我想依靠:

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

如果有人还可以提供旧版本中的示例/测试(以检查向后兼容性),例如1)是错误的,而2)是真实的,那将是非常好的.

If somebody could also provide examples/tests from older releases (to check for backward compatibility) where e.g. 1) is false while 2) is true, that would be great.

PS.我对accumarray的替代品几乎不感兴趣,除非非常简洁并且使用相同的subsval.

PS. I am mostly not interested in alternatives to accumarray, unless very succinct and using the same subs and val.

推荐答案

好,我做了一些测试,我认为

Ok I did some tests, and I think that "sorted" in the quote is meant in the linear indexing sense. (I'm on R2013a if that matters)

要了解accumarray如何调用指定的函数,我将使用技巧,方法是将fun = @(x) {x}指定为要应用的函数,将值分组到一个单元格中.

To understand how accumarray calls the specified function, I'll use the trick of grouping the values into a cellarray by specifying fun = @(x) {x} as the function to be applied.

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

First lets create some subscripts and values

N = 10; sz = 4;
subs = randi([1 sz], [N 1]);
vals = (1:N)'*100;

现在,我们对未排序的索引调用ACCUMARRAY(多次)

Now we call ACCUMARRAY on the non-sorted indices (multiple times)

C = cell(5,1);
for i=1:5
    C{i} = accumarray(subs, vals, [], @(x){x});
end

传递给函数的值的顺序是任意的,但在多次运行中仍保持一致:

The order of the values passed to the function is arbitrary but still consistent across the multiple runs:

>> 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不应依赖于传递给它的值的顺序的原因.

This is why the documentation warns you that fun should not depend on the order of the values passed to it.

现在,如果我们预先对下标进行排序:

Now if we sort the subscripts beforehand:

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

我们将看到将值传递给自己排序的函数:

we will see that the values are passed to the function sorted themselves:

ans{1} =
   700
   800
   900
ans{2} =
   300
ans{3} =
         100
         200
        1000
ans{4} =
   400
   500
   600

2)2D索引

在2D下标索引的情况下,我尝试过相同的操作.首先,我们从随机数据开始:

2) 2D indices

I've tried the same thing in the case of 2D subscript indices. First we start with random data:

%# some 2d subscripts and corresponding values
N = 10; sz = 2;
subs = randi([1 sz], [N 2]);
vals = (1:N)*100;

  • 未排序索引的情况如下:

    • Here is the case for non-sorted indices:

      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})
      

    • 我将省略长输出,并仅报告在最后一种情况下将值传递给函数 ordered 的情况.因此,我得出结论,排序"标准是基于线性指标的.

      I'll omit the long output, and report that only in the last case that the values were passed to the function ordered. So I conclude that the "sorted" criteria is based on the linear indices.

      ans{1,1} =
           []
      ans{2,1} =
         200
         600
         700
      ans{1,2} =
               100
               300
               400
               500
              1000
      ans{2,2} =
         800
         900
      


      奖金:

      尝试使用以下功能代替


      Bonus:

      Try using the following function instead:

      function out = fun(x)
          out = {x};
          disp('[')
          disp(x)
          disp(']')
      end
      

      您将看到该函数以一种无法预测的方式被调用,即使有一些重复!您可能必须增加数据的大小才能看到这种行为...

      you'll see that the function is called in an unpredictable way, even with some duplication! You might have to increase the size of the data to see such behavior...

      就向后兼容性而言,文档在MATLAB R14sp2 .鉴于自 2005 起便已对其进行了记录,因此我可以肯定地说

      As far as backward compatibility goes, the documentation mentions this note all the way back in MATLAB R14sp3 but not R14sp2. Given the fact that it's been documented since 2005, I'd say it is safe to rely on this feature (I doubt anyone using such old versions expects new code to just work anyway!)

      这篇关于有趣的是,取决于accumarray中子和值的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆