【问题标题】:Matlab: Odd linear indexing into array with singleton dimensionsMatlab:奇数线性索引到具有单维数的数组中
【发布时间】:2018-09-14 14:52:42
【问题描述】:

我无法理解线性索引适用的情况。

对于二维数组,看起来很直观:

>> clear x
>> x=[1 2;3 4]
x =
     1     2
     3     4
>> x([1 2])
ans =
     1     3
>> x([1;2])
ans =
     1
     3

对于 3D 矩阵,看起来很直观:

>> clear y
>> y(1:2,1:2,1)=x
y =
     1     2
     3     4
>> y(1:2,1:2,2)=x+10
y(:,:,1) =
     1     2
     3     4
y(:,:,2) =
    11    12
    13    14
>> y([1 2])
ans =
     1     3
>> y([1;2])
ans =
     1
     3

对于第一个二维是单例的 3D 矩阵,这不是我所期望的:

>> clear y
>> y(1,1,1)=1
y =
     1
>> y(1,1,2)=2
y(:,:,1) =
     1
y(:,:,2) =
     2
>> y([1 2])
ans(:,:,1) =
     1
ans(:,:,2) =
     2
>> y([1;2])
ans(:,:,1) =
     1
ans(:,:,2) =
     2

我本来期望与没有单一维度的 3D 矩阵完全相同。

是否有可以依赖的规则来预测线性索引的行为?

【问题讨论】:

    标签: matlab indexing


    【解决方案1】:

    数组x与数组ind的线性索引规则如下(取自this great post by Loren Shure):

    • 如果x 和ind 中的至少一个不是向量(也就是说,如果x 或ind 有多个非单一维度),则输出具有相同的形状 (size) as ind:

      >> x = rand(3,4);
      >> ind = [9 3];
      >> x(ind)
      ans =
         0.276922984960890   0.743132468124916
      
      >> x(ind.')
      ans =
         0.276922984960890
         0.743132468124916
      
      >> x = rand(2,3,4);
      >> ind = [1 2; 5 6];
      >> x(ind)
      ans =
         0.814723686393179   0.905791937075619
         0.632359246225410   0.097540404999410
      
    • 如果x 和ind 都是向量,则输出是一个与x 具有相同方向 的向量(即非单一的输出维度是@ 987654333@),以及与ind 相同的元素数:

      >> x = 10:10:70;
      >> ind = [1 3 5];
      >> x(ind)
      ans =
           10    30    50
      
      >> x(ind.')
      ans =
           10    30    50
      
      >> x = reshape(10:10:70,1,1,[]); % 1×1×7
      >> ind = reshape([2 3 4],1,1,1,1,[]); % 1×1×1×1×3
      >> x(ind)
      ans(:,:,1) =
          20
      ans(:,:,2) =
          30
      ans(:,:,3) =
          40
      

    为了完整起见,如果应用两个或更多索引数组(因此这不再是线性索引),输出的形状由哪个维度决定原始数组被索引,并由每个索引数组的元素数。它与索引数组的形状无关,它们像往常一样以列主要顺序简单地读取:

    >> x = [10 20 30 40; 50 60 70 80];
    >> x(2, [1 2; 3 4])
    ans =
        50    70    60    80
    
    >> x(2, [1 2 3 4])
    ans =
        50    60    70    80
    
    >> x(2, reshape([1 2 3 4],1,1,1,[]))
    ans =
        50    60    70    80
    

    如果索引的数量少于x 的维度数,则x 的尾随维度会在应用索引之前隐式折叠为一个:

    >> x = [10 20 30 40; 50 60 70 80];
    >> x(:,:,2) = x+100;
    >> x([1 2], [1; 5; 7; 8])
    ans =
        10   110   130   140
        50   150   170   180
    

    【讨论】:

    • 另一个很好的 MATLAB 中基于单一维度的不一致的例子。如果您不确定您的输入没有单一维度,则不能指望输出的形状。与max 和sum 以及所有那些在列上工作的函数相同,除非第一个维度是单例,那么它在行上工作。 :(
    • 作为写过多个版本的max 和sum 的人,我能感受到你的痛苦。但是,所有归约函数都支持显式维度参数,让您获得完全编程的行为。
    • @CrisLuengo IMO 它并非不一致 - 它适用于第一个非单维维度,如果您认为通常会有行或列向量并且您显然想要总和,这很有意义案例中的所有元素。它只是将相同的行为扩展到矩阵 - 不这样做将是一个“陷阱”。另一件事是 max 和 sum 都将最终矩阵维度减少了 1。在已经单例维度上操作不会实现这一点。但是,是的,您需要始终使用 max(A(:)) 或 max(A, dim);普通的旧 max(A) 肯定会出错。
    • @ZizyArcher:我了解其中的原因,也了解解决方法。但这仍然是用户错误的原因。这些不一致的真正原因是 MATLAB 没有真正的向量,总是至少有 2 个维度。向量和单维矩阵不应该是一回事。
    • @Luis Mendo:非常感谢。当您添加有关非线性索引的内容时,我的大脑开始受伤,因此我将把它留到咖啡店里另一个懒惰的星期天。顺便说一句,x = 10:10:7; 实际上应该是x = 10:10:70;吗?
    猜你喜欢
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 2019-01-09
    • 1970-01-01
    相关资源
    最近更新 更多