Create home authored by Ferdinand Fischer's avatar Ferdinand Fischer
# Names
- Use meaningful names and avoid abbreviations.
- Only use English vocabulary.
- Don't use names of existing keywords or built-in functions like `path()`, `figure()`, `plot()` or `sim()` (hint: check with `exist whateverNameYouIntendToUse`)
- The latter rule does not apply for methods of classes, since `kernel.plot();` is very nice and clear because of .-notation.
- **Class names** begin with a capital letter. All other names with a small letter.
- If the name consists of multiple words, use capitals at beginning of following words: `myFavoriteNumber = 7;`
- The latter also applies to all-caps abbreviations: use *pdeName* or *nameOfPde*, instead of *PDEName* or *nameOfPDE*.
- Don't use *i* or *j* as loop-variable since its confusing in context of imaginary numbers.
- In **for-loops** use names like *z*, *zeta* or *t* for the loop-variable, only if the loop variable contains the actual domain-value, for instance:
<pre><code>for z = linspace(0, 1, 11)
a = a + foo(z);
end</code></pre>
But name the loop variable *zIdx*, *zetaIdx*, *tIdx* if it is an integer index-variable. For example:
<pre><code>z = linspace(0, 1, 11);
for zIdx = 1 : numel(z)
b(zIdx) = foo(z(zIdx));
end</code></pre>
- Use the same name for formula symbols as in the literature.
- **Formula symbols** that are named in literature in capitals like the dynamics matrix *A* should use capitals in beginning.
- **Indices** of variables should be separated with an underscore `A_ij = A(it, jt)`.
- **Derivatives** should be indicated by `_dz` or similar, example `[A_dzeta, A_dz] = gradient(A, spacing)`. Consider using structs `[A.dzeta, A.dz] = gradient(A.value, spacing)` if there are no performance issues.
- If you call a function or method without using input arguments, always write `()` to distinguish properties from methods.
# Performance
- `numeric.interpolant()` and `griddedInterpolant()` are faster than `interp*()` if interpolation is performed repeatedly.
- `reshape()` is much faster than `squeeze()`, for example:
<pre><code>A = rand(10, 1, 2);
B = squeeze(A); % slow
C = reshape(A, [10, 2]); % fast</code></pre>
- `reshape()` is faster than `permute()`.
- `permute()` is the better than `.'`-transposing.
- Use *Run and Time* in the *Editor* menu from time to time to see where you can improve computation speed.
- Try to use parallel programming with `parfor`, but only if there is an significant benefit.
- Use `sum(abs(myMatrix(:)))` instead of `sum(sum(sum(abs(myMatrix(:,:,:)))))`.
- Avoid loops, see Matlab documentation [Vectorization](https://ch.mathworks.com/help/matlab/matlab_prog/vectorization.html).
# Classes
- Use explicit [definition of property type](https://ch.mathworks.com/help/matlab/matlab_oop/property-size-and-class-validation.html).
- Use [Property Validation Functions](https://ch.mathworks.com/help/matlab/matlab_oop/property-validator-functions.html) to shorten lengthy input check routines.
# Quality Assurance and Documentation
- Write meaningfull commit messenages. Don't put different content in one commit.
- Write unit-tests, see [Matlab - Testing](https://ch.mathworks.com/help/matlab/matlab-unit-test-framework.html)
- Talk about your code with colleagues from time to time to get feedback.
# Hints
- The default Matlab-Editor-Font (*Monospace*) is ambiguous, since the letter *l* and the number *1* look very similar. We suggest [Hack](https://github.com/source-foundry/Hack-windows-installer/releases/latest) or *DejaVu Sans Mono* instead. The font can be changed in *Home* &map; *Preferences* &map; *MATLAB* &map; *Fonts*.
- Structure your code with **`%% This is a helpful title`** sections.
- All comments, error messages, warnings, fprintf-prints in English only.
- Remove the *Tab key inserts spaces* setting in *Home &map; Preferences &map; MATLAB &map; Editor/Debugger &map; Tab*.
- Don't usue tabs in documentations. Tabs are displayed incorrectly in the documentation.
- If you use functions with a lot of input arguments, arrange your code clearly over multiple lines with tab. Use `...` notation for linebreaks. As orientation you should use the vertical line in the matlab editor.
- Use structs to structure related variables in your workspace, for instance
<pre><code>time = struct('start', 0, 'end', 7, 'stepSize', 1e-3, 'vector', 0:1e-3:7);</code></pre> or
<pre><code>option = struct('save', false, 'plot', true', 'simulate', true);</code></pre>
- Use `inputParser()` if you want to allow optional inputs. Hint, `misc.defaultParser()` does the same as `inputParser()` but with better default settings.
- Organize your programs in package-folders to avoid ridiculously long file names or file name conflicts. See documentation [Packages Create Namespaces](https://ch.mathworks.com/help/matlab/matlab_oop/scoping-classes-with-packages.html).
- Write a comment after `end` commands, that indicates to which starting command the end is belonging.
This is important for loops that reach over multiple lines, especially more than one screen's size.
e.g.
<pre><code>for zIdx = 1:nDisc
[long code]
end % for zIdx = 1:nDisc</code></pre>
- Use uniform colormaps for surfaces. [Viridis](https://de.mathworks.com/matlabcentral/fileexchange/51986-perceptually-uniform-colormaps) is nice, you can find it in the *infinitefirebutterfly/external/DrosteEffect* folder. Add `set(0, 'DefaultFigureColormap', viridis);` to your startup file.
- Since many journals are still black-and-white, consider using colors with different brightness.
- You can create shortcuts (`Alt` + `Number`) for your frequently used Matlab scripts and functions, see [Matlab documentation on favorite commands.](https://de.mathworks.com/help/matlab/matlab_env/create-matlab-favorites-to-rerun-commands.html)
# Known Matlab Issues
- `zeros(2) + [1; 1]` yields no error, but silently gives the same result as `ones(2)`.
- Be carefull with double comparison: `0.6 == 0.4 + 0.2` will result `false`.
\ No newline at end of file