繁体   English   中英

Octave和Matlab“wat”矩阵/向量不一致

[英]Octave and Matlab “wat” matrix/vector inconsistencies

我已经注意到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不同)

在编写八度/ matlab代码时,我应该注意哪些其他类似的情况?

每种语言都有自己的概念。 这种语言的一个重点是经常将矩阵视为向量数组,每列都是一个条目。 事情将开始有意义。 如果您不想要这种行为,请使用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%肯定,但可能与已经修复的这个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中将维度作为参数。 从该3.6.4帮助文本max

对于矢量参数,返回最大值。 对于矩阵参数,返回每列的最大值,作为行向量,或者如果定义则返回维度DIM,在这种情况下,Y应该设置为空矩阵(否则将忽略它)。

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

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) ,但在此这些函数存在“遗留”问题,这些问题在第一次创建数据时就会重新出现,现在很难在不打扰人的情况下进行更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM