Ing Mathematik: Numerische Mathematiksysteme am Beispiel von Octave

Aus Wikibooks
Zur Navigation springen Zur Suche springen
Wikibooks buchseite.svg Zurück zu Maxima | One wikibook.svg Hoch zu Gesamtinhaltsverzeichnis |


Hallo Welt und allgemeine Hinweise[Bearbeiten]

Was ist Octave[Bearbeiten]

  • Octave ist eine Software zur numerischen Lösung mathematischer Probleme.
  • Octave ist Open-Source (GPL-Lizenz).
  • Octave ist für viele Betriebssysteme erhältlich (z.B. für Linux, MS Windows, macOS).
  • Octave ist weitgehend kompatibel zum Numerik-Standardprogramm MATLAB.
  • Octave ist ein Interpreter.
  • Octave als Programmiersprache ist case-sensitive - d.h. Groß- und Kleinschreibung ist relevant bei der Eingabe von Befehlen.
Wikipedia hat einen Artikel zum Thema:

.

Octave installieren[Bearbeiten]

MS Windows[Bearbeiten]

Laden Sie das aktuelle Octave-Paket von der Webseite www.gnu.org/software/octave/ herunter. Weiter geht es wie bei jedem anderen größeren zu installierenden Programm. Einfach das Installationsprogramm im Explorer doppelklicken und den Anweisungen des Setup-Programmes folgen.

Linux[Bearbeiten]

Entweder ist Octave bereits standardmäßig installiert, ansonsten ist die Installation mittels Paketmanagementsystem einfach möglich.

Octave starten[Bearbeiten]

MS Windows[Bearbeiten]

Das Icon für das Octave-Programm doppelklicken (für das Konsolenprogramm ... CLI, für die grafische Benutzeroberfläche ... GUI). Und schon startet das Programm.

Octavestart1.jpg

Linux[Bearbeiten]

In einer Linux-Konsole den Befehl "octave" eintippen und das Programm startet.

Ein paar Worte zur Erklärung[Bearbeiten]

Im Folgenden wird immer das Konsolenprogramm (CLI ... Command Line Interface) für die Eingabe von Befehlen benutzt. Erst gegen Ende dieses Textes wird auch kurz auf das GUI von Octave eingegangen.

Teilweise werden Ergebnisse der älteren Octave-Version 3.0.3 dargestellt. Aktuell ist mit Stand Mai 2020 die Version 5.2, die auch mit diesem Text abgedeckt werden soll. Die dargestellten Grafiken können je nach Version leicht voneinander abweichen. Der Text wurde ursprünglich mit der Octave-Version 3.0.3 erstellt und anschließend auf die Version 5.2 aktualisiert. Dieser Mischmasch sollte aber kein Problem darstellen.

Getestet wurden die Beispiele unter dem Betriebssystem MS Windows 10.

Ein erstes Programm[Bearbeiten]

Kommentare werden in Octave mit dem Prozentzeichen (%) oder alternativ mit der Raute (#) eingeleitet. Sie werden vom Octave-Interpreter ignoriert. Text kann mit der disp-Funktion ausgegeben werden. Starten Sie Octave und geben sie folgende Anweisungen zeilenweise ein

octave-3.0.3.exe:1> % Das ist ein Kommentar
octave-3.0.3.exe:2> # und das auch
octave-3.0.3.exe:3> disp "Hallo Welt!"

Als Ergebnis erhalten Sie

Hallo Welt!

Der Prompt (z.B. octave-3.0.3.exe:1>) ist natürlich abhängig von der Octave-Version und den schon eingegebenen Zeilen. Er ist selbstverständlich nicht einzutippen, sondern wird vom Octave-System geliefert.

Strings können in Octave entweder in Anführungszeichen (") gesetzt werden oder in Hochkommatas('). In diesem Text wird die erste Variante bevorzugt eingesetzt.

Octave als Taschenrechner[Bearbeiten]

Allgemeines[Bearbeiten]

Wir wollen 3 * 5 berechnen. Dazu starten wir Octave. Geben Sie dann die Formel

octave-3.0.3.exe:1> 3 * 5

ein, drücken die Taste ENTER/RETURN und erhalten als Ergebnis

ans =  15

Auch kompliziertere Ausdrücke sind möglich. Beispielsweise mit Winkelfunktionen, Quadratwurzeln etc. Wir wollen nun den Ausdruck berechnen :

octave-3.0.3.exe:2> sin(sqrt(15))
ans = -0.66791

Octave kennt eine Handvoll von Konstanten, z.B.:

Zeilenweise Eingabe:

% Die Kreiszahl PI
pi
% Die Eulersche Zahl
e
% Zur Maschinengenauigkeit
eps

Ausgabe:

ans =  3.1416
ans =  2.7183
ans = 2.2204e-016

"ans" steht übrigens für den Begriff "answer" (auf Deutsch "Antwort"). Mit "ans" kann wie mit jeder anderen Variable oder Konstanten weitergerechnet werden, z.B.:

Eingabe:

% Der Kreisradius sei 10
10
% Die Kreisfläche mit diesem Radius sei folgendes
2 * pi * ans 

Ausgabe:

ans =  10
ans =  62.832

Die Ausgabe eines Befehls am Bildschirm (das "Echo") kann übrigens durch Anwendung des Semikolons (;) unterdrückt werden. Gezeigt werden soll dies nun mit Hilfe des obigen Beispiels. Es soll nur der Flächenwert ausgegeben werden, nicht der Radius.

Eingabe:

% Der Kreisradius sei 10
10;
% Die Kreisfläche mit diesem Radius sei folgendes
2 * pi * ans 

Ausgabe:

ans =  62.832

Vielleicht ist manchem die Genauigkeit, mit der Echo bzw. der Befehl disp Werte ausgibt, nicht ausreichend. Dem kann Abhilfe verschafft werden und zwar so:

Eingabe:

format short
pi 

format long
pi

format long E
pi

% usw.

Ausgabe:

ans =  3.1416
ans =  3.14159265358979
ans = 3.14159265358979E+000

Beenden lässt sich das Octave-Programm durch Eingabe von quit oder exit (und natürlich zur Bestätigung die RETURN-Taste drücken).

Die Hilfefunktion von Octave[Bearbeiten]

Die Eingabe von help mit Angabe eines Funktionsnamens liefert detaillierte Infos zu der gesuchten Funktion.

Eingabe:

help sin

Ausgabe:

'sin' is a built-in function from the file libinterp/corefcn/mappers.cc

 -- sin (X)
     Compute the sine for each element of X in radians.

     See also: asin, sind, sinh.

Additional help for built-in functions and operators is
available in the online version of the manual.  Use the command
'doc <topic>' to search the manual index.

Help and information about Octave is also available on the WWW
at https://www.octave.org and via the help@octave.org
mailing list.

Auch gibt es die doc-Funktion für eine vollständige Dokumentation des Octave-Systems, z.B.:

Eingabe:

doc

Ausgabe:

 Next: Preface,  Up: (dir)

GNU Octave (version 5.2.0)
**************************

This manual documents how to run, install and port GNU Octave, as well
as its new features and incompatibilities, and how to report bugs.  It
corresponds to GNU Octave version 5.2.0.

* Menu:

* Preface::
* Introduction::                A brief introduction to Octave.
* Getting Started::
* Data Types::
* Numeric Data Types::
* Strings::
* Data Containers::
* Variables::
* Expressions::
* Evaluation::

etc.

Aufgaben[Bearbeiten]

  • Berechnen Sie mit Octave den Ausdruck .
  • Berechnen Sie mit Octave den Ausdruck . Anmerkung: cosd erwartet den Parameter im Gradmaß (d für "degree"), sin erwartet den Parameter im Bogenmaß.
  • Erkunden Sie die Fehlerfunktion "erf" mittels Octave-Hilfe.

Octave als Scriptsprache[Bearbeiten]

Häufig wird man aber kompliziertere Anweisungsfolgen verarbeiten müssen. Diese will man normalerweise nicht jedesmal neu eingeben, sondern in einer Datei speichern und diese Datei dann zur Ausführung bringen. Speichern Sie dazu folgenden Code in einer Textdatei, z.B. unter MS Windows als c:\tmp\test1.m

% Das ist ein Kommentar
# und das auch
disp "Hallo Welt!"

Skriptdateien müssen mit der Dateiendung .m versehen werden. In der Octave-Konsole fügen Sie den Dateipfad mittels

octave-3.0.3.exe:1> addpath("c:/tmp")

hinzu (es ist der UNIX-spezifische Slash (/) zu benutzen). Alternativ können Sie zumindest unter MS Windows auch einen Doppel-Backslash (\\) einsetzen.

Danach bringen Sie die Skriptdatei test1.m (sozusagen das Hauptprogramm) zur Ausführung

octave-3.0.3.exe:2> test1

Achtung: Die Datei (die Funktion oder das Hauptprogramm) ist in der Octave-Kommandozeile ohne .m-Dateiendung anzugeben. Wie erwartet ergibt sich folgende Ausgabe am Bildschirm

Hallo Welt!

Blockkommentare[Bearbeiten]

In neueren Octave-Versionen sind auch Blockkommentare möglich. Blockkommentare werden wie normale Kommentare vom Octave-Interpreter ignoriert.

%{
  Das ist ein 
  Blockkommentar
%}

#{
  und das auch
#}

Variablen[Bearbeiten]

Variablenbezeichner können aus Buchstaben (A-Za-z), Ziffern (0-9) und Underscores (_) bestehen, dürfen aber nicht mit einer Zahl beginnen.

Gültige Variablenbezeichner wären also:

xyz
x1
_wert
name_anzahl

Da Octave case-sensitiv ist, repräsentieren folgende Bezeichner verschiedene Variablen:

xyz
XYZ
xYz

Werte werden an Variablen mittels Gleich-Zeichen (=) zugewiesen. Im Folgenden wird der Code immer in der Datei c:\tmp\test1.m gespeichert.

x = 5
y = 10
z = x*y

Bringen Sie die Datei test1.m zur Ausführung so erhalten Sie folgende Bildschirmausgabe

x =  5
y =  10
z =  50

Normalerweise will man aber nur z anzeigen, die Werte von x und y sind ja bereits bekannt. Dazu fügen Sie an den Anweisungsenden, wie bereits weiter oben erwähnt, bei x und y jeweils ein Semikolon (;) an, um das Anweisungsende explizit zu markieren.

x = 5;
y = 10;
z = x*y

Nun erhalten Sie als Ergebnis nur noch

z = 50

Sie können auch mehrere Anweisungen in einer Zeile durch Semikolon getrennt schreiben.

x = 5; y = 10; z = x*y

Ausgabe:

z =  50

Auch aus der Programmiersprache C/C++ oder Java bekannte Konstrukte können Sie verwenden, z.B.

x = 5;
% inkrementiere x
++x
% x = x - 2
x -= 2

Bildschirmausgabe:

ans =  6
x =  4

Beachten Sie, dass mit dem =-Zeichen eine Wertezuweisung durchgeführt wird. Dies ist nicht äquivalent zum mathematischen =-Zeichen, wie am vorigen Beispiel zu ersehen ist.

Soll eine Anweisung auf mehrere Zeilen verteilt werden, z.B. weil sie zu lang ist, so kann dies durch Verwendung von drei Punkten (...) geschehen, wie nachfolgend dargestellt.

x = 5;
y = 1000 * x + ...
    sin(x/2)

Ausgabe:

y = 5000.6

Variablen sind nicht an einen bestimmten Datentyp gebunden, folgendes ist in Octave problemlos möglich:

wert = 10
wert = 35.5
wert = "Hallo"
wert = pi

Ausgabe:

wert =  10
wert =  35.500
wert = Hallo
wert =  3.1416

Zahlenkolonnen[Bearbeiten]

Eine Zahlenkolonne (oder ein Vektor) mit gleichen Abständen der Werte kann folgendermaßen erzeugt werden:

% a ... Startwert
% b ... Schrittweite
% c ... Endwert
a = 0;
b = 10;
c = 100;

x = a : b : c;
disp(x); 

Ausgabe:

0   10   20   30   40   50   60   70   80   90  100

Ähnliche Resultate lassen sich auch durch Anwendung der linspace-Funktion erhalten, z.B.:

% a ... Startwert
% b ... Endwert
% c ... Anzahl der Werte
a = 0;
b = 100;
c = 11;
v = linspace(a, b, c)

Ausgabe:

v =

     0    10    20    30    40    50    60    70    80    90   100

Verzweigungen[Bearbeiten]

Die IF-Verzweigung[Bearbeiten]

Die IF-Verzweigung ist aus anderen Programmiersprachen bereits bekannt. In Pseudocode lässt sie sich folgendermaßen darstellen:

WENN bedingung TRUE
  führe block1 aus
SONST
  führe block2 aus
ENDE 

Die test1.m-Datei laute also wie folgt:

x = 5;

if x < 4
  disp "x ist kleiner als 4";
else
  disp "Der else-Zweig wird ausgefuehrt";
  disp "x ist groesser oder gleich 4";  
end

Ausgabe:

Der else-Zweig wird ausgefuehrt
x ist groesser oder gleich 4

Octave kennt eine Reihe von Vergleichs- und Verknüpfungsoperatoren:

  • <, <= ... kleiner (gleich)
  • >, >= ... größer (gleich)
  • == ... gleich
  • ~=, != ... ungleich
  • &, && ... AND
  • |, || ... OR
  • ~, ! ... NOT

Beispielsweise:

a = 5;
b = 9;

if a<=10 & b!=7
  disp("OK");
else
  disp("Nicht OK");
end

Ausgabe:

OK

Die SWITCH-Verzweigung[Bearbeiten]

In Pseudocode:

WECHSLE ZU var
  FALLS wert1 == var
    führe block1 aus
  FALLS wert2 == var
    führe block2 aus
  ...
  SONST
    führe blockn aus
ENDE

Eine Beispielsimplementierung in Octave könnte so aussehen:

x = "g";

switch(x)
  case "k"
    disp("klein");
  case "g"
    disp("gross");
  otherwise
    disp("sonstiges")
end 

Ausgabe:

gross

Schleifen[Bearbeiten]

Die WHILE-Schleife[Bearbeiten]

Die WHILE-Schleife ist kopfgesteuert. Sie funktioniert wie aus anderen Programmiersprachen bekannt.

In Pseudocode:

SOLANGE bedingung TRUE
  führe block aus
ENDE

In Octave:

x = 0;

while x <= 10
  disp(x);
  x++;
end

Ausgabe:

0
 1
 2
 3
 4
 5
 6
 7
 8
 9
 10

Die DO-UNTIL-Schleife[Bearbeiten]

Die DO-UNTIL-Schleife ist fußgesteuert. Beachte: Diese Schleife ist nicht äquivalent zu der aus anderen Programmiersprachen bekannten DO-WHILE-Schleife. DO-WHILE bedeutet "TUE SOLANGE", DO-UNTIL bedeutet "TUE BIS". Sie wird mindestens einmal ausgeführt.

Pseudocode:

 TUE
   führe block aus
 BIS bedingung TRUE

Mittels Octave:

x = 0;

do
  disp(x);
  x++;
until(x >= 5)

Ausgabe:

0
 1
 2
 3
 4

Die FOR-Schleife[Bearbeiten]

for x = 0 : 2 : 10
  disp(x);
end

Ausgabe:

0
 2
 4
 6
 8
 10

Der FOR-Schleifenkopf ist in Form einer Zahlenkolonne folgendermaßen aufgebaut:

for variable = startwert : schrittweite : endwert

Schleifen abbrechen[Bearbeiten]

Zum Abbrechen einer Schleife gibt es den Befehl "break".

for var = 0 : 1 : 100
  disp (var);
  if var == 5
    break;
  end
end

Ausgabe:

0
 1
 2
 3
 4
 5

"continue" setzt mit dem nächsten Schleifendurchlauf fort, z.B.

for var = 0 : 1 : 10
   if var == 5
     continue;
   end
   disp (var);
 end

Ausgabe:

0
 1
 2
 3
 4
 6
 7
 8
 9
 10

Aufgaben[Bearbeiten]

  • Berechnen Sie die Summe der ersten 100 natürlichen Zahlen (bei 1 beginnend)
    • in Form einer WHILE-Schleife
    • in Form einer DO-UNTIL-Schleife
    • in Form einer FOR-Schleife
    • mittels sum-Befehl (siehe dazu auch die von Octave zur Verfügung gestellte Hilfefunktion).

Grafiken zeichnen[Bearbeiten]

2D[Bearbeiten]

Graph einer Funktion[Bearbeiten]

Es soll die cosh-Funktion im Intervall gezeichnet werden. Der Programmcode lautet in der einfachsten Form:

x = -3 : .1: 3;
y = cosh(x);
plot(x,y);
grid on;

Ausgabe:

Octave cosh.jpg

Der Code ist quasi selbsterklärend. x läuft von -3 bis +3. y wird für jeden x-Wert per Formel ausgerechnet. "plot" ist der Zeichenbefehl. "grid on" schaltet ein Zeichengitter ein.

Die Schrittweite 0.1 wurde so gewählt, um einen ausreichend glatten Verlauf des Graphen zu gewährleisten. Das ist immer ein Kompromiss zwischen Berechnungszeit und Ansehnlichkeit. Testen Sie einfach ein paar verschiedene Werte, um ein Gefühl dafür zu zu bekommen.

Ein etwas komplexeres Beispiel ist folgendes

x = -3 : .1: 3;
y = cosh(x) + 2.^x;
plot(x,y);
grid on;

Man beachte den Punkt bei 2.^x (2 hoch x). Vergisst man den Punkt, dann erhält man eine Fehlermeldung (ähnlich dieser):

error: for x^A, A must be square
error: evaluating binary operator `^' near line 2, column 16
error: evaluating binary operator `+' near line 2, column 13
error: evaluating assignment expression near line 2, column 3
error: near line 2 of file `c:/tmp\test1.m'

Ausgabe:

Octave cosh2.jpg

Graphen mehrerer Funktionen und weiteres[Bearbeiten]

Mehrere Graphen lassen sich folgendermaßen in ein Fenster zeichnen:

x = -3 : .1: 3;
y1 = cosh(x) + 2.^x;
y2 = sin(x) .* cos(x);
plot(x,y1, x,y2);
title("Funktionsgraphen");
legend("cosh ...", "sin ...");
xlabel("x");
ylabel("y");
grid on;

Octave cosh14.jpg

Um die Linienstile etwas individueller zu gestalten, ist folgender Programmcode gedacht:

x = -3 : .1: 3;
y1 = cosh(x) + 2.^x;
y2 = sin(x) .* cos(x);
plot(x,y1,"*r", x,y2,"ob");
title("Funktionsgraphen");
legend("cosh ...", "sin ...");
xlabel("x");
ylabel("y");
grid on;

Octave cosh4.jpg

Bei plot kann auch der Linienstil des jeweiligen Graphen angegeben werden, z.B. steht

* für Sternchenlinie
o für Kreise in der Linie
r für rot
b für blau

Ein ähnliches Resultat liefert der Code:

x = -3 : .1: 3;
y1 = cosh(x) + 2.^x;
y2 = sin(x) .* cos(x);
plot(x,y1, "Color", "red", "*", x,y2, "Color", "blue", "o");
title("Funktionsgraphen");
legend("cosh ...", "sin ...");
xlabel("x");
ylabel("y");
grid on;

Will man mehrere Graphen in ein Fenster zeichnen, aber nicht alles in einen plot-Befehl quetschen, so kann die "hold on"-Anweisung die Lösung des Problems sein:

%Lösche alle benutzerdefinierten Variablen aus der Symboltabelle
clear;
%Schließe alle Fenster
close all;
%Lösche Konsolenfenster und setze Cursor zurück
clc;

x = -3 : .1: 3;
y1 = cosh(x) + 2.^x;
y2 = sin(x) .* cos(x);
plot(x,y1, "Color", "red");
hold on;
plot(x,y2, "Color", "blue");
title("Funktionsgraphen");
legend("cosh ...", "sin ...");
xlabel("x");
ylabel("y");
grid on;

Octave coshsin1.jpg

Bei diesem Program wurden auch einige Möglichkeiten (clear, close, clc) gezeigt, um das System aufzuräumen. Ein "hold off" würde natürlich die hold-Funktion wieder ausschalten.

Funktion in Parameterdarstellung[Bearbeiten]

Es soll die archimedische Spirale im Intervall gezeichnet werden.

clear;
close all;
clc;

t = 0 : .1: 6*pi;
x = t .* cos(t);
y = t .* sin(t);
plot(x,y);
grid on;

Octave spirale1.jpg

Diese Darstellung erscheint verzerrt. Will man gleiche Achsenskalierungen, so kann man den axis-Befehl verwenden (axis muss nach plot erscheinen).

t = 0 : .1: 6*pi;
x = t .* cos(t);
y = t .* sin(t);
plot(x,y);
grid on;
axis equal;

Octave spirale222.jpg

Strichstärke[Bearbeiten]

Für manche Zwecke ist es sinnvoll die Strichstärke des Graphen zu erhöhen. Dies kann über den Parameter "LineWidth" der plot-Funktion geschehen.

t = 0 : .1: 6*pi;
x = t .* cos(t);
y = t .* sin(t);
plot(x,y, "LineWidth", 2);
grid on;
axis equal;

Ausgabe:

Octave spirale3.jpg

Beliebigen Text ausgeben[Bearbeiten]

x = -10:0.1:10;
plot (x, sin (x), "LineWidth", 2);
text (2.7, 0.8, "Das ist die sin-Funktion");

Ausgabe:

Octave text1.jpg

Logarithmische Achseneinteilung[Bearbeiten]

x = -3 : .1: 3;
y = cosh(x) + 2.^x;
% Halblogarithmische Darstellung
semilogy(x,y);
grid on;

Ausgabe:

Octave semilog1.jpg

Auch die x-Achse kann mit "semilogx" logarithmisch skaliert werden. Mit "loglog" werden beide Achsen logarithmisch skaliert.

Aufgaben[Bearbeiten]

  • Zeichnen Sie die Strophoide . Das Ganze sollte in etwa so aussehen wie folgende Grafik:

Octave strophoide.jpg

  • Zeichnen Sie die verschlungene Hypozykloide . Das Ganze sollte in etwa so aussehen wie folgende Grafik:

Octave hypozykloide.jpg

  • Testen Sie bei den obigen Übungsaufgaben verschiedene Linienstile und Farben (Hinweis: Siehe dazu auch die Octave-Hilfefunktion für den plot-Befehl).
  • Testen Sie bei den obigen Übungsaufgaben verschiedene Werte für a, c, r und R.
  • Erkunden Sie in der Octave-Hilfe den ezplot-Befehl.

3D[Bearbeiten]

Räumliche Kurven[Bearbeiten]

Mittels "plot3" lassen sich Raumkurven zeichnen.

t = 0 : .1 : 9*pi;
x = cos(t);
y = sin(t);
z = 1.3 .^ t;
plot3(x,y,z);
grid on;

Octave raumkurve1.jpg

Flächen[Bearbeiten]

ezsurf[Bearbeiten]

Die wahrscheinlich einfachste Möglichkeit 3D-Flächen zu erzeugen, besteht in der Verwendung des ezsurf-Befehls. Beachten Sie beim folgenden Beispiel auch wieder den Punkt beim Multiplikationssymbol in der anonymen Funktion. Was eine anonyme Funktion ist, wird weiter hinten in diesem Text erklärt. Fürs Erste reicht es zu wissen, dass die Funktion f(x, y) jeweils im Intervall [0, 10] gezeichnet werden soll.

clear; close all; clc; clf;

f = @(x, y) sin(x) + 3.*cos(y);
ezsurf (f, [0, 10]);

Octave ezsurf1.jpg

Dieses Bild wurde mit der Octave-Version 5.2 erstellt. Es ist im Prinzip identisch zu jenen des folgenden Abschnitts, die mit der Version 3.0.3 erstellt wurden, nur die Farbschattierung ist anders. Ändern lässt sich diese Eigenschaft mit dem colormap-Befehl (siehe Octave-Hilfe).

surf und mesh[Bearbeiten]

Für das Zeichnen von Flächen existiert der surf-Befehl. Der meshgrid-Befehl kreiert ein Netz in der xy-Zeichenebene. Beachten Sie beim folgenden Beispiel auch wieder den Punkt beim Multiplikationssymbol der Formel für z.

x = 0 : .1 : 10;
y = 0 : .1 : 10;
[x_grid, y_grid] = meshgrid(x, y);
z = sin(x_grid) + 3.*cos(y_grid);
surf(x_grid, y_grid, z);

Octave flaeche1.jpg

Auch ein Farbstreifen kann via "colorbar" zur Grafik hinzugefügt werden.

x = 0 : .1 : 10;
y = 0 : .1 : 10;
[x_grid, y_grid] = meshgrid(x, y);
z = sin(x_grid) + 3.*cos(y_grid);
surf(x_grid, y_grid, z);
colorbar("East");

Octave flaeche2.jpg

Das Ganze in Netzdarstellung läßt sich so programmieren:

x = 0 : .2 : 10;
y = 0 : .2 : 10;
[x_grid, y_grid] = meshgrid(x, y);
z = sin(x_grid) + 3.*cos(y_grid);
mesh(x_grid, y_grid, z);

Ausgabe:

Octave mesh1.jpg

Ellipsoide und Kegel[Bearbeiten]

Für das Zeichnen von Kugeln oder Ellipsoiden stellt Octave den "sphere"-Befehl bzw. den "ellipsoid"-Befehl zur Verfügung.

clear; close all; clc;

% Ellipsoiden zeichnen
[x, y, z] = sphere(30);
surf(5*x, 4*y, 3*z); 

hold on;

[x, y, z] = ellipsoid(5, 5, 5, 6, 3, 2, 30); 
surf(x, y, z);

axis equal;

Octave ellipsoid2.jpg

Für Zylinder und Kegel ist der "cylinder"-Befehl zuständig.

clear; close all; clc;

% Kegel und Zylinder zeichnen
[x, y, z] = cylinder([1 2], 100); 
surf(x, y, z*3);

hold on;

[x, y, z] = cylinder([0.5 0.5], 50); 
surf(x+3, y, z*2);

axis equal;

Octave cylinder2.jpg

Aufgaben[Bearbeiten]

  • Zeichnen Sie die räumliche Kurve , , , . Das Ganze sollte etwa wie folgt aussehen:

Octave kurve10.jpg

  • Zeichnen Sie die Fläche . Das Ganze sollte etwa wie folgt aussehen:

Octave flaeche10.jpg

Weiteres[Bearbeiten]

subplot[Bearbeiten]

Zeichnen mit Untergrafiken: Hier wird z.B. ein Fenster mit drei Untergrafiken gezeichnet.

Eingabe:

t = 0 : .5 : 10;

[x_grid, y_grid] = meshgrid(t, t);

subplot(311);
  surf(x_grid, y_grid, sin(x_grid) + cos(y_grid) );

subplot(312);
  surf(x_grid, y_grid, sin(x_grid) + log(y_grid) );

subplot(313);
  surf(x_grid, y_grid, x_grid + cos(y_grid) );

Ausgabe:

Octave subplot2.jpg

Die dreistellige Ziffer beim subplot-Befehl bedeutet folgendes:

  • Die erste Ziffer ist die Zeilenanzahl
  • Die zweite Ziffer ist die Reihenanzahl und
  • Die dritte Ziffer ist der Index.

Nun sei ein Beispiel mit 3x2-Untergrafiken angeführt.

clear;
close all;
clc;

x = 0 : .1 : 10;

subplot(321);
  plot(x, sin(x));
  text(2, -0.5, "Index 1");

subplot(322);
  plot(x, tan(x));
  text(2, 2, "Index 2");

subplot(323); 
  plot(x, cosh(x) );
  text(2, 3000, "Index 3");
 
subplot(324); 
  plot(x, gamma(x) )
  text(2, 100000, "Index 4");

subplot(325); 
  plot(x, log(x) );  
  text(2, 0, "Index 5");

subplot(326); 
  plot(x, exp(x) );
  text(2, 10000, "Index 6");

Ausgabe:

Octave subplot3.jpg

Hier ist sehr gut zu sehen, in welcher Reihenfolge der Index läuft.

figure[Bearbeiten]

Zeichnen in verschiedene Fenster, z.B.

clear;
close all;
clc;

x = 0 : .1 : 10;
y = 0 : .1 : 10;

[x_grid, y_grid] = meshgrid(x, y);

figure(1)
  surf(x_grid, y_grid, sin(x_grid) + cos(y_grid));

figure(2)
  surf(x_grid, y_grid, sin(x_grid) + log(y_grid));

Ausgabe:

Octave figure111.jpg

Linien zeichnen[Bearbeiten]

Zeichnen Sie eine Linie von der Koordinate [-15, 0] zu [15, 5]:

clear;
close all;
clc; 

x = line([-15 15], [0, 5], "Color", "black", "LineWidth", 2);

Ausgabe:

Octave linie1.jpg

Man beachte, dass Octave nicht Punkte P1(x1, y1), P2(x2, y2) erwartet, sondern einen x-Vektor [x1 x2] und einen y-Vektor [y1 y2].

Ein allgemeines Viereck wird z.B. mit folgendem Befehl gezeichnet.

line([-15 15 10 -5, -15], [0, 5, 20, 15, 0], "LineWidth", 2);

Octave viereck2.jpg

Auch dreidimensionale Formen lassen sich mit dem line-Befehl zeichnen:

clear; close all; clc;
line([-15 15 10 -5, -15], [0, 5, 20, 15, 0], [10, 20, 30, 40, 50], "LineWidth", 2);

Octave dreidim2.jpg

Aufgaben[Bearbeiten]

  • Zeichnen Sie mittels "subplot" die Funktionsgrafen in folgender Form in ein Fenster:
    • in 2x2-Darstellung
    • in 1x4-Darstellung.
  • Zeichnen Sie die im obigen Beispiel angegebenen Funktionsgrafen mittels "figure" jeweils in ein eigenes Fenster.

Vektoren und Matrizen[Bearbeiten]

Vektoren[Bearbeiten]

Vektoren sollten jedem aus der Linearen Algebra bekannt sein.

Zeilen- und Spaltenvektoren[Bearbeiten]

% Ein Zeilenvektor
v1 = [1, 2, 3]

% Ein Spaltenvektor
v2 = [6; 7; 8]

Ausgabe:

v1 =

   1   2   3

v2 =

   6
   7
   8

Alternative Schreibweisen:

% Ein Zeilenvektor
v1 = [1 2 3]

% Ein Spaltenvektor
v2 = [6
      7
      8]

Die Ausgabe entspricht der obigen Darstellung.

Zugriff auf Vektorelemente[Bearbeiten]

Nachfolgend seien einige Zugriffsmöglichkeiten auf die einzelnen Vektorelemente erläutert.

Auf ein einzelnes Element kann via Index zugegriffen werden. Der Index startet bei 1:

v1 = [1 2 4 8 16];
v2 = v1(3)

Ausgabe:

v2 =  4

Mehrere Elemente werden folgendermaßen angesprochen:

v1 = [1 2 4 8 16];
v2 = v1(3:4)

Ausgabe:

v2 =

  4   8

Liefere den Teilvektor von einem gegebenen Index bis zum letzten Element:

v1 = [1 2 4 8 16];
v2 = v1(3:end)

Ausgabe:

v2 =

   4    8   16

Addition und Subtraktion von Vektoren[Bearbeiten]

v1 = [1, 2, 3];
v2 = [5, 7, 9];

res = v1 + v2
res = v1 - v2

Ausgabe:

res =

    6    9   12

res = 

  -4  -5  -6

Multiplikation mit Skalaren[Bearbeiten]

faktor = 3
v = [1, 2, 3];
res = faktor * v

Ausgabe:

res =

   3   6   9

Skalarprodukt[Bearbeiten]

Das Skalarprodukt ist bekanntermaßen als definiert. In Octave sieht das so aus:

v1 = [1, 2, 3];
v2 = [5, 6, 7];
res = dot(v1, v2)

Ausgabe:

res =  38

Vektorprodukt[Bearbeiten]

v1 = [1, 2, 3];
v2 = [5, 6, 7];
res = cross(v1, v2)

Ausgabe:

res =

  -4   8  -4

Enger an die mathematische Darstellung lehnt sich folgender Code an. Die zu multiplizierenden Vektoren seien in Form von Spaltenvektoren gegeben.

Mathematisch:

Octave-Code:

a  = [1
      2
      3];
 
b  = [5
      6
      7];

res = cross(a, b)

Ausgabe:

res =

  -4
   8
  -4

Transponierter Vektor[Bearbeiten]

v1 = [1, 2, 3];
v2 = [5; 6; 7];
res1 = v1'
res2 = v2'

Ausgabe:

res1 =

   1
   2
   3

res2 = 

   5   6   7

Einige weitere Vektorfunktionen[Bearbeiten]

Beispiel:

% 1 + 2 + 3
v = [1 2 3];
sum(v)

Ausgabe:

ans = 6

Beispiel:

% 1 * 2  * 3 * 4
v = [1 2 3 4];
prod(v)

Ausgabe:

ans = 24

Beispiel:

% 1^2 + 2^2 + 3^2
v = [1 2 3];
sumsq (v)

Ausgabe:

ans = 14

Matrizen[Bearbeiten]

Gegeben sei folgende 2x3-Matrix .

Eingabe:

m = [1, 2, 3; 4, 5, 6]

Ausgabe:

m =

   1   2   3
   4   5   6

Alternativ und anschaulicher kann diese 2x3-Matrix auch so eingegeben werden:

m = [1 2 3
     4 5 6]

Dies ist schon sehr nahe an der mathematischen Darstellungsweise.

Zugriff auf Matrizenelemente[Bearbeiten]

m = [1 2 3
     4 5 6];

% Element aus Zeile 2 und Spalte 3
m(2,3)

Ausgabe:

ans =  6

Eine andere Zugriffsmöglichkeit ist diese:

m = [1 2 3
     4 5 6];

% Auf das fünfte Element soll zugegriffen werden
m(5)

Ausgabe:

ans =  3

Die Matrix wird also spaltenweise durchlaufen (nicht zeilenweise). Dies ist vielleicht auf den ersten Blick etwas ungewöhnlich, wird aber z.B. auch in Fortran so gehandhabt.

Auch Teilmatrizen können einfach gebildet werden:

m = [1 2 3
     4 5 6];

m(2:end, 2:end)

Ausgabe:

ans =

   5   6

Siehe zu diesem Thema auch etwas weiter hinten in diesem Text den Abschnitt "Teilmatrizen".

Addition und Subtraktion von Matrizen[Bearbeiten]

m1 = [1, 2, 3; 4, 5, 6];
m2 = [-4, -2, 0; 2, 4, 6];
m1 + m2
m1 - m2

Ausgabe:

ans =

   -3    0    3
    6    9   12

ans =

   5   4   3
   2   1   0

Transponierte Matrix[Bearbeiten]

m = [1, 2, 3; 4, 5, 6];
m'

Ausgabe:

ans =

  1   4
  2   5
  3   6

Rang einer Matrix[Bearbeiten]

Der Rang einer Matrix Rg(M) ist die maximale Anzahl der linear unabhängigen Zeilenvektoren (Spaltenvektoren).

m1 = [1, 2, 3; 4, 5, 6];
m2 = [1, 2; 2, 4];
rank(m1)
rank(m2)

Ausgabe:

ans =  2
ans =  1

Regulär ist eine nxn-Matrix, wenn der Rg(M) = n. D.h. die erste Matrix m1 ist regulär, die zweite m2 singulär.

Inverse Matrix[Bearbeiten]

m1 = [1, 3; 0, -5 ];
m2 = [1, 2; 2, 4];
inv(m1)
inv(m2)

Ausgabe:

ans =

   1.00000   0.60000
   0.00000  -0.20000

warning: inverse: matrix singular to machine precision, rcond = 0
ans =

   Inf   Inf
   Inf   Inf

Die Matrix m2 in diesem Beispiel ist singulär (d.h. die Determinante ist 0). Determinanten werden etwas weiter unten in diesem Text behandelt. Inf steht für Infinity (= Unendlich).

Multiplikation von Matrizen (falksches Schema)[Bearbeiten]

m1 = [1, 3, 4; 0, -5, 1];
m2 = [1, 2; 2, 3; 0, 2];
m1 * m2

Ausgabe:

ans =

    7   19
  -10  -13

Determinante einer Matrix[Bearbeiten]

m1 = [1, 3; 0, -5 ];
m2 = [1, 2; 2, 4];
det(m1)
det(m2)

Ausgabe:

ans = -5
ans = 0

m1 ist regulär, m2 ist singulär. Determinanten können nur von quadratischen Matrizen gebildet werden.

Teilmatrizen[Bearbeiten]

m = [1, 2, 3; 0, 5, 1];

% Die Matrix in einen Spaltenvektor umwandeln
m1 = m(:)

% Das Element aus der 1. Zeile und der 2. Spalte extrahieren
m2 = m(1,2)

% Erste Zeile extrahieren
m3 = m(1, 1:3)
m4 = m(1, :)

% Zweite Spalte extrahieren
m5 = m(1:2, 2)
m6 = m(:, 2)

Ausgabe:

m1 = 

   1
   0
   2
   5
   3
   1 

m2 =  2
m3 =

   1   2   3

m4 =

   1   2   3

m5 =

   2
   5

m6 =

   2
   5

Einheitsmatrizen[Bearbeiten]

eye(3,2)

Ausgabe:

ans =

   1   0
   0   1
   0   0

Nullmatrizen[Bearbeiten]

zeros(2,3)

Ausgabe:

ans =

   0   0   0
   0   0   0

Diagonalmatrizen[Bearbeiten]

diag([1, 2, 3])

Ausgabe:

ans =

   1   0   0
   0   2   0
   0   0   3

Spur einer Matrix[Bearbeiten]

trace([1,2,3; 6,9, 0])

Ausgabe:

ans =  10

LR-Zerlegung einer Matrix[Bearbeiten]

Führen Sie die LR-Faktorisierung (LR ... links/rechts bzw. LU ... left/upper) einer Matrix m aus. l sei die linke Dreiecksmatrix, r die rechte Dreiecksmatrix und p die Permutationsmatrix

m = [1  0  5
     -1 1  -2
     0  0  3];
    
[l, r, p] = lu(m)

Ausgabe:

l =

   1   0   0
  -1   1   0
   0   0   1

r =
 
   1   0   5
   0   1   3
   0   0   3

p = 

   1   0   0
   0   1   0
   0   0   1

Eigenwerte[Bearbeiten]

a = [5 8
     1 3];

% Eigenvektoren und Eigenwerte 
[ev, ew] = eig(a)

Ausgabe:

ev =

   0.97014  -0.89443
   0.24254   0.44721

ew =

   7   0
   0   1

Die Eigenwerte sind hier und . Die Eigenvektoren sind [0.97014 0.24254] bzw. [-0.89443 0.44721]. Da das Gleichungssystem singulär ist, sind alle Lösungsvektoren Vielfache dieser Eigenvektoren.

Schwach besetzte Matrizen[Bearbeiten]

Wikipedia hat einen Artikel zum Thema:


Gegeben sei die schwach besetzte Matrix

m = [0  1  0  0  0
     0  0  0  3  0
     4  0  0  2  0
     0  0  1  0  0
     0  0  0  1  7]

Mittels dem sparse-Befehl kann man einfach die Elemente != 0 nach folgendem Schema eingeben.

sparse ([zeilenindizes] [spaltenindizes] [werte])

also in unserem Fall:

ms = sparse([1 2 3 3 4 5 5], [2 4 1 4 3 4 5], [1 3 4 2 1 1 7])

Ausgabe:

ms =

Compressed Column Sparse (rows = 5, cols = 5, nnz = 7)

  (3, 1) ->  4
  (1, 2) ->  1
  (4, 3) ->  1
  (2, 4) ->  3
  (3, 4) ->  2
  (5, 4) ->  1
  (5, 5) ->  7

Die volle Matrix erhält man mit dem Befehl full:

m = full(ms)

Ausgabe:

m =

   0   1   0   0   0
   0   0   0   3   0
   4   0   0   2   0
   0   0   1   0   0
   0   0   0   1   7

Grafisch anzeigen lassen kann man sich die Besetzung von Matrizen mit dem spy-Befehl:

spy(ms);

oder (für allgemeine Matrizen auch mittels)

spy(m);

Ausgabe:

Octave sparse1.jpg

Wirklich interessant ist der spy-Befehl für größere Matrizen, z.B. um die Bandstruktur zu visualisieren.

e = eye(200);
es = sparse(e);

% Auf sparse-Matrizen kann genauso zugegriffen werden wie auf normalen Matrizen
es(100, 15) = 100;

spy(es);

Ausgabe:

Octave sparse2.jpg

Matrizen mit Zufallswerten[Bearbeiten]

Insbesondere für Testzwecke kann es manchmal sinnvoll sein größere Matrizen mit Zufallswerten zu bilden. Dazu stellt Octave u.a. den rand-Befehl zur Verfügung.

m = rand(5, 6)

Ausgabe:

 m =

   0.86605   0.61108   0.71347   0.97119   0.52428   0.21993
   0.74059   0.49062   0.56073   0.68592   0.74737   0.62680
   0.20790   0.84874   0.36834   0.31102   0.25813   0.28933
   0.84732   0.98777   0.91512   0.42240   0.87891   0.63757
   0.76823   0.80367   0.24639   0.78208   0.77170   0.95281

Die Zufallszahlen liegen gleichverteilt zwischen 0 und 1 und werden nach dem Mersenne-Twister-Verfahren mit einer Periode von gebildet.

Andere Verfahren sind:

  • randn: Normalverteilte Pseudozufallselemente mit Mittelwert=0 und Varianz=1
  • rande: Exponentialverteilte Zufallselemente
  • randg: Gammaverteilte Zufallselemente
  • randp: Poissonverteilte Zufallselemente

Details dazu siehe in der Octave-Hilfefunktion.

Aufgaben[Bearbeiten]

  • Berechnen Sie den Winkel zwischen den beiden Vektoren a = [1 2 0] und b = [2 1 1]. Hinweis: Siehe diesbezüglich auch im Oktave-Hilfesystem den Befehl "norm".
  • Gegeben seien Vektoren a = [1 2 5], b = [0 0 -1] und c = [-1 -2 2]. Berechnen Sie das Spatprodukt aus diesen drei Vektoren.
  • Multiplizieren Sie die beiden Matrizen A und B (mit Octave und zur Kontrolle händisch)
A = [0 0 1
     1 2 1]
B = [1 1
     1 2
     0 4]
  • Ist die Matrix C regulär? Wenn ja, dann bilden Sie die inverse Matrix.
C = [-1 0 0 -4
      2 0 1  5
      7 6 2  0
      3 0 2  6]
  • Ist die Matrix D regulär? Wenn ja, dann bilden Sie die inverse Matrix.
D = [2 1 0 0
     0 0 2 1
     0 0 0 2
     1 1 0 0]
  • Berechnen Sie die Konditionszahl der folgenden Matrix. Hinweis: Siehe diesbezüglich im Oktave-Hilfesystem den Befehl cond
[3  4 -5
 6  0  3
 1  1  2]
  • Berechnen Sie die Eigenwerte und Eigenvektoren der folgenden Matrix
[6 -3   4  0
 0  7  -1  1
 0  10 -3 -2
 0  1  -2  1]

Komplexe Zahlen[Bearbeiten]

Die imaginäre Einheit wird in Octave durch den Buchstaben i, j, I oder J symbolisiert. Darstellen kann man eine komplexe Zahl bekannterweise in mehreren Formen:

  • Kartesische Darstellung
  • Polardarstellungen z =

Die konjugiert komplexe Zahl ist

Mit komplexen Zahlen rechnen[Bearbeiten]

z1 = 2 + 5i;        % kartesische Darstellung
z2 = 3 * exp(3j);   % Polardarstellung

% Addition
res = z1 + z2;
disp("z1 + z2 = "); disp(res);

% Multiplikation
res = z1 * z2;
disp("z1 * z2 = "); disp(res);

% Realteil
res = real(z2);
disp("Realteil von z2 = "); disp(res);

% Imaginärteil
res = imag(z2);
disp("Imaginaerteil von z2 = "); disp(res);

% Betrag
res = abs(z1);
disp("Betrag von z1 = "); disp(res);

% Argument
res = angle(z1);
disp("Argument von z1 = "); disp(res);

% Konjugiert komplexe Zahl
res = conj(z1);
disp("Konjugiert komplexe Zahl von z1 = "); disp(res);

Ausgabe:

z1 + z2 =
-0.96998 + 5.42336i
z1 * z2 =
 -8.0568 - 14.0032i
Realteil von z2 =
-2.9700
Imaginaerteil von z2 =
 0.42336
Betrag von z1 =
 5.3852
Argument von z1 =
 1.1903
Konjugiert komplexe Zahl von z1 =
 2 - 5i

Die gaußsche Zahlenebene[Bearbeiten]

clear; close all; clc;

z1 = 3 + 5i;
z2 = 5 * exp(0.5i);
hold on;
plot(z1, "*");
compass(z1);
plot(z2, "o");
compass(z2);
grid on;

Octave komplex1.jpg

Aufgaben[Bearbeiten]

  • Berechnen Sie die Quadratwurzel der komplexen Zahl .
  • Verwandeln Sie folgende Zahlen in die Polarkoordinatendarstellung: und
  • Verwandeln Sie folgende Zahlen in die Normaldarstellung: und
  • Zeichnen Sie die Zahl in der gaußschen Zahlenebene als Zeiger.

Funktionen[Bearbeiten]

Um Programme zu strukturieren und einfacher zu gestalten können Programmteile in Funktionen ausgelagert werden. Eingebaute Funktionen haben wir schon kennengelernt (z.B. die Sinus-Funktion sin). Nun wollen wir sehen, wie man selbst solche Funktionen schreiben kann.

Eine einfache Funktion schreiben[Bearbeiten]

Datei addiere.m:

function res = addiere(a, b)
  % Addiere zwei Zahlen a + b
  res = a + b;
end

Datei test1.m:

addiere(10, 15)

Ausgabe:

ans =  25
  • Jede Funktion sollte in einer eigenen m-Datei stehen.
  • Der Dateiname sollte mit dem Funktionsnamen (natürlich ohne Dateiendung .m) übereinstimmen.
  • Der Kommentar unter dem Funktionskopf wird als Hilfstext angezeigt, wenn die help-Funktion (hier "help addiere") aufgerufen wird.

Inline-Funktionen[Bearbeiten]

Kurze Funktionen können auch als Inline-Funktionen geschrieben werden.

addiere = inline("a + b");
x = 5;
y = 10;
z = addiere(x, y)

Oder in diesem Fall noch kürzer

addiere = inline("a + b");
z = addiere(5, 10)

Ausgabe:

z =  15

Funktionsstring[Bearbeiten]

addiere = "a + b";
a = 5;
b = 10;
z = eval(addiere)

Ausgabe:

z =  15

Anonyme Funktionen[Bearbeiten]

Wikipedia hat einen Artikel zum Thema:


addiere = @(a, b) a + b;
x = 10;
y = 20;
z = addiere(x, y)

oder kürzer

addiere = @(a, b) a + b;
z = addiere(10, 20)

Ausgabe:

z =  30

Nullstellen von Funktionen bestimmen[Bearbeiten]

sinh2 = @(x) sinh(x) + 2;
z = fzero(sinh2, 1)

Ausgabe:

z = -1.4436

Zur Kontrolle soll hier der Graph der Funktion dargestellt werden

clear;
close all;
clc;

sinh2 = @(x) sinh(x) + 2;

x = -2 : 0.1 : 0;
y = sinh2(x);
z = fzero(sinh2, 1)

plot(x, y);
hold on;
plot(z, 0, "o", "Color", "red", "LineWidth", 2);

text (-1.8, 0.8, "Nullstelle");
line([z -1.7], [0, .7], "Color", "black");

grid on;

Ausgabe:

Octave funktion5.jpg

Weiter unten im Text wird die ähnliche Funktion "fsolve" beschrieben. "fzero" benutzt zwei verschiedene Funktionen zur Problemlösung, darunter eben auch "fsolve".

Für die Nullstellenbestimmung von Polynomen gibt es die Funktion "roots". Näheres dazu folgt im nächsten Kapitel.

Globale Variablen[Bearbeiten]

Datei addiere.m:

function res = addiere()
  global a b;  
  res = a + b;
end

Datei test1.m:

clear;
close all;
clc;

global a b;

a = 5; 
b = 3;
 
addiere() 

Ausgabe:

ans =  8

Aufgaben[Bearbeiten]

  • Schreiben Sie eine Funktion "ellipse", welche eine Ellipse am Bildschirm darstellt. Zur Erinnerung: Die Parameterdarstellung der Ellipse lautet , Funktionsargumente seien a und b.
  • Schreiben Sie
    • als normale Funktion
    • als Funktionsstring
    • als Inlinefunktion
    • als anonyme Funktion
    • stellen Sie dieses Funktion grafisch am Bildschirm dar.

Polynome[Bearbeiten]

Einzelne Polynomwerte berechnen[Bearbeiten]

% y = 2*x^3 + 5*x^2 + 4 für x = 2 berechnen
p = [2, 5, 0, 4];
polyval(p, 2)

Ausgabe:

ans =  40

Polynome zeichnen[Bearbeiten]

% y = 2*x^3 - 5*x^2 + 4 für das Intervall -5 <= x <= 5 grafisch darstellen
x = -5 : .1 : 5;
p = [2, 5, 0, 4];
y = polyval(p, x);
plot(x,y);
grid on;

Ausgabe:

Octave polynom1.jpg

Nullstellen bestimmen[Bearbeiten]

Für Polynome existiert die Funktion "roots" zur Nullstellenbestimmung.

% Nullstellen für y = 2*x^3 - 5*x^2 + 4 bestimmen
p = [2, 5, 0, 4];
r = roots(p)

Ausgabe:

r =

  -2.76214 + 0.00000i
   0.13107 + 0.84077i
   0.13107 - 0.84077i

Dieses Polynom hat nur eine reelle Nullstelle. Diese liegt, wie am obigen Grafen zu ersehen ist, in der Nähe von -2.762. Die beiden anderen Nullstellen sind konjugiert komplex zueinander (wie es auch sein sollte).

Aufgaben[Bearbeiten]

  • Berechnen Sie den Wert für x = 3 des Polynoms .
  • Berechnen Sie die Nullstellen von .
  • Zeichnen Sie das Polynom im Intervall .

Lineare Gleichungssysteme[Bearbeiten]

Sei ein lineares Gleichungssystem. sei die Koeffizientenmatrix, der Lösungsvektor und ein bekannter Vektor.

Einfache Berechnung mittels Gauß-Verfahren[Bearbeiten]

Wikipedia hat einen Artikel zum Thema:


Beispiel:

A = [5 1
     0 2];
b = [1
     2];   
x = A \ b

Ausgabe:

x =

   0
   1

Das gmres-Verfahren[Bearbeiten]

gmres steht für Generalized Minimal Residual.

Wikipedia hat einen Artikel zum Thema:


A = [5 1
     0 2];
b = [1
     2];   
x = gmres(A, b)

Ausgabe:

gmres converged at iteration 2 to a solution with relative residual 2.22045e-16
x =

  -1.6653e-16
   1.0000e+00

Das Ergebnis weicht etwas vom gaußschen Verfahren ab, ist aber trotzdem im Rahmen der Näherung korrekt.

Weiters kennt Octave noch andere iterative Verfahren, z.B. cgs (Conjugate Gradient Squared) oder bicgstab (Bi-Conjugate Gradient Stabilized). Näheres zu diesen Verfahren siehe in der weiterführenden Literatur (z.B. bei Meister: Numerik linearer Gleichungssysteme, Vieweg+Teubner, 2011)

Wikipedia hat einen Artikel zum Thema:


Aufgabe[Bearbeiten]

  • Lösen Sie folgendes Gleichungssystem mittels Octave (und zur Kontrolle auch händisch):
5x + 6y - 2z = 12
3x - y  - 3z = 6
2x + 2y + 4z = 5

Nichtlineare Gleichungssysteme[Bearbeiten]

fsolve[Bearbeiten]

Löse eine beliebige Gleichung f(x) = 0, z.B. :

f = @(x) x^2 - 5*cos(x) - 10;
xstart = 1;
[x, fval, info] = fsolve(f, xstart)

Ausgabe:

x =  2.4681
fval = -1.7764e-015
info =  1
  • x ist eine Nullstelle in der Nähe vom Startwert xstart.
  • fval ist die Abweichung, den f bei x aufweist.
  • info ist ein "Fehlercode": 1 bedeutet, dass der relative Fehler in der spezifizierten Toleranz liegt (wie es sein soll). 3 würde bedeuten, dass der Algorithmus nicht konvergiert (z.B. weil keine Nullstelle existiert).

Zur Kontrolle plotten wir den Funktionsgraphen:

x = - 1 : .1 : 3;
y = x.^2 - 5.*cos(x) - 10;
plot(x,y, "LineWidth", 2);
grid on;

Ausgabe:

Octave nichtlin1.jpg

Und siehe da, die gesuchte Nullstelle liegt wie berechnet bei einem Wert nahe 2,5. Die Funktion hat noch eine zweite Nullstelle, wie in der folgenden Abbildung zu erkennen ist.

Octave nichtlin2.jpg

Diese zweite Nullstelle erhalten wir, wenn der Startwert in der Nähe dieser zweiten Nullstelle liegt, als z.B. bei -1. Ändern Sie einfach den entsprechenden Startwert im obigen Programmcode, und das Programm sollte die Nullstelle in der Nähe von -2.5 liefern.

Gleichungssysteme[Bearbeiten]

Folgende Aufgabe ist dem Buch "Knorrenschild: Numerische Mathematik, Hanser, 2017, Seite 72" entnommen. Zu lösen ist das nichtlineare Gleichungssystem

Lösung:

f.m:

function y = f(x)
  y(1) = 2*x(1) + 4*x(2);
  y(2) = 4*x(1) + 8*x(2)^3;
end

test1.m:

clear;
close all;
clc;

[x, fval, info] = fsolve (@f, [0, 1])
[x, fval, info] = fsolve (@f, [0, -1])
[x, fval, info] = fsolve (@f, [0, 0])

Ausgabe:

x =
   -2
   1

fval =
   0
   0

info =  1

x =
   2
  -1

fval =
   0
   0

info =  1

x =
   0
   0

fval =
   0
   0

info =  1

Aufgaben[Bearbeiten]

  • Bestimmen Sie die Nullstellen von . Plotten Sie den Grafen.
  • Bestimmen Sie die Nullstelle von . Plotten Sie den Grafen.
  • Lösen Sie das folgende Gleichungssystem (und stellen Sie das Ganze grafisch am Bildschirm dar):

Interpolation[Bearbeiten]

Eindimensionale Interpolation[Bearbeiten]

Wikipedia hat einen Artikel zum Thema:


Bezüglich eindimensionaler Interpolation sei auf die Octave-Dokumentation und Hilfefunktion zum Befehl " interp1" verwiesen. Dort findet sich auch ein Programmbeispiel, das als Grundlage des folgenden Plots dient:

Octave interpol1.jpg

Mehrdimensionale Interpolation[Bearbeiten]

Bezüglich mehrdimensionaler Interpolation siehe die Hilfefunktion zu "interp2", "interp3" und "interpn".

Aufgabe[Bearbeiten]

  • Gegeben seinen die fünf Stützpunkte p1 = [1, 0], p2 = [2, -5], p3 = [3, 2], p4 = [4, 7], p5 = [5, 6]. Legen Sie eine Funktion (die Interpolierende) durch diese Stützpunkte. Eine Lösungsmöglichkeit:
xp = [1 2 3 4 5]; 
yp = [0, -5, 2, 7, 6];
xf = 1 : .1 : 5; 

spl = interp1(xp, yp, xf, "spline");
pch = interp1(xp, yp, xf, "pchip");

plot(xp, yp, "or", "LineWidth", 2, xf, spl, "LineWidth", 2, ...
     xf, pch, "LineWidth", 2);
legend("stuetzpunkte", "spline", "pchip", "location", "southeast");

Octave interpol3.jpg

Differenzialrechnung[Bearbeiten]

Polynome differenzieren[Bearbeiten]

Es soll das Polynom differenziert werden.

% Diffenzieren des Polynoms y = 2*x^3 - 5*x^2 + 7
p = [2, -5, 0, 7];
polyder(p)

Ausgabe:

ans =

    6  -10    0

D.h. also, die Ableitung von ist .

Sonstige Funktionen differenzieren[Bearbeiten]

Als Beispiel differenzieren wir und stellen das Ganze grafisch dar.

clear;
close all;
clc;

x = 0 : 0.01 : 10; 

y = 5 .* x .* sin(x);
y_strich = diff(y) / 0.01;

plot(x, y, "Color", "red", "LineWidth", 2);

hold on;

plot(x(1:length(x)-1), y_strich,  "Color", "blue", "LineWidth", 2);

legend("y", "y'");

grid on;

Ausgabe:

Octave diff1.jpg

diff(y) ist der Vektor aus den Differenzen y(2)-y(1), ..., y(n)-y(n-1). Für die genaue Arbeitsweise der diff-Funktion siehe "help diff".

Aufgaben[Bearbeiten]

  • Differenzieren Sie das Polynom .
  • Differenzieren Sie die Funktion und stellen Sie y, sowie y' grafisch am Bildschirm dar.
  • Differenzieren Sie die Funktion und stellen Sie y, sowie y' grafisch am Bildschirm dar.

Integralrechnung[Bearbeiten]

Polynome integrieren[Bearbeiten]

Berechnen Sie das unbestimmte Integral von

p = [2, -7, 0, 7];
p_int = polyint(p)

Ausgabe:

p_int =

   0.50000  -2.33333   0.00000   7.00000   0.00000

Das Ergebnis lautet also (auf die Integrationskonstante C darf nicht vergessen werden!).

Gauß-Quadratur[Bearbeiten]

Wikipedia hat einen Artikel zum Thema:


Berechnen Sie das Integral mittels Gauß-Quadratur.

Datei f.m:

function y = f(x)
  y = x^2;
end


Datei test1.m:

[v, ier, nfun, err] = quad ("f", 0, 3)

Ausgabe:

v =  9.0000
ier = 0
nfun =  21
err = 9.9920e-014

Erläuterung zur Ausgabe:

  • v ... Resultat der Integration
  • ier ... integer error code
  • nfun ... Anzahl der Funktionsaufrufe
  • err ... Fehler in der Lösung

Quadratur mittels adaptiver Lobatto-Regel[Bearbeiten]

Berechnen Sie diesmal das Integral mittels Lobatto-Quadratur.

f = inline("x.^2");
v = quadl (f, 0, 3)

Ausgabe:

v =  9

Zwecks Übung sei nachfolgend nochmals dieses Beispiel berechnet. Diesmal wird aber eine anonyme Funktion verwendet.

v = quadl (@(x) x.^2, 0, 3)

Aufgaben[Bearbeiten]

  • Integrieren Sie das Polynom .
  • Integrieren Sie die Funktion von -5 bis 5.
  • Integrieren Sie die Funktion von 0 bis 4. Verwenden Sie hierzu die Simpsonregel (siehe dazu in der Hilfefunktion den Befehl "quadv").

Gewöhnliche Differenzialgleichungen[Bearbeiten]

ode23, ode45 und lsode[Bearbeiten]

Für die Lösung von Differenzialgleichungen stehen die Funktionen

  • ode23

bzw.

  • ode45

zur Verfügung. Diese Funktionen implementieren das Runge-Kutta-Verfahren. "ode" steht für "Ordinary Differential Equation" (also auf Deutsch für "Gewöhnliche Differentialgleichung"). Die Zahlen bei ode23 oder ode45 stehen für die Ordnung.

Wikipedia hat einen Artikel zum Thema:


Beispiel :

clear;
close all;
clc;

[x, y] = ode45(@(x,y) (x^2+y^3), [0 1], 0);
plot(x, y, "LineWidth", 2);

Ausgabe:

Octave ode1.jpg

Bezüglich der genauen Funktionsweise von "ode45" (oder "ode23") siehe die Octave-Hilfe.

Auch die Funktion "lsode" steht zur Lösung von ODEs zur Verfügung.

Beispiel :

clear;
close all;
clc;

t = 0 : .1 : 5;

[y2, istate, msg] = lsode(@(x,y) (x + y), 1, t);
istate
msg
plot(t, y2);

Ausgabe:

istate =  2
msg = successful exit

Octave lsode1.jpg

Bezüglich der genauen Funktionsweise von "lsode" siehe die Octave-Hilfe.

Aufgaben[Bearbeiten]

  • Lösen Sie die Differenzialgleichung mit Octave. Kontrollieren Sie das Ergebnis, indem Sie die DGl händisch lösen.
  • Lösen Sie die Differenzialgleichung . Kontrollieren Sie das Ergebnis, indem Sie die DGl händisch lösen.
  • Lösen Sie die Differenzialgleichung .

Die Fast-Fourier-Transformation[Bearbeiten]

Wikipedia hat einen Artikel zum Thema:


Für die Funktion "fft" siehe das Octave-Hilfesystem.

Mengenrechnung[Bearbeiten]

Vereinigungsmenge[Bearbeiten]

v1 = [1 2 3 4];
v2 = [2 4 6];
union(v1, v2)

Ausgabe:

ans =

   1   2   3   4   6

Schnittmenge[Bearbeiten]

v1 = [1 2 3 4];
v2 = [2 4 6];
intersect(v1, v2)

Ausgabe:

ans =

   2   4

Stochastik[Bearbeiten]

Deskriptive Statistik[Bearbeiten]

Lageparameter[Bearbeiten]

Arithmetischer Mittelwert:

vec = [1 2 3 4 5 12 13];
mw = mean(vec)

Ausgabe:

mw =  5.7143

Geometrischer Mittelwert:

vec = [1 2 3 4 5 12 13];
mw = mean(vec, "g")

Ausgabe:

mw =  4.0769

Harmonischer Mittelwert:

vec = [1 2 3 4 5 12 13];
mw = mean(vec, "h")

Ausgabe:

mw =  2.8646 

Der Median oder Zentralwert läßt sich folgendermaßen berechnen:

vec = [1 2 3 4 5 12 13];
median(vec)

Ausgabe:

mw = 4

Der Modus oder häufigste Wert läßt sich mittels "mode"-Funktion eruieren:

vec = [1 2 1 3 5 1 2 7];
[m, f, c] = mode (vec);
disp(m);
disp(f);
disp(c);

Ausgabe:

 1
 3
{
  [1,1] =  1
}

m (erste Zeile der Ausgabe) ist der Modus. f (zweite Zeile) ist die Häufigkeit. Näheres dazu siehe im Octave-Hilfesystem.

Streuungsparameter[Bearbeiten]

Varianz:

vec = [1 2 3 1 1 6 7];
v = var(vec)

Ausgabe:

v =  6.3333

Standardabweichung:

vec = [1 2 3 1 1 6 7];
s = std(vec)

Ausgabe:

s =  2.5166

Zweidimensionale Häufigkeitsverteilungen[Bearbeiten]

Kovarianz:

v1 = [1 2 3 1 1 6 7];
v2 = [7 9 6 2 5 9 6];
c = cov(v1, v2)

Ausgabe:

c =  2.3333

Korrelation:

v1 = [1 2 3 1 1 6 7];
v2 = [7 9 6 2 5 9 6];
c = corr(v1, v2)

Ausgabe:

c =  0.38156

Grafiken erzeugen[Bearbeiten]

Histogramme:

v = [1 1 2 3 1 6 7 6 1 1 1 2];
hist(v, max(v));

Ausgabe:

Octave histo2.jpg

Balkendiagramme:

v = [1 1 2 3 1 6 7 6];
bar(v);

Ausgabe:

Octave bar111.jpg

Treppendiagramm:

v = [1 1 2 3 1 6 7 6];
stairs(v);

Ausgabe:

Octave stairs1.jpg

Stabdiagramm:

v = [1 1 2 3 1 6 7 6];
stem(v);

Ausgabe:

Octave stem1.jpg

Aufgaben[Bearbeiten]

Gegeben sei folgende Datentabelle mit den Werten:

v1 = [3 4 1 1 7 2 1 9 2 5 9 7 2 2 9 2 2 1 2 8]
v2 = [1 1 0 2 3 4 1 2 7 0 2 1 5 5 5 4 5 2 5 0]
  • Berechnen Sie die Lageparameter und Streuungsparameter des Vektors v1.
  • Berechnen Sie Kovarianz und Korrelationskoeffizient der beiden zugeordneten Vektoren v1 und v2.
  • Zeichnen Sie das Histogramm des Vektors v1.

Wahrscheinlichkeitsrechnung[Bearbeiten]

Kombinatorik[Bearbeiten]

Der Binomialkoeffizient:

In Octave z.B.:

n = 30;
k = 4;
n_ueber_k = nchoosek (n, k)

Ausgabe:

n_ueber_k =  27405

Permutationen sind die verschiedenen Anordnungsmöglichkeiten mit der Anzahl n! = n * (n-1) * ... * 2 * 1.

Beispiel:

v = [1, 2, 3];
p = perms(v)

Ausgabe:

p =

  1   2   3
  2   1   3
  1   3   2
  2   3   1
  3   1   2
  3   2   1

n! (n-Fakultät) selbst kann so berechnet werden:

 % 10!
 n = 10;
 factorial (n)

Ausgabe:

ans =  3628800

Verteilungen[Bearbeiten]

Octave kennt eine ganze Reihe von Dichte- und Verteilungsfunktionen und zwar

  • Probability Density Functions (PDF, Dichtefunktionen)
  • Cumulative Distribution Functions (CDF, Verteilungsfunktionen)

Z.B.:

  • Binomialverteilung:
    • binopdf
    • binocdf
  • Hypergeometrische Verteilung:
    • hygepdf
    • hygecdf
  • Normalverteilung:
    • normpdf
    • normcdf
  • Studentverteilung:
    • tpdf
    • tcdf
  • Weibullverteilung:
    • wblpdf
    • wblcdf

Ein Codebeispiel zur Binomialverteilung:

clear;
close all;
clc;

x = 0 : 1 : 10;
n = 10;
p = 0.1;
b1 = binopdf (x, n, p);
b2 = binocdf (x, n, p);

subplot(221);
  bar(x, b1);
  title("binopdf");
  text(1, 0.1, "n=10; p=0.1");
subplot(222);
  bar(x, b2);
  title("binocdf");
  text(1, 0.5, "n=10; p=0.1");

 n = 10;
 p = 0.5;

b1 = binopdf (x, n, p);
b2 = binocdf (x, n, p);

subplot(223);
  bar(x, b1);
  text(1, 0.1, "n=10; p=0.5");
subplot(224);
  bar(x, b2);
  text(1, 0.1, "n=10; p=0.5");

Ausgabe:

Octave bino3.jpg

Möglicherweise erhalten Sie bei diesem Beispiel eine Fehlermeldung in der Form

warning: the 'binopdf' function belongs to the statistics package from Octave
Forge which you have installed but not loaded.  To load the package, run
'pkg load statistics' from the Octave prompt.

Laden Sie einfach das Paket für die Statistikfunktionen, wie in der Fehlermeldung beschrieben.

Ein Codebeispiel zur Normalverteilung:

clear;
close all;
clc;

x = -4 : .1 : 4;
b1 = normpdf(x);
b2 = normcdf(x);

subplot(121);
  plot(x, b1);
  title("normpdf");
  grid on;
subplot(122);
  plot(x, b2);
  title("normcdf");  
  grid on;

Ausgabe:

Octave norm111.jpg

Zufallszahlengeneratoren[Bearbeiten]

Octave kann Zufallszahlen aus einer großen Anzahl von Verteilungen generieren, z.B.

  • Chi-Quadrat-Verteilung: chi2rnd
  • Log-Normal-Verteilung: lognrnd
  • Normalverteilung: normrnd

Codebeispiel:

mean = 0;
standardabweichung = 1;
zufallszahl = normrnd (mean, standardabweichung)

Ausgabe (gibt eine Zufallszahl rund um den Mittelwert 0 aus), z.B.

zufallszahl =  1.0451

Auch Zufallsvektoren (oder Zufallsmatrizen) können erstellt werden:

mean = [0 0 0 0 0];
standardabweichung = 1;
zufallsvektor = normrnd (mean, standardabweichung)

Ausgabe, z.B.:

zufallsvektor =

   1.47108  -0.51280   0.52726   0.31730  -1.04422

Einfache Benutzeroberflächen erstellen[Bearbeiten]

Input[Bearbeiten]

fflush (stdout);
x = input("Gib eine Zahl ein: ");
disp(2 * x);

Ein-/Ausgabe:

Gib eine Zahl ein: 12
 24

Der "fflush"-Befehl sollte immer vor dem Aufruf des input-Befehls aufgerufen werden. Näheres zu "fflush" siehe im Octave-Hilfesystem.

Diverse einfache vorgefertigte Dialoge[Bearbeiten]

Fehlermeldung:

errordlg("Fehlermeldung");

Octave fehlermeldung1.jpg

Warnung:

warndlg("Warnung");

Octave warnung1.jpg

Hilfedialog:

helpdlg

Octave hilfe1.jpg

Abfragedialog:

button = questdlg ("Frage")

Octave abfrage1.jpg

Eingabedialog:

in = inputdlg("Eingabe")

Octave eingabe1.jpg

Messagebox:

h = msgbox ("Eine Mitteilung!");

Octave messagebox1.jpg

Komplexere vorgefertigte Dialogboxen[Bearbeiten]

Menübox[Bearbeiten]

auswahl = menu("Auswahl", "Affe", "Elefant", "Loewe", "Sonstiges");

switch(auswahl)
  case 1
    disp "Affe quietscht"
  case 2
    disp "Elefant trompetet"
  case 3
    disp "Loewe bruellt"
  otherwise
    disp "Sonstiges"
end

Ausgabe:

Octave menu1.jpg

Es werde beispielsweise die Nummer 2 gewählt.

Ausgabe:

Elefant trompetet

Dialogliste[Bearbeiten]

clear;
close all;
clc;

opt = {"Eins", "Zwei", "Drei"}; 

[sel, ok] = listdlg ("ListString", opt, "SelectionMode", "Multiple");
          
if (ok == 1)
  for i = 1 : numel(sel)
    disp(opt{sel(i)});
  end
else
  disp("Cancel");
end

Octave dialog1.jpg

Es werden beispielsweise alle Optionen ausgewählt.

Ausgabe:

Eins
Zwei
Drei

Fortschrittsbalken[Bearbeiten]

h = waitbar ([0.5])

Octave fortschritt1.jpg

Datei- und Verzeichnisdialoge[Bearbeiten]

Dateidialog:

[fname, fpath, fltidx] = uigetfile ()

Octave dateidialog2.jpg

Ähnlich sind die Befehle "uiputfile" und "uigetdir". Dazu sei auf die Octave-Hilfe verwiesen.

Eigene Dialoge kreieren[Bearbeiten]

Dieses Thema sei hier nicht näher vertieft. Wer mehr dazu wissen will, sei auf die Octave-Dokumentation verwiesen. Insbesondere siehe auch

  • dialog
  • uicontrol
  • uipanel
  • uibuttongroup
  • uitable
  • uimenu
  • uitoolbar

Fehlerhandling mit try/catch[Bearbeiten]

Die try/catch-Anweisung entspricht weitgehend jener, die aus höheren Programmiersprachen wie C++ oder Java bekannt sind. Aufgebaut ist diese Anweisungsfolge so:

try
  BODY
catch
  CLEANUP
end

Beispiel:

clear;
close all;
clc; 

try
  a = 10 / "zahl";
  disp(a);
  disp("Weiter im try-Block");
catch
  disp("Catch: Kann nicht durch einen String dividieren");
end

Ausgabe:

Catch: Kann nicht durch einen String dividieren

Sinnvoll ist die try/catch-Folge, wenn z.B. auch in einem Fehlerfall Dateien wieder geschlossen werden sollen.

Ein- und Ausgabe[Bearbeiten]

Formatierte Ausgabe am Bildschirm, formatiertes Lesen von der Tastatur[Bearbeiten]

Folgendes Beispiel ist der Octave-Hilfe (von Octave 3.0.3) entnommen:

pct = 37;
filename = "foo.txt";
printf ("Processed %d%% of `%s'.\nPlease be patient.\n", pct, filename);

Ausgabe:

Processed 37% of `foo.txt'.
Please be patient.

"printf" gibt einen formatierten String am Bildschirm (genauer in den Stream stdout) aus. Wie man sieht, orientiert sich das Format an der Programmiersprache C.

Für das formatierte Lesen vom Stream stdin (normalerweise also von der Tastatur) steht das Pendant "scanf" bereit.

Von einem String lesen bzw. in einen String schreiben[Bearbeiten]

Bezüglich der Funktionen

  • sprintf

und

  • sscanf

sei auf die Octave-Hilfefunktion verwiesen.

Lesen und Schreiben von einer Datei[Bearbeiten]

Datei schreiben[Bearbeiten]

% Datei c:\tmp\datei.test zum Schreiben öffnen
datei = fopen ("c:/tmp/datei.test", "w");

% Etwas in die Datei schreiben
fprintf(datei, "Hallo, Welt!");

% Datei schließen
fclose(datei);

Datei lesen[Bearbeiten]

% Datei c:\tmp\datei.test zum Lesen öffnen
datei = fopen ("c:/tmp/datei.test", "r");

% Etwas aus der Datei lesen
[string] = fscanf(datei, "%s");
disp(string);

% Datei schließen
fclose(datei);

Ausgabe:

Hallo,Welt!

Dateiende prüfen[Bearbeiten]

Mittels des Befehls

feof(FID);

kann das Dateiende geprüft werden. Wenn die EOF-Bedingung zutrifft, dann wird 1 zurückgegeben, wenn nicht dann 0. Ein Beispiel folgt später als Lösung einer Aufgabe.

warning und error[Bearbeiten]

Eine Warnung kann man am stderr-Stream ausgeben. Die warning-Funktion entspricht ansonsten der printf-Funktion. Nach Ausgabe der Warnung wird das Programm normal fortgesetzt.

m = [1  2
     3  6]; 

if(det(m) == 0)
  warning("Matrix ist singulaer");
end

disp("Weiter geht's");

Ausgabe:

warning: Matrix ist singulaer
Weiter geht's

Schärfer ist der error-Befehl. Die Fehlermeldung wird am stderr-Stream ausgegeben. Vom Format her entspricht diese Funktion dem printf-Befehl. Nach Ausgabe der Fehlermeldung wird das Programm beendet.

m = [1  2
     3  6]; 

if(det(m) == 0)
  error("Matrix ist singulaer");
end

disp("Weiter geht's");

Ausgabe:

error: Matrix ist singulaer
error: evaluating if command near line 4, column 1
error: near line 6 of file `c:/tmp\test1.m'

Aufgaben[Bearbeiten]

  • Schreiben Sie ein Programm, das die Zahlen 1 bis 10 zeilenweise in eine Datei ausgibt.
  • Lesen Sie diese Zeilen wieder von der Datei ein und geben Sie sie am Bildschirm aus.
  • Gegeben sei eine Datei. Lesen Sie die Daten aus dieser Datei ein und rechnen Sie per Octave-Programm den Gesamtpreis für alle Tiere aus. Die Anzahl der Zeilen und der genaue Dateinhalt sei Ihnen vorab nicht bekannt. Bekannt ist nur das Datenformat wie folgt:
Nr. Name       Einzelpreis      Stueck
1   Affe       15000.50         2
2   Loewe      11000.90         1
3   Nashorn    45000.10         1
4   Elefant    51245.90         3
5   Tiger       9000.70         2
6   Maus          34.90         12

Eine einfache Lösung ohne Schnickschnack (Fehlerüberprüfungen etc.) für dieses Beispiel könnte wie folgt aussehen:

clear;
close all;
clc;

datei = fopen ("c:/tmp/daten1.txt", "r");

gesamtpreis = 0;

% Kopfzeile einlesen  
[nr, name, preis, stk] = fscanf(datei, "%s %s %s %s", "C");

while(feof(datei) == 0)
  % Datensätze einlesen
  [nr, name, preis, stk] = fscanf(datei, "%d %s %f %d", "C");
  gesamtpreis += preis*stk;
end

fclose(datei);

disp("Gesamtpreis = ");
format long;
disp(gesamtpreis);

Ausgabe:

Gesamtpreis =
 258159.900000000

Datencontainer[Bearbeiten]

Datenstrukturen[Bearbeiten]

Pseudocode:

STRUKTUR s
  ZAHL a
  VEKTOR b
  STRING c
END

Octave-Code:

s.a = 45.9;
s.b = [1 2 3 4 5];
s.c = "Hallo!";

s

Ausgabe:

s =
{
  a =  45.900
  b =

     1   2   3   4   5

  c = Hallo!
}

Um ein paar weitere Möglichkeiten zum Handling mit Datenstrukturen aufzuzeigen, sei folgender Code aufgeführt.

Datei addsub.m

function res = addsub(a, b)
  res.x = a + b;
  res.y = a - b;
end

Datei test1.m

clear;
clc;

addsub(10, 50)

r = addsub(30, 70)
r.x
r.y

++r.x

Ausgabe:

ans =
{
  x =  60
  y = -40
}

r =
{
  x =  100
  y = -40
}

ans =  100
ans = -40
ans =  101

Die Funktion "addsub" liefert die Struktur res mit zwei Zahlenwerten. Die Elemente der Datenstruktur können auch außerhalb der Funktion angesprochen werden. Auch gerechnet werden kann mit diesen Elementen.

Cell Arrays[Bearbeiten]

Manchmal kann es sinnvoll sein mehrere Variablen verschiedenen Typs und Größe in einer Variablen zu speichern. Dies funktioniert ähnlich wie bei Vektoren. Es werden aber geschweifte Klammern verwendet.

Eingabe:

c = {"Hallo Welt!", [2 2], 44} 
c{1}
c{1:2}

Ausgabe:

c =

{
  [1,1] = Hallo Welt!
  [1,2] =

     2   2

  [1,3] =  44
}

ans = Hallo Welt!
ans =

(,
  [1] = Hallo Welt!
  [2] =

     2   2

,)

Elemente des Cell Arrays können auch wieder mit Variablen anderen Typs überschrieben werden.

c = {"Hallo Welt!", [2 2], 44};
c{1} = 5;
c

Ausgabe:

c =

{
  [1,1] =  5
  [1,2] =

     2   2

  [1,3] =  44
}

Objektorientierte Programmierung[Bearbeiten]

Octave unterstützt auch objektorientierte Programmierung. Dieses Thema ist aber etwas für fortgeschrittene Anwender und wird hier nicht behandelt. Wen es trotzdem interessiert, der sei auf die Octave-Dokumentation verwiesen.

Octave GUI[Bearbeiten]

Das GUI-Programm von Octave entspricht im Wesentlichen anderen Programmier-Benutzeroberflächen, wie z.B. Eclipse oder Code::Blocks. Nachfolgend ist ein Screenshot des Octave-GUI mit einigen Anmerkungen dargestellt.

Octave gui2.jpg

Probieren Sie einfach die Möglichkeiten der zur Verfügung gestellten GUI aus.

Komplexere Aufgaben[Bearbeiten]

  • Berechnen Sie die Fläche, den Umfang, die Seitenlängen, den Inkreis und den Umkreis eines Dreiecks. Stellen Sie das Dreieck inklusive In- und Umkreis grafisch dar. Speichern Sie die Daten in einer Datei. Die drei Eckpunkte dieses Dreiecks sollen vom Benutzer beliebig vorgegeben werden.
  • Die Werte einer beliebig großen quadratischen Matrix seien in einer Datei gespeichert. Lesen Sie diese Datei ein und berechnen Sie daraus die Determinante der Matrix, die inverse Matrix, die Eigenvektoren und -werte, die Spur. Führen Sie die LR-Zerlegung durch. Geben Sie diese Werte am Bildschirm aus.

Ausblick[Bearbeiten]

Dies war eine kurze Einführung in die Berechnungs- und Darstellungsmöglichkeiten mit Octave. Es sollten etliche relevante Themen behandelt, oder zumindest kurz angesprochen worden sein. Wem dieser Text nicht ausreichend ist, der sei auf die entsprechende weiterführende Literatur, die Octave-Hilfefunktion und die Octave-Dokumentation verwiesen. Octave kennt noch viel mehr Befehle, als hier dargestellt wurden. Aber auch Octave selbst ist erweiterbar. Man siehe z.B. Octave-Forge (https://octave.sourceforge.io/packages.php) oder man schreibt selbst Erweiterungen.

Wikibooks buchseite.svg Zurück zu Maxima | One wikibook.svg Hoch zu Gesamtinhaltsverzeichnis |