Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
51 changes: 50 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,34 @@ The file was started with Version `0.4`.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.6.0] unreleased

This is a breaking change since the JuMP extension is dropped.

### Added

* `nonpositive_curvature_behavior` for `QuasiNewtonLimitedMemoryDirectionUpdate` that determines how transported (y, s) vector pairs are treated after transport; if their inner product gets too low, it may lead to non-positive-definite Hessians which needs to be avoided. This resolves issue #549. (#554)
* `GeneralizedCauchyDirectionSubsolver` for handling direction selection in the presence of box (`Hyperrectangle`) constraints in quasi-Newton methods. This allows for L-BFGS-B-style box constraint handling. (#554)
* New stopping criteria: `StopWhenRelativeAPosterioriCostChangeLessOrEqual` and `StopWhenProjectedNegativeGradientNormLess`. (#554).
* `HagerZhangLinesearch` stepsize, a state-of-the-art line search for smooth objectives with cubic interpolation and adaptive Wolfe condition checking. (#554)
* Stopping criteria can now be initialized using `initialize_stepsize!`, similar to solvers. (#554)

### Fixed

* Fixed `show` methods of various state and stopping criteria to properly handle both `repr` and multiline printing (#569)
* Unified all `show` methods and their human readable analoga `status_summary` throughout the package (#569)
* Fixed some text descriptions of a few stopping criteria.
* unify naming of fields, `debugDictionary` of the debug state is now called `debug_dictionary`
* the `NesterovRule` now also stores an actual `AbstractRetractionMethod` instead of implicitly always using the default one.
* Line searches consistently respect `stop_when_stepsize_exceeds` keyword argument as a hard limit. (#554)
* `StopWhenChangeLess` falsely claimed to indicate convergence. This is now fixed. (#554)

### Removed

* The extension to JuMP. A replacement as a separate package is planned when the support for variables beyond vectors is more accessible in JuMP
* the plotting functions to `Asymptote`. They can now be found in the separate package [`ManifoldAsymptote.jl`]()
this way, `Manopt.jl` has less dependencies, especially the color and colorschemes dependencies are dropped

## [0.5.37] May 5, 2026

### Changed
Expand All @@ -28,6 +56,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

* The default restart rule for `conjugate_gradient_descent` is now `RestartOnNonDescent` instead of `NeverRestart`, which makes the algorithm more robust to non-convexity and numerical issues. The old default can still be used by explicitly passing `restart_condition=NeverRestart()`. (#604)
* `HagerZhangCoefficientRule` now has a safeguard against the denominator being too close to zero (the `denom_threshold` field). By default it is set to 1.0e-10. You can set it to a lower positive value (or even zero) to weaken the safeguard, but it is recommended to keep it to avoid numerical issues. (#604)
* introduce for all `Rule`s also a variant without being encapsulated in a memory, where the old values have to be passed as keywords. This is now used by the `ConjugateGradientBealeRestartRule` when evaluating its inner rule. (#604)

## [0.5.36] April 24, 2026

### Added

* a function `stopped_at(state)` to access the number of iterations it took a solver to stop. (#599)

### Fixed

* a small bug where `get_count(sc::StopWhenAny, Val(:Iteration))` wrongly reported it stopped before the first iteration when it actually did not yet stop. (#599)

## [0.5.35] April 16, 2026

### Changed

* `NonlinearLeastSquaresObjective` is now called `ManifoldNonlinearLeastSquaresObjective` (#569).
* This is a breaking release in order to move a few parts to a unified naming and since we
discontinue the `JuMP` extension. (#532)
* Improved formatting of the references in the Readme.md (#586)
* Bump compat for RecursiveArrayTools.jl to include version 4
* deactivate CompatHelper Action and solely use dependabot
Expand Down Expand Up @@ -94,7 +143,7 @@ Moved the documentation glossaries to using the new [Glossaries.jl](https://gith
* Removed `atol` from `DebugFeasibility` and instead use the one newly added `atol` from the `ConstrainedManifoldObjective`. (#546)
* Move from CompatHelper to dependabot to keep track of dependency updates in Julia packages. (#547)
* moved the `ManoptTestSuite` module to a sub module `Manopt.Test` within `Manopt.jl`,
so it can be easier reused by others as well (#550)
so it can be easier reused by others as well (#550)
* moved to using a `Project.toml` for tests and an overall `[Workspace]`.
This also allows finally to run single test files without installing all packages manually, but instead just switching to and instantiating the test environment. (#550)
* for compatibility, state also `[source]` entries consistently in the sub `Project.toml` files. (#550)
Expand Down
19 changes: 11 additions & 8 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
name = "Manopt"
uuid = "0fc0a36d-df90-57f3-8f93-d78a9fc72bb5"
version = "0.5.37"
authors = [{family-names = "Bergmann", given-names = "Ronny", alias = "kellertuer", city = "Trondheim", affiliation = "Norwegian University of Science and Technology", country = "NO", email = "manopt@ronnybergmann.net", orcid = "https://orcid.org/0000-0001-8342-7218", website = "https://ronnybergmann.net"}]

[workspace]
projects = ["test", "docs", "tutorials"]

[deps]
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Glossaries = "8f48dd54-e453-4cdc-9500-53b96149560b"
Expand All @@ -34,17 +30,13 @@ RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
RipQP = "1e40b3f8-35eb-4cd8-8edd-3e515bb9de08"

[extensions]
ManoptJuMPExt = "JuMP"
ManoptLRUCacheExt = "LRUCache"
ManoptLineSearchesExt = "LineSearches"
ManoptManifoldsExt = "Manifolds"
ManoptRecursiveArrayToolsExt = "RecursiveArrayTools"
ManoptRipQPQuadraticModelsExt = ["RipQP", "QuadraticModels"]

[compat]
ColorSchemes = "3.5.0"
ColorTypes = "0.9.1, 0.10, 0.11, 0.12"
Colors = "0.11.2, 0.12, 0.13"
DataStructures = "0.17, 0.18, 0.19"
Dates = "1.10"
Glossaries = "0.1.1"
Expand All @@ -66,3 +58,14 @@ RipQP = "0.6.4, 0.7"
SparseArrays = "1.10"
Statistics = "1.10"
julia = "1.10"

[[authors]]
affiliation = "Norwegian University of Science and Technology"
alias = "kellertuer"
city = "Trondheim"
country = "NO"
email = "manopt@ronnybergmann.net"
family-names = "Bergmann"
given-names = "Ronny"
orcid = "https://orcid.org/0000-0001-8342-7218"
website = "https://ronnybergmann.net"
2 changes: 1 addition & 1 deletion _typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ methodes = "methodes" # french
Serie = "Serie" # french
sur = "sur" # french
cmo = "cmo" # often used abbreviation for constrained manifold objective

nd = "nd" # like in 2nd
[files]
extend-exclude = [
"tutorials/*.html",
Expand Down
6 changes: 2 additions & 4 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656"
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637"
LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand All @@ -23,8 +22,8 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
RipQP = "1e40b3f8-35eb-4cd8-8edd-3e515bb9de08"

[sources.Manopt]
path = ".."
[sources]
Manopt = {path = ".."}

[compat]
BenchmarkTools = "1.3"
Expand All @@ -37,7 +36,6 @@ DocumenterInterLinks = "0.3, 1"
FiniteDifferences = "0.12"
Images = "0.26"
JLD2 = "0.4, 0.5, 0.6"
JuMP = "1"
LRUCache = "1"
LineSearches = "7"
Literate = "2"
Expand Down
6 changes: 3 additions & 3 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ tutorials_menu =
"Implement a solver" => "tutorials/ImplementASolver.md",
"Optimize on your own manifold" => "tutorials/ImplementOwnManifold.md",
"Do constrained optimization" => "tutorials/ConstrainedOptimization.md",
"Do optimization with bounds" => "tutorials/BoxDomain.md",
]
# Check whether all tutorials are rendered, issue a warning if not (and quarto if not set)
all_tutorials_exist = true
Expand Down Expand Up @@ -101,7 +102,7 @@ end
# (c) load necessary packages for the docs
using Documenter
using DocumenterCitations, DocumenterInterLinks
using JuMP, LineSearches, LRUCache, Manopt, Manifolds, Plots, RecursiveArrayTools
using LineSearches, LRUCache, Manopt, Manifolds, Plots, RecursiveArrayTools
using RipQP, QuadraticModels

# (d) add contributing.md and changelog.md to the docs – and link to releases and issues
Expand Down Expand Up @@ -162,7 +163,6 @@ makedocs(;
),
modules = [
Manopt,
Base.get_extension(Manopt, :ManoptJuMPExt),
Base.get_extension(Manopt, :ManoptLineSearchesExt),
Base.get_extension(Manopt, :ManoptLRUCacheExt),
Base.get_extension(Manopt, :ManoptManifoldsExt),
Expand All @@ -189,6 +189,7 @@ makedocs(;
"Douglas—Rachford" => "solvers/DouglasRachford.md",
"Exact Penalty Method" => "solvers/exact_penalty_method.md",
"Frank-Wolfe" => "solvers/FrankWolfe.md",
"Generalized Cauchy direction subsolver" => "solvers/generalized_cauchy_direction_subsolver.md",
"Gradient Descent" => "solvers/gradient_descent.md",
"Interior Point Newton" => "solvers/interior_point_Newton.md",
"Levenberg–Marquardt" => "solvers/LevenbergMarquardt.md",
Expand Down Expand Up @@ -218,7 +219,6 @@ makedocs(;
],
"Helpers" => [
"Checks" => "helpers/checks.md",
"Exports" => "helpers/exports.md",
"Test" => "helpers/test.md",
],
"Contributing to Manopt.jl" => "contributing.md",
Expand Down
1 change: 1 addition & 0 deletions docs/src/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Thanks to the following contributors to `Manopt.jl`:
* Mathias Ravn Munkvold contributed most of the implementation of the [Adaptive Regularization with Cubics](solvers/adaptive-regularization-with-cubics.md) solver as well as its [Lanczos](@ref arc-Lanczos) subsolver
* [Sander Engen Oddsen](https://github.com/oddsen) contributed to the implementation of the [LTMADS](solvers/mesh_adaptive_direct_search.md) solver.
* [Jonas Püschel](https://www.uni-augsburg.de/de/fakultaet/mntf/math/prof/numa/team/jonas-pueschel/) contributed [restart rules for the conjugate gradient solver](@ref cg-restart).
* [Patryk Przybysz](https://www.linkedin.com/in/patryk-przybysz-5644aa1a1/) contributed to the [Generalized Cauchy Direction](solvers/generalized_cauchy_direction_subsolver.md).
* [Tom-Christian Riemer](https://www.tu-chemnitz.de/mathematik/wire/mitarbeiter.php) implemented the [trust regions](solvers/trust_regions.md) and [quasi Newton](solvers/quasi_Newton.md) solvers as well as the [truncated conjugate gradient descent](solvers/truncated_conjugate_gradient_descent.md) subsolver.
* [Markus A. Stokkenes](https://www.linkedin.com/in/markus-a-stokkenes-b41bba17b/) contributed most of the implementation of the [Interior Point Newton Method](solvers/interior_point_Newton.md) as well as its default [Conjugate Residual](solvers/conjugate_residual.md) subsolver
* [Laura Weigl](https://num.math.uni-bayreuth.de/en/team/laura-weigl/index.php) implemented the [Vector bundle Newton Method](solvers/vectorbundle_newton.md).
Expand Down
53 changes: 3 additions & 50 deletions docs/src/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ x_opt = quasi_Newton(
)
```

In general this defines the following new [stepsize](@ref Stepsize)
In general this defines the following new [stepsize](@ref Stepsize) with helper functions for setting and getting the maximum step size:

```@docs
Manopt.LineSearchesStepsize
Manopt.linesearches_get_max_alpha
Manopt.linesearches_set_max_alpha
```

## Manifolds.jl
Expand All @@ -69,52 +71,3 @@ Euclidean space when needed as
Manopt.Rn
Manopt.Rn_default
```

## [JuMP.jl](@extref JuMP :std:doc:`index`)

Manopt can be used from within [`JuMP.jl`](@extref JuMP :std:doc:`index`).
The manifold is provided in the `@variable` macro. Note that until now,
only variables (points on manifolds) are supported, that are arrays, especially structs do not yet work.
The algebraic expression of the objective function is specified in the `@objective` macro.
The `descent_state_type` attribute specifies the solver.

```julia
using JuMP, Manopt, Manifolds
model = Model(Manopt.JuMP_Optimizer)
# Change the solver with this option, `GradientDescentState` is the default
set_attribute(model, "descent_state_type", GradientDescentState)
@variable(model, U[1:2, 1:2] in Stiefel(2, 2), start = 1.0)
@objective(model, Min, sum((A - U) .^ 2))
optimize!(model)
solution_summary(model)
```

Several functions from the [Mathematical Optimization Interface (MOI)](@extref JuMP :std:label:`The-MOI-interface`) are
extended when both `Manopt.jl` and [`JuMP.jl`](@extref JuMP :std:doc:`index`) are loaded:

```@docs
Manopt.JuMP_Optimizer
```

### Internal functions

```@docs
JuMP.build_variable
MOI.add_constrained_variables
MOI.copy_to
MOI.empty!
MOI.dimension
MOI.supports_add_constrained_variables
MOI.get
MOI.is_valid
MOI.supports
MOI.supports_incremental_interface
MOI.set
```

### Internal wrappers and their functions

```@autodocs
Modules = [Base.get_extension(Manopt, :ManoptJuMPExt)]
Order = [:type, :function]
```
14 changes: 0 additions & 14 deletions docs/src/helpers/exports.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ The notation in the documentation aims to follow the same [notation](https://jul

### Visualization

To visualize and interpret results, `Manopt.jl` aims to provide both easy plot functions as well as [exports](helpers/exports.md). Furthermore a system to get [debug](plans/debug.md) during the iterations of an algorithms as well as [record](plans/record.md) capabilities, for example to record a specified tuple of values per iteration, most prominently [`RecordCost`](@ref) and
To visualize and interpret results, `Manopt.jl` provides a system to get [debug](plans/debug.md) during the iterations of an algorithms as well as [record](plans/record.md) capabilities, for example to record a specified tuple of values per iteration, most prominently [`RecordCost`](@ref) and
[`RecordIterate`](@ref). Take a look at the [🏔️ Get started with Manopt.jl](tutorials/getstarted.md) tutorial on how to easily activate this.

## Literature
Expand Down
2 changes: 1 addition & 1 deletion docs/src/plans/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The following symbols are used.
| `:Activity` | [`DebugWhenActive`](@ref) | activity of the debug action stored within |
| `:Basepoint` | [`TangentSpace`](@extref ManifoldsBase `ManifoldsBase.TangentSpace`) | the point the tangent space is at |
| `:Cost` | generic |the cost function (within an objective, as pass down) |
| `:Debug` | [`DebugSolverState`](@ref) | the stored `debugDictionary` |
| `:Debug` | [`DebugSolverState`](@ref) | the stored `debug_dictionary` |
| `:Gradient` | generic | the gradient function (within an objective, as pass down) |
| `:Iterate` | generic | the (current) iterate, similar to [`set_iterate!`](@ref), within a state |
| `:Manifold` | generic |the manifold (within a problem, as pass down) |
Expand Down
2 changes: 1 addition & 1 deletion docs/src/plans/objective.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ AbstractManifoldFirstOrderObjective
ManifoldFirstOrderObjective
ManifoldAlternatingGradientObjective
ManifoldStochasticGradientObjective
NonlinearLeastSquaresObjective
ManifoldNonlinearLeastSquaresObjective
```

While the [`ManifoldFirstOrderObjective`](@ref) allows to provide different
Expand Down
52 changes: 51 additions & 1 deletion docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ @article{BacakBergmannSteidlWeinmann:2016
VOLUME = {38},
}

@misc{BaranBergmannPrzybysz:2026,
title = {A {Riemannian} quasi-{Newton} algorithm for optimization with {Euclidean} bounds},
doi = {10.48550/arXiv.2605.10573},
publisher = {arXiv},
author = {Baran, Mateusz and Bergmann, Ronny and Przybysz, Patryk},
month = may,
year = {2026},
note = {arXiv:2605.10573 [math.OC]},
}

@inproceedings{Beale:1972,
ADDRESS = {London},
AUTHOR = {Beale, E. M. L.},
Expand Down Expand Up @@ -260,6 +270,33 @@ @book{Boumal:2023
ISBN = {978-1-00-916616-4}
}

@article{ByrdNocedalSchnabel:1994,
title = {Representations of quasi-{Newton} matrices and their use in limited memory methods},
volume = {63},
issn = {1436-4646},
doi = {10.1007/BF01582063},
number = {1},
journal = {Mathematical Programming},
author = {Byrd, Richard H. and Nocedal, Jorge and Schnabel, Robert B.},
month = jan,
year = {1994},
pages = {129--156},
}

@article{ByrdLuNocedalZhu:1995,
title = {A {Limited} {Memory} {Algorithm} for {Bound} {Constrained} {Optimization}},
volume = {16},
issn = {1064-8275},
doi = {10.1137/0916069},
number = {5},
journal = {SIAM Journal on Scientific Computing},
author = {Byrd, Richard H. and Lu, Peihuang and Nocedal, Jorge and Zhu, Ciyou},
month = sep,
year = {1995},
note = {Publisher: Society for Industrial and Applied Mathematics},
pages = {1190--1208},
}

% --- C
%
%
Expand Down Expand Up @@ -882,4 +919,17 @@ @article{ZhangSra:2018
TITLE = {Towards Riemannian accelerated gradient methods},
URL = {https://arxiv.org/abs/1806.02812},
YEAR = {2018},
}
}

@article{ZhuByrdLuNocedal:1997,
title = {Algorithm 778: {L}-{BFGS}-{B}: {Fortran} subroutines for large-scale bound-constrained optimization},
volume = {23},
issn = {0098-3500},
doi = {10.1145/279232.279236},
number = {4},
journal = {ACM Trans. Math. Softw.},
author = {Zhu, Ciyou and Byrd, Richard H. and Lu, Peihuang and Nocedal, Jorge},
month = dec,
year = {1997},
pages = {550--560},
}
Loading