Julia中的1元素数组到标量

vuk*_*ung 2 vector matrix-multiplication julia

将行和列向量相乘,我期望结果是标量,但它是一维的1元素数组:

julia> [1 2 3] * [4; 5; 6]
1-element Array{Int64,1}:
 32
Run Code Online (Sandbox Code Playgroud)

问题1:这背后的理由是什么?

问题2:接受这个作为Julia的怪癖,我想将1元素数组转换为标量.使用[1]的第一个元素是一个选项,但不是很可读.这种特殊方式是什么?

Chr*_*kas 6

每个表达式都可以执行,因此您可以使用

([1 2 3] * [4; 5; 6])[1]
Run Code Online (Sandbox Code Playgroud)

得到第一个(唯一的价值).

这有一个主要的性能原因:类型稳定性.基本上,在编译语言中,如果不进行大量转换,则无法更改类型.Julia有点聪明,但是如果你做了很多转换,那么你的代码将会变慢,因为编译器必须保留很多"kruft",以防万一你的类型错误.因此,通过确保类型稳定性,编译器可以预先知道类型是什么,并进行更多优化.这是性能提示之一.实际上,由于多次调度和类型稳定性,Julia速度快且达到C速度,因此应该受到尊重.

Array*Array给出一个数组.为了使其类型稳定,它必须总是给出一个数组.否则,编译器需要在每个使用输出的地方放置额外的代码来检查该变量是否为数组!那么你应该使用*with arrays来获取数组.如果你想得到一个标量,那么简单的答案就是使用这个dot函数:

dot([1;2;3],[4;5;6])
Run Code Online (Sandbox Code Playgroud)

当然我可以这样说,但是知道"为什么"是很好的,因为类型稳定性对于高性能代码来说是一个非常重要的想法.

  • 我更喜欢使用“[]”,这反过来又提醒我这是一个单元素数组。 (2认同)
  • FWIW,编写“dot”方法将是最快的,因为您可以在不分配数组的情况下完成它。带有“[1]”的“*”将分配一个大小为1的数组和一个数字,并且在求和时必须保持解引用。因此,我更愿意只编写一个带有 for 循环的“点”函数(因为普通点需要两个向量)(如果实际矩阵足够大,那么您也可以轻松地进行多线程或并行化它)。 (2认同)