与:: getfield()

时间:2019-01-18 23:10:04

标签: julia mathematical-optimization gradient-descent automatic-differentiation

我正在尝试使用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编写的任何库。我确实在整个过程中广泛使用自定义数据类型(可变结构),但是我不明白为什么这会导致问题...

2 个答案:

答案 0 :(得分:1)

如果没有一种方法具有与要调用的类型签名匹配的类型签名,则从Julia docs中抛出MethodError: no method matching。 Julia具有动态类型系统,但是允许类型注释,如果值不是预期类型,则该注释会引发异常。由于您正在广泛使用自定义数据类型,因此可能是将自定义数据类型的值传递给ForwardDiff / ReverseDiff中期望使用其他类型的方法的原因-很难确认而看不到代码,但这就是我在d开始寻找。

答案 1 :(得分:1)

没有代码真的很难说,但是:

Julia显示匿名功能和闭包的方式类似于(::getfield(CalibrationModule, Symbol(...)){...}(...)。您收到方法错误,表明该匿名函数或闭包不支持采用ArrayDual数字的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 }}。我建议您走得更远,不要在意元素类型-您通常不需要在意它。