a lot of tiny changes and fixes

This commit is contained in:
Jan Grewe 2018-10-18 13:41:16 +02:00
parent 8ebf497880
commit c2dfa9ab47
4 changed files with 114 additions and 106 deletions

View File

@ -419,14 +419,14 @@ output format (box\,\ref{graphicsformatbox}).
\end{tabular} \end{tabular}
\end{minipage} \end{minipage}
It is often meaningful to store of data plots generated by \matlab{} It is advisable to store of data plots generated by \matlab{}
using a vector graphics format. When in doubt they can usually be using a vector graphics format. In doubt they can usually be
easily converted to a bitmap format. The way from a bitmap to a easily converted to a bitmap format. The way from a bitmap to a
vector graphic is not possible without a loss in quality. Storing a vector graphic is not possible without a loss in quality. Storing a
plot that contains a very large set of graphical elements (e.g.\,a plot that contains very large sets of graphical elements (e.g.\,a
raster-plot showing thousands of action potentials) may, on the raster-plot showing thousands of action potentials) may, on the
other hand, lead to very large files that can be hard to other hand, lead to very large files that can be hard to
handle. Saving such a plot using a bitmap format may be more handle. Saving such plots using a bitmap format may be more
efficient. efficient.
\end{ibox} \end{ibox}
@ -584,24 +584,24 @@ its properties. See the \matlab{} help for more information.
\begin{figure}[ht] \begin{figure}[ht]
\includegraphics[width=0.9\linewidth]{errorbars} \includegraphics[width=0.9\linewidth]{errorbars}
\titlecaption{Adding error bars to a line plot}{\textbf{A} \titlecaption{Indicating the estimation error in plots.}{\textbf{A}
symmetrical error around the mean (e.g.\ using the standard symmetrical error around the mean (e.g.\ using the standard
deviation). \textbf{B} Errorbars of an asymmetrical distribution deviation). \textbf{B} Errorbars of an asymmetrical distribution
of the data (note: the average value is now the median and the of the data (note: the average value is now the median and the
errors are the lower and upper quartiles). \textbf{C} A shaded errors are the lower and upper quartiles). \textbf{C} A shaded
area is used to illustrate the spread of the data. See area is used to illustrate the spread of the data. See
listing\,\ref{errorbarlisting}}\label{errorbarplot} listing\,\ref{errorbarlisting} for A and C and listing\,\ref{errorbarlisting2} }\label{errorbarplot}
\end{figure} \end{figure}
\lstinputlisting[caption={Illustrating estimation errors. Script that \lstinputlisting[caption={Illustrating estimation errors using error bars. Script that
creates \figref{errorbarplot}.}, creates \figref{errorbarplot}. A, B},
label=errorbarlisting, firstline=13, lastline=29, label=errorbarlisting, firstline=13, lastline=29,
basicstyle=\ttfamily\scriptsize]{errorbarplot.m} basicstyle=\ttfamily\scriptsize]{errorbarplot.m}
\subsubsection{Fill} \subsubsection{Fill}
For a few years now it has become fancy to illustrate the error not For a few years now it has become fancy to illustrate the error not
using errorbars but by drawing a shaded area around the mean. Beside using errorbars but by drawing a shaded area around the mean. Beside
their fancyness there is also a real argument in favor of using error the fancyness there is also a real argument in favor of using error
areas instead of errorbars: In case you have a lot of data points with areas instead of errorbars: In case you have a lot of data points with
respective errorbars such that they would merge in the figure it is respective errorbars such that they would merge in the figure it is
cleaner and probably easier to read and handle if one uses an error cleaner and probably easier to read and handle if one uses an error
@ -613,8 +613,8 @@ with the vertex points of the polygon. For each x-value we now have
two y-values (average minus error and average plus error). Further, we two y-values (average minus error and average plus error). Further, we
want the vertices to be connected in a defined order. One can achieve want the vertices to be connected in a defined order. One can achieve
this by going back and forth on the x-axis; we append a reversed this by going back and forth on the x-axis; we append a reversed
version of the x-values to the original x-values using the \code{cat} version of the x-values to the original x-values using \code{cat} and
and inversion is done using the \code{fliplr} command (line 3 in \code{fliplr} for concatenation and inversion, respectively (line 3 in
listing \ref{errorbarlisting2}; Depending on the layout of your data listing \ref{errorbarlisting2}; Depending on the layout of your data
you may need concatenate along a different dimension of the data and you may need concatenate along a different dimension of the data and
use \code{flipud} instead). The y-coordinates of the polygon vertices use \code{flipud} instead). The y-coordinates of the polygon vertices
@ -625,27 +625,26 @@ property defines the transparency (or rather the opaqueness) of the
area. The provided alpha value is a number between 0 and 1 with zero area. The provided alpha value is a number between 0 and 1 with zero
leading to invisibility and a value of one to complete leading to invisibility and a value of one to complete
opaqueness. Finally, we use the normal plot command to draw a line opaqueness. Finally, we use the normal plot command to draw a line
connecting the average values. connecting the average values (line 12).
\lstinputlisting[caption={Illustrating estimation errors. Script that \lstinputlisting[caption={Illustrating estimation errors using a shaded area. Script that
creates \figref{errorbarplot}.}, label=errorbarlisting2, creates \figref{errorbarplot} C.}, label=errorbarlisting2,
firstline=30, firstline=30,
basicstyle=\ttfamily\scriptsize]{errorbarplot.m} basicstyle=\ttfamily\scriptsize]{errorbarplot.m}
\subsection{Annotations, text} \subsection{Annotations, text}
Sometimes want to highlight certain parts of a plot or simply add an The \code[text()]{text()} or \code[annotation()]{annotation()} are
annotation that does not fit or belong to the legend. In these cases used for highlighting certain parts of a plot or simply adding an
we can use the \code[text()]{text()} or annotation that does not fit or does not belong into the legend.
\code[annotation()]{annotation()} function to add this information to While \varcode{text} simply prints out the given text string at the
the plot. While \varcode{text} simply prints out the given text string defined position (for example line in
at the defined position (for example line in
listing\,\ref{regularsubplotlisting}) the \varcode{annotation} listing\,\ref{regularsubplotlisting}) the \varcode{annotation}
function allows to add some more advanced highlights like arrows, function allows to add some more advanced highlights like arrows,
lines, ellipses, or rectangles. Figure\,\ref{annotationsplot} shows lines, ellipses, or rectangles. Figure\,\ref{annotationsplot} shows
some examples, the respective code can be found in some examples, the respective code can be found in
listing\,\ref{annotationsplotlisting}. For more options consult the listing\,\ref{annotationsplotlisting}. For more options consult the
documentation. \matlab{} help.
\begin{figure}[ht] \begin{figure}[ht]
\includegraphics[width=0.5\linewidth]{annotations} \includegraphics[width=0.5\linewidth]{annotations}
@ -716,18 +715,16 @@ Lissajous figure. The basic steps are:
\section{Summary} \section{Summary}
A good plot of scientific data displays the data completely and A good plot of scientific data displays the data completely and
seriously without too many distractions. Misleading or suggestive seriously without too many distractions. Misleading or suggestive
plots as may result from perspective presentations, inappropriate plots as may result from perspective presentations, inappropriate
scaling of axes of symbols should be avoided. scaling of axes and symbols should be avoided.
\noindent When combining several line plots within the same figure one should \noindent When combining several line plots within the same figure one should
consider adapting color \textbf{and} line style (solid, dashed, consider adapting color \textbf{and} line style (solid, dashed,
dotted. etc.) to make the distinguishable even in black-and-white dotted. etc.) to make the distinguishable even in black-and-white
prints. Combinations of red and green are no good choice since they prints. Combinations of red and green are not a good choice since they
cannot be distinguished by people with red-green blindness. cannot be distinguished by people with red-green blindness.
\vspace{2ex} \vspace{2ex}
@ -737,6 +734,8 @@ Key ingredients for a good data plot:
\item Complete labeling. \item Complete labeling.
\item Plotted lines and curves must be distinguishable. \item Plotted lines and curves must be distinguishable.
\item No suggestive or misleading presentation. \item No suggestive or misleading presentation.
\item The right balance of line width, font size and size of the figure. \item The right balance of line width, font size and size of the
figure, this may depend on the purpose, for presentations slightly
thicker lines help.
\item Error bars wherever they are appropriate. \item Error bars wherever they are appropriate.
\end{itemize} \end{itemize}

View File

@ -1,5 +1,7 @@
function sines = calculateSines(x, amplitudes, frequencies) function sines = calculateSines(x, amplitudes, frequencies)
% Function calculates sinewaves with all combinations of % sines = calculateSines(x, amplitudes, frequencies)
%
% Function calculates sinewaves with all combinations of
% given amplitudes and frequencies. % given amplitudes and frequencies.
% Arguments: x, a vector of radiants for which the sine should be % Arguments: x, a vector of radiants for which the sine should be
% computed. % computed.
@ -8,11 +10,11 @@ function sines = calculateSines(x, amplitudes, frequencies)
% %
% Returns: a 3-D Matrix of sinewaves, 2nd dimension represents % Returns: a 3-D Matrix of sinewaves, 2nd dimension represents
% the amplitudes, 3rd the frequencies. % the amplitudes, 3rd the frequencies.
sines = zeros(length(x), length(amplitudes), length(frequencies)); sines = zeros(length(x), length(amplitudes), length(frequencies));
for i = 1:length(amplitudes) for i = 1:length(amplitudes)
sines(:,i,:) = sinesWithFrequencies(x, amplitudes(i), frequencies); sines(:,i,:) = sinesWithFrequencies(x, amplitudes(i), frequencies);
end end
end end

View File

@ -6,20 +6,19 @@
%\selectlanguage{ngerman} %\selectlanguage{ngerman}
Cultivating a good code style not a matter of good taste but is Cultivating a good code style not a matter of good taste but is
a key ingredient for understandability, maintainability and in the end a key ingredient for understandability, maintainability and, in the end,
facilitates reproducibility of scientific results. Programs should be facilitates reproducibility of scientific results. Programs should be
written and structured in a way that supports outsiders as well the written and structured in a way that supports outsiders as well the
author himself --- a few weeks or months after it was written --- to author himself --- a few weeks or months after it was written --- to
understand the programs' rationale. Clean code pays off for the understand the programs' rationale. Clean code pays off for the
original author as well as others that are supposed to use the code. original author as well as others that are supposed to use the code.
Clean code addresses several issues: Clean code addresses several issues:
\begin{enumerate} \begin{enumerate}
\item The programs' structure. \item The programs' structure.
\item Naming of scripts and functions. \item Naming of scripts and functions.
\item Naming of variables and constants. \item Naming of variables and constants.
\item Application of indentation empty lines to define blocks. \item Application of indentation and empty lines to define blocks.
\item Use of comments and inline documentation. \item Use of comments and inline documentation.
\item Delegation of repeated code to functions and dedicated \item Delegation of repeated code to functions and dedicated
subroutines. subroutines.
@ -29,13 +28,12 @@ Clean code addresses several issues:
While introducing scripts and functions we suggested a typical program While introducing scripts and functions we suggested a typical program
layout (box\,\ref{whenscriptsbox}). The idea is to create a single layout (box\,\ref{whenscriptsbox}). The idea is to create a single
entry point by having one script that controls the rest of program by entry point by having one script that controls the rest of the program
managing data and results and calling functions that work on the data by calling functions that work on the data and managing the
and produce the results. Applying this structure makes it easy to results. Applying this structure makes it easy to understand the flow
understand the flow of the program but two questions remain: (i) How of the program but two questions remain: (i) How to organize the files
to organize the files on the file system and (ii) how to name them on the file system and (ii) how to name them that the controlling
that the controlling script is easily identified among the other script is easily identified among the other \codeterm{m-files}.
\codeterm{m-files}.
Upon installation ``MATLAB'' creates a folder called \emph{MATLAB} in Upon installation ``MATLAB'' creates a folder called \emph{MATLAB} in
the user space (Windows: My files, Linux: Documents, MacOS: the user space (Windows: My files, Linux: Documents, MacOS:
@ -110,24 +108,11 @@ Box~\ref{matlabpathbox}).
\end{lstlisting} \end{lstlisting}
\end{ibox} \end{ibox}
\section{Naming scripts and functions} \section{Naming things}
\matlab{} will search the search path (Box \ref{matlabpathbox}) The dictum of good code style is: ``Program code must be readable.''
exclusively by name. It is case-sensitive this implies that the files Expressive names are extraordinarily important in this respect. Even
\file{test\_function.m} and \file{Test\_function.m} are two different if it is tricky to find expressive names that are not overly long,
things. It is self-evident that choosing such names is nonsensical naming should be taken seriously.
because the name contains no cue about the difference between the two
and it further tells close to nothing about the purpose. Finding good
names is not trivial sometimes it is harder than the programming
itself. Expressive names, however, pay off! Expressive means that the
name provides information about the purpose.
\begin{important}[Naming scripts and functions]
Function and script names should be expressive in the sense that the
name provides information about the function's purpose
(\file{estimate\_firingrate.m} tells much more than
\file{exercise1.m}). Choosing a good name replaces large parts of
the documentation.
\end{important}
\matlab{} has a few rules about names: Names must not start with a \matlab{} has a few rules about names: Names must not start with a
number, they must not contain blanks or other special characters like number, they must not contain blanks or other special characters like
@ -144,26 +129,41 @@ patterns:
There are other common patterns such as the \emph{camelCase} in which There are other common patterns such as the \emph{camelCase} in which
the first character of compound words is capitalized. Other the first character of compound words is capitalized. Other
conventions use the underscore to separate the individual words conventions use the underscore to separate the individual words (
\emph{snake\_case}. A function that counts the number of action \emph{snake\_case}). A function that counts the number of action
potentials could be named \file{spikeCount.m} or potentials could be named \file{spikeCount.m} or
\file{spike\_count.m}. \file{spike\_count.m}.
The same naming rules apply for scripts and functions as well as
variables and constants.
\section{Naming variables and constants} \subsection{Naming scripts and functions}
\matlab{} will search the search path (Box \ref{matlabpathbox})
exclusively by name. This search is case-sensitive which implies that
the files \file{test\_function.m} and \file{Test\_function.m} are two
different things. It is self-evident that choosing such names is
nonsensical because the tiny difference in the name contains no cue
about the difference between the two versions and the function names
themselves tell close to nothing about the purpose. Finding good names
is not trivial. Sometimes it is harder than the programming
itself. Choosing \emph{expressive names} that provide information about a
function's purpose, however, pays off!
\begin{important}[Naming scripts and functions]
Names of functions and scripts should be expressive in the sense
that the name provides information about the function's purpose.
(\file{estimate\_firingrate.m} tells much more than
\file{exercise1.m}). Choosing a good name replaces large parts of
the documentation.
\end{important}
\matlab{} applies the same rules for naming variables and constants as \subsection{Naming variables and constants}
for the naming of scripts and functions. The dictum of good
code style is: ``Program code must be readable.'' Expressive
names are extraordinarily important in this respect. Even if it is
tricky to find expressive names that are not overly long, naming
should be taken seriously.
While the names of scripts and functions describe the purpose, names While the names of scripts and functions describe the purpose, names
of variables describe the stored content. A variable storing the of variables describe the stored content. A variable storing the
average number of actions potentials could be called average number of actions potentials could be called\\
\varcode{average\_spike\_count}. If this variable is meant to store \varcode{average\_spike\_count}. If this variable is meant to store
multiple spike counts the plural form would be appropriate multiple spike counts the plural form would be appropriate\\
(\varcode{average\_spike\_counts}). (\varcode{average\_spike\_counts}).
The control variables used in the head of a \code{for} loop are often The control variables used in the head of a \code{for} loop are often
@ -190,7 +190,7 @@ to comprehend. Even though the \matlab{} language (as many others)
does not enforce indentation, indentation is very powerful for does not enforce indentation, indentation is very powerful for
defining coherent blocks. The \matlab{} editor supports this by an defining coherent blocks. The \matlab{} editor supports this by an
auto-indentation mechanism. A selected section of the code and be auto-indentation mechanism. A selected section of the code and be
automatically indented by pressing the \keycode{Ctrl-I} combination. automatically indented by pressing \keycode{Ctrl-I}.
Interspersing empty lines is very helpful to separate regions in the Interspersing empty lines is very helpful to separate regions in the
code that belong together. Too many empty lines, however lead to code that belong together. Too many empty lines, however lead to
@ -198,8 +198,11 @@ hard-to-read code because it might require more space than a granted
by the screen and thus takes overview. by the screen and thus takes overview.
The following two listings show basically the same implementation of a The following two listings show basically the same implementation of a
random walk once in a rather chaotic version (listing random walk\footnote{A random walk is a simple simulation of Brownian
\ref{chaoticcode}) then in cleaner way (listing \ref{cleancode}) motion. In each simulation step an agent takes a step into a
randomly chosen direction.} once in a rather chaotic version
(listing \ref{chaoticcode}) then in cleaner way (listing
\ref{cleancode})
\begin{lstlisting}[label=chaoticcode, caption={Chaotic implementation of the random-walk.}] \begin{lstlisting}[label=chaoticcode, caption={Chaotic implementation of the random-walk.}]
num_runs = 10; max_steps = 1000; num_runs = 10; max_steps = 1000;
@ -245,25 +248,24 @@ end
\section{Using comments} \section{Using comments}
It is common to provide extra information about the meaning of program It is common to provide extra information about the meaning of program
code by adding comments to it. In \matlab{} comments are indicated by code by adding comments. In \matlab{} comments are indicated by the
the percent character \code{\%}. Anything that is written in the percent character \code{\%}. Anything that follows the percent
respective line following the percent is ignored and considered a character in a line is ignored and considered a comment. When used
comment. When used sparsely comments can immensely important for sparsely comments can be immensely helpful. Comments
understanding. Comments are short sentences that describe the meaning are short sentences that describe the meaning of the (following) lines
of the (following) lines in the program code. During the initial in the program code. During the initial implementation of a function
implementation of a function they can be used to guide the development they can be used to guide the development but have the tendency to
but have the tendency to blow up the code and decrease readability. By blow up the code and decrease readability. By choosing expressive
choosing expressive variable and function names, most lines should be variable and function names, most lines should be self-explanatory.
self-explanatory.
For example stating the obvious does not really help and should be
For example stating the obvious does not really help:\\ avoided:\\ \varcode{ x = x + 2; \% add two to x}\\
\varcode{ x = x + 2; \% add two to x}\\
\begin{important}[Using comments] \begin{important}[Using comments]
\begin{itemize} \begin{itemize}
\item Comments describe the rationale of the respective code block. \item Comments describe the rationale of the respective code block.
\item Comments are good and helpful --- they have to be true, however! \item Comments are good and helpful --- they must be true, however!
\item A wrong comment is worse than a non-existent comment! \item A wrong comment is worse than a non-existent one!
\item Comments must be maintained just as the code. Otherwise they \item Comments must be maintained just as the code. Otherwise they
may become wrong and worse than meaningless! may become wrong and worse than meaningless!
\end{itemize} \end{itemize}
@ -303,7 +305,7 @@ well documented function.
Comments and empty lines are used to organize code into logical blocks Comments and empty lines are used to organize code into logical blocks
and to briefly explain what they do. Whenever one feels tempted to do and to briefly explain what they do. Whenever one feels tempted to do
this, one could also consider to delegate the respective task to a this, one could also consider to delegate the respective task to a
function. In most cases this is preferable. function. In most cases this is preferable.
Not delegating the tasks leads to very long \codeterm{m-files} which Not delegating the tasks leads to very long \codeterm{m-files} which
can be confusing. Sometimes such a code is called ``spaghetti can be confusing. Sometimes such a code is called ``spaghetti
@ -325,9 +327,9 @@ Generally, functions live in their own \codeterm{m-files} that have
the same name as the function itself. Delegating tasks to functions the same name as the function itself. Delegating tasks to functions
thus leads to a large set of \codeterm{m-files} which increases thus leads to a large set of \codeterm{m-files} which increases
complexity and may lead to confusion. If the delegated functionality complexity and may lead to confusion. If the delegated functionality
is used in multiple instances, it is advisable to do so. On the other is used in multiple instances, it is still advisable to do so. On the
hand, when the delegated functionality is only used within the context other hand, when the delegated functionality is only used within the
of another function \matlab{} allows to define context of another function \matlab{} allows to define
\codeterm[function!local]{local functions} and \codeterm[function!local]{local functions} and
\codeterm[function!nested]{nested functions} within the same \codeterm[function!nested]{nested functions} within the same
file. Listing \ref{localfunctions} shows an example of a local file. Listing \ref{localfunctions} shows an example of a local
@ -336,17 +338,19 @@ function definition.
\pagebreak[3] \lstinputlisting[label=localfunctions, caption={Example \pagebreak[3] \lstinputlisting[label=localfunctions, caption={Example
for local functions.}]{calculateSines.m} for local functions.}]{calculateSines.m}
Local function live in the same \codeterm{m-file} as the main function \emph{Local function} live in the same \codeterm{m-file} as the main
and are only available in this context. Each local function has its function and are only available in this context. Each local function
own \codeterm{scope}, that is, the local function can not access (read has its own \codeterm{scope}, that is, the local function can not
or write) variables of the calling function. access (read or write) variables of the calling function. Interaction
with the local function requires to pass all required arguments and to
take care of the return values of the function.
This is different in so called \codeterm[function!nested]{nested \emp{Nested functions} are different in this respect. They are
functions}. These are defined within the body of the parent function defined within the body of the parent function (between the keywords
(between the keywords \code{function} and \code{end}) and have full \code{function} and \code{end}) and have full access to all variables
access to all variables defined in the parent function. Working (in defined in the parent function. Working (in particular changing) the
particular changing) the parent's variables is handy on the one side, parent's variables is handy on the one side, but is also risky. One
but is also risky. One should take care when defining nested functions. should take care when defining nested functions.
\section{Specifics when using scripts} \section{Specifics when using scripts}
@ -355,7 +359,7 @@ A similar problem as with nested function arises when using scripts
become available in the global \codeterm{Workspace}. There is the risk become available in the global \codeterm{Workspace}. There is the risk
of name conflicts, that is, a called sub-script redefines or uses the of name conflicts, that is, a called sub-script redefines or uses the
same variable name and may \emph{silently} change its content. The same variable name and may \emph{silently} change its content. The
user will not be notified by this change and the calling script may user will not be notified about this change and the calling script may
expect a completely different content. Bugs that are based on such expect a completely different content. Bugs that are based on such
mistakes are hard to find since the program itself looks perfectly mistakes are hard to find since the program itself looks perfectly
fine. fine.
@ -379,12 +383,15 @@ provides important information to track and fix the bug.
\item Scripts should work independently of existing variables in the \item Scripts should work independently of existing variables in the
global workspace. global workspace.
\item It is advisable to start a script with deleting variables \item Often it is advisable to start a script with deleting
(\code{clear}) from the workspace and most of the times it is also variables (\code{clear}) from the workspace and most of the times
good to close all open figures (\code{close all}). it is also good to close all open figures (\code{close all}). Be
careful if a the respective script has been called by another one.
\item Clean up the workspace at the end of a script. Delete \item Clean up the workspace at the end of a script. Delete
(\code{clear}) all variables that are no longer needed. (\code{clear}) all variables that are no longer needed.
\item Consider to write functions instead of scripts.
\end{itemize} \end{itemize}
\end{important} \end{important}

View File

@ -383,7 +383,7 @@ introduce how this can be done without using the gradient descent
Problems that involve nonlinear computations on parameters, e.g. the Problems that involve nonlinear computations on parameters, e.g. the
rate $\lambda$ in the exponential function $f(x;\lambda) = rate $\lambda$ in the exponential function $f(x;\lambda) =
\exp(\lambda x)$, do not have an analytical solution. To find minima e^{\lambda x}$, do not have an analytical solution. To find minima
in such functions numerical methods such as the gradient descent have in such functions numerical methods such as the gradient descent have
to be applied. to be applied.
@ -396,7 +396,7 @@ objective functions while more specialized functions are specifically
designed for optimizations in the least square error sense designed for optimizations in the least square error sense
\matlabfun{lsqcurvefit()}. \matlabfun{lsqcurvefit()}.
\newpage %\newpage
\begin{important}[Beware of secondary minima!] \begin{important}[Beware of secondary minima!]
Finding the absolute minimum is not always as easy as in the case of Finding the absolute minimum is not always as easy as in the case of
the linear equation. Often, the error surface has secondary or local the linear equation. Often, the error surface has secondary or local