简体   繁体   English

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

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

I've noticed various cases in Matlab and octave where functions accept both matrices and vectors, but doesn't do the same thing with vectors as it does with matrices. 我已经注意到Matlab和octave中的各种情况,其中函数同时接受矩阵和向量,但是对于向量和对矩阵没有做同样的事情。

This can be frustrating because when you input a matrix with a variable number of rows/columns, it could be interpreted as a vector and do something you don't expect when the height/width is 1 making for difficult debugging and weird conditional edge cases. 这可能令人沮丧,因为当您输入具有可变数量的行/列的矩阵时,它可以被解释为向量并且当高度/宽度为1时执行您不期望的事情,这使得难以进行调试和奇怪的条件边缘情况。

I'll list a few I've found, but I'm curious what others people have run into 我会列出一些我发现的,但我很好奇其他人遇到的情况

(Note: I'm only looking for cases where code accepts matrices as valid input. Anything that raises an exception when a non-vector matrix is given as an argument doesn't count) (注意:我只是在寻找代码接受矩阵作为有效输入的情况。当非向量矩阵作为参数给出时引发异常的任何事情都不计算在内)

1) "diag" can be used to mean diagonal of a matrix or turn a vector into a diagonal matrix 1)“diag”可用于表示矩阵的对角线或将矢量转换为对角矩阵

Since the former is generally only used for square matrices this isn't so egregious in matlab, but in Octave it can be particularly painful when Octave interperets a vector beginning with a nonzero element and everything else zeros as a "diagonal matrix" ie 由于前者通常仅用于方形矩阵,因此在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) Indexing into a row-vector with logicals returns a row-vector 2)索引到具有逻辑的行向量返回行向量

Indexing into anything else with logicals returns a column vector 使用逻辑索引到任何其他内容会返回列向量

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

3) Indexing into a vector v with an index vector i returns a vector of the same (row/col) type as v. But if either v or i is a matrix, the return value has the same size as i. 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 etc. operate on the columns of a matrix M individiually unless M is 1xn in which case they operate on M as a single row-vector 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 is particularly bad since it can't even take a dimension as an argument (unlike sum) max特别糟糕,因为它甚至不能将维度作为参数(与sum不同)

What other such cases should I watch out for when writing octave/matlab code? 在编写八度/ matlab代码时,我应该注意哪些其他类似的情况?

Each language has its own concepts. 每种语言都有自己的概念。 An important point of this language is to very often think of matrices as an array of vectors, each column an entry. 这种语言的一个重点是经常将矩阵视为向量数组,每列都是一个条目。 Things will start to make sense then. 事情将开始有意义。 If you don't want that behavior, use matrix(:) as the argument to those functions which will pass a single vector, rather than a matrix. 如果您不想要这种行为,请使用matrix(:)作为那些将传递单个向量而不是矩阵的函数的参数。 For example: 例如:

octave> a = magic (5);
octave> max (a)
ans =

   23   24   25   21   22

octave> max (a(:))
ans =  25

1) This is not true with at least Octave 3.6.4. 1)至少Octave 3.6.4不是这样。 I'm not 100% sure but may be related related to this bug which has already been fixed. 我不是100%肯定,但可能与已经修复的这个bug有关。

2) If you index with boolean values, it will considered to be a mask and treated as such. 2)如果使用布尔值进行索引,则将其视为掩码并将其视为此类。 If you index with non-boolean values, then it's treated as the indexes for the values. 如果使用非布尔值进行索引,则将其视为值的索引。 This makes perfect sense to me. 这对我来说非常有意义。

3) This is not true. 3)事实并非如此。 The returned has always the same size of the index, independent if it's a matrix or vector. 返回的索引总是与索引大小相同,如果它是矩阵或向量则是独立的。 The only exception is that if the index is a vector, the output will be a single row. 唯一的例外是如果索引是向量,则输出将是单行。 The idea is that indexing with a single vector/matrix returns something of the same size: 我们的想法是使用单个向量/矩阵进行索引会返回相同大小的内容:

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 does take dimension as argument at least in Octave. 4) max确实至少在Octave中将维度作为参数。 From the 3.6.4 help text of max : 从该3.6.4帮助文本max

For a vector argument, return the maximum value. 对于矢量参数,返回最大值。 For a matrix argument, return the maximum value from each column, as a row vector, or over the dimension DIM if defined, in which case Y should be set to the empty matrix (it's ignored otherwise). 对于矩阵参数,返回每列的最大值,作为行向量,或者如果定义则返回维度DIM,在这种情况下,Y应该设置为空矩阵(否则将忽略它)。

The rest applies like I said on the intro. 其余的适用就像我在介绍中说的那样。 If you supply a matrix, it will think of each column as a dataset. 如果提供矩阵,它会将每列视为数据集。

1) As pointed out by the other user, this is not true with at Octave >= 3.6.4. 1)正如其他用户所指出的那样,在Octave> = 3.6.4时不是这样。

In case 2) the rule is for vectors, return always the same shape of vector, for anything else return a column vector, consider: 在情况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

You can see that this makes sense since vectors have a clear 'direction' but other shaped matrices do not when you remove elements. 您可以看到这是有道理的,因为向量具有明确的“方向”,但是当您移除元素时,其他形状的矩阵则不会。 EDIT: actually I just checked and Octave doesn't seem work this way exactly, but probably should. 编辑:实际上我刚刚检查过,Octave看起来并不像这样,但可能应该。

3) This is consistent with 2). 3)这与2)一致。 Essentially if you supply a list of indices the direction of the indexed vector is preserved. 基本上,如果提供索引列表,则保留索引向量的方向。 If you supply indices with a shape like a matrix, the new information is the index matrix shape is used. 如果提供具有类似矩阵的形状的索引,则新信息是使用的索引矩阵形状。 This is more flexible, since you can always do a(b(:)) to preserve the shape of a if you so wish. 这是更灵活,因为你总是可以做a(b(:))保持的形状a ,如果你愿意的话。 You may say it is not consistent, but remember indexing with logicals may reduce the number of elements to be returned, so they cannot be reshaped in this way. 您可能会说它不一致,但请记住使用逻辑索引可能会减少要返回的元素数量,因此无法以这种方式重新整形。

4) As pointed out in a comment, you can specify dimension for max/min to operate on: min(rand(3),[],1) or max(rand(3),[],2) , but in this case there are 'legacy' issues with these functions which data back to when they were first created and now are very difficult to change without upsetting people. 4)正如评论中所指出的,您可以指定操作的最大/最小维度: min(rand(3),[],1)max(rand(3),[],2) ,但在此这些函数存在“遗留”问题,这些问题在第一次创建数据时就会重新出现,现在很难在不打扰人的情况下进行更改。

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

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