从矩阵切片创建行向量

Nos*_*All 3 vector slice julia

我想知道是否有人有明确的方法从矩阵切片返回行向量?

matrix[k,:]
Run Code Online (Sandbox Code Playgroud)

实际上返回一个 size 的向量(n,),因此 Julia 自动将其视为向量,而不是行向量。到目前为止,我一直在使用语法

matrix[k,:]'
Run Code Online (Sandbox Code Playgroud)

来表示 size 的行向量(1,n),但不知何故,这看起来很笨拙,并且根本不直观地表明这是一个行向量而不是列向量。我交谈过的大多数数学家都错误地认为这不是行向量。

是否有一种更朱利安式的方法来获取行向量切片,​​更清晰?

Prz*_*fel 5

julia> m=rand(1:10,3,4)\n3\xc3\x974 Array{Int64,2}:\n 4  5  3  9\n 6  8  1  5\n 4  5  3  4\n\njulia> m[[1],:]\n1\xc3\x974 Array{Int64,2}:\n 4  5  3  9\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,使用views 来避免数据复制几乎总是更好:

\n\n
julia> @view m[[1],:]\n1\xc3\x974 view(::Array{Int64,2}, [1], :) with eltype Int64:\n 4  5  3  9\n
Run Code Online (Sandbox Code Playgroud)\n\n

解释:

\n\n

元素的选择Array可以通过使用标量或使用迭代来完成。使用标量会导致给定的维度被删除。另一方面,使用集合不会降低维度。为了更好的解释,请考虑另一个例子:

\n\n
julia> m[1:1,1:1]\n1\xc3\x971 Array{Int64,2}:\n 4\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以看到仅选择了一个元素,但尺寸尚未删除。因此,您最终得到的Matrix(即二维Array)只有一行和一列。

\n\n

编辑(Colin T Bowers 的评论 - 谢谢!)

\n\n

决定是否使用视图并不是一件小事 - 主要是你的代码是否受益于缓冲。然而,令人惊讶的是,views 往往更好。

\n\n
julia> const vals = rand(200,200);\n\njulia> using BenchmarkTools\n\njulia> @btime sum(view(vals,1,:))\n  169.392 ns (1 allocation: 48 bytes)\n95.08924081258299\n\njulia> @btime sum(vals[1,:])\n  184.384 ns (1 allocation: 1.77 KiB)\n95.08924081258299\n
Run Code Online (Sandbox Code Playgroud)\n\n

让我们定义自己的求和函数。

\n\n
julia> function mysum(a::AbstractVector{A}) where A <: Number\n    v = zero(A)\n    @inbounds @simd for i in 1:length(a)\n        v += a[i]\n    end\n    v\nend;\n\njulia> @btime mysum(view(vals,1,:))\n  141.931 ns (0 allocations: 0 bytes)\n95.08924081258299\n\njulia> @btime mysum(vals[1,:])\n  174.934 ns (1 allocation: 1.77 KiB)\n95.08924081258297\n
Run Code Online (Sandbox Code Playgroud)\n\n

可以清楚地看到,当您对 row Once 进行求和时,view仍然更好。\n最后但并非最不重要的一点是,按列求和当然要快几倍,并且复制数据非常昂贵:

\n\n
julia> @btime sum(view(vals,:,1))\n  25.828 ns (1 allocation: 48 bytes)\n96.04440265541243\n\njulia> @btime mysum(view(vals,:,1))\n  13.927 ns (0 allocations: 0 bytes)\n96.04440265541243\n\njulia> @btime sum(vals[:,1])\n  167.745 ns (1 allocation: 1.77 KiB)\n96.04440265541243\n
Run Code Online (Sandbox Code Playgroud)\n

  • 令人惊讶的是,对于行向量,有时“不”使用“view”会更好。这是因为 Julia 中的矩阵按列优先顺序存储,因此矩阵中的行切片在内存中不是连续的。当输入在内存中连续时,许多常见的 BLAS 操作(例如对向量求和)具有出色的优化,因此在许多情况下,创建行切片的新副本所浪费的时间足以抵消新副本是连续的事实在内存中并且可以利用 BLAS 优化。 (2认同)