为什么Julia中的加号运算符是矢量化的,而不是除法运算符?

为什么Julia中的加号运算符是矢量化的,而不是除法运算符?,julia,Julia,我对Julia很陌生,我对Julia中的向量化操作很好奇 例如: x = [2 3 4] y = [3 4 5] 如果我使用以下命令运行上述命令: x + y 我得到: 1×3 Array{Int64,2}: 5 7 9 1×1 Array{Float64,2}: 0.7600000000000002 但如果我这样做: x/y 我得到: 1×3 Array{Int64,2}: 5 7 9 1×1 Array{Float64,2}: 0.7600000000000002

我对Julia很陌生,我对Julia中的向量化操作很好奇

例如:

x = [2 3 4]
y = [3 4 5]
如果我使用以下命令运行上述命令:

x + y
我得到:

1×3 Array{Int64,2}:
 5  7  9
1×1 Array{Float64,2}:
 0.7600000000000002
但如果我这样做:

x/y
我得到:

1×3 Array{Int64,2}:
 5  7  9
1×1 Array{Float64,2}:
 0.7600000000000002
这是我无法理解的,经过一些研究,我发现x/y是进行矢量化运算的正确方法,但我想知道为什么加号会起作用

以下是我的问题:

这背后的直觉是什么(使加号矢量化而不是除法运算符)

当我做x/y时会发生什么?为什么。76000是一个答案


我希望这不是复制品,如果是请告诉我。我将把它移走。非常感谢。请帮助。

注意:此解释是错误的,请阅读评论。我把它忘在这里了,所以以后没人会说这样的话


也许语言创建者可以给出更好的答案,但据我记忆所及,最初,大多数操作都是矢量化的。当广播发明时,运营商的大多数矢量化版本都被从基础中删除,除非它会包括对基础的大规模重写(或者如果它以某种方式影响性能,我不知道)。自然地,加法是比除法更常见的操作,因此它被省去了。

+
在任何数组上下文中都是明确的。它按元素运行,没有其他常见的解释。如果数组不是公共大小,则抛出错误

*
在矩阵上下文(二维数组)中是明确的。它指的是矩阵乘法。第一个输入的第二个维度的长度必须与第二个输入的第一个维度的长度匹配,否则将引发错误

但是,对于一般数组,
*
是不明确的。例如,如果
x
y
是数字向量(一维数组),那么
x*y
意味着什么?也许您想要执行操作元素,或者您想要内部产品?还是张量积?因此,如果使用两个向量作为输入调用,
*
将抛出错误。请注意,
*
是明确的,因为根据广播的定义,它只意味着元素乘法

这与
/
有什么关系?请注意,
/
是右除法运算符,即
x
y
的逆或伪逆相乘(其中
y
位于
x
的右侧)。因此,
*
的语义在这里适用,还有一个额外的约束条件,即
y
必须能够反转(或者至少是摩尔-彭罗斯反转)。如果满足这些约束,则
/
是明确的,因此定义。如果他们不满意,那么
/
将抛出一个错误(至少应该是这样):-)

此操作绝对不是元素操作,这就是为什么对于两个向量的情况,
/
不同于
/

现在,记住所有这些,以你的例子为例。首先,请注意,实际上并没有定义向量。向量定义为
[1,2]
。但是你正在做的是一个矩阵。因此操作
[12]/[34]
相当于
[12]*pinv([34])
。这里定义了伪逆,因为
[12]
是1x2,
pinv([34])
是2x1,结果将是1x2x1数组,即1x1矩阵,这正是您得到的


请注意,
[1,2]/[3,4]
返回一个2x2矩阵。同样,这也是有意义的,因为
[1,2]
隐式地是2x1,而
pinv([3,4])
是1x2,所以输出将是2x1 x 1x2,或者更确切地说,是2x2矩阵。

AFAICT
+
运算符不会自动广播:

julia> 1 + [2, 3]
ERROR: MethodError: no method matching +(::Int64, ::Array{Int64,1})
For element-wise addition, use broadcasting with dot syntax: scalar .+ array

julia> [1 2] + [3, 4]
ERROR: DimensionMismatch("dimensions must match: a has dims (Base.OneTo(1), Base.OneTo(2)), b has dims (Base.OneTo(2),), mismatch at 1")
你必须分别写下:

julia> 1 .+ [2, 3]
2-element Array{Int64,1}:
 3
 4

julia> [1 2] .+ [3, 4]
2×2 Array{Int64,2}:
 4  5
 5  6
然而,重要的是,
+
对于维度完全相同的数组来说是一种有效的操作(从数学意义上讲),这就是为什么这样做的原因:

julia> [2 3 4] + [3 4 5]
1×3 Array{Int64,2}:
 5  7  9
请注意,这不是广播,而是线性代数

现在关于
x/y
,您可以检查它是否定义为:

help?>  x / y
  /(x, y)

  Right division operator: multiplication of x by the inverse of y on the right.
所以你有:

julia> using LinearAlgebra

julia> x * pinv(y)
1×1 Array{Float64,2}:
 0.7600000000000005

(实际实现有点不同-我在这里使用简化的方法)

y
不必反转。在AICT中使用伪逆。不幸的是,
/
的docstring有点不精确,例如,
rand(3)/rand(3)
没有错误,因为两个向量的列数相同(即1)。@BogumiłKamiński是的,我在提交答案后检查了REPL,并意识到psuedo反转是允许的:-)我正在修复我的问题answer@PKumar别担心。我现在已经修复了这一切,并解释了给定输入的psuedo倒数的维度,您可以期望什么样的输出。如果您认为我已经回答了问题,请随意单击我的答案旁边的勾号,标记已回答的问题。干杯。不,标准不是重写。我们留下了线性代数所要求的向量化运算,即那些对数组有明确的标准数学定义的运算。