# Contributing to `Manopt.jl`

First, thanks for taking the time to contribute. Any contribution is appreciated and welcome.

The following is a set of guidelines to `Manopt.jl`

.

#### Table of Contents

## I just have a question

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.

## How can I file an issue?

If you found a bug or want to propose a feature, we track our issues within the GitHub repository.

## How can I contribute?

### Add a missing method

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.

### Provide a new algorithm

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 `i`

th 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 `initialize_solver!`

and `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.

### Provide a new example

Example problems are available at `ManoptExamples.jl`

, where also their reproducible Quarto-Markdown files are stored.

### Code style

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
`=`

signs. - 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.
- All
`import`

/`using`

/`include`

should be in the main module file.