You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am working on the Gauss-Newton method, but need a bit more control over the computation than what is provided in LsqFit.jl. That I was thinking of is to use the Newton() algorithm in Optim.jl, but change the hessian and gradient as follows:
""" min 1/2 ||r(x)||^2"""# r(x) = .... # predictive function# J_r(x) = .... # Jacobian of rfunctiongauss_newton_fgh!(F, G, H, x)
ifany([!(H ==nothing), !(G ==nothing)])
J =J_r(x)
if!(H ==nothing)
# mutating calculations specific to h!
H[:,:] = J'*J
endif!(G ==nothing)
G[:] = J'*r(x)
# mutating calculations specific to g!endendif!(F ==nothing)
r_k =r(x)
returndot(r_k, r_k)/2.0endendTwiceDifferentiable(only_fgh!(gauss_newton_fgh!), x0)
However, from the TwiceDifferentiable type
mutable struct TwiceDifferentiable{T,TDF,TH,TX} <:AbstractObjective
f
df
fdf
h
....end
functionTwiceDifferentiable(t::InPlaceFGH, x::AbstractVector, F::Real=real(zero(eltype(x))), G::AbstractVector=similar(x)) where {TH}
H =alloc_H(x, F)
f = x -> t.fgh(F, nothing, nothing, x)
df = (G, x) -> t.fgh(nothing, G, nothing, x)
fdf = (G, x) -> t.fgh(F, G, nothing, x)
h = (H, x) -> t.fgh(F, nothing, H, x)
TwiceDifferentiable(f, df, fdf, h, x, F, G, H)
end
it seems that the gradient and hessian cannot be evaluated simultaneously, and the Gauss-Newton above evaluates the Jacobian of r one time more than needed.
Is there something I have missed, or would it make sensor to add fields to TwiceDifferentiable such that
mutable struct TwiceDifferentiable{T,TDF,TH,TX} <:AbstractObjective
f
df
fdf
h
fdfh
....endfunctionTwiceDifferentiable(t::InPlaceFGH, x::AbstractVector, F::Real=real(zero(eltype(x))), G::AbstractVector=similar(x)) where {TH}
H =alloc_H(x, F)
f = x -> t.fgh(F, nothing, nothing, x)
df = (G, x) -> t.fgh(nothing, G, nothing, x)
fdf = (G, x) -> t.fgh(F, G, nothing, x)
h = (H, x) -> t.fgh(F, nothing, H, x)
fdfh = (H,x) -> t.fgh(F, G, H, x)
TwiceDifferentiable(f, df, fdf, h, fdfh, x, F, G, H)
end
Edit: After some thinking, to avoid evaluating the jacobian of r one more time, one can also wrap the r function in a TwiceDifferentiable object:
"""Minimize f(x) = 1/2||r(x)||^2"""functionget_gauss_newton_df(dr, x0)
functiongauss_newton_fgh!(F, G, H, x)
if!(H ==nothing)
jacobian!(dr, x)
J_r =jacobian(dr)
# mutating calculations specific to h!
H[:,:] = J_r'*J_r
endif!(G ==nothing)
jacobian!(dr, x)
J_r =jacobian(dr)
value!(dr)
r =value(dr)
G[:] = J_r'*r
# mutating calculations specific to g!endif!(F ==nothing)
value!(dr)
r =value(dr)
returndot(r, r)/2.0endendTwiceDifferentiable(only_fgh!(gauss_newton_fgh!), x0)
end
But I think the original question is still relevant.
The text was updated successfully, but these errors were encountered:
I think it is a good idea, yes. Optim currently evaluates h seperately, but in extremely many cases it would be useful to evaluate them all at once, yes.
I am working on the Gauss-Newton method, but need a bit more control over the computation than what is provided in LsqFit.jl. That I was thinking of is to use the
Newton()
algorithm in Optim.jl, but change the hessian and gradient as follows:However, from the
TwiceDifferentiable
typeand the constructor for inplace functions:
it seems that the gradient and hessian cannot be evaluated simultaneously, and the Gauss-Newton above evaluates the Jacobian of
r
one time more than needed.Is there something I have missed, or would it make sensor to add fields to
TwiceDifferentiable
such thatEdit: After some thinking, to avoid evaluating the jacobian of
r
one more time, one can also wrap ther
function in aTwiceDifferentiable
object:But I think the original question is still relevant.
The text was updated successfully, but these errors were encountered: