%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Design Pattern} Beim Programmieren sind sich viel Codes in ihrer Grundstruktur sehr \"ahnlich. Viele Konstrukte kommen in den verschiedensten Kontexten immer wieder in \"ahnlicher Weise vor. In diesem Kapitel stellen wir einige dieser ``Design pattern'' zusammen. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{for Schleifen \"uber Vektoren} Grundlegend ist das Iterieren \"uber den Inhalt eines Vektors mit einer \code{for}-Schleife: \begin{lstlisting}[caption={for-Schleife mit Indexen \"uber einen Vektor}] x = [2:3:20]; % irgendein Vektor for i=1:length(x) % Mit der for-Schleife "loopen" wir ueber den Vektor i % das ist der Index, der die Elemente des Vektors indiziert. x(i) % das ist der Wert des i-ten Elements des Vektors x. a = x(i); % die Variable a bekommt den Wert des i-ten Elements des Vektors x zugewiesen. % Benutze den Wert: do_something( x(i) ); end \end{lstlisting} Wenn in der Schleife das Ergebnis in einen Vektor gespeichert werden soll, sollten wir vor der Schleife schon einen Vektor f\"ur die Ergebnisse erstellen: \begin{lstlisting}[caption={for-Schleife zum Schreiben eines Vektors}] x = [1.2 2.3 2.6 3.1]; % irgendein Vektor y = zeros(length(x),1); % Platz fuer die Ergebnisse, genauso viele wie Loops der Schleife for i=1:length(x) % Schreibe den Rueckgabewert der Funktion get_something an die i-te % Stelle von y: y(i) = get_something( x(i) ); end % jetzt koennen wir den Ergebnisvektor weiter bearbeiten: mean(y) \end{lstlisting} Die Berechnungen in der Schleife k\"onnen statt einer Zahl auch einen Vektor zur\"uckgeben. Wenn die L\"ange diese Vektors bekannt ist, dann kann vorher eine entsprechend gro{\ss}e Matrix angelegt werden: \begin{lstlisting}[caption={for-Schleife zum Schreiben von Zeilen einer Matrix}] x = [2:3:20]; % irgendein Vektor y = zeros(length(x),10); % Platz fuer die Ergebnisse for i=1:length(x) % Schreibe den Rueckgabewert der Funktion get_something - jetzt ein % Vektor mit 10 Elementen - in die i-te % Zeile von y: y(i,:) = get_something( x(i) ); end % jetzt koennen wir die Ergebnismatrix weiter bearbeiten: mean(y, 1) \end{lstlisting} Alternativ k\"onnen die in der Schleife erzeugten Vektoren zu einem einzigen, durchgehenden Vektor zusammengestellt werden: \begin{lstlisting}[caption={for-Schleife zum Aneinanderh\"angen von Vektoren}] x = [2:3:20]; % irgendein Vektor y = []; % Leerer Vektor fuer die Ergebnisse for i=1:length(x) % Die Funktion get_something gibt einen Vektor zurueck: z = get_something( x(i) ); % dessen Inhalt h\"angen wir an den Ergebnissvektor an: y = [y; z(:)]; % z(:) stellt sicher, das wir auf jeden Fall einen Spaltenvektoren aneinanderreihen. end % jetzt koennen wir dem Ergebnisvektor weiter bearbeiten: mean(y) \end{lstlisting} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Skalieren und Verschieben nicht nur von Zufallszahlen} Zufallsgeneratoren geben oft nur Zufallszahlen mit festen Mittelwerten und Standardabweichungen (auch Skalierungen) zur\"uck. Multiplikation mit einem Faktor skaliert die Standardabweichung und Addition einer Zahl verschiebt den Mittelwert. \begin{lstlisting}[caption={Skalierung von Zufallszahlen}] % 100 random numbers draw from a Gaussian distribution with mean 0 and standard deviation 1. x = randn(100, 1); % 100 random numbers drawn from a Gaussian distribution with mean 4.8 and standard deviation 2.3. mu = 4.8; sigma = 2.3; y = randn(100, 1)*sigma + mu; \end{lstlisting} Das gleiche Prinzip ist manchmal auch sinnvoll f\"ur \code{zeros()} oder \code{ones()}: \begin{lstlisting}[caption={Skalierung von zeros und ones}] x = -1:0.01:2; % Vektor mit x-Werten plot(x, exp(-x.*x)); % Plotte f\"ur die gleichen x-Werte eine Linie mit y=0.8: plot(x, zeros(size(x))+0.8); % ... Linie mit y=0.5: plot(x, ones(size(x))*0.5); \end{lstlisting} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Plotten einer mathematischen Funktion} Eine mathematische Funktion ordnet einem beliebigen $x$-Wert einen $y$-Wert zu. Um eine solche Funktion zeichnen zu k\"onnen, m\"ussen wir eine Wertetabelle aus vielen $x$-Werten und den dazugeh\"origen Funktionswerten $y=f(x)$ erstellen. Wir erstellen dazu einen Vektor mit geeigneten $x$-Werten, die von dem kleinsten bis zu dem gr\"o{\ss}ten $x$-Wert laufen, den wir plotten wollen. Die Schrittweite f\"ur die $x$-Werte w\"ahlen wir klein genug, um eine sch\"one glatte Kurve zu bekommen. F\"ur jeden Wert $x_i$ dieses Vektors berechnen wir den entsprechenden Funktionswert und erzeugen damit einen Vektor mit den $y$-Werten. Die Werte des $y$-Vektors k\"onnen dann gegen die Werte des $x$-Vektors geplottet werden. Folgende Programme berechnen und plotten die Funktion $f(x)=e^{-x^2}$: \begin{lstlisting}[caption={Plotten einer mathematischen Funktion --- sehr ausf\"uhrlich}] xmin = -1.0; xmax = 2.0; dx = 0.01; % Schrittweite x = xmin:dx:xmax; % Vektor mit x-Werten y = exp(-x.*x); % keine for Schleife! '.*' fuer elementweises multiplizieren plot(x, y); \end{lstlisting} \begin{lstlisting}[caption={Plotten einer mathematischen Funktion --- k\"urzer}] x = -1:0.01:2; % Vektor mit x-Werten y = exp(-x.*x); % keine for Schleife! '.*' fuer elementweises multiplizieren plot(x, y); \end{lstlisting} \begin{lstlisting}[caption={Plotten einer mathematischen Funktion --- sehr kompakt}] x = -1:0.01:2; % Vektor mit x-Werten plot(x, exp(-x.*x)); \end{lstlisting} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Normierung von Histogrammen} Meistens sollten Histogramme normiert werden, damit sie vergleichbar mit anderen Histogrammen oder mit theoretischen Wahrscheinlichkeitsverteilungen werden. Die \code{histogram()} Funktion macht das mit den entsprechenden Parametern automatisch: \begin{lstlisting}[caption={Probability-density-function mit der histogram-Funktion}] x = randn(100, 1); % irgendwelche reellwertige Daten histogram(x, 'Normalization', 'pdf'); \end{lstlisting} \begin{lstlisting}[caption={Probability mit der histogram-Funktion}] x = randi(6, 100, 1); % irgendwelche integer Daten histogram(x, 'Normalization', 'probability'); \end{lstlisting} So geht es aber auch: \begin{lstlisting}[caption={Probability-density-function mit der hist- und bar-Funktion}] x = randn(100, 1); % irgendwelche reellwertige Daten [h, b] = hist(x); % Histogram berechnen h = h/sum(h)/(b(2)-b(1)); % normieren zu einer Wahrscheinlichkeitsdichte bar(b, h); % und plotten. \end{lstlisting} \begin{lstlisting}[caption={Probability mit der hist- und bar-Funktion}] x = randi(6, 100, 1); % irgendwelche integer Daten [h, b] = hist(x); % Histogram berechnen h = h/sum(h); % normieren zu Wahrscheinlichkeiten bar(b, h); % und plotten. \end{lstlisting}