考虑以下代码
function test(m,B)
@show typeof(B)
all_u = rand(m,10)
one_u = all_u[:,1]
B*one_u
end
# Works
@show test(3, [1 1 1; 2 2 2])
# Works
@show test(2, [1 1; 2 2])
# Fails
@show test(1, [1; 2])
最后一行以
失败`*` has no method matching *(::Array{Int64,1}, ::Array{Float64,1})
因为B
现在是一维矢量(不行),所以one_u
也是如此(总是如此,并且不会导致问题)。
如何编写test(m,B)
来处理m==1
不需要为m==1
实际特殊包装的情况(即使用if
)?我知道,对于m==1
,我实际上可以编写另一种方法来分析B
是Vector
这一事实,但这看起来非常浪费。
答案 0 :(得分:7)
B
有时是矩阵,有时是向量/ 1D矩阵 - 这就是问题所在。
您可以使用“切片”操作[:;:]
将矢量转换为2D数组。换句话说,如果B
的类型为Array{T,1}
,则B[:,:]
的类型为Array{T,2}
:
julia> B = [1; 2]
2-element Array{Int64,1}:
1
2
julia> typeof(B[:, :])
Array{Int64,2}
另一方面,如果B
已经有Array{T,2}
类型,那么[:;:]
就是无操作:
julia> B = [1 1; 2 2]
2x2 Array{Int64,2}:
1 1
2 2
julia> typeof(B[:, :])
Array{Int64,2}
julia> B[:, :] == B
true
因此,为了适应案例m==1
的函数定义(即在需要时将B
转换为2D数组),您只需将B[:,:]*one_u
替换为B*one_u
}:
julia> function test(m, B)
@show typeof(B)
all_u = rand(m, 10)
one_u = all_u[:, 1]
B[:, :] * one_u
end
test (generic function with 1 method)
julia> @show test(3, [1 1 1; 2 2 2])
typeof(B) => Array{Int64,2}
test(3,[1 1 1;2 2 2]) => [1.4490640717303116,2.898128143460623]
2-element Array{Float64,1}:
1.44906
2.89813
julia> @show test(2, [1 1; 2 2])
typeof(B) => Array{Int64,2}
test(2,[1 1;2 2]) => [0.9245851832116978,1.8491703664233956]
2-element Array{Float64,1}:
0.924585
1.84917
julia> @show test(1, [1; 2])
typeof(B) => Array{Int64,1}
test(1,[1,2]) => [0.04497125985152639,0.08994251970305278]
2-element Array{Float64,1}:
0.0449713
0.0899425