Contributing to Manifolds.jl

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

The following is a set of guidelines to Manifolds.jl.

Table of contents

How to ask a question

You can most easily reach the developers 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 to file an issue

If you found a bug or want to propose a feature, issues are tracked within the GitHub repository.

How to contribute

Overview of resources

Add a missing method

Within Manifolds.jl, there might be manifolds, that are only partially define the list of methods from the interface given in ManifoldsBase.jl. If you notice a missing method but are aware of an algorithm or theory about it, contributing the method is welcome. Even just the smallest function is a good contribution.

Provide a new manifold

A main contribution you can provide is another manifold that is not yet included in the package. A manifold is a concrete subtype of AbstractManifold from ManifoldsBase.jl. A tutorial on how to define a manifold helps to get started on a new manifold. Every new manifold is welcome, even if you only add a few functions, for example when your use case for now does not require more features.

One important detail is that the interface provides an in-place as well as a non-mutating variant See for example exp! and exp. The non-mutating one, exp, always falls back to allocating the according memory, here a point on the manifold, to then call the in-place variant. This way it suffices to provide the in-place variant, exp!. The allocating variant only needs to defined if a more efficient version than the default is available.

Note that since the first argument is always the AbstractManifold, the mutated argument is always the second one in the signature. In the example there are exp(M, p, X, t) for the exponential map that allocates its result q, and exp!(M, q, p, X, t) for the in-place one, which computes and returns the q.

Since a user probably looks for the documentation on the allocating variant, we recommend to attach the documentation string to this variant, mentioning all possible function signatures including the mutating one. You can best achieve this by adding a documentation string to the method with a general signature with the first argument being your manifold:

struct MyManifold <: AbstractManifold end

@doc """
    exp(M::MyManifold, p, X)
    exp!(M::MyManifold, q, p, X)

Describe the function, its input and output as well as a mathematical formula.
"""
exp(::MyManifold, ::Any...)

You can also save the string to a variable, for example _doc_myM_exp and attach it to both functions

Code style

Please follow the documentation guidelines from the Julia documentation as well as Blue Style. Run JuliaFormatter.jl on the repository running using JuliaFormatter; format(".") on the main folder of the project.

Please follow a few internal conventions:

  • Please include a description of the manifold and a reference to the general theory in the struct of your manifold that inherits from AbstractManifold'.
  • Include the mathematical formulae for any implemented function if a closed form exists.
  • Within the source code of one manifold, the struct the manifold should be the first element of the file.
  • an alphabetical order of functions in every file is preferable.
  • The preceding 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 allocating and in-place variants).
  • Prefer to have no newline between methods for the same function; when reasonable, merge the documentation string.
  • Always document all input variables and keyword arguments
  • if possible provide both mathematical formulae and literature references using DocumenterCitations.jl and BibTeX where possible
  • All import/using/include should be in the main module file.