为什么 nansum 对超过矩阵维度的输入有效?

Why does nansum work for input that exceeds matrix dimensions?

我想知道 matlab 的 nansum 函数。

当我用的例子from the documentation

X = magic(3);
X([1 6:9]) = repmat(NaN, 1, 5);

X =

   NaN     1   NaN
     3     5   NaN
     4   NaN   NaN

然后调用

>> nansum(X, 1)

ans =

     7     6     0

>> nansum(X, 2)

ans =

     1
     8
     4

它按预期工作。

然而,没想到的是,它也适用于

>> nansum(X, 400)

ans =

     0     1     0
     3     5     0
     4     0     0

这里的推理是什么?为什么这不会因 dim 超出矩阵维度的错误而崩溃?

矩阵确实有第 400 维。它是 1。因此,当您在这个维度上求和时,它只是 returns 您作为输入给出的矩阵,其中 NaN 被省略/计为 0。

与标准相同sum

>>A = magic(3)

A =

     8     1     6
     3     5     7
     4     9     2

>>sum(A,400)

ans =

     8     1     6
     3     5     7
     4     9     2

编辑: 一个可能更好的例子是

A = 5;

这个变量有 size(A)=[1,1]; 换句话说维度 1 的大小是 1 就像它的第 400 个维度一样,但是总和

仍然有意义
sum(A)

ans =

     5

在 MATLAB 中,所有 arrays/matrices 都有无限的单例尾随维度。

单一维度是维度 dim,其中 size(A,dim) = 1。当它出现在所有非单一维度之后时,它被称为尾随单一维度(即它不会改变矩阵的结构)。

任何可以在特定维度上运行的函数(包括 nansum)都可以在任何一个无限单例维度上运行。通常你不会看到任何影响(例如以这种方式使用 maxsum 只是 returns 输入 [1]),但是 nansumNaN 替换为零,所以就是这样。

注意 nansum(A,dim)sum(A,dim,'omitnan') 相同。您可以通过键入 edit nansum 来查看。所以我的例子使用 sum 是为了方便。有关已定义行为的参考,请参阅此答案的底部。

让我们想象一下:

A = ones(3,4);
size( A ) % >> ans = [3, 4]
% Under the hood:
% size( A ) = [3, 4, 1, 1, 1, 1, ...]
sum( A, 1 )   % Sum through the rows, or the 1st dimension, which has 3 elements per sum
              % >> ans = [3 3 3 3]
sum( A, 2 )   % Sum through the columns, or the 2nd dimension, which has 4 elements per sum
              % >> ans = [4; 4; 4]
sum( A, 400 ) % Sum through the ???, the 400th dimension, which has 1 element per sum
              % >> ans = [1 1 1 1; 1 1 1 1; 1 1 1 1]

如果需要,您可以 reshape 原始矩阵具有第 2 维到第 399 维的单一矩阵,以进一步实现:

% Set up dimensions as [3, 1, 1, ..., 1, 1, 4], for a 400-D array!
dims = num2cell( [3 ones(1,398), 4] );
% Note we'll now still have trailing singleton dims, but have 398 in the structure too
B = reshape( A, dims{:} ); 

现在我们可以做一个类似的sum例子。最后要知道的是 squeeze 删除了非尾随单例维度,我们可以用它来整理输出:

sum( B, 1 ); % >> ans(:,:,1,1,1,...,1) = 3 
             % >> ans(:,:,1,1,1,...,2) = 3
             % >> ans(:,:,1,1,1,...,3) = 3
             % >> ans(:,:,1,1,1,...,4) = 3
squeeze( sum( B, 1 ) ); % >> ans = [3; 3; 3; 3] 

% similarly  
squeeze( sum( B, 2 ) );   % >> ans = [1 1 1 1; 1 1 1 1; 1 1 1 1]
squeeze( sum( B, 400 ) ); % >> ans = [4; 4; 4]

我们可以看到,现在我们已经重塑了事物,在第 400 维求和与最初在 2 维求和的效果相同,反之亦然。如果将 400 替换为 3!

,这将更容易可视化

[ 1 ] 请参阅 sum and max 文档作为明确定义行为的示例 "if dim is greater than ndims(A)." 在这两种情况下,仅通过返回 A。在 nansum 的情况下,如果元素是 NaN.

则必须进行一些计算

矩阵没有第 400 维(更好的是,它具有无限隐式单例维),简单地实现 sum return 当 dim 输入超过矩阵维时矩阵作为 sum 的文档说:

sum returns A 当dim大于ndims(A)或当size(A,dim)为1

https://it.mathworks.com/help/matlab/ref/sum.html#btv6ok6-3