# A Manopt problem

A problem describes all static data of an optimisation task and has as a super type

`Manopt.AbstractManoptProblem`

— Type`AbstractManoptProblem{M<:AbstractManifold}`

Describe a Riemannian optimization problem with all static (not-changing) properties.

The most prominent features that should always be stated here are

- the
`AbstractManifold`

$\mathcal M$ - the cost function $f: \mathcal M → ℝ$

Usually the cost should be within an `AbstractManifoldObjective`

.

`Manopt.get_objective`

— Function`get_objective(o::AbstractManifoldObjective, recursive=true)`

return the (one step) undecorated `AbstractManifoldObjective`

of the (possibly) decorated `o`

. As long as your decorated objective stores the objective within `o.objective`

and the `dispatch_objective_decorator`

is set to `Val{true}`

, the internal state are extracted automatically.

By default the objective that is stored within a decorated objective is assumed to be at `o.objective`

. Overwrite `_get_objective(o, ::Val{true}, recursive) to change this behaviour for your objective`

o` for both the recursive and the direct case.

If `recursive`

is set to `false`

, only the most outer decorator is taken away instead of all.

`get_objective(mp::AbstractManoptProblem, recursive=false)`

return the objective `AbstractManifoldObjective`

stored within an `AbstractManoptProblem`

. If `recursive is set to true, it additionally unwraps all decorators of the objective`

`get_objective(amso::AbstractManifoldSubObjective)`

Return the (original) objective stored the sub objective is build on.

`Manopt.get_manifold`

— Function`get_manifold(amp::AbstractManoptProblem)`

return the manifold stored within an `AbstractManoptProblem`

Usually, such a problem is determined by the manifold or domain of the optimisation and the objective with all its properties used within an algorithm, see The Objective. For that one can just use

`Manopt.DefaultManoptProblem`

— Type`DefaultManoptProblem{TM <: AbstractManifold, Objective <: AbstractManifoldObjective}`

Model a default manifold problem, that (just) consists of the domain of optimisation, that is an `AbstractManifold`

and an `AbstractManifoldObjective`

For the constraint optimisation, there are different possibilities to represent the gradients of the constraints. This can be done with a

`ConstraintProblem`

The primal dual-based solvers (Chambolle-Pock and the PD Semi-smooth Newton), both need two manifolds as their domains, hence there also exists a

`Manopt.TwoManifoldProblem`

— Type```
TwoManifoldProblem{
MT<:AbstractManifold,NT<:AbstractManifold,O<:AbstractManifoldObjective
} <: AbstractManoptProblem{MT}
```

An abstract type for primal-dual-based problems.

From the two ingredients here, you can find more information about