我正在尝试使用ForwardDiff.jl和/或ReverseDiff.jl库来计算优化问题中的梯度。
这两个软件包都给我一条与:: getfield()有关的错误消息。
ReverseDiff给我一个LoadError:
MethodError: no method matching (::getfield(CalibrationModule, Symbol("#f#4"))
{AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}})
(::ReverseDiff.TrackedArray{Float64,Float64,1,Array{Float64,1},Array{Float64,1}})
ForwardDiff给我一个LoadError:
MethodError: no method matching (::getfield(CalibrationModule, Symbol("#f#10"))
{AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}})
(::Array{ForwardDiff.Dual{ForwardDiff.Tag{getfield(CalibrationModule,
Symbol("#f#10"))
{AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}},Float64},Float64,6},1})
我不知道如何理解此错误消息。我的代码太复杂了,无法在此处发布,但据我所知,我没有使用未用Julia编写的任何库。我确实在整个过程中广泛使用自定义数据类型(可变结构),但是我不明白为什么这会导致问题...
答案 0 :(得分:1)
如果没有一种方法具有与要调用的类型签名匹配的类型签名,则从Julia docs中抛出MethodError: no method matching
。 Julia具有动态类型系统,但是允许类型注释,如果值不是预期类型,则该注释会引发异常。由于您正在广泛使用自定义数据类型,因此可能是将自定义数据类型的值传递给ForwardDiff / ReverseDiff中期望使用其他类型的方法的原因-很难确认而看不到代码,但这就是我在d开始寻找。
答案 1 :(得分:1)
没有代码真的很难说,但是:
Julia显示匿名功能和闭包的方式类似于(::getfield(CalibrationModule, Symbol(...)){...}(...)
。您收到方法错误,表明该匿名函数或闭包不支持采用Array
或Dual
数字的Tracked
签名。您可能具有以下功能:
function main()
...
f(A::Array{Float64}) = # ... some closure
...
f(...)
end
但是ForwardDiff和ReverseDiff都需要使用双数或跟踪数字(而不是Float64
)运行程序。因此,您收到一个方法错误,名为f
的闭包不接受这些双数或跟踪数字的数组。
将f
闭包的特异性降低到它可以支持的最广泛的范围,例如f(A::AbstractArray{<:Number}) = ...
。请注意,这两个库的执行方式略有不同-ForwardDiff创建对偶数组,而ReverseDiff创建跟踪的浮点数 array 。因此,您希望两个::AbstractArray
都支持多个Array
(除非您要调用C,否则几乎应该始终这样做),并且希望将元素类型放宽为{{1 }}。我建议您走得更远,不要在意元素类型-您通常不需要在意它。