单例向量不同于它在 Julia 中的转置

Singleton vector different from its transpose in Julia

如果我定义 A = [1] 我得到 A 不等于 A' 因为它们是不同的类型:

julia> A=[1]
1-element Array{Int64,1}:
 1

julia> A'
1×1 LinearAlgebra.Adjoint{Int64,Array{Int64,1}}:
 1

julia> A == A'
false

如果我定义另一个向量 B = [1, 2, 3] 并尝试使用 A'A 进行乘积,我将获得以下输出:

B=[1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

julia> B*A'
3×1 Array{Int64,2}:
 1
 2
 3

julia> B*A
ERROR: MethodError: no method matching *(::Array{Int64,1}, ::Array{Int64,1})
...
...

这似乎是 * 运算符签名的问题,在定义另一个向量时似乎不接受两个 Array{Int64,1} 作为操作数 C = [4 5] 我们得到:

julia> C=[4 5]
1×2 Array{Int64,2}:
 4  5

julia> B*C
3×2 Array{Int64,2}:
  4   5
  8  10
 12  15

所以*分别定义为Array{Int64,1}Array{Int64,2}类型的操作数。为什么我不能将列向量乘以单例向量 A 但我可以使用 A'?

这个问题的答案取决于你对线性代数的理解程度。 Julia 的数组乘法遵循线性代数的约定,如果您需要复习,wikipedia's page 是一个很好的来源。

归结为这样一个事实,即您的 A 是一个列向量,而 A' 是一个行向量(如 C)。在 (n, k)(k, m) 矩阵之间定义矩阵乘法以生成 (n, m) 矩阵。列向量有时可以被认为是 (n, 1) 矩阵,因此两个列向量之间没有明确定义的乘法概念。

如果您想要点积,请使用 dot 函数(您需要先执行 using LinearAlgebra)。如果你想要一个元素级产品,你可以使用广播符号,u .* v

在 Julia 中,Vectors 是一维的 Arrays,而转置适用于二维矩阵(Array{T,2} 相当于 Matrix{T}

julia> A=[1]
1-element Array{Int64,1}:
 1

julia> collect(A')
1×1 Array{Int64,2}:
 1

由于 Julia 中的转置不会具体化数据,而是保留对原始数据的引用,因此我需要使用 collect 来实际查看发生了什么。

在二维数组上使用乘法时,您实际上是在使用线性代数运算。

如果您想按元素相乘,请改用点 . 运算符:

julia> A .== A'
1×1 BitArray{2}:
 1

注意它 return 一个 Array 而不是单个值。

如果您想按元素相乘(而不是使用线性代数矩阵乘法),您需要再次向量化:

julia> B.*A
3-element Array{Int64,1}:
 1
 2
 3