提高`hvcat`类型稳定性的最佳实践?

时间:2017-11-15 05:27:28

标签: 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()
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无法推断出类型,因为它需要知道Rt的大小,而不是编译时间信息。我目前的解决方法是写这样的东西:

y = zeros(4,4)
y[1:3,1:3] = R
y[:,4] = [t; 1]

但它看起来有点麻烦,有没有简洁的方法来做到这一点?

1 个答案:

答案 0 :(得分:3)

用数组类型替换标量参数似乎可以解决这个问题:

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

@code_warntype是:

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}