First, thanks for taking the time to contribute. Any contribution is appreciated and welcome.
The following is a set of guidelines to
- Contributing to
Manopt.jl- Table of Contents
The developer can most easily be reached in the Julia Slack channel #manifolds. You can apply for the Julia Slack workspace here if you haven't joined yet. You can also ask your question on discourse.julialang.org.
If you found a bug or want to propose a feature, we track our issues within the GitHub repository.
There is still a lot of methods for within the optimization framework of
Manopt.jl, may it be functions, gradients, differentials, proximal maps, step size rules or stopping criteria. If you notice a method missing and can contribute an implementation, please do so! Even providing a single new method is a good contribution.
A main contribution you can provide is another algorithm that is not yet included in the package. An algorithm is always based on a concrete type of a
AbstractManoptProblem storing the main information of the task and a concrete type of an
AbstractManoptSolverState storing all information that needs to be known to the solver in general. The actual algorithm is split into an initialization phase, see
initialize_solver!, and the implementation of the
ith step of the solver itself, see before the iterative procedure, see
step_solver!. For these two functions, it would be great if a new algorithm uses functions from the
ManifoldsBase.jl interface as generically as possible. For example, if possible use
retract!(M,q,p,X) in favor of
exp!(M,q,p,X) to perform a step starting in
p in direction
X (in place of
q), since the exponential map might be too expensive to evaluate or might not be available on a certain manifold. See Retractions and inverse retractions for more details. Further, if possible, prefer
retract!(M,q,p,X) in favor of
retract(M,p,X), since a computation in place of a suitable variable
q reduces memory allocations.
Usually, the methods implemented in
Manopt.jl also have a high-level interface, that is easier to call, creates the necessary problem and options structure and calls the solver.
The two technical functions
step_solver! should be documented with technical details, while the high level interface should usually provide a general description and some literature references to the algorithm at hand.
Example problems are available at
ManoptExamples.jl, where also their reproducible Quarto-Markdown files are stored.
We try to follow the documentation guidelines from the Julia documentation as well as Blue Style. We run
JuliaFormatter.jl on the repo in the way set in the
.JuliaFormatter.toml file, which enforces a number of conventions consistent with the Blue Style.
We also follow a few internal conventions:
- It is preferred that the
AbstractManoptProblem's struct contains information about the general structure of the problem.
- Any implemented function should be accompanied by its mathematical formulae if a closed form exists.
- AbstractManoptProblem and option structures are stored within the
plan/folder and sorted by properties of the problem and/or solver at hand.
- Within the source code of one algorithm, the high level interface should be first, then the initialization, then the step.
- Otherwise an alphabetical order is preferable.
- The above implies that the mutating variant of a function follows the non-mutating variant.
- There should be no dangling
- Always add a newline between things of different types (struct/method/const).
- Always add a newline between methods for different functions (including mutating/nonmutating variants).
- Prefer to have no newline between methods for the same function; when reasonable, merge the docstrings.
includeshould be in the main module file.