Julia中nx1数组和n元素数组的区别

时间:2014-01-16 01:56:54

标签: julia

在Julia中,如果我定义一个包含1列和n行的数组,它似乎实例化了一个“n元素数组”,我不明白它与nx1数组有什么不同:

julia> a = [1 2 3]
1x3 Array{Int64,2}:
 1  2  3

julia> b = [1;2;3]
3-element Array{Int64,1}:
 1
 2
 3

令人困惑的是,如果我对n元素数组进行两次转置,则返回结果为nx1数组:

julia> transpose(transpose(b))
3x1 Array{Int64,2}:
 1
 2
 3

这导致了一些意想不到的(对我而言)行为,如:

julia> size(b) == size(transpose(transpose(b)))
false

我的问题:

  1. nx1数组和n元素数组有什么区别?
  2. 如何创建nx1数组而不执行像我给出的双转置示例。

1 个答案:

答案 0 :(得分:21)

快速回答:

  1. n x1或1x n数组是一个二维矩阵(恰好只有一行或一列),而你的n元素数组是一维列矢量。
  2. 我认为创建n x1数组文字的最简单方法是采用行向量的转置:[1 2 3]'。另一方面,您可以使用vec将任何n维数组展平为一维向量。

  3. 但是,考虑一下为什么这很重要,这更有启发性。 Julia的类型系统设计完全基于类型,而不是值。数组的维度包含在其类型信息中,但行数和列数不包括在内。因此,nx1矩阵和n元素向量之间的区别在于它们具有不同的类型......并且类型推理引擎无法看到矩阵只有一列。

    为了从Julia获得最佳性能,您(尤其是核心语言和库设计者)希望编写类型稳定的函数。也就是说,函数应该能够推断出它们将基于参数的类型纯粹返回的类型。这允许编译器通过函数跟踪变量,而不会丢失类型的跟踪...这反过来又允许它为特定类型生成非常高度优化的代码。

    现在,再考虑转座。如果你想要一个类型稳定的转置函数,它必须至少返回一个二维数组。如果其中一个维度为1并且仍然保持良好的性能,它就不能做一些棘手的事情。

    所有这一切,关于邮件列表和GitHub问题中的矢量转置仍然有很多讨论。这是一个开始的好地方:Issue #2686: ones(3) != ones(3)''。或者就相关问题进行更深入的讨论:Issue #3262: embed tensor-like objects as higher-dimensional objects with trailing singleton dimensions。两者最终被取代并归入Issue #4774: Taking vector transposes seriously


    Julia 0.6的更新:Julia现在非常重视矢量转置!向量转置现在返回一个特殊的RowVector类型,其行为类似于1行矩阵,但附加知识只有一行。它也是对原始矢量的懒惰“视图”。通过问题中的示例,这意味着size(b) == size(transpose(transpose(b)))不仅是真的,还有b'' === b

    在Julia 0.6中指定改变维度的重塑操作也更容易一些。上面问题2(创建nx1数组)的一个很好的答案是reshape([1,2,3], :, 1)。计算:指定的维度以匹配源数组的长度。