Please note that this project is released with a Contributor Code of
Conduct. By participating in this project you
agree to abide by its terms. Note further, that we follow
and would like to emphasize the following additional examples of
unacceptable behavior:
- Publishing or applying others' algorithms, implementations, or research ideas present in the private development repository (e.g. in a WIP branch or merge request), without their explicit permission.
When contributing to this project, please note the following style conventions that are enforced (partially strictly enforced by the CI server).
Most importantly, reflect your changes in the Changelog so we do not have to reconstruct it from the GIT history.
When you have contributed code to M-M.E.S.S., you and the content of your contribution will be mentioned in the project's contributors file. Contributions are grouped by release, so if you have contributed code to multiple releases, you will be mentioned for each of these releases.
If, for some reason, you do not wish to be mentioned in the contributors file, please give us a short note. Also note that we cannot give attributions to trivial changes, such as fixing a typo in the documentation or correcting a very simple bug. However, your changes including your authorship will always be included in the git history of the project.
In general we prefer descriptive identifiers that support easier reading and understanding of the code. Other than that, follow the guidelines below:
Naming of functions:
- to avoid shadowing of functions from other toolboxes/packages or
the MATLAB/Octave core, all M-M.E.S.S. solver functions start with
mess_ - demonstration routines can have names deviating from the above principle, but should be descriptive enough such that a basic idea of their contents is evident.
- user supplied functions need to have a special naming scheme
described in the documentation and found in the
operatormanagerfunction inside theusfsfolder - Routines that do not obey the above have to be put into a
privatefolder, or embedded into their calling functions source file.
Code Style:
- We try to follow the Mathworks recommendation for maximum line lengths where possible. In exceptional cases lines of at most 120 characters are allowed. The latter is enforced by our CI settings, i.e. the tests will fail when a longer line is detected. Documentation strings should strictly keep the 80 characters bound for readability reasons.
- any checked-in code must pass the
checkcodetests in MATLAB, i.e. you are not allowed to have red or orange marks in the MATLAB editor. However, when absolutely necessary those warnings may be suppressed. (E.g. in ADI the growth of the solution factor is avoidable only with significant implementation overhead) - We always use
not()rather than~for negation for easier reading. (Enforced by CI!) - To support our abstraction and provide maximum flexibility to users,
all functions that are not explicitly intended for matrices need
to have
eqn,opts, andoperas mandatory input and output arguments. For examplemess_lradiis a core Lyapunov solver that is intended for maximum abstraction and needs these arguments, whilemess_lyapis intended as a large-scale replacement for MATLAB'slyapand thus intended for matrices. - For the same abstraction reason, in core solvers, all operations
with the system matrices have to be implemented via the
usfssystem and access to, e.g.,eqn.A_oreqn.E_is prohibited. (seehelp mess_usfsfor details on theusfssystem and philosophy) - The options structure
optsshould contain a separate substructure for each algorithm/solver-function and options are only allowed on the top level when they are absolutely necessary for consistent operation. For examplemess_lrnmandmess_lradihave their options inopts.nmandopts.adi. On the other hand,opts.LDL_Toropts.normused to decide global settings like the shape of the factorization computed, or the norm that should consistently be used for measuring progress are allowed on the top level. - Avoid code duplication. If code blocks, or variations thereof, need to be repeated, consider to put them into a function and call it where necessary. If a helper function lacks functionality consider extending rather than doubling it.
- We prefer comments to start with a space for readability, i.e.
% commentrather than%comment. - We use blanks around operators and after commas in argument lists,
e.g.
y = a * x + b;and noty=a*x+b; - Transposes, denoted by
', only occur on capital letters. (this is currently required by our spellcheckers and may be dropped in the future)
Warnings, Errors and Logging:
- We provide or own logging mechanisms. We, therefore, do not call
error, orwarningdirectly, but viamess_errandmess_warnfound in theloggerfolder. mess_log_matrixadditionally allows to write matrices to.matfiles.mess_log_plotcan store the figures in image files.- All M-M.E.S.S. code must use these and demonstration examples have
to initialize and finalize the logger via
mess_log_initialize,mess_log_finalize. - It is mandatory to use
mess_fprintfrather thanfprintfordisp. - CI tests in
_testscan be an exception from this rule.
Our GIT repository provides maximum flexibility for forking, branching, merging, and commenting on work done. For the sake of maintainability follow these guidelines:
- Try to break down things to as small issues as possible.
- Work on a single issue per merge request or branch.
- branch and merge often, since long living branches tend to become messy to handle and synchronize with the master.
- Try to 'rebase' your work onto the main branch before merging or requesting a merge, if possible.
We use an extensive test system on our continuous integration (CI) server to ensure that new features do not break old functionality and all features work in both MATLAB and GNU Octave, both with and without toolboxes/packages installed. Currently CI time is limited to 6 hours and all tests should be finished in that time.
We distinguish between so called unit tests, system tests, and extended tests. Here, unit tests are testing the smallest possible building blocks. As a rule of thumb, a routine that does not call external functions, or only private functions is a candidate for a unit test.
Larger routines that run a hierarchy of other stuff, such as our
demonstrator functions in the DEMOS folder should be used to perform
the bigger system tests.
If runtimes become an issue, consider moving system tests to the extended tests category. While unit and system tests are executed on every push that affects them and included in our weekly pipelines, extended tests (that run exceptionally long) are executed only in our monthly extended pipelines.
- All files in
DEMOSshould be accompanied by a system test calling them on an, ideally, small example. (See comment about the CI time above) - All
usfssets should be checked by unit tests. Use non-symmetric systems and system matrices where possible! - Consider to provide a unit test for every helper routine in your code.