我有一个带有标题的函数
integrateL(f, lb::SArray{Tuple{S},Float64,1, S} where S<:Integer, ub::SArray{Tuple{S},Float64,1, S} where S<:Integer, y::Float64)
return nothing
end
我不共享该问题的内容,因为问题不在内部,这会造成混淆。该问题是可以重现的。转换变量后,此函数与HCubature.jl包执行半无限多维集成。在参数中,我按照程序包文档中的建议使用StaticArrays来提高性能。要重现该错误,请执行以下操作。
lb = zeros(SVector{1}) #1-element SArray{Tuple{1},Float64,1,1}
ub = ones(SVector{1}) #1-element SArray{Tuple{1},Float64,1,1}
f(y) = y ^2
IntegrateL(f, lb, ub, 5.0)
返回的错误是
no method matching integrateL(::typeof(f), ::SArray{Tuple{1},Float64,1,1}, ::SArray{Tuple{1},Float64,1,1}, ::Float64)
Closest candidates are:
integrateL(::Any, ::SArray{Tuple{S},Float64,1,S} where S<:Integer, ::SArray{Tuple{S},Float64,1,S} where S<:Integer, ::Float64)
所以我的猜测是它不接受ub和lb作为SArray {Tuple {S},Float64,1,S},其中S <:Integer类型,尽管我指定S应该是Integer参数值。我可能会误用这里的“哪里”。请注意,我最初想使用
::SArray{Tuple{Int64},Float64,1,Int64}
在我的函数定义中,但不能。
答案 0 :(得分:3)
我不知道正确的词来解释这一点,但是where T <: SomeType
用于类型。 Tuple{1}
中的1不是类型,而是 non-type 参数。
下面的示例可能使事情变得很清楚。
julia> abstract type Pointy{T<:Real} end
julia> Pointy{1.0}
ERROR: TypeError: in Pointy, in T, expected T<:Real, got Float64
julia> Pointy{Float64}
Pointy{Float64}
julia> abstract type Smooth{T} end
julia> Smooth{1.0}
Smooth{1.0}
因此,您的问题的解决方案是仅用where S<:Integer
代替where S
。
此外,您可能想使用SVector{S, Float64}
别名而不是SArray{Tuple{S},Float64,1, S}
。
julia> SArray{Tuple{2},Float64,1, 2} === SVector{2, Float64}
true
请注意,我使用StaticArrays
的次数很少,但我认为您的函数过于具体,没有任何好处。例如,您的函数不适用于内置Array
。如果您确实需要在函数定义中使用S
,则可以像使用length
一样使用Array
函数。与StaticArrays
一样,这样做不会对性能造成任何影响,因为在编译时,对length的调用实际上将由S
替换,并且编译器将对循环等进行专门化,就像在原始函数定义中一样