Kapitel 3: Funktionen
Transcrição
Kapitel 3: Funktionen
Kapitel 3 Funktionen Die Darstellung von Funktionen und Daten ist eine wichtige Anwendung von MatLab. Sie wird in diesem Kapitel einen breiten Rahmen einnehmen, da die zugehörigen Fertigkeiten auch bei der Darstellung von Messdaten, z.B. im Praktikum, hilfreich sind. Da MatLab kein algebraisches System ist, ist eine Differentiation oder Integration von Funktionen nur numerisch möglich. Die zugehörigen Verfahren werden im zweiten Teil dieses Kapitels beschrieben. Sie geben gleichzeitig eine Einführung in die Verwendung der if und do Strukturen in MatLab, wie sie in komplexen Problemen zur Steuerung benötigt werden. 3.1 Darstellung von Funktionen In diesem einführenden Teil werden wir uns auf Funktionen einer Variablen beschränken, d.h. Funktionen der Form x(t) oder y = f (x). Die Darstellung von Funktionen von zwei Variablen, f (x, y), erfolgt ähnlich; sie wird in Abschn. 3.2 genauer dargestellt. 3.1.1 Einfache Plots Die Erzeugung funktionaler Zusammenhänge und eine sehr einfache Form der Darstellung haben wir bereits im Zusammenhang mit Abb. 1.2 abgesprochen. Wir können daher kommentarlos mit der Sequenz >> x=[0:0.01:5]; ←Testbild 1 1 1 berechnete Werte, VORLÄUFIG! 0.8 0.8 0.6 y=exp(x)*sin(10*x) 0.6 0.4 0.2 0 −0.2 0.4 0.2 0 −0.2 −0.4 −0.4 −0.6 −0.6 −0.8 −0.8 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 0 0.5 1 1.5 2 2.5 3 3.5 4 x−Achse 5 Abbildung 3.1: Einfacher (links) und beschrifteter (rechts) Funktionsplot 22 4.5 5 3.1. DARSTELLUNG VON FUNKTIONEN 23 Abbildung 3.2: Links: Axes-Property Editor zur interaktiven Erstellung einer Bildbeschriftung; Rechts: einfaches Pull-Down Menü zur Veränderung der Abbildung >> y=exp(-x).*cos(10.*x); ←>> plot(x,y) ←den im linken Teil von Abb. 3.1 gezeigten Plot der Funktion y = e−x cos(10x) erzeugen. Dieser Abbildung fehlt allerdings ein wichtiger Bestandteil: die Achsenbeschriftung. Diese kann interaktiv ergänzt werden, auch können Beschriftungsgrößen, Abstände der Ticks usw. verändert werden. Dazu kann im Menü des Figure-Fensters unter Edit → Axes Properties ein Menü geöffnet werden, entsprechend dem im linken Teil von Abb. 3.2 gezeigten. In diesem Menü lassen sich die Achsenbeschriftungen für alle Achsen sowie die Eigenschaften der Achsen, inklusive des dargestellten Wertebereichs, recht komfortabel einstellen. Eine noch einfachere Alternative ist im rechten Teil von Abb. 3.2 angedeutet: unter dem Menüpunkt insert erscheint eine Auswahl von einzufügenden Objekten. Wählt man X Label aus, so erscheint unterhalb der x-Achse ein kleines weißes Kästchen, in das der Text eingetragen werden kann. Klickt man dieses Kästchen später mit der linken Maustaste an, so erscheint ein weiteres Menü, mit dessen Hilfe die Eigenschaften der Achsenbeschriftung verändert werden können. Über die entsprechenden Punkte in diesen Menüs lassen sich auch weitere Eigenschaften der Abbildung verändern, wie z.B. Farben der Kurven, Symbole, Strichstärke usw. Das Speichern der Abbildung (inklusive der daran vor genommenen Manipulationen) erfolgt über den Unterpunkte Export im File-Menü. Dort kann auch das Datenformat auswählt werden, in das die Abbildung exportiert werden soll, z.B. pdf, jpeg, eps oder bmp. 3.1.2 Fine-Tuning Das interaktive Schönen der Abbildungen erscheint anfangs zwar angenehm, da die einzelnen Schritte leicht zu kontrollieren sind, erfordert aber umgekehrt viele Einzelschritte und wird daher leicht unübersichtlich und fehleranfällig, insbesondere, wenn wir für ein Protokoll oder eine Arbeit viele Abbildungen in einheitlichem Stil erzeugen wollen. Für eine einfache Beschriftung können wir die folgende Befehlssequenz in ein MatLabSkript einbauen >> x=[0:0.01:5]; ←c M.-B. Kallenrode 12. Januar 2005 24 KAPITEL 3. FUNKTIONEN -: -. none durchgezogene Linie (default) gestrichelte Linie gepunktete Linie strichpunktierte Linie keine Linie, nur die Marker an den Punkten Tabelle 3.1: LineStyles beim Plotten in MatLab >> >> >> >> >> >> ←>> plot beschrift y=exp(-x).*cos(10.*x); ←testbild = plot(x,y,’k’); ←xlabel(’x-Achse’,’Fontsize’,16); ←ylabel(’y=exp(x)*sin(10*x)’,’Fontsize’,16); ←title(’Testbild 1’,’Fontsize’,20); ←text(0.5,0.92,’berechnete Werte, VORLÄUFIG!’,’Color’,’red’,’FontWeight’,’bold’,’Fontsize’,14); saveas(testbild,’Testbild1.pdf’) ←- und erhalten als Ergebnis den Plot im rechten Teil von Abb. 3.1. Dieses Beispiel findet sich im m-File plot beschrift. Kurvenparameter: Farben und Symbole plot Die ersten beiden Zeilen des obigen MatLab-Fragments sind bekannt, die dritte Zeile enthält den normalen Plotbefehl, zusätzlich wird zwischen den Hochkommata ein k als Parameter übergeben. Dieser Parameter weist MatLab an, die Kurve nicht in blau sondern in schwarz zu plotten. Beim Aufruf von plot können verschiedene Parameter übergeben werden, die die Darstellung der Kurve spezifizieren. Dazu gehören auch Strichstärke und Linienart. Der allgemeine Aufruf von plot beinhaltet daher auch die Größe PropertyName, die zusammen mit einem sie spezifizierenden Wert angegeben werden muss: plot(...,’PropertyName’,PropertyValue,...) Die wichtigsten Eigenschaften sind: • LineWidth wird als Skalar übergeben, der die Linienstärke in pt angibt; Standardeinstellung ist 0.5pt. LineStyle • LineStyle spezifiziert die Art der Linie, als Eingabe werden die in Tabelle 3.1 gegebenen Zeichen, jeweils in Hochkommata eingeschlossen, akzeptiert: • zur Markierung der einzelnen Datenpunkte in einem Plot können Marker verwendet werden. Diese Marker können einfach mit der weiter unten gegebene Kurzform Linespec Linespec definiert werden, die in einem String die drei Parameter Linientyp, Marker und Farbe übergibt. Bei der Markierung kann über den PropertyName MarkerSize die Größe des MarkerSize Markers eingestellt werden. Wie bei der Linienweite wird sie in Punkten pt angegeben, die Voreinstellung entspricht einer Größe von 6 pt. Außerdem können die Marker farbig MarkerEdgeColor dargestellt werden, wobei über den PropertyName MarkerEdgeColor die Farbe für die Umrandung des Markers gewählt werden kann, über den PropertyName MarkerFaceColor die MarkerFaceColor Farbe innerhalb des Markers. Für die Marker sind verschiedene Symbole vereinbart, die jeweils durch ein einzelnes Zeichen spezifiziert werden. Die Symbole für die Marker können über den Shortcut Linespec Linespec übergeben werden, die Abkürzungen sind in Tabelle 3.2 zusammen gefasst. • Farben werden über ihre Darstellung im RGB-Code gewählt oder über die Abkürzungen in der untersten Zeile von Tabelle 3.3. LineWidth Eine verküzte Form gibt nicht PropertyName und den dazugehörigen Wert an sondern enthält alle Zusatzinformationen in einer Zeichenkette: >> plot(x,y,’-.or’) ←12. Januar 2005 c M.-B. Kallenrode 3.1. DARSTELLUNG VON FUNKTIONEN + o * . x s d ∧ v > < p h 25 Plus-Zeichen Kreis Sternchen (Asterisk) Punkte Kreuzchen Quadrate (square) Rhomben (diamond) aufwärts gerichtetes Dreieck abwärts gerichtetes Dreieck nach rechts gerichtetes Dreieck nach links gerichtetes Dreieck Pentagram (5zackiger Stern) Hexagram (6zackiger Stern) Tabelle 3.2: Marker und die zu ihrer Eingabe verwendeten Abkürzungen FontAngle FontName Fontsize FontWeight Color z.B. kursiv Schrifttype Größe Schriftsatz in Punkten z.B. Fettdruck Textfarbe normal, italic, oblique Helvetica 14, 16, ... light, normal, demi, bold y, m, c, r, g, b, w, k Tabelle 3.3: Parameter zur Definition der Achsenbeschriftung und zulässige Werte. Bei der Farbe können statt der Abkürzungen auch die langen Farbnamen verwendet werden: yellow, magenta, cyan, red, green, blue, white, black plottet die y-Werte gegen die x-Werte, wobei die einzelnen Werte mit einer strichpunktierten Linie (-.) verbunden sind, durch einen Kreis (o) markiert sind und wobei Linie und Marker in rot (r) dargestellt werden. Anschließend können weitere Spezifikationen (z.B. Markergröße) über einen PropertyName mit seinem Wert angegeben werden. Auf diese Weise kann auch die Farbe der Marker gesetzt werden – dann haben Linie und Marker gegebenenfalls unterschiedliche Farben. Im Beispiel wurde der Befehl plot(x,y) nicht einfach aufgerufen sondern es wurde ihm durch phandle = plot(x,y) ein Handle zugewiesen, mit dem die Abbildung eindeutig identifiziert werden kann. Dieser Handle ist z.B. notwendig beim Speichern der Abbildung (letzte Zeile im Beispiel). Er kann auch verwendet werden, um Eigenschaften der Abbildung wie Kurven- oder Achsenparameter nachträglich zu verändern. Achsenparameter: Griechisch-römischer Freistil Die folgenden drei Zeilen im zum rechten Teil von Abb. 3.1 gehörigen Fragment legen die Achsen- und Bildbeschriftung fest. Die allgemeine Syntax für den Befehl xlabel ist xlabel(...,’Textstring’,’PropertName’,PropertyValue,...) wobei Textstring den in Hochkomma gesetzten Text der Achsenbeschriftung enthält und PropertyName den Namen für eine bestimmte Eigenschaft der Achsenbeschriftung, im Beispiel für die Schriftgröße. MatLab akzeptiert für die Eigenschaften u.a. die in Tabelle 3.3 gegebenen PropertyNames und PropertyValues, weitere Details können in der Hilfe unter Text ←- Property List gefunden werden. Die einfachste Variante von xlabel enthält nur den in Hochkommata gesetzten Text der Achsenbeschriftung: xlabel(’x-Achse’). Die Achsenbeschrftung erfolgt in schwarz mit einer Schriftgröße von 10 pt. Bei der Darstellung physikalischer Größen benötigen wir häufig Sonderzeichen, z.B. π, griechische Buchstaben, Verknüpfungen wie ± oder Vergleichsoperationen wie ≤. Diese stellt c M.-B. Kallenrode 12. Januar 2005 xlabel 26 KAPITEL 3. FUNKTIONEN \alpha \beta \gamma \delta \epsilon \zeta \eta \theta \vartheta \iota \kappa \lambda \mu \nu \xi \pi \rho \sigma \varsigma \tau \equiv \Im \otimes \cap \supset \int \rfloor \lfloor \perp \wedge \rceil \vee \langle α β γ δ ζ η θ ϑ ι κ λ µ ν ξ π ρ σ ς τ ≡ = ⊗ ∩ ⊃ R c b ⊥ ∧ e ∨ h \upsilon \phi \chi \psi \omega \Gamma \Delta \Theta \Lambda \Xi \Pi \Sigma \Upsilon \Phi \Psi \Omega \ forall \exists \ni \cong \approx \Re \oplus \cup \subseteq \in \lceil \cdot \neg \times \surd \varpi \rangle υ φ χ ψ ω Γ ∆ Θ Λ Ξ Π Σ Υ Φ Ψ Ω ∀ ∃ 3 ∼ = ≈ < ⊕ ∪ ⊆ ∈ d · ¬ × √ $ i \sim \leq \infty \clubsuit \diamondsuit \heartsuit \spadesuit \leftrightarrow \leftarrow \uparrow \rightarrow \downarrow \circ \pm \geq \propto \partial \bullet \div \neq \aleph \wp \oslash \supseteq \subset \o \nabla \ldots \prime \O \mid \copyright ∼ ≤ ∞ ♣ ♦ ♥ ♠ ↔ ← ↑ → ↓ ◦ ± ≥ ∝ ∂ • ÷ 6 = ℵ ℘ ⊇ ⊂ ø ∇ ... 0 Ø | c Tabelle 3.4: Eingabe von Sonderzeichen bei der Beschriftung von Abbildungen MATLAB in der gleichen Form dar, wie sie bei der Eingabe in LATEX verwendet werden. Die Symbole sind in Tabelle 3.4 zusammen gefasst. Text innerhalb der Abbildung text Auch innerhalb einer Abbildung kann mit Hilfe der Funktion text Text angegeben werden, z.B. um Kurven zu beschriften oder besondere Punkte zu markieren. Der Befehl dazu lautet text(x,y,’String’,’PropertyName’,PropertyValue,...) saveas Die Parameter x und y geben die Koordinaten der linken unteren Ecke der Textbox an, der String ’String’ enthält den Text und über PropertyName kann dessen Darstellung verändert werden. Die vorletzte Zeile des Beispiels enthält diesen Befehl und erzeugt damit die warnende Beschriftung innerhalb der Abbildung. Diese Zeile liefert gleichzeitig auch ein Beispiel für die Anwendung der in Tabelle 3.3 vorgestellten Eigenschaften. In der letzten Zeile des Beispiels dient der Befehl saveas der Speicherung der Abbildung in einer Datei: der erste Parameter in der Klammer ist der Handle des Bildes, d.h. dient der Identifikation der zu speichernden Abbildung, der zweite Parameter übergibt als String 12. Januar 2005 c M.-B. Kallenrode 3.1. DARSTELLUNG VON FUNKTIONEN 27 Winkelfunktionen ↓ cos(x) 1 0.8 0.6 y−Achse) 0.4 0.2 ← sin(x) 0 −0.2 −0.4 −0.6 −0.8 −1 −6 −4 −2 0 2 4 6 x−Achse Abbildung 3.3: Zwei Kurven in einer Abbildung, erzeugt mit dem Skript winkelfunktionen den Namen der Datei, in der die Abbildung gespeichert werden soll.1 Die Dateiendung gibt gleichzeitig das Format, in dem die Abbildung gespeichert wird, in diesem Fall pdf. 3.1.3 Linear oder Logarithmisch? Erstrecken sich die Funktionswerte über mehrere Größenordnungen, so ist es sinnvoller, sie logarithmisch darzustellen. Die MatLab-Funktion plot stellt beide Achsen linear dar, allerdings kann mit Hilfe der Menüs nachträglich interaktiv eine Änderung auf logarithmische Darstellung vorgenommen werden, z.B. durch Verwendung des Pop-Up Menüs unten im Axes-Property Editor (vgl. linkes Teilbild in Abb. 3.1). Eleganter ist natürlich die direkte Wahl einer logarithmischen Darstellung. Dazu wird der Befehl plot durch semilog ersetzt und wir erhalten eine halblogarithmische Darstellung mit linearer x und logarithmischer y-Achse. Mit dem Befehl loglog statt plot lässt sich eine Abbildung erzeugen, in der beide Achsen logarithmisch skaliert sind (doppeltlogarithmischee Darstellung). Die Syntax beider Befehle entspricht der von plot. 3.1.4 semilog loglog Mehrere Kurven in ein Bild Die Darstellung mehrerer Kurven erfordert die mehrfache Verwendung des Befehls plot. Da dieser jedoch jedes mal das Fenster erst löscht und dann den Plot neu erstellt, lassen sich auf diese Weise nicht mehrere Kurven in einer Abbildung darstellen. Abhilfe schafft der Befehl hold: mit hold on hält MatLab die vorherige Abbildung fest. Jeder folgende Aufruf von plot zeichnet die Abbildung in den gleichen Rahmen. Auf diese Weise lassen sich mehrere Funktionen in einer Abbildung darstellen. Am Ende sollte allerdings auch ein hold off gegeben werden, da MatLab sonst auch alle weiteren folgenden Abbildungen in diese zeichnen würde. Abbildung 3.3 zeigt ein Beispiel für eine Abbildung mit zwei Kurven, erzeugt mit dem Skript winkelfunktionen: clear x=[-2*pi:0.01:2*pi]; y1=cos(x);y2=sin(x); 1 Die Umkehrung, das Einlesen einer Abbildung aus einer Datei, erfolgt mit dem Befehl imread. Das Einlesen von Bildern in MatLab eher für fortgeschrittene Bildbearbeitung von Interesse als für unsere mathematischen Anwendungen, daher wird im Rahmen des Skripts nicht weiter darauf eingegangen. Alle näheren Informationen finden Sie in der MatLab-Hilfe. c M.-B. Kallenrode 12. Januar 2005 hold on hold off winkelfunktionen 28 KAPITEL 3. FUNKTIONEN 20 8 0 6 −20 4 −40 2 −60 0 −10 −8 −6 −4 −2 0 2 4 6 8 y2=−x2*x2+9 y1=x1*x1/10 Plot zweier Funktion in einen Graphen 10 −80 10 x−Achse Abbildung 3.4: Abbildung mit zwei y-Achsen, erzeugt mit dem MatLab-Skript plot 2yachs phandle = plot(x,y1,’-k’); hold on; plot(x,y2,’-.k’); axis([-2*pi 2*pi -1.2 1.2]); xlabel(’x-Achse’,’Fontsize’,16); ylabel(’y-Achse)’,’Fontsize’,16); title(’Winkelfunktionen’,’Fontsize’,20); text(0-0.1,cos(0)+0.04,’\downarrow cos(x)’); text(0,sin(0),’\leftarrow sin(x)’); saveas(phandle,’winkelfunktionen.pdf’); hold off axis Neu in diesem MatLab-Fragment sind die bereits besprochenen Befehle hold on und hold off in den Zeilen 5 und 14, die Verwendung von Funktionen zur Bestimmung der Orte des Textes in den Zeilen 11 und 12 sowie der Befehl axis, der eine Veränderung der Achsen erlaubt – in diesem Fall eine Festlegung des dargestellten Bereichs in der Form axis([xmin xmax ymin ymax]). 3.1.5 plot 2yachs Plots mit zwei y-Achsen Stellt man zwei Funktionen in einer Abbildung dar, so haben nicht zwingend beide die gleiche y-Achse: zum einen, auf Grund unterschiedlicher Wertebereiche, zum anderen, da die Funktionen unterschiedliche Dinge darstellen, z.B. Weg und Geschwindigkeit oder Bruttosozialprodukt und Geburtenrate. Das MatLab-Skript plot 2yachs gibt ein Beispiel für die Darstellung von zwei Funktionen mit getrennten y-Achsen in einem Bild; das Ergebnis ist in Abb. 3.4 gezeigt. Ohne Kommentierung ist die wesentliche Befehlssequenz des Skriptes x=[-10:0.02:10]; x2 = [-7:0.01:9]; ←y1 = x1.*x1/10; y2 = -x2.*x2 +9; ←[ax,h1,h2] = plotyy(x1,y1,x2,y2); ←title(’Plot zweier Funktion in einen Graphen’,’Fontsize’,20); ←xlabel(’x-Achse’,’Fontsize’,16); ←set(get(ax(1),’Ylabel’),’String’,’y1=x1*x1/10’,’Fontsize’,16); ←set(get(ax(2),’Ylabel’),’String’,’y2=-x2*x2+9’,’Fontsize’,16); ←set(h1,’LineStyle’,’--’); ←12. Januar 2005 c M.-B. Kallenrode 3.1. DARSTELLUNG VON FUNKTIONEN 29 set(h2,’LineStyle’,’-.’); ←saveas(h1,’plot2yachs.pdf’) ←In der ersten Zeile wird der x-Wertebereich für die beiden Funktionen fest gelegt – trotz gemeinsamer x-Achse haben sie unterschiedliche Wertebereiche. Dies kann bei Messdaten, insbesondere Zeitreihen, häufiger vorkommen: Klimatologen vergleichen z.B. Temperaturen und den Kohlendioxid-Gehalt der Atmosphäre, wobei erstere bereits seit ca. 1870 zuverlässig und kontinuierlich gemessen werden, letztere jedoch erst seit ca. 1950. In der zweiten Zeile werden die beiden Funktionen berechnet, in der dritten geplottet, wobei der Handle etwas aufwendig ist, da nicht nur für die Abbildung sondern auch für jede der y-Achsen ein Handle übergeben werden muss, damit diese getrennt verändert werden können. Diese Änderungen erfolgen jeweils mit den set-Befehlen: der erste bestimmt die Beschriftung der ersten y-Achse, der zweite die der zweiten. Die beiden anderen set Befehle bestimmen die Darstellung der Funktionsgraphen. Weitere Informationen finden sich in der MatLab-Hilfe unter plotyy. 3.1.6 set plotty Funktionen in Parameterdarstellung Funktionen in Parameterdarstellung können in MatLab einfach dargestellt werden. Dazu wird als erstes der Wertebereich des Parameters definiert und ein Vektor mit Werten dieses Parameters erzeugt. Zu diesem Vektor werden jeweils die x- und y-Werte bestimmt und anschließend gegeneinander geplottet. Beispiel 5 Eine Archimedische Spirale entsteht, wenn sich ein Körper mit konstanter Geschwindigkeit v entlang eines Strahls nach außen bewegt und dieser Strahl gleichzeitig mit konstanter Winkelgeschwindigkeit ω um den Ursprung rotiert. Für den radialen Abstand r(t) und den Drehwinkel ϕ(t) erhalten wir r(t) = v t und archimedespolar φ(t) = ω t . Für eine graphische Darstellung können wir zwei Formen wählen, Polarkoordinaten oder kartesische Koordinaten. Für die Darstellung in Polarkoordinaten benötigen wir außer der oben gegebenen Parameterdarstellung nur den Befehl polar für die graphische Darstellung. Die zugehörige Befehlssequenz ist polar archimedeskartesisch >> v=1; ohm = 1.; t=[0:0.01:20]; ←>> r = v*t; phi = ohm*t; ←>> phandle=polar(phi,r,’k’); ←In der ersten Zeile werden die beiden Parameter v und ohm, d.h. die Geschwindigkeit v und die Winkelgeschwindigkeit ω vorgegeben. In der zweiten Zeile werden die zugehörigen Abstände und Drehwinkel berechnet und in der dritten geplottet. Das Ergebnis ist im linken Teil von Abb. 3.5 gezeigt. Für die Darstellung in kartesischen Koordinaten müssen wir die Polarkoordinaten erst mit Hilfe von pol2cart umwandeln und dann als kartesische Koordinaten konventionell mit plot darstellen: pol2cart >> [x,y] = pol2cart(phi,r); ←>> plot(x,y,’k’); ←>> axis equal; ←Das Ergebnis ist im rechten Teil von Abb. 3.5 dargestellt. Der Befehl axis equal bewirkt, dass beide Achsen gleiche Skalierung haben – sonst wird die Spirale verzerrt dargestellt. 2 3.1.7 Im Vorgriff aus Praktikum: Darstellung von Messdaten Die Darstellung von Messdaten folgt den gleichen Regeln wie die Darstellung von Funktionen. Die wesentlichen Unterschiede dürften darin liegen, dass bei den Messdaten nicht unbedingt eine Linie dargestellt wird sondern die Betonung auf der Darstellung der einzelnen Messpunkte durch Marker liegt und dass die Messdaten möglicherweise in einer externen Datei liegen, aus der sie erst eingelesen werden müssen. c M.-B. Kallenrode 12. Januar 2005 axis equal 30 KAPITEL 3. FUNKTIONEN 90 20 120 60 15 15 10 150 30 10 5 5 180 0 0 −5 330 210 −10 −15 300 240 270 −20 −15 −10 −5 0 5 10 15 20 Abbildung 3.5: Archimedische Spirale als Beispiel für eine Funktion in Parameterdarstellung. Links Darstellung in Polarkoordinaten (Skript archimedespolar), rechts Darstellung in kartesischen Koordinaten (Skript archimedeskartesisch) 10 120 100 9.5 Ort Temperatur 80 9 60 40 20 8.5 0 2 4 6 8 10 12 14 16 18 20 0 1 Messpunkt # 2 3 4 5 6 7 8 9 10 Zeit Abbildung 3.6: Zwei Beispiele für die Darstellung von Messwerten tempplot Messdaten liegen in der Regel als eine Matrix vor. Im einfachsten Fall handelt es sich dabei um einen Spaltenvektor, der eine Reihe von Zahlen enthält. Diese Art von Messdaten entsteht u.a. bei der Aufnahme einer Zeitserie, d.h. wenn alle 5 min die Temperatur gemessen und weg geschrieben wird. Als Beispiel dient der Datenfile temp.dat. Seine Darstellung im linken Teil von Abb. 3.6 erfolgte mit Hilfe des Skripts tempplot: T=load(’temp.dat’); tplot=plot(T,’--sr’); xlabel(’Messpunkt #’,’FontSize’,14); ylabel(’Temperatur’,’FontSize’,14); saveas(tplot,’tplot.pdf’) plot speedplot Die wesentliche Neuerung ist die Verwendung von plot in der zweiten Zeile: hier wird nur ein Vektor als Parameter übergeben; die Elemente des Vektors werden gegen ihre Ordnungsnummer aufgetragen. Daten können auch als mehrspaltige Matrix vorliegen, z.B. bei der Beobachtung einer Bewegung in einer Datei, die in der ersten Spalte die Zeitpunkte enthält, zu denen gemessen wurde, und in den folgenden Spalten jeweils die Messungen des Ortes zu diesen Zeiten für unterschiedliche Messreihen. Ein Beispiel ist in der Datei speed.dat gegeben; die im rechten Teil von Abb. 3.6 gezeigte Abbildung wurde daraus mit Hilfe des Skripts speedplot erzeugt: v=load(’speed.dat’); tplot=plot(v(:,1),v(:,2),’--sr’); hold on; 12. Januar 2005 c M.-B. Kallenrode 3.1. DARSTELLUNG VON FUNKTIONEN 31 plot(v(:,1),v(:,3),’--og’); plot(v(:,1),v(:,4),’-->b’); for i=1:length(v) vm(i) = sum(v(i,2:4))/3; end plot(v(:,1),vm,’k’,’LineWidth’,2); xlabel(’Zeit’,’FontSize’,14); ylabel(’Ort’,’FontSize’,14); hold off saveas(tplot,’splot.pdf’) In der ersten Zeile wird die Tabelle der Messwerte aus der Datei speed.dat in die Matrix v eingelesen. In den folgenden Zeilen werden die Spalten 2 bis 4 der Matrix jeweils gegen die erste Spalte geplottet. Die for-Schleife mittelt über die Spalten 2 bis 4 der Matrix, d.h. es wird zu jedem Zeitpunkt der Mittelwert der Messungen des Ortes gebildet. Dieses Information wird anschließend als dicke schwarze Linie in den Plot eingetragen. Der Rest ist Achsenbeschriftung und Speichern der Abbildung. Gerade bei der Darstellung von Messwerten kann es zur Orientierung hilfreich sein, ein Gitternetz aus waagerechten und senkrechten Linien in der Zeichnung zu haben. Dieses lässt sich, nach dem Aufruf der Funktion plot, mit Hilfe von grid on ein- und mit Hilfe des Befehls grid off wieder ausschalten. 3.1.8 grid on grid off Ergänzung: fplot statt plot Zur Darstellung eines gegebenen funktionalen Zusammenhangs kann statt der MatLabFunktion plot die Funktion fplot verwendet werden. Während bei plot die x- und y-Werte als Vektoren übergegeben werden, akzeptiert fplot als Eingabe die Funktion als String: >> fplot(’x + sin(x).*cos(x)’,[-2*pi 2*pi],’k’) ←Die weiteren Modifikationen an der Abbildung erfolgen wie bei plot. Die darzustellende Funktion wird an fplot entweder, wie im Beispiel, als in Hochkommata gesetzter String übergeben, als Name eines m-Files, in dem die Funktion definiert ist, oder als Handle einer an anderer Stelle im m-File definierten Funktion. Eine etwas längere Formulierung des obigen Beispiels weist erst die Funktion und ihre Grenzen jeweils einer Variablen zu und ruft anschließend fplot auf: >> fun=’x + sin(x).*cos(x)’; lims=[-2*pi 2*pi]; fplot(fun,lims,’k’) ←Eine andere Möglichkeit, die Funktion an fplot zu übergeben, ist die Verwendung eines Handles: >> fhandle = @(x) x+sin(x).*cos(x); fplot(fhandle,[-2*pi 2*pi],’k’) ←Der Parameter hinter dem Klammeraffen @ gibt an, welches (bzw. bei einer Liste welche) Argumente an die im anschließenden Ausdruck dargestellte Funktion übergeben werden sollen. In diesem Fall ist es ein Parameter. Die Funktion wird bei der Definition des Handles nicht als String angegeben sondern ohne Hochkommata, so wie wir sie auch direkt in einem m-File eingeben würden. Genauere Informationen finden sich in der MatLab-Hilfe unter Anonymous Functions. In der oben gegebenen Form erzeugt fplot keine Vektoren der x und y-Werte – im Workspace treten keine zusätzlichen Variablen auf. fplot kann jedoch auch verwendet werden, um anstelle der Abbildung zwei Vektoren X und Y mit den Ordinaten- und Abszissenwerten zu erstellen: >> [x y] = fplot(’x.*x + 2*x + 4’,[-5 5]); ←Diese können dann mit plot dargestellt werden. c M.-B. Kallenrode 12. Januar 2005 fplot 32 KAPITEL 3. FUNKTIONEN eval und feval Die Funktion fplot greift auf die MatLab-Funktion eval zurück, die eine als String oder über einen Handle gegebene Funktion an verschiedenen Stellen bestimmt: >> fun=’x + sin(x).*cos(x)’; x=2; eval(fun) ←y = 1.6216 liefert den Funktionswert von y = x + sin x cos x an der Stelle x = 2; >> fun=’x + sin(x).*cos(x)’; x=[1 2 3 4]; eval(fun) ←y = 1.4546 1.6216 2.8603 4.4947 feval liefert die Funktionswerte an den im Vektor x spezifizierten Punkten.2 Eng mit eval verwandt ist die universeller verwendbare Funktion feval: >> fhandle = @(x) x+sin(x).*cos(x); x=2; y=feval(fhandle,x) ←y = 1.6216 Der Vorteil von feval liegt darin, dass feval ein Handle als Argument akzeptiert. Die Möglichkeit, eine Funktion als String, über einen Handle oder durch Aufruf einer Datei auszuwerten, hat immer dann Vorteile, wenn die Funktion nicht direkt in den m-File geschrieben werden kann (z.B. bei einem GUI oder einem Algorithmus, der mehrfach auf verschiedene Funktionen angewandt werden soll) oder wenn die Funktion innerhalb eines Programms mehrfach ausgewertet werden muss. Letzteres ist z.B. bei vielen numerischen Verfahren der Fall. 3.2 Funktionen mehrerer Variablen Funktionen von mehreren Variablen lassen sich auf Grund der Beschränktheit unserer Wahrnehmung nur in geringem Maße darstellen: für Funktionen in Abhängigkeit von zwei Variablen kann der Funktionsgraph als eine Fläche im dreidimensionalen Raum dargestellt werden, für die parametrische Darstellung einer Funktion im 3D kann diese als Bahn dargestellt werden. 3.2.1 meshgrid mesh surf Funktionen als Flächen im 3D Die Darstellung von Funktionen als Flächen im 3D erfolgt analog zur der von Funktionen in Abhängigkeit von einer Variablen. Als erstes definieren wir ein Gitter in der xy-Ebene mit einem vorgegebenen Bereich und Gitterabstand mit Hilfe des Befehls meshgrid. Dies entspricht der Definition der x-Achse als Vektor bei der Darstellung von Funktionen einer Variablen. Anschließend wird die Funktion berechnet und mit mesh oder surf dargestellt. Als Beispiel verwenden wir wieder das Tal f (x, y) = x2 + y für den Bereich x ∈ [−2, 2] und y ∈ [0, 4]. Als erstes definieren wir das Grundgitter: >> [x,y] = meshgrid([-2:0.2:2],[0:0.1:4]); ←- meshgrid Die beiden Parameter von meshgrid sind Vektoren, wie wir sie bei der Definition der x-Achse 2 Achten Sie auf das Multiplikationszeichen! fplot arbeitet auch dann vernünftig, wenn bei der Definition der Funktion ein Multiplikationszeichen * statt der punktweisen Multiplikation .* verwendet wurde. Auch eval liefert beim ersten Beispiel einen vernünftigen Wert zurück, da die Funktion nur für einen Skalar ausgewertet wird. Beim zweiten Beispiel dagegen wird die Funktion für einen Vektor ausgewertet, so dass es bei Verwendung von * Probleme bei der Ausführung des Produkts sin(x)*cos(x) gibt und MatLab sich mit der üblichen Fehlermeldung ??? Error using ==> mtimes; Inner matrix dimensions must agree. verabschiedet. 12. Januar 2005 c M.-B. Kallenrode eval 3.2. FUNKTIONEN MEHRERER VARIABLEN 8 8 6 6 4 4 2 2 0 4 0 4 3 2 1 2 0 1 −1 0 33 3 2 1 2 0 1 −2 −1 0 −2 Abbildung 3.7: mesh und surf zur Darstellung von Funktionen als Flächen im 3D als Vektor verwendet haben. Sind x und y-Bereich identisch, so ist es ausreichend, einen Vektor anzugeben, z.B. meshgrid([-2:0.2:2]). Anschließend berechnen wir die Funktionswerte >> z=x.∧ 2+y; ←und stellen sie mit Hilfe von mesh >> mesh(x,y,z) als Gitternetz (linkes Teilbild in Abb. 3.7) oder mit Hilfe von surf >> surf(x,y,z) als Oberfläche (rechtes Teilbild in Abb. 3.7) im 3D dar. Achsenbeschriftung und Kurvenparameter werden wie bei normalen Funktionsplots im 2D manipuliert. Beispiel 6 Mit Hilfe des Skripts sombrero >> >> >> >> >> >> >> >> >> >> >> >> sombrero [x,y] = meshgrid([-15:1:15]);←r = sqrt(x.*x + y.*y) + eps; ←z = sin(r)./r;←subplot(2,2,1), mesh(x,y,z); ←title(’Mesh’)←subplot(2,2,2), surf(x,y,z); ←title(’Surf’) ←subplot(2,2,3),surf(x,y,z); ←shading interp ←title(’Surf + interpolated Shading’) ←subplot(2,2,4), contour(z,9); ←title(’Contour’) ←- wurden die verschiedenen in Abb. 3.8 gezeigten Darstellungsformen für eine Funktion von zwei Variablen erzeugt. Neben den bekannten Formen mesh (links oben) und surf (rechts oben) findet sich eine Variante von surf im linken unteren Teil. Hier wurde durch den Befehl shading interp auf eine interpolierende Schattierung umgeschaltet und das normalerweise bei surf schwarz dargestellte Gitter unterdrückt. Die Darstellung im rechten unteren Teilbild unterscheidet sich von den anderen, da hier die Funktion nicht im 3D sondern über Isolinien auf die Ebene projiziert dargestellt wird. Der zugehörige Befehl ist contour. 2 Verwendet man an Stelle der Befehle mesh und surf die Befehle meshc und surfc, so werden zusätzlich zu den Gittern bzw. Flächen im 3D auf der xy-Ebene die Isolinien dargestellt. Außerdem haben wir in dem Beispiel die Funktion subplot kennen gelernt: sie ermöglicht es, mehrere Abbildungen auf einem Blatt darzustellen. Die ersten beiden Parameter in c M.-B. Kallenrode 12. Januar 2005 contour meshc surfc subplot 34 KAPITEL 3. FUNKTIONEN Mesh Surf 1 1 0 0 −1 20 −1 20 20 0 −20 −20 20 0 0 −20 −20 Surf + interpolated Shading 0 Contour 30 1 20 0 10 −1 20 20 0 −20 −20 0 10 20 30 Abbildung 3.8: Darstellung von Funktionen im 3D subplot spezifizieren die Zahl der Teilabbildungen pro Spalte bzw. Zeile, die dritte Zahl entspricht der laufenden Nummer des Feldes, in das der folgende plot-Befehl die Abbildung platzieren soll. GUI plottest popup ezsurf ezsurfc ezmesh ezmesh contour setplot Zur Darstellung von Funktionen zweier Variablen kann das GUI plottest popup verwendet werden, vgl. Abb. 3.9. Es erlaubt die Eingabe einer Funktion, die Eingabe eines (um Null symmetrischen) Wertebereichs für die x- und y-Achse sowie über ein Pop-Up Menü die graphische Darstellung als Oberfläche (ezsurf), als Oberfläche mit zugehöriger Darstellung der Höhenlinien in der xy-Ebene (ezsurfc), als Gitter (ezmesh), gegebenenfalls ebenfalls mit Konturen (ezmeshc), oder als einfacher Konturplot (Höhenlinien) in der xy-Ebene (contour). plottest popup ruft die Funktion setplot auf, die sich im gleichen Verzeichnis befinden muss. In diesem GUI werden die Funktionen ezmesh oder ezmeshc statt mesh oder meshc verwendet. Bei mesh und ähnlichen Plotfunktionen haben wir die Funktionswerte erst explizit ausgerechnet. Das bedeutet, das im MatLab-Skript an einer Stelle diese Funktion wirklich berechnet werden muss.3 Beim GUI wollen wir die Funktion jedoch nicht als Zeile eines MatLab-Skripts eingeben sondern als Zeichenkette, die auch für nicht-MatLab-User verständlich ist. Genau hier kommen die Plotroutinen mit dem Präfix ez ins Spiel. Ihre Syntax akzeptiert die Eingabe einer Funktion (statt der bereits berechneten Funktionswerte) und plottet diese routinemäßig im Bereich −2π ≤ x ≤ 2π und −2π ≤ y ≤ 2π. Werden die 3 Dies entspricht dem Unterschied zwischen den Funktionen plot und fplot bei der Darstellung von Funktionen. 12. Januar 2005 c M.-B. Kallenrode 3.2. FUNKTIONEN MEHRERER VARIABLEN 35 Abbildung 3.9: Screenshot des GUI plottest popup y/(1 + x2 + y2) 0.5 0 −0.5 5 5 0 0 −5 y −5 x Abbildung 3.10: Funktionsplot mit ezmeshc als Einzeiler: ezmeshc(’y/(1 + x∧ 2 + y∧ 2)’,[-5,5,-2*pi,2*pi]) x und y Bereiche explizit angegeben, wie im GUI möglich, so stellt ezmesh die Funktion in diesem Bereich dar. Mit Hilfe der ez-Routinen lassen sich Funktionsdarstellungen als Einzeiler erzeugen. So liefert die Zeile >> ezmeshc(’y/(1 + x∧ 2 + y∧ 2)’,[-5,5,-2*pi,2*pi]) ←den in Abb. 3.10 gezeigten 3D-Plot mit den zugehörigen Konturen. Veränderungen von Achsenbeschriftung und -parametern wieder wie bei plot, weitere Informationen in der MatLabHilfe unter ezmeshc. 3.2.2 Funktionen als Linien im 3D Beispiel 7 Gyriert ein Elektron um eine Magnetfeldlinie, so entsteht eine Bahn im dreidimensionalen Raum. In Parameterform können wir diese Helix in Polarkoordinaten beschreiben als %(t) = % = const , c M.-B. Kallenrode ϕ(t) = ω t und z = vz t . 12. Januar 2005 36 KAPITEL 3. FUNKTIONEN 4 3 2 1 0 1 2 1 0 −1 0 −1 Abbildung 3.11: Bahn eines geladenen Teilchens um eine Magnetfeldlinie, dargestellt mit plot3 Darin ist % der Abstand des Elektrons vom Mittelpunkt seines Gyratioorbits (und damit von der Feldlinie), ω die Winkelgeschwindigkeit der Gyration um die Feldlinie und vz die konstante Geschwindigkeit der Translation entlang der Feldlinie. Zur Darstellung der sich ergebenden Bewegung definieren wir zuerst die Konstanten und einen Vektor, der den Parameter Zeit enthält: >> ohm=2.; vz = 0.4; r = 2.; t=[0:0.02:10]; ←Damit berechnen wir zu jedem Zeitpunkt den Aufenthaltsort des Elektrons in Polarkoordinaten mit >> phi=ohm*t; z = vz*t; ←und wandeln anschließend in kartesische Koordinaten um >> [X,Y,Z] = pol2cart(phi,r,z); ←plot3 Die kartesischen Koordinaten lassen sich dann mit dem Befehl plot3 darstellen >> plot3(X,Y,Z,’k’); axis equal; ←der Befehl axis equal wird wieder benötigt, um Verzerrungen zu vermeiden. Das Ergebnis ist in Abb. 3.11 gezeigt. 2 3.3 Differentialrechnung MatLab ist kein symbolisches oder algebraisches sondern ein numerisches System. Daher kann MatLab weder differenzieren noch integrieren in dem Sinne, dass es einen geschlossenen Ausdruck für die Ableitung oder das Integral liefert. MatLab bedient sich jedoch verschiedener numerischer Verfahren mit deren Hilfe die Steigung einer Funktion in einem bestimmten Intervall als Wertetabelle bzw. in graphischer Form gegeben werden kann ebenso wie ein bestimmtes Integral.4 3.3.1 Nullstellen Eines der einfachsten Merkmale zur Charakterisierung einer Funktion sind deren Nullstellen, d.h. die Punkte, an denen der Graph der Funktion die x-Achse schneidet. Analytisch werden diese durch Nullsetzen der Funktion und auflösen nach x bestimmt. Da MatLab die 4 Es ist nicht ganz korrekt, dass MatLab überhaupt keine algebraischen Rechnungen vornehmen kann. Mit der Symbolic Math Toolbox als Erweiterung könnte MatLab korrekt symbolisch rechnen. In der normalen MatLab-Version ist dies nicht allgemein möglich sondern auf Polynome beschränkt, vgl. Anhang ??. 12. Januar 2005 c M.-B. Kallenrode 3.3. DIFFERENTIALRECHNUNG 37 dazu erforderlichen Operationen nicht durchführen kann, werden in MatLab die Nullstellen numerisch gesucht: in einer Wertetabelle der Funktion wird in der Umgebung eines vorgegebenen Wertes nach einem Vorzeichenwechsel gesucht und dieser zur genaueren Bestimmung der Nullstelle weiter eingeschachtelt. Diese Nulltstellensucher erfolgt mit Hilfe der Funktion fzero. Die Argumente sind die Funktion als String (oder als String in eine Variable geschrieben) sowie ein Wert in dessen Umgebung oder ein Intervall in dem die Nullstelle gesucht werden soll. Der Befehl >> x=fzero(’x*x-1’,0.9) ←x = 1 sucht die Nullstelle der Funktion f (x) = x2 − 1 in der Nähe von 0.9 und findet ganz korrekt die +1. Mit dem Befehl >> x=fzero(’x*x-1’,[-1.1 0.9]) ←x = - 1 sucht MATLAB im Intervall von -1.1 bis 0.9 und findet als Nullstelle die -1. Da die Nullstellensuche über einen Vorzeichenwechsel der Funktionswerte erfolgt, wird für die Funktion x2 keine Nullstelle gefunden: >> x=fzero(’x*x’,0.01) ←Exiting fzero: aborting search for an interval containing a sign change because NaN or Inf function value encountered during search (Function value at -1.553326e+154 is Inf) Check function or try again with a different starting value. x = NaN Ebenso scheitert MatLab bei der Nullstellensuche, wenn bei der uns bereits bekannten Funktion f (x) = x2 − 1 das Intervall so gross gewählt wird, dass es beide Nullstellen enthält: >> fzero(’x*x-1’,[-1.1 1.1]) ←??? Error using ==> fzero The function values at the interval endpoints must differ in sign. Auch hier kann die Funktion natürlich vorher definiert und dann aus fzero aufgerufen werden: >> fun=’x*x-1’;lims=[-1.1 0.9];fzero(fun,lims) ←Ein derartiges Verfahren kann z.B. dann sinnvoll sein, wenn man nacheinander mehrere Funktion oder nacheinander mehrere Intervalle bei einer Funktion auf Nullstellen untersuchen möchte und die verschiedenen Werte von fun bzw. lims mit Hilfe einer Schleife nacheinander in fzero füttert. 3.3.2 Numerisches Differenzieren Die Ableitung einer Funktion ist definiert als der Quotient aus der Differenz der Funktionswerte an zwei um ∆x aus einander liegenden Stellen dividiert durch ∆x für den Grenzwert ∆x → 0: f 0 (x) = lim ∆x→0 f (x) + f (x + ∆x) . ∆x Numerische Differentiation verwendet den gleichen Quotienten, jedoch ohne den Grenzübergang ∆x → 0. Für die praktische Durchführung des numerischen Verfahrens gibt es verschiedene Möglichkeiten: c M.-B. Kallenrode 12. Januar 2005 fzero 38 KAPITEL 3. FUNKTIONEN • Die Vorwärts-Differenz (forward finite difference) δf+ (x) ist der eigentlichen Definition der Ableitung am ähnlichsten: f (xo + ∆x) − f (xo ) . ∆x In ihrer Genauigkeit ist diese Differenz von erster Ordnung: die Genauigkeit hängt von der zweiten Ableitung der Funktion ab, d.h. von der ersten Ableitung der gesuchten Ableitung. Für stark veränderliche Funktionen ist diese aber relativ groß, so dass die VorwärtsDifferenz in der Nähe starker Veränderungen ungenau wird. Die Ordnung der Genauigkeit lässt sich durch Taylor-Entwicklung zeigen. • Die Rückwärts-Differenz (backward finite difference) δf− (x) ist auf ähnliche Weise definiert δf+ (xo ) = f (xo ) − f (xo − ∆x) ∆x und ebenfalls von einer Genauigkeit erster Ordnung. • Die zentrale Differenz (centered finite difference) δf (x) ist definiert als δf− (xo ) = f (xo + ∆x) − f (xo − ∆x) . 2∆x Sie hat eine Genauigkeit von zweiter Ordnung und ist daher wesentlich robuster als die beiden anderen Differenzen-Verfahren. δf (xo ) = diff Ein einfaches Verfahren zur numerischen Differentiation verwendet die MatLab-Funktion diff, die aus einem n-elementigen Vektor einen (n-1)-elementigen Vektor erzeugt, der die Differenzen benachbarter Werte enthält: >> x=[1 2 4 7 11 16 22 29 37]; ←>> dx=diff(x) ←dx = 1 2 3 4 5 6 7 8 Beispiel 8 Die Ableitung der Funktion y = sin(x) ist y 0 = cos(x), die zweite Ableitung ist y 00 = − sin(x). Mit der folgenden Befehlssequenz soll diese Ableitung numerisch im Intervall ug bis og bestimmt und mit der analytischen Lösung verglichen werden. Da der Vektor, der die Werte der Ableitung enthält, um ein Element kürzer ist als der Vektor der Funktionswerte, müssen wir für die graphische Darstellung drei x-Achsen definieren: x für die Funktion, xv für die Ableitung und xvv für die zweite Ableitung. >> >> >> >> >> >> >> >> >> >> winkelableit ug=0;og=10;deltx=0.1; ←x=[ug:deltx:og];xv=[ug+deltx/2:deltx:og-deltx/2];xvv=[ug+deltx:deltx:og-deltx];←dx=diff(x);dy=diff(sin(x));abl1=dy./dx; ←d2x=diff(xv);d2y=diff(abl1);abl2=d2y./d2x; ←plot(x,sin(x),’k’);hold on;plot(xv,cos(xv),’r’);plot(xvv,-sin(xvv),’g’);←plot(xv,abl1,’vr’);plot(xvv,abl2,’og’); ←xlabel(’x’,’Fontsize’,16); ylabel(’y’,’Fontsize’,16); ←title(’sin(x) und seine Ableitungen (Symbole)’,’Fontsize’,20); ←text(2.2,0.8,’ \leftarrow sin(x)’); text(3*pi/2,0,’ \leftarrow cos(x)’);←text(5.9,-0.8,’-sin(x) \rightarrow’); hold off ←- Abbildung 3.12 zeigt die Funktion (schwarz) mit ihren beiden analytisch bestimmten Ableitungen (rote bzw. grüne Kurve) sowie die numerisch mit Hilfe der obigen Befehlssequenz bestimmten Ableitungen (Symbole). Trotz des relativ groben Gitters (anschaulich durch den Abstand benachbarter Symbole), stimmt selbst die zweite numerische Ableitung sehr gut mit den analytischen Werten überein. Das Skript winkelableit basiert auf obiger Befehlssequenz. 2 Das von uns in MATLAB verwendete Verfahren ähnelt dem einer zentralen Differenz, wobei allerdings die Ableitung nur an jedem zweiten Gitterpunkt bestimmt wurde. In der 12. Januar 2005 c M.-B. Kallenrode 3.4. NUMERISCHE INTEGRATION 39 sin(x) und seine Ableitungen (Symbole) 1 ← sin(x) 0.8 0.6 0.4 y 0.2 ← cos(x) 0 −0.2 −0.4 −0.6 −sin(x) → −0.8 −1 0 1 2 3 4 5 6 7 8 9 10 x Abbildung 3.12: Funktion y = sin(x) (schwarz) und analytisch bestimmte Ableitungen y 0 = cos(x) (rote Kurve) bzw. y 00 = − sin(x) (grüne Kurve) sowie zugehörige numerisch bestimmte Ableitungen (Symbole) echten zentralen Differenz würden wir Funtkionswerte auch an den Gitterpunkten benötigen, in denen wir jetzt die Steigung angeben, und würden auch Steigungen in den Gitterpunkten erhalten, für die wir die Funktionswerte angegeben haben. 3.3.3 Extrema Neben der Bestimmung von Nullstellen und Ableitungen ist ein Aspekt von Kurvendiskussionen die Bestimmung von Extrema. Diese sind die Punkte mit waagerechter Tangente und damit die Nullstellen der Ableitung. MatLab stellt neben fzero für die Nullstellensuche die Funktion fminbnd für die Suche nach Extrema. Auch hier wird die Funktion als String eingegeben. Als weitere Argumente werden zwei x-Werte übergeben, die das Intervall definieren, in dem fminbnd das Minimum sucht: >> fminbnd(’x*x’,-3,3) ←ans = 1.1102e-016 Das Ergebnis weicht um die interne Rechnergenauigkeit von Null ab. Bei der Verwendung von fminbnd ist jedoch Vorsicht geboten, da die Funktion das Minimum innerhalb des betrachteten Intervalls bestimmt – was nicht zwingend ein Extremum der Funktion ist. So liefert auch der Befehl >> fminbnd(’x*x’,-3,-1) ←ans = -1.0000 ein Minimum (eben das in dem Intervall), aber keinen Extremwert. 3.4 Numerische Integration Auch die Integration von Funktionen erfolgt numerisch. MatLab verfügt über fest eingebaute Funktionen, wir können MatLab jedoch auch verwenden, um verschiedene einfachere Verfahren wie Mittelpunkts- oder Trapezformel zu benutzen. Eine Übersicht über die Codierung derartiger numerischer Verfahren in verschiedenen Programmiersprachen mit etlichen Beispielen und guten Erläuterungen der Verfahren gibt [1]. c M.-B. Kallenrode 12. Januar 2005 fminbnd 40 KAPITEL 3. FUNKTIONEN Für alle folgenden Beispiele ist die Aufgabe die Bestimmung des bestimmten Integrals der Funktion f (x) im Intervall von a bis b: Zb f (x) dx . I= a Das Interval [a, b] kann in M Schritte der Länge ∆x eingeteilt werden: ∆x = (b − a)/M . Beispiel 9 Als Beispiel werden wir die Funktion f (x) = 3x2 + 2 im Intervall von 2 bis 4 betrachten, d.h. es ist das Integral Z4 (3x2 + 2) dx I= 2 zu bestimmen. Als Referenz für unsere numerischen Verfahren erhalten wir die analytische Lösung Z4 4 (3x2 + 2) dx = x3 + 2x I= 2 = 60 . 2 2 3.4.1 Mittelpunktsformel Bei Verwendung der Mittelpunktsformel wird das Integral aus Rechtecken der Breite ∆x zusammengesetzt, die Höhe der Rechtecke wird durch den Funktionswert in der Intervallmitte gegeben: M M X X xk−1 + xk f f (xmk ) ∆x = ∆x . IMP = 2 k=1 k=1 In MatLab können wir dieses Integral auswerten, in dem wir einen Vektor der Intervallmitten erzeugen, den zugehörigen Vektor der Funktionswerte ausrechnen, beide Vektoren punktweise multiplizieren und die Komponenten des sich dabei ergebenden Vektors addieren: >> a=2;b=4;M=100;deltx=(b-a)/M; ←>> x=[a+deltx/2:deltx:b-deltx/2]; y=(3*x.*x+2).*deltx; ←>> I = sum(y) ←I = 59.9998 Das Ergebnis ist in guter Übereinstimmung mit dem analytischen Wert aus Beispiel 9. Die Abhängigkeit der Genauigkeit des numerischen Ergebnisses von der Zahl M der Schritte bzw. der Schrittweite ∆x ist in folgender Tabelle gegeben: M ∆x I 3.4.2 1 2 58 2 1 59.5 5 0.4 59.92 10 0.2 59.98 20 0.1 59.995 50 0.04 59.9992 100 0.02 59.9998 200 0.01 60.0000 500 0.004 60.0000 Trapezformel Bei der Trapezformel wird das Integral durch Trapeze der Breite ∆x und der durch die Funktionswerte an den Intervallrändern gegebenen Höhen zusammen gesetzt: IT = M X 1 k=1 2 (f (xk ) + f (xk−1 )) ∆x . Die Regeln für die numerische Integration in MatLab entsprechen denen bei der Mittelpunktsformel. Dort ist nur die zweite Zeile (Vektor der Punkte, an denen der Funktionswert zu nehmen ist und Verfahren der Bestimmung der Fläche) zu ersetzen durch 12. Januar 2005 c M.-B. Kallenrode 3.4. NUMERISCHE INTEGRATION 41 x=[a:deltx:b]; for k=1:M; y(k)=(3*x(k)*x(k) +2 + 3*x(k+1)*x(k+1) + 2)*deltx/2; end und wir erhalten als Ergebnis 60.0004, ebenfalls in guter Übereinstimmung mit dem in Beispiel 9 gefundenen analytischen Wert. Das vollständige Verfahren ist im Skript trapez zusammen gefasst. Die Abhängigkeit des Ergebnis von der Schrittweite ist in folgender Tabelle gegeben: M ∆x I 1 2 64 2 1 61 5 0.4 60.16 10 0.2 60.04 20 0.1 60.01 50 0.04 60.0016 100 0.02 60.0004 200 0.01 60.0001 trapez 500 0.004 60.0000 Im oben gegebenen Beispiel für die Trapezformel ist die Funktion zwei mal im m-File eingetragen. Hier ist eine alternative Codierung zu empfehlen, bei der die Funktion über einen Handle definiert und mit feval ausgewertet wird: feval x=[a:deltx:b]; fhandle = @(x) 3*x.*x +2; for k=1:M; y(k) = (feval(fhandle,x(k))+feval(fhandle,x(k+1)))*deltx/2; end Mit dieser Vorübung können wir satt eines Skripts jetzt eine Funktion trapezfunk schreiben, die die Integration gemäß Trapezformel ausführt: function I = trapezfunk(f,a,b,M) % Trapezformel % Eingabe: Funktion f, Grenzen a und b, Zahl der Schritte M % Ausgabe: Skalar I als Fläche deltx=(b-a)/M; x=[a:deltx:b]; for k=1:M; y(k) = (feval(f,x(k))+feval(f,x(k+1)))*deltx/2; end I=sum(y); Diese Funktion kann aus einem Skript oder dem MatLab Befehlsfenster heraus aufgerufen werden. In beiden Fällen müssen die zu übergebenden Parameter vorher vereinbart werden. Für den Aufruf aus dem Kommandofenster heraus könnte dies wie folgt aussehen: >> a=2; b=4; M=100; fun = @(x) 3*x.*x +2; >> I=trapezfunk(fun,a,b,M) I = 60 Der Vorteil der Darstellung der Trapezformel als eine Funktion ist offensichtlich: jetzt müssen Integrationsgrenzen, Schrittzahlen oder die zu integrierende Funktion nicht mehr im m-File geändert werden sondern nur in der ersten Eingabezeile im Befehlsfenster bzw. falls die Funktion trapezfunk aus einem m-File aufgerufen wird in diesem. Auf Grund dieses offensichtlichen Vorteils werden die folgenden numerischen Verfahren stets als Funktionen und mit Hilfe eines Handles zur Beschreibung der zu integrierenden mathematischen Funktion eingeführt. 3.4.3 Simpson-Regel Bei der Simpson-Regel wird der Integrand durch ein Polynom zweiten Grades angenähert. Für die Teilintegrale werden dazu in einem Intervall ∆x Funktionswerte an den Intervallgrenzen c M.-B. Kallenrode 12. Januar 2005 trapezfunk 42 KAPITEL 3. FUNKTIONEN xk und xk−1 bestimmt sowie in der Intervallmitte xmk . Für das Integral ergibt sich dann M ISimpson = 1X (f (xk−1 ) + 4f (xmk ) + f (xk ))∆x . 6 k=1 simpsonfunk Für das Integral aus Beispiel 9 lässt sich das Simpson-Verfahren in folgender MatLabFunktion simpsonfunk realisieren: function I = simpsonfunk(f,a,b,M) % Simpson-Regel % Eingabe: Funktion f, Grenzen a und b, Zahl der Schritte M % Ausgabe: Skalar I als Fläche deltx=(b-a)/M; x=[a:deltx:b]; xm=[a+deltx/2:deltx:b-deltx/2]; for k=1:M; y(k) = (feval(f,x(k))+4*feval(f,xm(k))+feval(f,x(k+1)))*deltx/6; end I=sum(y); Der Aufruf erfolgt wie bei trapezfunk; zum Vergleich können auch beide Funktionen aus einem Skript heraus gestartet werden. Als Ergebnis für die Standard-Eingabeparameter erhalten wir 60.000. Das Simpson-Verfahren liefert also bereits für recht kleine Schrittzahlen M bzw. recht große Schrittweiten ∆x bessere Ergebnisse als die beiden anderen Verfahren, wie aus der folgenden Tabelle zu erkennen ist: M ∆x I 3.4.4 quad 1 2 60 2 1 60 5 0.4 60 10 0.2 60 20 0.1 60 50 0.04 60.0000 100 0.02 60.0000 200 0.01 60.0000 500 0.004 60.0000 Adaptives Simpson-Verfahren Durch geeignete Wahl der Schrittweite kann man mit Hilfe des Simpson-Verfahrens sehr genaue Ergebnisse für die numerische Integration erzielen. Diese werden, wie bei jedem numerischen Verfahren, mit abnehmender Schrittweite immer besser (sorry, in obigem Beispiel waren sie leider zu gut). Ein sehr feines Gitter bedeutet jedoch auch eine lange Rechenzeit. Dieses feine Gitter ist aber nicht erforderlich in den Bereichen, in denen sich eine Funktion nur schwach ändert: im Extremfall konstanter Intensität in einem Bereich der Funktion reicht ein einziges Rechteck oder Trapez. Allgemein muss die Gitterweite um so feiner sein, je stärker sich die Funktion ändert. Bei Funktionen, die sich in einigen Bereich stark, in anderen kaum verändern, ist daher die Verwendung eines feinen Gitters über den gesamten Integrationsbereich zwar eine sichere aber auch eine rechenintensive Methode. Besser wäre die Verwendung eines feinen Gitters in einigen Bereichen und eines groben Gitters in anderen. Dann kann bei gleicher Rechengenauigkeit Rechenzeit gespart werden. Eine derartige Anpassung des Integrationsverfahrens an die Funktion ist in MatLab als adpatives Simpson-Verfahren realisiert und wird mit der Funktion quad aufgerufen. Das adaptive Simpson-Verfahren angewandt auf unsere Beispielfunktion ist >> I = quad(f,a,b) ←wobei f wieder die Funktion und a und b die Grenzen geben, in denen diese Funktion integriert werden soll. Beim Aufruf von quad lässt sich eine Toleranz als weiterer Parameter angeben, die MatLab anweist, bis zu welcher Genauigkeit die Integration erfolgen soll (und damit auch, wie zeitintensiv diese sein darf). Statt der Zuweisung der Funktion zu einer Variablen kann die Funktion auch direkt in als Parameter beim Funktionsaufruf übergeben werden: >> I = quad(’3*x.∧ 2+2’,2,4) ←- 12. Januar 2005 c M.-B. Kallenrode 3.4. NUMERISCHE INTEGRATION 43 Abbildung 3.13: GUI numint zur numerischen Integration 3.4.5 Weitere MatLab Funktionen Für die numerische Integration stehen in MatLab abgesehen von den oben gegebenen einfachen ‘Selbstbau-Skripten’ verschiedene Funktionen zur Verfügung: • quad verwendet ein adaptives Simpson-Verfahren für die numerische Integration. • quadl verwendet ein adaptives Lobatto-Verfahren. • dblquad kann für Doppelintegrale verwendet werden. Sie basiert auf einem adaptiven Simpson-Verfahren, ist also eine Anwendung von quad. • triplequad hilft bei der numerischen Lösung von Dreifachintegralen, ebenfalls basierend auf einem adaptiven Simpson-Verfahren. Die MatLab-Funktionen folgen in ihrer Syntax alle dem bei quad besagten; nähere Informationen bietet die MatLab-Hilfe. 3.4.6 GUI zur numerischen Integration Die Datei numint enthält ein einfaches GUI zu numerischen Integration von Funktionen, vgl. Abb. 3.13. Die Eingabeparameter (rechts oben) beschränken sich auf die Funktion, die untere und obere Grenze sowie die Schrittzahl. Über das Pop-Up Menü können die verschiedenen bisher diskutierten Verfahren zur numerischen Integration ausgewählt werden. Als Ergebnis wird im linken Teil der Funktionsgraph im zu untersuchenden Bereich geplottet, der Wert des sich ergebenden Integrals ist ebenfalls angegeben. Das GUI besteht aus dem eigentlichen Skript numint, einer Routine setintegration, die für den Plot und die Zuordnung zu den verschiedenen Integrationsverfahren erforderlich ist, sowie den Funktionen mittelgui, trapezgui und simpsongui, die jeweils die numerischen Verfahren ausführen. Diese Funktionen unterscheiden sich von den weiter oben eingeführten Funktionen nur durch die Art und Weise, in der die mathematische Funktion übergeben wird (Handle vs. String) und damit wie sie ausgewertet wird (feval vs. eval). 3.4.7 Monte-Carlo Integration Ein ganz anderes Verfahren zur Integration ist die Monte-Carlo Methode. Monte-Carlo Verfahren basieren auf der Verwendung von Zufallszahlen, d.h. sie unterscheiden sich in ihrem Ansatz von den bisher betrachteten Verfahren. Diese waren streng deterministisch und damit reproduzierbar, während in Monte-Carlo Verfahren ein Zufallselement ins Spiel kommt. Monte-Carlo Verfahren finden in allen Bereichen Anwendung, in denen Prozesse formal eher c M.-B. Kallenrode 12. Januar 2005 numint 44 KAPITEL 3. FUNKTIONEN auf der Basis von Wahrscheinlichkeitsverteilungen beschrieben werden als in Gleichungen mit genau definierten Parametern. Ein Beispiel für ein Monte-Carlo Verfahren ist die Bestimmung von π = 3.14159265358979. Die Zahl π können wir weder als rationale Zahl noch über einen funktionalen Zusammenhang einführen – außer über die Bedeutung von π für die Bestimmung der Fläche oder des Umfangs eines Kreises. So gibt π z.B. die Fläche eines Einheitskreises. Wenn wir ein numerisches Verfahren zur Bestimmung der Fläche des Einheitskreises anwenden, bestimmen wir gleichzeitig auch π. Malen wir also einen Einheitskreis auf ein quadratisches Stück Pappe, das diesen Kreis genau umschreibt. Legen wir das Ganze auf den Boden und lassen aus großer Höhe Reiskörner auf die Pappe rieseln. Diese treffen statistisch gleichmäßig verteilt auf. Daher sollte sich die Zahl der Reiskörner im Kreis zur Gesamtzahl der Reiskörner so verhalten, wie die Fläche des Einheitskreises zur Gesamtfläche: Reisk. in Einheitsk Einheitskreis π = = . Reisk. gesamt Quadrat 4 rand Durch Auszählen der Reiskörner lässt sich also π bestimmen. Das Verfahren lässt sich auch in MATLAB anwenden. Dazu benötigen wir Zufallszahlen, die mit der Funktion rand erzeugen. Wird rand ohne Argument auf gerufen, so erzeugt es im Intervall (0,1) gleich verteilte Zufallszahlen. Werden Argumente an rand übergeben, so kann rand z.B. Matrizen aus Zufallszahlen erzeugen: >> rand(3) ←ans = 0.2028 0.2722 0.1987 0.1988 0.6038 0.0153 0.7468 0.4451 0.9318 oder >> rand(1,3) ←ans = 0.7095 0.4289 montecarlopi 0.3046 Für die Bestimmung der Fläche des Kreises benötigen wir die folgende Sequenz aus dem Skript montecarlopi: n=1000; z=0; x=2*rand(1,n)-1; y=2*rand(1,n)-1; r= sqrt(x.*x + y.*y); for i=1:n if r(i) <= 1 z = z +1; end end Pi = 4*z/n; str=num2str(Pi,4);label = [’\pi n = ’ str]; plot(x,y,’.r’);hold on;axis equal; phi=[0:0.1:2*pi];R=1.;[xk,yk]=pol2cart(phi,R); plot(xk,yk,’k’,’Linewidth’,1.5); text(-0.98,0.92,label,’Fontsize’,14); xq=[1;-1;-1;1;1];yq=[1;1;-1;-1;1];plot(xq,yq,’k’,’Linewidth’,1.5) Die erste Zeile definiert die Zahl n der Reiskörner, setzt den Zähler z für die im Kreis gelandeten Reiskörner auf Null. In der folgenden Zeile werden Vektoren der Länge n aus Zufallszahlen im Intervall [-1 1] erzeugt. Diese können wir als die Koordinaten unserer Reiskörner interpretieren. In der folgenden Zeile wird der Abstand jedes Punktes vom Ursprung bestimmt, in der folgenden Zählschleife wird für jeden Wert überprüft ob er im Kreis liegt und wenn ja wird der Zähler z um 1 hoch gesetzt. Die folgende Zeile berechnet π und wandelt die Variable in einen String um, der in der anschließenden Plotroutine benötigt wird. Ein Beispiel für das so bestimmte π ist in Abb. 3.14 gezeigt. 12. Januar 2005 c M.-B. Kallenrode 3.4. NUMERISCHE INTEGRATION 1 45 πn = 3.248 0.8 0.6 0.4 0.2 0 −0.2 −0.4 −0.6 −0.8 −1 −1 −0.5 0 0.5 1 Abbildung 3.14: Bestimmung von π mit Monte Carlo Lassen wir das Skript einige Male laufen, so erhalten wir (mit jeweils 1000 Reiskörnern) für π z.B.: 3.1000, 3.1400, 3.1920, 3.2120, 3.1480, 3.1240, 3.0760, 3.0840, 3.1160, 3.1240, 3.2000, 3.1680, 3.0760, 3.1560. Diese Werte sind eine vernünftige Näherung an π, genauere Ergebnisse erhalten wir mit einer größeren Zahl von Reiskörnern (jeweils 10000): 3.1324, 3.1560, 3.1672, 3.1408, 3.1520, 3.1232, 3.1604, 3.1400, 3.1452, 3.1268, 3.1308, 3.1592, 3.1468, 3.1408. In beiden “Versuchsreihen” erhalten wir eine Verteilung der Werte, die um π herum streut, wobei die Verteilung um so schmaler wird, je größer die Zahl der verwendeten Reiskörner. Fragen Frage 10 Informieren Sie sich an Hand der MatLab-Hilfe über die Möglichkeiten, eine mathematische Funkion darzustellen und an eine MatLab-Funktion zu übergeben. Welche Bedeutung hat ein Handle für eine Funktion? Frage 11 Welche Möglichkeiten gibt es, der Funktion plot Parameter für die Darstellung der Kurve (gestrichelt ...) zu übergeben? Frage 12 Welche Möglichkeiten der Achsenbeschriftung gibt es? Frage 13 Die MatLab Funktion fplot bietet gegenüber Plot die Möglichkeit, eine mathematische Funktion direkt als Parameter zu übergeben ohne erst die x und y-Werte als Vektoren zu bestimmen. Bringen Sie plot bei, ebenfalls die Funktion als Eingabe zu akzeptieren – im Unterschied zu fplot müssen sie die x-Werte allerdings weiterhin vorgeben. Frage 14 Bei Plots im 3D werden durch mesh Flächen im Raum, durch plot3 dagegen Linien im Raum dargestellt. Was bedeuten diese unterschiedlichen Darstellungsformen inhaltlich? Aufgaben Aufgabe 9 Schreiben Sie ein Skript zur Darstellung einer Zykloide. Aufgabe 10 Schreiben Sie ein Skript zur Darstellung der Funktion f (x, y) = cos(x/2) sin(y 2 ) Frage 15 Schreiben Sie ein Skript, mit dem Sie Weg-Zeit- und Geschwindigkeitszeit-Diagramm einer Bewegung (nehmen Sie irgendwelche Werte an) (a) mit Hilfe von zwei Abbildungen auf einem Blatt und (b) innerhalb einer Abbildung mit zwei verschiedenen y-Achsen darstellen lassen. c M.-B. Kallenrode 12. Januar 2005 46 KAPITEL 3. FUNKTIONEN Aufgabe 11 Schreiben Sie eine MatLab-Funktion, an die aus dem Befehlsfenster oder über ein Skript verschiedene mathematische Funktionen mit dem Zweck einer einheitlichen graphischen Darstellung übergeben werden können. Probieren Sie verschiedene Möglichkeiten der Übergabe der mathematischen Funktion aus. Aufgabe 12 Schreiben Sie ein Skript zur Bildung der zweiten Ableitung der Funktion f (x) = x3 + 2x2 + 9 und stellen Sie Funktion und beide Ableitungen graphisch dar. Vergleichen Sie mit den analytisch bestimmten Werten. Aufgabe 13 Schreiben Sie ein Skript zur numerischen Bestimmung des bestimmten Integrals Z5 (x2 + ex ) dx . 1 Aufgabe 14 Bestimmen Sie Verteilungen für π wie mit montearlopi bestimmt für (a) 1000 und (b) 10000 Reiskörner. Variieren Sie das gegebene Skript derart, dass sie die Bestimmung der Verteilungen automatisiert kriegen. Aufgabe 15 Schreiben Sie ein Skript zur Bestimmung des Volumens einer Einheitskugel mit Hilfe der Monte-Carlo Methode. Aufgabe 16 Schreiben Sie ein Skript zur Bestimmung des bestimmten Integrals Zπ sin x dx 0 mit Hilfe der Monte-Carlo-Methode, stellen Sie die Lösung graphisch dar und vergleichen Sie mit der analytischen Lösung. Aufgabe 17 Das folgende MatLab-Fragment zur Bestimmung des Volumens der Einheitskugel enthält einige Fehler. Finden Sie diese und korrigieren Sie sie: n=1000; x=2*rand(1,n)-1; y=2*rand(1:n)-1, z=2*rand(1,n)-1; r = sqrt(x.*x+y*y+z.*z); for i=1,n if r(i) >=1 zaehl = zaehl + 1; end end vol = (n-zaehl)/n Literaturverzeichnis [1] Press, W.H., B.P. Flannery, S.A. Teukolsky and W.T. Vetterling, Numerical Recepies in C, Numerical Recepies in Fortran, Numerical Recepies in C++, Cambridge University Press; die C und Fortran Versionen sind zum Download unter http://www.nr.com/ zu finden. 39 12. Januar 2005 c M.-B. Kallenrode