Changelog

All notable Changes to the Julia package Manopt.jl will be documented in this file. The file was started with Version 0.4.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.4.58] - March 18, 2024

Added

  • more advanced methods to add debug to the beginning of an algorithm, a step, or the end of the algorithm with DebugAction entries at :Start, :BeforeIteration, :Iteration, and :Stop, respectively.
  • Introduce a Pair-based format to add elements to these hooks, while all others ar now added to :Iteration (no longer to :All)
  • (planned) add an easy possibility to also record the initial stage and not only after the first iteration.

Changed

  • Changed the symbol for the :Step dictionary to be :Iteration, to unify this with the symbols used in recording, and removed the :All symbol. On the fine granular scale, all but :Start debugs are now reset on init. Since these are merely internal entries in the debug dictionary, this is considered non-breaking.
  • introduce a StopWhenSwarmVelocityLess stopping criterion for particle_swarm replacing the current default of the swarm change, since this is a bit more effective to compute

Fixed

  • fixed the outdated documentation of TruncatedConjugateGradientState, that now correcly state that p is no longer stored, but the algorithm runs on TpM.
  • implemented the missing get_iterate for TruncatedConjugateGradientState.

[0.4.57] - March 15, 2024

Changed

  • convex_bundle_method uses the sectional_curvature from ManifoldsBase.jl.
  • convex_bundle_method no longer has the unused k_min keyword argument.
  • ManifoldsBase.jl now is running on Documenter 1.3, Manopt.jl documentation now uses DocumenterInterLinks to refer to sections and functions from ManifoldsBase.jl

Fixed

  • fixes a type that when passing sub_kwargs to trust_regions caused an error in the decoration of the sub objective.

[0.4.56] - March 4, 2024

Added

  • The option :step_towards_negative_gradient for nondescent_direction_behavior in quasi-Newton solvers does no longer emit a warning by default. This has been moved to a message, that can be accessed/displayed with DebugMessages
  • DebugMessages now has a second positional argument, specifying whether all messages, or just the first (:Once) should be displayed.

[0.4.55] - March 3, 2024

Added

  • Option nondescent_direction_behavior for quasi-Newton solvers. By default it checks for non-descent direction which may not be handled well by some stepsize selection algorithms.

Fixed

  • unified documentation, especially function signatures further.
  • fixed a few typos related to math formulae in the doc strings.

[0.4.54] - February 28, 2024

Added

  • convex_bundle_method optimization algorithm for non-smooth geodesically convex functions
  • proximal_bundle_method optimization algorithm for non-smooth functions.
  • StopWhenSubgradientNormLess, StopWhenLagrangeMultiplierLess, and stopping criteria.

Fixed

  • Doc strings now follow a vale.sh policy. Though this is not fully working, this PR improves a lot of the doc strings concerning wording and spelling.

[0.4.53] - February 13, 2024

Fixed

  • fixes two storage action defaults, that accidentally still tried to initialize a :Population (as modified back to :Iterate 0.4.49).
  • fix a few typos in the documentation and add a reference for the subgradient menthod.

[0.4.52] - February 5, 2024

Added

  • introduce an environment persistent way of setting global values with the set_manopt_parameter! function using Preferences.jl.
  • introduce such a value named :Mode to enable a "Tutorial" mode that shall often provide more warnings and information for people getting started with optimisation on manifolds

[0.4.51] - January 30, 2024

Added

  • A StopWhenSubgradientNormLess stopping criterion for subgradient-based optimization.
  • Allow the message= of the DebugIfEntry debug action to contain a format element to print the field in the message as well.

[0.4.50] - January 26, 2024

Fixed

  • Fix Quasi Newton on complex manifolds.

[0.4.49] - January 18, 2024

Added

  • A StopWhenEntryChangeLess to be able to stop on arbitrary small changes of specific fields
  • generalises StopWhenGradientNormLess to accept arbitrary norm= functions
  • refactor the default in particle_swarm to no longer “misuse” the iteration change check, but actually the new one one the :swarm entry

[0.4.48] - January 16, 2024

Fixed

  • fixes an imprecision in the interface of get_iterate that sometimes led to the swarm of particle_swarm being returned as the iterate.
  • refactor particle_swarm in naming and access functions to avoid this also in the future. To access the whole swarm, one now should use get_manopt_parameter(pss, :Population)

[0.4.47] - January 6, 2024

Fixed

  • fixed a bug, where the retraction set in check_Hessian was not passed on to the optional inner check_gradient call, which could lead to unwanted side effects, see #342.

[0.4.46] - January 1, 2024

Changed

  • An error is thrown when a line search from LineSearches.jl reports search failure.
  • Changed default stopping criterion in ALM algorithm to mitigate an issue occurring when step size is very small.
  • Default memory length in default ALM subsolver is now capped at manifold dimension.
  • Replaced CI testing on Julia 1.8 with testing on Julia 1.10.

Fixed

  • A bug in LineSearches.jl extension leading to slower convergence.
  • Fixed a bug in L-BFGS related to memory storage, which caused significantly slower convergence.

[0.4.45] - December 28, 2023

Added

  • Introduce sub_kwargs and sub_stopping_criterion for trust_regions as noticed in #336

Changed

  • WolfePowellLineSearch, ArmijoLineSearch step sizes now allocate less
  • linesearch_backtrack! is now available
  • Quasi Newton Updates can work in-place of a direction vector as well.
  • Faster safe_indices in L-BFGS.

[0.4.44] - December 12, 2023

Formally one could consider this version breaking, since a few functions have been moved, that in earlier versions (0.3.x) have been used in example scripts. These examples are now available again within ManoptExamples.jl, and with their “reappearance” the corresponding costs, gradients, differentials, adjoint differentials, and proximal maps have been moved there as well. This is not considered breaking, since the functions were only used in the old, removed examples. Each and every moved function is still documented. They have been partly renamed, and their documentation and testing has been extended.

Changed

[0.4.43] - November 19, 2023

Added

  • vale.sh as a CI to keep track of a consistent documenttion

[0.4.42] - November 6, 2023

Added

  • add Manopt.JuMP_Optimizer implementing JuMP's solver interface

[0.4.41] - November 2, 2023

Changed

  • trust_regions is now more flexible and the sub solver (Steihaug-Toint tCG by default) can now be exchanged.
  • adaptive_regularization_with_cubics is now more flexible as well, where it previously was a bit too much tightened to the Lanczos solver as well.
  • Unified documentation notation and bumped dependencies to use DocumenterCitations 1.3

[0.4.40] - October 24, 2023

Added

  • add a --help argument to docs/make.jl to document all available command line arguments
  • add a --exclude-tutorials argument to docs/make.jl. This way, when quarto is not available on a computer, the docs can still be build with the tutorials not being added to the menu such that documenter does not expect them to exist.

Changes

  • Bump dependencies to ManifoldsBase.jl 0.15 and Manifolds.jl 0.9
  • move the ARC CG subsolver to the main package, since TangentSpace is now already available from ManifoldsBase.

[0.4.39] - October 9, 2023

Changes

  • also use the pair of a retraction and the inverse retraction (see last update) to perform the relaxation within the Douglas-Rachford algorithm.

[0.4.38] - October 8, 2023

Changes

  • avoid allocations when calling get_jacobian! within the Levenberg-Marquard Algorithm.

Fixed

  • Fix a lot of typos in the documentation

[0.4.37] - September 28, 2023

Changes

  • add more of the Riemannian Levenberg-Marquard algorithms parameters as keywords, so they can be changed on call
  • generalize the internal reflection of Douglas-Rachford, such that is also works with an arbitrary pair of a reflection and an inverse reflection.

[0.4.36] - September 20, 2023

Fixed

  • Fixed a bug that caused non-matrix points and vectors to fail when working with approximate

[0.4.35] - September 14, 2023

Added

  • The access to functions of the objective is now unified and encapsulated in proper get_ functions.

[0.4.34] - September 02, 2023

Added

  • an ManifoldEuclideanGradientObjective to allow the cost, gradient, and Hessian and other first or second derivative based elements to be Euclidean and converted when needed.
  • a keyword objective_type=:Euclidean for all solvers, that specifies that an Objective shall be created of the above type

[0.4.33] - August 24, 2023

Added

  • ConstantStepsize and DecreasingStepsize now have an additional field type::Symbol to assess whether the step-size should be relatively (to the gradient norm) or absolutely constant.

[0.4.32] - August 23, 2023

Added

  • The adaptive regularization with cubics (ARC) solver.

[0.4.31] - August 14, 2023

Added

  • A :Subsolver keyword in the debug= keyword argument, that activates the new DebugWhenActiveto de/activate subsolver debug from the main solversDebugEvery`.

[0.4.30] - August 3, 2023

Changed

  • References in the documentation are now rendered using DocumenterCitations.jl
  • Asymptote export now also accepts a size in pixel instead of its default 4cm size and render can be deactivated setting it to nothing.

[0.4.29] - July 12, 2023

Fixed

  • fixed a bug, where cyclic_proximal_point did not work with decorated objectives.

[0.4.28] - June 24, 2023

Changed

  • max_stepsize was specialized for FixedRankManifold to follow Matlab Manopt.

[0.4.27] - June 15, 2023

Added

  • The AdaptiveWNGrad stepsize is available as a new stepsize functor.

Fixed

  • Levenberg-Marquardt now possesses its parameters initial_residual_values and initial_jacobian_f also as keyword arguments, such that their default initialisations can be adapted, if necessary

[0.4.26] - June 11, 2023

Added

  • simplify usage of gradient descent as sub solver in the DoC solvers.
  • add a get_state function
  • document indicates_convergence.

[0.4.25] - June 5, 2023

Fixed

  • Fixes an allocation bug in the difference of convex algorithm

[0.4.24] - June 4, 2023

Added

  • another workflow that deletes old PR renderings from the docs to keep them smaller in overall size.

Changes

  • bump dependencies since the extension between Manifolds.jl and ManifoldsDiff.jl has been moved to Manifolds.jl

[0.4.23] - June 4, 2023

Added

  • More details on the Count and Cache tutorial

Changed

  • loosen constraints slightly

[0.4.22] - May 31, 2023

Added

  • A tutorial on how to implement a solver

[0.4.21] - May 22, 2023

Added

  • A ManifoldCacheObjective as a decorator for objectives to cache results of calls, using LRU Caches as a weak dependency. For now this works with cost and gradient evaluations
  • A ManifoldCountObjective as a decorator for objectives to enable counting of calls to for example the cost and the gradient
  • adds a return_objective keyword, that switches the return of a solver to a tuple (o, s), where o is the (possibly decorated) objective, and s is the “classical” solver return (state or point). This way the counted values can be accessed and the cache can be reused.
  • change solvers on the mid level (form solver(M, objective, p)) to also accept decorated objectives

Changed

  • Switch all Requires weak dependencies to actual weak dependencies starting in Julia 1.9

[0.4.20] - May 11, 2023

Changed

  • the default tolerances for the numerical check_ functions were loosened a bit, such that check_vector can also be changed in its tolerances.

[0.4.19] - May 7, 2023

Added

  • the sub solver for trust_regions is now customizable and can now be exchanged.

Changed

  • slightly changed the definitions of the solver states for ALM and EPM to be type stable

[0.4.18] - May 4, 2023

Added

  • A function check_Hessian(M, f, grad_f, Hess_f) to numerically check the (Riemannian) Hessian of a function f

[0.4.17] - April 28, 2023

Added

  • A new interface of the form alg(M, objective, p0) to allow to reuse objectives without creating AbstractManoptSolverStates and calling solve!. This especially still allows for any decoration of the objective and/or the state using debug=, or record=.

Changed

  • All solvers now have the initial point p as an optional parameter making it more accessible to first time users, gradient_descent(M, f, grad_f) is equivalent to gradient_descent(M, f, grad_f, rand(M))

Fixed

  • Unified the framework to work on manifold where points are represented by numbers for several solvers

[0.4.16] - April 18, 2023

Fixed

  • the inner products used in truncated_gradient_descent now also work thoroughly on complex matrix manifolds

[0.4.15] - April 13, 2023

Changed

  • trust_regions(M, f, grad_f, hess_f, p) now has the Hessian hess_f as well as the start point p0 as an optional parameter and approximate it otherwise.
  • trust_regions!(M, f, grad_f, hess_f, p) has the Hessian as an optional parameter and approximate it otherwise.

Removed

  • support for ManifoldsBase.jl 0.13.x, since with the definition of copy(M,p::Number), in 0.14.4, that one is used instead of defining it ourselves.

[0.4.14] - April 06, 2023

Changed

  • particle_swarm now uses much more in-place operations

Fixed

  • particle_swarm used quite a few deepcopy(p) commands still, which were replaced by copy(M, p)

[0.4.13] - April 09, 2023

Added

  • get_message to obtain messages from sub steps of a solver
  • DebugMessages to display the new messages in debug
  • safeguards in Armijo line search and L-BFGS against numerical over- and underflow that report in messages

[0.4.12] - April 4, 2023

Added

[0.4.11] - March 27, 2023

Changed

  • adapt tolerances in tests to the speed/accuracy optimized distance on the sphere in Manifolds.jl (part II)

[0.4.10] - March 26, 2023

Changed

  • adapt tolerances in tests to the speed/accuracy optimized distance on the sphere in Manifolds.jl

[0.4.9] - March 3, 2023

Added

[0.4.8] - February 21, 2023

Added

  • a status_summary that displays the main parameters within several structures of Manopt, most prominently a solver state

Changed

  • Improved storage performance by introducing separate named tuples for points and vectors
  • changed the show methods of AbstractManoptSolverStates to display their `state_summary
  • Move tutorials to be rendered with Quarto into the documentation.

[0.4.7] - February 14, 2023

Changed

  • Bump [compat] entry of ManifoldDiff to also include 0.3

[0.4.6] - February 3, 2023

Fixed

  • Fixed a few stopping criteria even indicated to stop before the algorithm started.

[0.4.5] - January 24, 2023

Changed

  • the new default functions that include p are used where possible
  • a first step towards faster storage handling

[0.4.4] - January 20, 2023

Added

  • Introduce ConjugateGradientBealeRestart to allow CG restarts using Beale‘s rule

Fixed

  • fix a type in HestenesStiefelCoefficient

[0.4.3] - January 17, 2023

Fixed

  • the CG coefficient β can now be complex
  • fix a bug in grad_distance

[0.4.2] - January 16, 2023

Changed

  • the usage of inner in line search methods, such that they work well with complex manifolds as well

[0.4.1] - January 15, 2023

Fixed

  • a max_stepsize per manifold to avoid leaving the injectivity radius, which it also defaults to

[0.4.0] - January 10, 2023

Added

  • Dependency on ManifoldDiff.jl and a start of moving actual derivatives, differentials, and gradients there.
  • AbstractManifoldObjective to store the objective within the AbstractManoptProblem
  • Introduce a CostGrad structure to store a function that computes the cost and gradient within one function.

Changed

  • AbstractManoptProblem replaces Problem
  • the problem now contains a
  • AbstractManoptSolverState replaces Options
  • random_point(M) is replaced by rand(M) from `ManifoldsBase.jl
  • random_tangent(M, p) is replaced by rand(M; vector_at=p)