I'm trying to solve a constrained optimization problem with the interior_point_Newton method on a ProductManifold and come across two problems (so far), where I think I was able to solve the first one, but am still struggling with the second one.
The MWE I am using is:
using Manifolds, Manopt
using RecursiveArrayTools
N = 5
M1 = SkewSymmetricMatrices(N)
M2 = PositiveVectors(N)
M = ProductManifold(M1, M2)
# Just some dummy objective and constraint
f(M, x) = 1.0
grad_f(M, x) = 0.0
h(M, x) = 0.0
grad_h(M, x) = 0.0
objective = ConstrainedManifoldObjective(f, grad_f; h = h, grad_h = grad_h, g = nothing,
grad_g = nothing, equality_constraints = 1)
p = rand(M)
interior_point_Newton(M, objective, p)
For the first one I needed to adjust Manopt.jl in three places, namely:
|
N = M × vector_space(length(μ)) × vector_space(length(λ)) × vector_space(length(s)), |
|
_step_M::AbstractManifold = M × vector_space(length(μ)) × vector_space(length(λ)) × |
and
|
_sub_M = M × vector_space(length(λ)), |
where in each place I needed to replace the
× by explicit calls to
ProductManifold (e.g., for the first one
N = ProductManifold(M, vector_space(length(μ)), vector_space(length(λ)), vector_space(length(s))). As I understand this is necessary for
M being already a
ProductManifold because the code relies on things like
N[1] being
M again, which in the
× case would only return the first component of
M and not the
ProductManifold itself. However, by using
ProductManifold(M, ...) one gets a nested
ProductManifold, which seems to me as the wanted behavior in this case. If you agree, I am happy to create a PR for that.
After resolving this, I get the stacktrace
ERROR: LoadError: MethodError: no method matching get_hessian(::ProductManifold{…}, ::ManifoldFirstOrderObjective{…}, ::ArrayPartition{…}, ::ArrayPartition{…})
The function `get_hessian` exists, but no method is defined for this combination of argument types.
Closest candidates are:
get_hessian(::AbstractManifold, ::EmbeddedManifoldObjective{P, Missing, E} where E, ::Any, ::Any) where P
@ Manopt ~/.julia/dev/Manopt/src/plans/embedded_objective.jl:139
get_hessian(::AbstractManifold, ::EmbeddedManifoldObjective{P, T, E} where E, ::Any, ::Any) where {P, T}
@ Manopt ~/.julia/dev/Manopt/src/plans/embedded_objective.jl:151
get_hessian(::AbstractManifold, ::ScaledManifoldObjective, ::Any, ::Any)
@ Manopt ~/.julia/dev/Manopt/src/plans/scaled_objective.jl:105
...
Stacktrace:
[1] get_hessian(M::ProductManifold{…}, co::ConstrainedManifoldObjective{…}, p::ArrayPartition{…}, X::ArrayPartition{…})
@ Manopt ~/.julia/dev/Manopt/src/plans/constrained_plan.jl:805
[2] (::CondensedKKTVectorFieldJacobian{…})(N::ProductManifold{…}, Y::ArrayPartition{…}, q::ArrayPartition{…}, X::ArrayPartition{…})
@ Manopt ~/.julia/dev/Manopt/src/plans/interior_point_Newton_plan.jl:432
[3] (::CondensedKKTVectorFieldJacobian{…})(N::ProductManifold{…}, q::ArrayPartition{…}, X::ArrayPartition{…})
@ Manopt ~/.julia/dev/Manopt/src/plans/interior_point_Newton_plan.jl:420
[4] get_hessian(TpM::Fiber{…}, slso::SymmetricLinearSystemObjective{…}, X::ArrayPartition{…}, V::ArrayPartition{…})
@ Manopt ~/.julia/dev/Manopt/src/plans/conjugate_residual_plan.jl:149
[5] get_gradient(TpM::Fiber{…}, slso::SymmetricLinearSystemObjective{…}, X::ArrayPartition{…})
@ Manopt ~/.julia/dev/Manopt/src/plans/conjugate_residual_plan.jl:113
[6] interior_point_Newton(M::ProductManifold{…}, cmo::ConstrainedManifoldObjective{…}, p::ArrayPartition{…}; kwargs::@Kwargs{…})
@ Manopt ~/.julia/dev/Manopt/src/solvers/interior_point_Newton.jl:142
[7] top-level scope
@ ~/.julia/dev/SummationByPartsOperatorsExtra/run/debug_Manopt.jl:89
[8] include(mapexpr::Function, mod::Module, _path::String)
@ Base ./Base.jl:307
[9] top-level scope
@ REPL[1]:1
in expression starting at /home/lampert/.julia/dev/SummationByPartsOperatorsExtra/run/debug_Manopt.jl:89
Some type information was truncated. Use `show(err)` to see complete types.
which comes from trying to create the sub_state here:
|
sub_state::St = decorate_state!( |
|
ConjugateResidualState( |
|
TangentSpace(_sub_M, _sub_p), |
|
sub_objective; |
|
X = _sub_X, |
|
stop = sub_stopping_criterion, |
|
sub_kwargs..., |
|
); |
|
sub_kwargs..., |
|
), |
Reducing this even further one can also get the same error by calling
Xp = rand(M)
get_hessian(M, objective, p, Xp)
instead of the whole call to interior_point_Newton in the MWE above. Is there a missing definition of get_hessian or do you have an idea how to fix this?
I'm trying to solve a constrained optimization problem with the
interior_point_Newtonmethod on aProductManifoldand come across two problems (so far), where I think I was able to solve the first one, but am still struggling with the second one.The MWE I am using is:
For the first one I needed to adjust Manopt.jl in three places, namely:
Manopt.jl/src/plans/interior_point_Newton_plan.jl
Line 1015 in 44e2bfc
Manopt.jl/src/solvers/interior_point_Newton.jl
Line 190 in 44e2bfc
and
Manopt.jl/src/solvers/interior_point_Newton.jl
Line 207 in 44e2bfc
where in each place I needed to replace the
×by explicit calls toProductManifold(e.g., for the first oneN = ProductManifold(M, vector_space(length(μ)), vector_space(length(λ)), vector_space(length(s))). As I understand this is necessary forMbeing already aProductManifoldbecause the code relies on things likeN[1]beingMagain, which in the×case would only return the first component ofMand not theProductManifolditself. However, by usingProductManifold(M, ...)one gets a nestedProductManifold, which seems to me as the wanted behavior in this case. If you agree, I am happy to create a PR for that.After resolving this, I get the stacktrace
which comes from trying to create the
sub_statehere:Manopt.jl/src/solvers/interior_point_Newton.jl
Lines 222 to 231 in 44e2bfc
Reducing this even further one can also get the same error by calling
instead of the whole call to
interior_point_Newtonin the MWE above. Is there a missing definition ofget_hessianor do you have an idea how to fix this?