Julia 提高“hvcat”类型稳定性的最佳实践?
请查看以下MWE:Julia 提高“hvcat”类型稳定性的最佳实践?,julia,Julia,请查看以下MWE: julia> function foo() # do something R = rand(3,3) t = rand(3) y = [ R t; 0 0 0 1] # do something end foo (generic function with 1 method) julia> @code_warntype foo() Var
julia> function foo()
# do something
R = rand(3,3)
t = rand(3)
y = [ R t;
0 0 0 1]
# do something
end
foo (generic function with 1 method)
julia> @code_warntype foo()
Variables:
#self#::#foo
R::Array{Float64,2}
t::Array{Float64,1}
Body:
begin
# ..........................
R::Array{Float64,2} = $(Expr(:invoke, MethodInstance for rand!(::MersenneT
wister, ::Array{Float64,2}, ::Int64, ::Type{Base.Random.CloseOpen}), :(Base.Rand
om.rand!), :(Base.Random.GLOBAL_RNG), SSAValue(4), :((Base.arraylen)(SSAValue(4)
)::Int64), :(Base.Random.CloseOpen))) # line 3:
# .............................
t::Array{Float64,1} = $(Expr(:invoke, MethodInstance for rand!(::MersenneT
wister, ::Array{Float64,1}, ::Int64, ::Type{Base.Random.CloseOpen}), :(Base.Rand
om.rand!), :(Base.Random.GLOBAL_RNG), SSAValue(8), :((Base.arraylen)(SSAValue(8)
)::Int64), :(Base.Random.CloseOpen))) # line 4:
return $(Expr(:invoke, MethodInstance for hvcat(::Tuple{Int64,Int64}, ::Ar
ray{Float64,2}, ::Vararg{Any,N} where N), :(Main.hvcat), (2, 4), :(R), :(t), 0,
0, 0, 1))
end::Any
它表明hvcat
无法推断类型,因为它需要知道R
和t
的大小,这不是编译时信息。我目前的解决方法是编写如下内容:
y = zeros(4,4)
y[1:3,1:3] = R
y[:,4] = [t; 1]
但是它看起来有点麻烦,有什么简洁的方法可以做到这一点吗?用数组类型的参数替换标量参数似乎可以做到这一点:
function foo()
# do something
R = rand(3,3)
t = rand(3)
y = [ R t;
[0 0 0 1]] # <-- the change is here
# do something
end
Thx@Dan,你刚刚救了我一个下午!我发现您的“数组类型化方法”触发了一个未记录的函数
Base.typed_hvcat
,这似乎就是我要找的。vcat([rt],[0 0 0 0 1])
也是类型稳定的,有趣的是,这两种方法都是在
julia> @code_warntype foo()
Variables:
#self# <optimized out>
R::Array{Float64,2}
t::Array{Float64,1}
y <optimized out>
Body:
begin
⋮
⋮
return SSAValue(0)
end::Array{Float64,2}