Ing Mathematik: Numerische Mathematiksysteme am Beispiel von Octave


Hallo Welt und allgemeine HinweiseBearbeiten

Was ist OctaveBearbeiten

  • 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 installierenBearbeiten

MS WindowsBearbeiten

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.

LinuxBearbeiten

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

Octave startenBearbeiten

MS WindowsBearbeiten

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.

 

LinuxBearbeiten

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

Ein paar Worte zur ErklärungBearbeiten

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 Juli 2021 die Version 6.3, die auch mit diesem Text abgedeckt werden soll. Die dargestellten Grafiken und Ausgabetexte 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 ProgrammBearbeiten

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 TaschenrechnerBearbeiten

AllgemeinesBearbeiten

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 OctaveBearbeiten

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.

AufgabenBearbeiten

  • 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 ScriptspracheBearbeiten

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!

BlockkommentareBearbeiten

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
#}

VariablenBearbeiten

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

ZahlenkolonnenBearbeiten

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

VerzweigungenBearbeiten

Die IF-VerzweigungBearbeiten

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-VerzweigungBearbeiten

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

SchleifenBearbeiten

Die WHILE-SchleifeBearbeiten

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-SchleifeBearbeiten

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-SchleifeBearbeiten

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 abbrechenBearbeiten

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

AufgabenBearbeiten

  • 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 zeichnenBearbeiten

2DBearbeiten

Graph einer FunktionBearbeiten

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:

 

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:

 

Graphen mehrerer Funktionen und weiteresBearbeiten

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;

 

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;

 

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;

 

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 ParameterdarstellungBearbeiten

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;

 

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;

 

StrichstärkeBearbeiten

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:

 

Beliebigen Text ausgebenBearbeiten

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

Ausgabe:

 

Logarithmische AchseneinteilungBearbeiten

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

Ausgabe:

 

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

AufgabenBearbeiten

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

 

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

 

  • 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.

3DBearbeiten

Räumliche KurvenBearbeiten

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;

 

FlächenBearbeiten

ezsurfBearbeiten

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]);

 

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 meshBearbeiten

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);

 

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");

 

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:

 

Ellipsoide und KegelBearbeiten

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;

 

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;

 

AufgabenBearbeiten

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

 

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

 

WeiteresBearbeiten

subplotBearbeiten

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:

 

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:

 

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

figureBearbeiten

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:

 

Linien zeichnenBearbeiten

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:

 

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);

 

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);

 

AufgabenBearbeiten

  • 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 MatrizenBearbeiten

VektorenBearbeiten

Vektoren sollten jedem aus der Linearen Algebra bekannt sein.

Zeilen- und SpaltenvektorenBearbeiten

% 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 VektorelementeBearbeiten

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 VektorenBearbeiten

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 SkalarenBearbeiten

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

Ausgabe:

res =

   3   6   9

SkalarproduktBearbeiten

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

VektorproduktBearbeiten

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 VektorBearbeiten

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

Ausgabe:

res1 =

   1
   2
   3

res2 = 

   5   6   7

Einige weitere VektorfunktionenBearbeiten

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

MatrizenBearbeiten

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 MatrizenelementeBearbeiten

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 MatrizenBearbeiten

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 MatrixBearbeiten

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

Ausgabe:

ans =

  1   4
  2   5
  3   6

Rang einer MatrixBearbeiten

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 MatrixBearbeiten

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 MatrixBearbeiten

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.

TeilmatrizenBearbeiten

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

EinheitsmatrizenBearbeiten

eye(3,2)

Ausgabe:

ans =

   1   0
   0   1
   0   0

NullmatrizenBearbeiten

zeros(2,3)

Ausgabe:

ans =

   0   0   0
   0   0   0

DiagonalmatrizenBearbeiten

diag([1, 2, 3])

Ausgabe:

ans =

   1   0   0
   0   2   0
   0   0   3

Spur einer MatrixBearbeiten

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

Ausgabe:

ans =  10

LR-Zerlegung einer MatrixBearbeiten

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

EigenwerteBearbeiten

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 MatrizenBearbeiten

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:

 

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:

 

Matrizen mit ZufallswertenBearbeiten

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.

AufgabenBearbeiten

  • 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 ZahlenBearbeiten

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  

Die konjugiert komplexe Zahl ist  

Mit komplexen Zahlen rechnenBearbeiten

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 ZahlenebeneBearbeiten

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;

 

AufgabenBearbeiten

  • 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.

FunktionenBearbeiten

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 schreibenBearbeiten

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-FunktionenBearbeiten

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

FunktionsstringBearbeiten

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

Ausgabe:

z =  15

Anonyme FunktionenBearbeiten

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 bestimmenBearbeiten

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:

 

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 VariablenBearbeiten

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

AufgabenBearbeiten

  • 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 diese Funktion grafisch am Bildschirm dar.

PolynomeBearbeiten

Einzelne Polynomwerte berechnenBearbeiten

% 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 zeichnenBearbeiten

% 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:

 

Nullstellen bestimmenBearbeiten

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).

AufgabenBearbeiten

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

Lineare GleichungssystemeBearbeiten

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

Einfache Berechnung mittels Gauß-VerfahrenBearbeiten

Wikipedia hat einen Artikel zum Thema:


Beispiel:

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

Ausgabe:

x =

   0
   1

Das gmres-VerfahrenBearbeiten

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:


AufgabeBearbeiten

  • 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 GleichungssystemeBearbeiten

fsolveBearbeiten

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:

 

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.

 

Diese zweite Nullstelle erhalten wir, wenn der Startwert in der Nähe dieser zweiten Nullstelle liegt, also 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.

GleichungssystemeBearbeiten

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

AufgabenBearbeiten

  • 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):  

InterpolationBearbeiten

Eindimensionale InterpolationBearbeiten

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:

 

Mehrdimensionale InterpolationBearbeiten

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

AufgabeBearbeiten

  • 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");

 

DifferenzialrechnungBearbeiten

Polynome differenzierenBearbeiten

Es soll das Polynom   differenziert werden.

% Differenzieren 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 differenzierenBearbeiten

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:

 

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".

AufgabenBearbeiten

  • 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.

IntegralrechnungBearbeiten

Polynome integrierenBearbeiten

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ß-QuadraturBearbeiten

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-RegelBearbeiten

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)

AufgabenBearbeiten

  • 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 DifferenzialgleichungenBearbeiten

ode23, ode45 und lsodeBearbeiten

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:

 

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

 

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

AufgabenBearbeiten

  • 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-TransformationBearbeiten

Wikipedia hat einen Artikel zum Thema:


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

MengenrechnungBearbeiten

VereinigungsmengeBearbeiten

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

Ausgabe:

ans =

   1   2   3   4   6

SchnittmengeBearbeiten

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

Ausgabe:

ans =

   2   4

StochastikBearbeiten

Deskriptive StatistikBearbeiten

LageparameterBearbeiten

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.

StreuungsparameterBearbeiten

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äufigkeitsverteilungenBearbeiten

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 erzeugenBearbeiten

Histogramme:

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

Ausgabe:

 

Balkendiagramme:

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

Ausgabe:

 

Treppendiagramm:

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

Ausgabe:

 

Stabdiagramm:

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

Ausgabe:

 

AufgabenBearbeiten

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.

WahrscheinlichkeitsrechnungBearbeiten

KombinatorikBearbeiten

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

VerteilungenBearbeiten

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:

 

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:

 

ZufallszahlengeneratorenBearbeiten

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 erstellenBearbeiten

InputBearbeiten

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 DialogeBearbeiten

Fehlermeldung:

errordlg("Fehlermeldung");

 

Warnung:

warndlg("Warnung");

 

Hilfedialog:

helpdlg

 

Abfragedialog:

button = questdlg ("Frage")

 

Eingabedialog:

in = inputdlg("Eingabe")

 

Messagebox:

h = msgbox ("Eine Mitteilung!");

 

Komplexere vorgefertigte DialogboxenBearbeiten

MenüboxBearbeiten

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:

 

Es werde beispielsweise die Nummer 2 gewählt.

Ausgabe:

Elefant trompetet

DialoglisteBearbeiten

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

 

Es werden beispielsweise alle Optionen ausgewählt.

Ausgabe:

Eins
Zwei
Drei

FortschrittsbalkenBearbeiten

h = waitbar ([0.5])

 

Datei- und VerzeichnisdialogeBearbeiten

Dateidialog:

[fname, fpath, fltidx] = uigetfile ()

 

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

Eigene Dialoge kreierenBearbeiten

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/catchBearbeiten

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 AusgabeBearbeiten

Formatierte Ausgabe am Bildschirm, formatiertes Lesen von der TastaturBearbeiten

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 schreibenBearbeiten

Bezüglich der Funktionen

  • sprintf

und

  • sscanf

sei auf die Octave-Hilfefunktion verwiesen.

Lesen und Schreiben von einer DateiBearbeiten

Datei schreibenBearbeiten

% 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 lesenBearbeiten

% 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üfenBearbeiten

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 errorBearbeiten

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'

AufgabenBearbeiten

  • 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

DatencontainerBearbeiten

DatenstrukturenBearbeiten

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 ArraysBearbeiten

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 ProgrammierungBearbeiten

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 GUIBearbeiten

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.

 

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

Komplexere AufgabenBearbeiten

  • 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.

AusblickBearbeiten

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.