【问题标题】:Octave and Matlab "wat" matrix/vector inconsistenciesOctave 和 Matlab“wat”矩阵/向量不一致
【发布时间】:2013-04-13 08:22:05
【问题描述】:

我注意到 Matlab 和 octave 中的各种情况,其中函数接受矩阵和向量,但对向量的作用与对矩阵的作用不同。

这可能会令人沮丧,因为当您输入具有可变行数/列数的矩阵时,它可能会被解释为一个向量,并且当高度/宽度为 1 时会执行您不期望的事情,从而导致调试困难和怪异有条件的边缘情况。

我会列出一些我发现的,但我很好奇其他人遇到了什么

(注意:我只是在寻找代码接受矩阵作为有效输入的情况。当将非向量矩阵作为参数给出时引发异常的任何事情都不算数)

1) "diag" 可用于表示矩阵的对角线或将向量转为对角矩阵

由于前者通常只用于方阵,这在 matlab 中并不那么令人震惊,但在 Octave 中,当 Octave 将一个以非零元素开头的向量解释为“对角矩阵”时,可能会特别痛苦即

t=eye(3);
size(diag(t(:,3))) == [3,3]
size(diag(t(:,2))) == [3,3]
size(diag(t(:,1))) == [1,1]

2) 使用逻辑索引到行向量返回行向量

用逻辑索引到其他任何东西都会返回一个列向量

a = 1:3;
b = true(1,3);
size(a(b)) == [1, 3]
a = [a; a];
b = [b; b];
size(a(b)) == [6, 1]

3) 使用索引向量 i 对向量 v 进行索引会返回与 v 类型相同(行/列)的向量。但如果 v 或 i 是矩阵,则返回值的大小与 i 相同。

a = 1:3;
b = a';
size(a(b)) == [1, 3]
b = [b,b];
size(a(b)) == [3, 2]

4) max、min、sum 等单独对矩阵 M 的列进行运算,除非 M 为 1xn,在这种情况下,它们将 M 作为单个行向量进行运算

a = 1:3
size(max(a)) == [1, 1]
a = [a;a]
size(max(a)) == [1, 3]

max 特别糟糕,因为它甚至不能将维度作为参数(与 sum 不同)

在编写 octave/matlab 代码时我还应该注意哪些其他此类情况?

【问题讨论】:

  • 澄清一下:您可以指定最大/最小尺寸:min(rand(3),[],1)max(rand(3),[],2)

标签: matlab matrix vector octave


【解决方案1】:

1) 正如其他用户所指出的,在 Octave >= 3.6.4 时情况并非如此。

在情况 2) 中,规则是针对向量,始终返回相同形状的向量,对于其他任何内容,都返回列向量,请考虑:

>> a = reshape (1:3, 1,1,3)

a(:,:,1) =

     1.0000e+000


a(:,:,2) =

     2.0000e+000


a(:,:,3) =

     3.0000e+000

>> b = true(1,3)

b =

  1×3 logical array

   1   1   1

>> a(b)

ans(:,:,1) =

     1.0000e+000


ans(:,:,2) =

     2.0000e+000


ans(:,:,3) =

     3.0000e+000

>> a = [a;a]

a(:,:,1) =

     1.0000e+000
     1.0000e+000


a(:,:,2) =

     2.0000e+000
     2.0000e+000


a(:,:,3) =

     3.0000e+000
     3.0000e+000

>> b = [b;b]

b =

  2×3 logical array

   1   1   1
   1   1   1

>> a(b)

ans =

     1.0000e+000
     1.0000e+000
     2.0000e+000
     2.0000e+000
     3.0000e+000
     3.0000e+000

你可以看到这是有道理的,因为向量有一个明确的“方向”,但当你删除元素时,其他形状的矩阵没有。编辑:实际上我刚刚检查过,Octave 似乎并不完全以这种方式工作,但可能应该。

3) 这与 2) 一致。本质上,如果您提供索引列表,则会保留索引向量的方向。如果您提供具有矩阵形状的索引,则新信息是使用索引矩阵形状。这更加灵活,因为如果您愿意,您可以随时使用a(b(:)) 来保留a 的形状。您可能会说它不一致,但请记住,使用逻辑索引可能会减少要返回的元素数量,因此不能以这种方式重新调整它们。

4) 正如评论中指出的那样,您可以指定要操作的最大/最小维度:min(rand(3),[],1)max(rand(3),[],2),但在这种情况下,这些函数存在“遗留”问题,这些函数会在何时返回数据它们最初是被创造出来的,现在很难在不惹恼人们的情况下改变它们。

【讨论】:

    【解决方案2】:

    每种语言都有自己的概念。这种语言的一个重点是经常将矩阵视为一个向量数组,每列一个条目。事情将开始变得有意义。如果您不想要这种行为,请使用 matrix(:) 作为那些将传递单个向量而不是矩阵的函数的参数。例如:

    octave> a = magic (5);
    octave> max (a)
    ans =
    
       23   24   25   21   22
    
    octave> max (a(:))
    ans =  25
    

    1) 至少 Octave 3.6.4 并非如此。我不是 100% 确定,但可能与已修复的 this bug 有关。

    2) 如果您使用布尔值进行索引,它将被视为掩码并被视为掩码。如果您使用非布尔值进行索引,则将其视为值的索引。这对我来说很有意义。

    3) 这不是真的。返回的索引始终具有相同的大小,无论它是矩阵还是向量。唯一的例外是,如果索引是向量,则输出将是单行。这个想法是,使用单个向量/矩阵进行索引会返回相同大小的内容:

    octave> a = 4:7
    a =
    
       4   5   6   7
    
    octave> a([1 1])
    ans =
    
       4   4
    
    octave> a([1 3])
    ans =
    
       4   6
    
    octave> a([1 3; 3 1])
    ans =
    
       4   6
       6   4
    

    4) max 至少在 Octave 中确实将维度作为参数。来自max的3.6.4帮助文本:

    对于向量参数,返回最大值。对于矩阵 参数,返回每列的最大值,作为行向量, 或超过尺寸 DIM(如果已定义),在这种情况下 Y 应设置为 空矩阵(否则将被忽略)。

    其余的都适用,就像我在介绍中所说的那样。如果您提供一个矩阵,它会将每一列视为一个数据集。

    【讨论】:

    • 我认为你不明白我在问什么。我通常抱怨向量不被视为矩阵(而您似乎认为我的问题是矩阵不被视为向量)在情况 2 中,我只使用布尔值索引,而不是数字索引(在这两种情况下都没有) ),但一个返回行向量,另一个返回列向量。在案例 3 中,您提到的异常正是我所抱怨的。如果我有一个需要索引的矩阵,但该矩阵的列数是可变的,那么我必须为该异常编写一个 if 语句,只有 1
    猜你喜欢
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 2014-08-06
    • 2021-12-04
    • 1970-01-01
    • 2014-01-02
    相关资源
    最近更新 更多