Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce an EmbeddedObjective #286

Merged
merged 26 commits into from
Sep 2, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
544e5b5
Introduce a sketch for an EmbeddedObjective.
kellertuer Aug 15, 2023
0c821f9
Improve a menu entry.
kellertuer Aug 15, 2023
99a2af2
Apply suggestions from code review
kellertuer Aug 16, 2023
215f49c
Merge branch 'kellertuer/EmbeddedObjective' of github.com:JuliaManifo…
kellertuer Aug 16, 2023
f445f49
removes a spurious variable name.
kellertuer Aug 17, 2023
db2c200
Fix docs for the object decorator.
kellertuer Aug 17, 2023
9e103c8
Write the wrapper for the Euclidean Hessian.
kellertuer Aug 17, 2023
353b211
Change the keyword to `objective_type`.
kellertuer Aug 17, 2023
687f1b6
use embed from ManifoldsBase.
kellertuer Aug 18, 2023
74c80aa
Constraint gradient conversion.
kellertuer Aug 26, 2023
ae8304d
Merge branch 'master' into kellertuer/EmbeddedObjective
kellertuer Aug 26, 2023
ebf3cf8
Work on the docs.
kellertuer Aug 27, 2023
1dc369d
Fix two typos.
kellertuer Aug 27, 2023
2b689cd
fix another typo.
kellertuer Aug 27, 2023
29818c3
Sketch Tutorial and debug the code a bit.
kellertuer Aug 28, 2023
4a9178c
Finish the tutorial.
kellertuer Aug 28, 2023
45f2b07
Update Tutorial and fix Docs.
kellertuer Aug 30, 2023
8589d51
Gradient and Hessian conversion tests.
kellertuer Aug 31, 2023
1c0c461
Test Coverage I.
kellertuer Aug 31, 2023
534bd63
Code Coverage II.
kellertuer Aug 31, 2023
bedba7e
Fix a small bug in the deco initialisation.
kellertuer Aug 31, 2023
ca9e2a8
Fix interaction of embedded objectives and sub solvers in default cre…
kellertuer Aug 31, 2023
96abe9b
Test Coverage III, read the new tutorial again, runs formatter.
kellertuer Aug 31, 2023
215bd37
Bump version.
kellertuer Sep 1, 2023
40c41a2
remove output from a few function definitions.
kellertuer Sep 1, 2023
b0d2d7a
Run the new embedding tutorial on dev.
kellertuer Sep 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ Colors = "0.11.2, 0.12"
DataStructures = "0.17, 0.18"
LRUCache = "1.4"
ManifoldDiff = "0.2, 0.3.3"
Manifolds = "0.8.69"
ManifoldsBase = "0.14.4"
Manifolds = "0.8.75"
ManifoldsBase = "0.14.10"
PolynomialRoots = "1"
Requires = "0.5, 1"
julia = "1.6"
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
BenchmarkTools = "1.3"
CondaPkg = "0.2"
Documenter = "0.27"
Manifolds = "0.8.27"
Manifolds = "0.8.75"
ManifoldsBase = "0.13, 0.14"
27 changes: 25 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,29 @@ makedocs(
format=Documenter.HTML(;
mathengine=MathJax3(), prettyurls=get(ENV, "CI", nothing) == "true"
),
modules=[Manopt],
modules=[
Manopt,
if isdefined(Base, :get_extension)
Base.get_extension(Manopt, :ManoptLineSearchesExt)
else
Manopt.ManoptLineSearchesExt
end,
if isdefined(Base, :get_extension)
Base.get_extension(Manopt, :ManoptLRUCacheExt)
else
Manopt.ManoptLRUCacheExt
end,
if isdefined(Base, :get_extension)
Base.get_extension(Manopt, :ManoptManifoldsExt)
else
Manopt.ManoptManifoldsExt
end,
if isdefined(Base, :get_extension)
Base.get_extension(Manopt, :ManoptPlotsExt)
else
Manopt.ManoptPlotsExt
end,
],
authors="Ronny Bergmann and contributors.",
sitename="Manopt.jl",
strict=[
Expand All @@ -86,8 +108,9 @@ makedocs(
"Get started: Optimize!" => "tutorials/Optimize!.md",
"Speedup using Inplace computations" => "tutorials/InplaceGradient.md",
"Use Automatic Differentiation" => "tutorials/AutomaticDifferentiation.md",
"Define Objectives in the Embedding" => "tutorials/EmbeddingObjectives.md",
"Count and use a Cache" => "tutorials/CountAndCache.md",
"Perform Debug Output" => "tutorials/HowToDebug.md",
"Print Debug Output" => "tutorials/HowToDebug.md",
"Record values" => "tutorials/HowToRecord.md",
"Implement a Solver" => "tutorials/ImplementASolver.md",
"Do Contrained Optimization" => "tutorials/ConstrainedOptimization.md",
Expand Down
5 changes: 5 additions & 0 deletions docs/src/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ x_opt = quasi_Newton(
)
```

### Manifolds.jl

```@docs
Manopt.LineSearchesStepsize
mid_point
Manopt.max_stepsize(::TangentBundle, ::Any)
Manopt.max_stepsize(::FixedRankMatrices, ::Any)
```
137 changes: 75 additions & 62 deletions docs/src/plans/objective.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,83 @@ InplaceEvaluation
evaluation_type
```

It sometimes might be nice to set certain parameters within

## Cost Objective
## Decorators for Objectives

An objective can be decorated using the following trait and function to initialize

```@docs
dispatch_objective_decorator
is_objective_decorator
decorate_objective!
```

### [Embedded Objectives](@id ManifoldEmbeddedObjective)

```@docs
EmbeddedManifoldObjective
```

### [Cache Objective](@id CacheSection)

Since single function calls, e.g. to the cost or the gradient, might be expensive,
a simple cache objective exists as a decorator, that caches one cost value or gradient.

It can be activated/used with the `cache=` keyword argument available for every solver.

```@docs
Manopt.reset_counters!
Manopt.objective_cache_factory
```

#### A simple cache

A first generic cache is always available, but it only caches one gradient and one cost function evaluation (for the same point).

```@docs
SimpleManifoldCachedObjective
```

#### A Generic Cache

For the more advanced cache, you need to implement some type of cache yourself, that provides a `get!`
and implement [`init_caches`](@ref).
This is for example provided if you load [`LRUCache.jl`](https://github.com/JuliaCollections/LRUCache.jl). Then you obtain

```@docs
ManifoldCachedObjective
init_caches
```

### [Count Objective](@id ManifoldCountObjective)

```@docs
ManifoldCountObjective
```

### Internal Decorators

```@docs
ReturnManifoldObjective
```

## Specific Objective typed and their access functions

### Cost Objective

```@docs
AbstractManifoldCostObjective
ManifoldCostObjective
```

### Access functions
#### Access functions

```@docs
get_cost
get_cost_function
```

## Gradient Objectives
### Gradient Objectives

```@docs
AbstractManifoldGradientObjective
Expand All @@ -52,61 +112,61 @@ There is also a second variant, if just one function is responsible for computin
ManifoldCostGradientObjective
```

### Access functions
#### Access functions

```@docs
get_gradient
get_gradients
get_gradient_function
```

## Subgradient Objective
### Subgradient Objective

```@docs
ManifoldSubgradientObjective
```

### Access Functions
#### Access Functions

```@docs
get_subgradient
```

## Proximal Map Objective
### Proximal Map Objective

```@docs
ManifoldProximalMapObjective
```

### Access Functions
#### Access Functions

```@docs
get_proximal_map
```


## Hessian Objective
### Hessian Objective

```@docs
ManifoldHessianObjective
```

### Access functions
#### Access functions

```@docs
get_hessian
get_preconditioner
```

## Primal-Dual based Objetives
### Primal-Dual based Objectives

```@docs
AbstractPrimalDualManifoldObjective
PrimalDualManifoldObjective
PrimalDualManifoldSemismoothNewtonObjective
```

### Access functions
#### Access functions

```@docs
adjoint_linearized_operator
Expand All @@ -118,7 +178,7 @@ get_primal_prox
linearized_forward_operator
```

## Constrained Objective
### Constrained Objective

Besides the [`AbstractEvaluationType`](@ref) there is one further property to
distinguish among constraint functions, especially the gradients of the constraints.
Expand All @@ -135,7 +195,7 @@ The [`ConstraintType`](@ref) is a parameter of the corresponding Objective.
ConstrainedManifoldObjective
```

### Access functions
#### Access functions

```@docs
get_constraints
Expand All @@ -152,50 +212,3 @@ get_grad_inequality_constraint!
get_grad_inequality_constraints
get_grad_inequality_constraints!
```

## Decorators for AbstractManoptSolverState

An objective can be decorated using the following trait and function to initialize

```@docs
dispatch_objective_decorator
is_objective_decorator
decorate_objective!
```

### [Cache Objective](@id CacheSection)

Since single function calls, e.g. to the cost or the gradient, might be expensive,
a simple cache objective exists as a decorator, that caches one cost value or gradient.

It can be activated/used with the `cache=` keyword argument available for every solver.

```@docs
Manopt.reset_counters!
Manopt.objective_cache_factory
```

#### A simple cache

A first generic cache is always available, but it only caches one gradient and one cost function evaluation (for the same point).

```@docs
SimpleManifoldCachedObjective
```

#### A Generic Cache

For the more advanced cache, you need to implement some type of cache yourself, that provides a `get!`
and implement [`init_caches`](@ref).
This is for example provided if you load [`LRUCache.jl`](https://github.com/JuliaCollections/LRUCache.jl). Then you obtain

```@docs
ManifoldCachedObjective
init_caches
```

### [Count Objective](@id ManifoldCountObjective)

```@docs
ManifoldCountObjective
```
2 changes: 1 addition & 1 deletion docs/src/plans/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This might be useful to continue investigation at the current iterate, or to set
```@docs
get_iterate
set_iterate!
get_gradient(::AbstractManifoldGradientObjective)
get_gradient(s::AbstractManoptSolverState)
set_gradient!
```

Expand Down
14 changes: 14 additions & 0 deletions docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,20 @@ @article{LiuStorey:1991
% --- N
%
%
@article{Nguyen:2023,
DOI = {10.1007/s10957-023-02242-z},
EPRINT = {2009.10159},
EPRINTTYPE = {arXiv},
YEAR = {2023},
MONTH = jun,
PUBLISHER = {Springer Science and Business Media {LLC}},
VOLUME = {198},
NUMBER = {1},
PAGES = {135--164},
AUTHOR = {Du Nguyen},
TITLE = {Operator-Valued Formulas for Riemannian Gradient and Hessian and Families of Tractable Metrics in Riemannian Optimization},
JOURNAL = {Journal of Optimization Theory and Applications}
}
@book{NocedalWright:2006,
ADDRESS = {New York},
AUTHOR = {Nocedal, Jorge and Wright, Steven J.},
Expand Down
11 changes: 10 additions & 1 deletion src/Manopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
* 🎯 Issues: [github.com/JuliaManifolds/Manopt.jl/issues](https://github.com/JuliaManifolds/Manopt.jl/issues)
"""
module Manopt

import Base: &, copy, getindex, identity, setindex!, show, |
import LinearAlgebra: reflect!
import ManifoldsBase: embed!

using ColorSchemes
using ColorTypes
Expand Down Expand Up @@ -45,7 +47,11 @@ using ManifoldDiff:
differential_shortest_geodesic_startpoint,
differential_shortest_geodesic_startpoint!,
jacobi_field,
jacobi_field!
jacobi_field!,
riemannian_gradient,
riemannian_gradient!,
riemannian_Hessian,
riemannian_Hessian!
using ManifoldsBase:
AbstractBasis,
AbstractDecoratorManifold,
Expand Down Expand Up @@ -78,6 +84,7 @@ using ManifoldsBase:
default_retraction_method,
default_vector_transport_method,
distance,
embed,
embed_project,
embed_project!,
exp,
Expand All @@ -87,6 +94,7 @@ using ManifoldsBase:
get_component,
get_coordinates,
get_coordinates!,
get_embedding,
get_iterator,
get_vector,
get_vector!,
Expand Down Expand Up @@ -206,6 +214,7 @@ export AbstractDecoratedManifoldObjective,
AbstractManifoldObjective,
AbstractPrimalDualManifoldObjective,
ConstrainedManifoldObjective,
EmbeddedManifoldObjective,
ManifoldCountObjective,
NonlinearLeastSquaresObjective,
ManifoldAlternatingGradientObjective,
Expand Down
6 changes: 3 additions & 3 deletions src/plans/constrained_plan.jl
Original file line number Diff line number Diff line change
Expand Up @@ -515,9 +515,9 @@ eevaluate all gradients of the equality constraints ``\operatorname{grad} h(x)``
of the [`ConstrainedManifoldObjective`](@ref) `P` at `p`.

!!! note
for the [`InplaceEvaluation`](@ref) and [`FunctionConstraint`](@ref) variant of the problem,
this function currently also calls [`get_equality_constraints`](@ref),
since this is the only way to determine the number of cconstraints.
For the [`InplaceEvaluation`](@ref) and [`FunctionConstraint`](@ref) variant of the problem,
this function currently also calls [`get_equality_constraints`](@ref),
since this is the only way to determine the number of cconstraints.
"""
get_grad_equality_constraints(M::AbstractManifold, co::ConstrainedManifoldObjective, p)
function get_grad_equality_constraints(
Expand Down
Loading