如何在linspace上使用理解来创建矩阵

Rob*_*son 5 julia

我想生成一个nx 3矩阵,其中n是像素数(宽度*高度).

x = linspace(-1, 1, width)
y = linspace(-1, 1, height)

r = 1.0

viewDirections = [[i j 1.0] for i in x for j in y]
Run Code Online (Sandbox Code Playgroud)

但是,当我运行这个时,我得到一个:

16-element Array{Array{Float64,2},1}
Run Code Online (Sandbox Code Playgroud)

而不是我想要的16x3 Array{Float64,2}.我显然没有正确地使用理解来构造矩阵.我尝试使用comprehensions来创建一个元组数组,但我不能将这些元组转换为矩阵.

Gni*_*muc 2

这里的问题是array comprehension会给我们一个嵌套数组而不是Matrix. 这是正确的理解行为,它不会为我们做额外的猜测,因此我们需要手动将嵌套数组转换为矩阵,这可以使用vcatsplating 运算符(...)来完成:

\n\n
julia> vcat(viewDirections...)\n6\xc3\x973 Array{Float64,2}:\n -1.0  -1.0  1.0\n -1.0   1.0  1.0\n  0.0  -1.0  1.0\n  0.0   1.0  1.0\n  1.0  -1.0  1.0\n  1.0   1.0  1.0\n
Run Code Online (Sandbox Code Playgroud)\n\n

看起来您正在从二维欧几里得空间构建齐次坐标。使用Base.Iterators.product是一种更简洁、更健壮的方式来创建迭代器:

\n\n
julia> w = linspace(-1,1,3)\n-1.0:1.0:1.0\n\njulia> h = linspace(-1,1,2)\n-1.0:2.0:1.0\n\njulia> r = 1.0\n1.0\n\njulia> viewDirections = [collect(i) for i in Iterators.product(w, h, r)]\n3\xc3\x972 Array{Array{Float64,1},2}:\n [-1.0, -1.0, 1.0]  [-1.0, 1.0, 1.0]\n [0.0, -1.0, 1.0]   [0.0, 1.0, 1.0] \n [1.0, -1.0, 1.0]   [1.0, 1.0, 1.0] \n\njulia> hcat(viewDirections...).\'\n6\xc3\x973 Array{Float64,2}:\n -1.0  -1.0  1.0\n  0.0  -1.0  1.0\n  1.0  -1.0  1.0\n -1.0   1.0  1.0\n  0.0   1.0  1.0\n  1.0   1.0  1.0\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,坐标的顺序与原始版本不同,这是因为 Julia 是列主的,Iterators.product将“向外”迭代最右边的维度,即[[i j r] for j in y for i in x ]。如果顺序在您的用例中很重要,请注意它。\n以下是width/height变大时的一些基准测试结果:

\n\n
julia> w = linspace(-1,1,300)\n-1.0:0.006688963210702341:1.0\n\njulia> h = linspace(-1,1,200)\n-1.0:0.010050251256281407:1.0\n\njulia> foo(w,h,r) = hcat([collect(i) for i in Iterators.product(w, h, r)]...).\'\n\njulia> bar(w,h,r) = vcat([[i j r] for i in w for j in h]...)\n\njulia> @btime foo($w,$h,$r);\n  6.172 ms (60018 allocations: 10.99 MiB)\n\njulia> @btime bar($w,$h,$r);\n  11.294 ms (360028 allocations: 17.02 MiB)\n
Run Code Online (Sandbox Code Playgroud)\n