Julia 如何使用linspace上的理解创建矩阵
我想生成一个nx3矩阵,其中n是像素数(宽度*高度) 但是,当我运行此命令时,我得到一个:Julia 如何使用linspace上的理解创建矩阵,julia,Julia,我想生成一个nx3矩阵,其中n是像素数(宽度*高度) 但是,当我运行此命令时,我得到一个: 16-element Array{Array{Float64,2},1} 而不是我想要的16x3数组{Float64,2}。我显然没有正确地使用理解来构造矩阵。我尝试使用理解来创建元组数组,但我无法将这些元组转换为矩阵。这里的问题是数组理解将为我们提供嵌套数组,而不是矩阵。这是正确的理解行为,它不会为我们做额外的猜测,因此我们需要手动将嵌套数组转换为矩阵,这可以使用带有splating运算符(…)的vc
16-element Array{Array{Float64,2},1}
而不是我想要的16x3
数组{Float64,2}
。我显然没有正确地使用理解来构造矩阵。我尝试使用理解来创建元组数组,但我无法将这些元组转换为矩阵。这里的问题是数组理解将为我们提供嵌套数组,而不是矩阵。这是正确的理解行为,它不会为我们做额外的猜测,因此我们需要手动将嵌套数组转换为矩阵,这可以使用带有splating运算符(…
)的vcat
来完成:
看起来你是从二维欧几里德空间构造的。使用Base.Iterators.product
是创建迭代器的一种更简洁、更健壮的方法:
julia> w = linspace(-1,1,3)
-1.0:1.0:1.0
julia> h = linspace(-1,1,2)
-1.0:2.0:1.0
julia> r = 1.0
1.0
julia> viewDirections = [collect(i) for i in Iterators.product(w, h, r)]
3×2 Array{Array{Float64,1},2}:
[-1.0, -1.0, 1.0] [-1.0, 1.0, 1.0]
[0.0, -1.0, 1.0] [0.0, 1.0, 1.0]
[1.0, -1.0, 1.0] [1.0, 1.0, 1.0]
julia> hcat(viewDirections...).'
6×3 Array{Float64,2}:
-1.0 -1.0 1.0
0.0 -1.0 1.0
1.0 -1.0 1.0
-1.0 1.0 1.0
0.0 1.0 1.0
1.0 1.0 1.0
请注意,坐标顺序与原始版本不同,这是因为Julia是列主迭代器,迭代器。product
将迭代最右边的维度“最外层”,即[[i j r]对于j in y对于i in x]
。如果顺序在您的用例中很重要,请注意它。
以下是width/height
变大时的一些基准测试结果:
julia> w = linspace(-1,1,300)
-1.0:0.006688963210702341:1.0
julia> h = linspace(-1,1,200)
-1.0:0.010050251256281407:1.0
julia> foo(w,h,r) = hcat([collect(i) for i in Iterators.product(w, h, r)]...).'
julia> bar(w,h,r) = vcat([[i j r] for i in w for j in h]...)
julia> @btime foo($w,$h,$r);
6.172 ms (60018 allocations: 10.99 MiB)
julia> @btime bar($w,$h,$r);
11.294 ms (360028 allocations: 17.02 MiB)
我认为这可能是一个解决方案,重新解释(Float64,viewDirections,(3,nPixels))非常好!这种splat和vcat技术工作得非常好。是的,为光线跟踪器创建标准化的摄影机空间坐标。@RobertF.Dickerson如果您不关心矩阵中的坐标顺序,那么hcat+product
是更好的选择(大约快2倍)。仅供参考,如果您可以在迭代器中将计算写成i的。product(w,h,r)不要(i)结束
。Matlab和其他速度较慢的语言要求您计算这样的数组,因为需要矢量化以获得良好的性能,但对于Julia来说,这不是一个问题。@tholy矩阵不是创建了两次吗?(转置)@Liso在那里创建了许多小矩阵/向量(注意tholy的意思是最终结果),因此转置不是什么大问题;)另外,是否使用转置取决于您编写以下代码的方式,我使用转置是因为OP的要求是16x3矩阵。如上所述,在某些用例中,使用for循环可以完全避免所有这些问题。
julia> w = linspace(-1,1,3)
-1.0:1.0:1.0
julia> h = linspace(-1,1,2)
-1.0:2.0:1.0
julia> r = 1.0
1.0
julia> viewDirections = [collect(i) for i in Iterators.product(w, h, r)]
3×2 Array{Array{Float64,1},2}:
[-1.0, -1.0, 1.0] [-1.0, 1.0, 1.0]
[0.0, -1.0, 1.0] [0.0, 1.0, 1.0]
[1.0, -1.0, 1.0] [1.0, 1.0, 1.0]
julia> hcat(viewDirections...).'
6×3 Array{Float64,2}:
-1.0 -1.0 1.0
0.0 -1.0 1.0
1.0 -1.0 1.0
-1.0 1.0 1.0
0.0 1.0 1.0
1.0 1.0 1.0
julia> w = linspace(-1,1,300)
-1.0:0.006688963210702341:1.0
julia> h = linspace(-1,1,200)
-1.0:0.010050251256281407:1.0
julia> foo(w,h,r) = hcat([collect(i) for i in Iterators.product(w, h, r)]...).'
julia> bar(w,h,r) = vcat([[i j r] for i in w for j in h]...)
julia> @btime foo($w,$h,$r);
6.172 ms (60018 allocations: 10.99 MiB)
julia> @btime bar($w,$h,$r);
11.294 ms (360028 allocations: 17.02 MiB)