Hubert Selhofer, mit Änderungen von Marcel Oliver
Date: 2001/11/09
Octave ist eine interaktive Scriptsprache, die speziell für vektorisierbare Berechnungen optimiert ist und dabei Standardroutinen der numerischen Mathematik (z.B. EISPACK oder LAPACK) auf einfache Weise zugänglich macht.
Der Syntax von Octave ist dem proprietären Matlab sehr ähnlich, d.h. ein Octave Programm kann meist auch von Matlab ausgeführt werden. Die Rückwärtskompatibilität ist nicht immer gegeben, da Matlab besonders im Grafikbereich um einen erheblich größeren Funktionsumfang verfügt.
octave:1> help eig
< | kleiner | <= | kleiner oder gleich | & | und |
> | größer | >= | größer oder gleich | | | oder |
== | gleich | <> | ungleich | ~ |
nicht |
octave:1> x12 = 1/8, long_name = 'Ein String' x12 = 0.12500 long_name = Ein String octave:2> sqrt(-1)-i ans = 0 octave:3> x = sqrt(2); sin(x)/x ans = 0.69846Und hier ein Script doless, der in der Datei doless.m gespeichert ist:
eins = 1; zwei = 2; drei = eins + zwei;Aufruf des Scripts:
octave:1> doless octave:2> whos *** local user variables: prot type rows cols name ==== ==== ==== ==== ==== wd real scalar 1 1 drei wd real scalar 1 1 eins wd real scalar 1 1 zwei
Matrizen und Vektoren sind die wichtigsten Grundbausteine zur Programmierung in Octave.
v = [ 1 2 3 ]
v = [ 1; 2; 3 ]
Anfang[:Inkrement]:Ende
octave:1> x = 3:6 x = 3 4 5 6 octave:2> y = 0:.15:.7 y = 0.00000 0.15000 0.30000 0.45000 0.60000 octave:3> z = pi:-pi/4:0 z = 3.14159 2.35619 1.57080 0.78540 0.00000
Eine Matrix wird erzeugt durch:
octave:1> A = [ 1 2; 3 4] A = 1 2 3 4Matrizen können folgenderweise aus Teilmatrizen zusammengesetzt werden:
octave:2> b = [5; 6]; octave:3> M = [A b] M = 1 2 5 3 4 6
Für einige wichtige -Matrizen existieren eigene Befehle. Falls m gleich n ist, muß nur ein Argument angegeben werden.
octave:1> A = [1 2; 3 4]; B = 2*ones(2,2); octave:2> A+B, A-B, A*B ans = 3 4 5 6 ans = -1 0 1 2 ans = 6 6 14 14
Während z.B. * die standard Matrixmultiplikation bezeichnet, gibt es alle Operatoren mit vorangestelltem Punkt für elementweise Verknüpfung: .*, ./, .^, u.s.w.
octave:1> A = [1 2; 3 4]; A.^2 % elementweise Potenz ans = 1 4 9 16 octave:2> A^2 % Zum Vergleich die matrixweise Potenz ans = 7 10 15 22
octave:1> A = [1 2 3; 4 5 6]; v = [7; 8]; octave:2> A(2,3) = v(2) A = 1 2 3 4 5 8 octave:3> A(:,2) = v A = 1 7 3 4 8 8 octave:4> A(1,1:2) = v' A = 7 8 3 4 8 8
A\b
löst die Gleichung Ax = b.
Falls A eine -Matrix ist, wird Gaußelimination verwendet, sonst wird via QR-Zerlegung eine Lösung im Sinne der kleinsten Fehlerquadrate berechnet. Ist A schlecht konditioniert oder singulär, wird eine Warnung ausgegeben.
Traditionell sind Funktionen ebenfalls Textdateien mit Suffix .m. Im Unterschied zu Skripts können Funktionen mit Argumenten aufgerufen werden, und alle innerhalb der Funktion verwendeten Variablen sind lokal (sie beeinflussen die vorher definierten Variablen nicht).
Eine Funktion f, die in der Datei f.m gespeichert ist.
function y = f (x) y = cos(x/2)+x; end
In Octave kann man--sinnvollerweise--beliebig viele Funktionen in einer Skriptdatei definieren. Matlab hingegen lässt strikt nur eine Funktion pro .m Datei zu, und der Funktionsname muss mit dem Dateinamen übereinstimmen. Falls Kompatibilität mit Matlab wichtig ist, sollte diese Einschränkung auch auf Octave-Programme angewandt werden.
Eine Funktion dolittle, die in der Datei dolittle.m gespeichert ist.
function [out1,out2] = dolittle (x) out1 = x^2; out2 = out1*x; endAufruf der Funktion:
octave:1> [x1,x2]=dolittle(2) x1 = 4 x2 = 8 octave:2> whos *** currently compiled functions: prot type rows cols name ==== ==== ==== ==== ==== wd user function - - dolittle *** local user variables: prot type rows cols name ==== ==== ==== ==== ==== wd real scalar 1 1 x1 wd real scalar 1 1 x2Offensichtlich waren die beiden Variablen out1, out2 in dolittle lokal. Eine vorher definierte Variable out1 oder out2 wird durch den Aufruf der Funktion nicht beeinflußt.
global name deklariert name als globale Variable.
Eine Funktion foo in der Datei foo.m:
function out = foo(arg1,arg2) global N % verwende N als globale Variable <Berechnung> endWird N in der Funktion verändert, ändert das auch den ursprünglichen Wert von N im ,,workplace``.
Die Syntax von for- und while-Schleifen wird an folgenden Beipielen klar:
for n = 1:10 [x(n),y(n)]=dolittle(n); end while t<T t = t+h; endFor-Schleife rückwärts:
for n = 10:-1:1 ...
Bedingte Verzweigungen lassen sich so programmieren:
if x==0 error('x ist 0!'); else y = 1/x; end switch pnorm case 1; sum(abs(v)) case inf; max(abs(v)) otherwise sqrt(v'*v) end
Berechne mit der Mittelpunktsregel:
function y = gauss(x) y = exp(-x.^2/2); end function S = mpr(fun,a,b,N) h = (b-a)/N; S = h*sum(feval(fun,[a+h/2:h:b])); endJetzt kann man die Funktion gauss durch folgenden Aufruf integrieren:
octave:1> mpr('gauss',0,5,500)
Schleifen und Funktionsaufrufe, insbesondere über den Umweg feval, sind sehr teuer. Deswegen möglichst alle Operationen vektorisieren.
Wir programmieren die Mittelpunktsregel aus dem vorherigen Abschnitt
mit einer for-Schleife (Datei mpr_langsam.m
):
function S = mpr_langsam(fun,a,b,N) h = (b-a)/N; S = 0; for k = 0:(N-1), S = S + feval(fun,a+h*(k+1/2)); end S = h*S; endMan vergleiche die Ausführungszeiten:
octave:1> t = cputime; > Int1=mpr('gauss',0,5,500); t1=cputime-t; octave:2> t = cputime; > Int2=mpr_langsam('gauss',0,5,500); t2=cputime-t; octave:3> Int1-Int2, t2/t1 ans = 0 ans = 45.250
octave:1> for k = .1:.2:.5, > fprintf('1/%g = %10.2e\n',k,1/k); end 1/0.1 = 1.00e+01 1/0.3 = 3.33e+00 1/0.5 = 2.00e+00
Soll eine Funktion y=f(x) geplottet werden, geht man praktischerweise folgendermassen vor:
x = x_min:schrittweite:x_max;(Siehe auch Abschnitt 2.1.)
y = f(x);Wichtig: Damit f elementweise operiert, müssen die Operatoren .+, .-, .^ usw. anstelle der üblichen +, - und ^ verwendent werden! (Siehe Abschnitt 2.4.)
plot(x,y); grid; replot
octave:1> x = -10:.1:10; octave:2> y = sin(x).*exp(-abs(x)); octave:3> plot(x,y); grid; replot
octave:1> x = -2:0.1:2; octave:2> [xx,yy] = meshgrid(x,x); octave:3> z = sin(xx.^2-yy.^2); octave:4> mesh(x,x,z);
Erzeugen Sie eine Matrix A und einen Vektor b mit
A = reshape(1:4,2,2).'; b = [36; 88]; A\b [L,U,P] = lu(A) [Q,R] = qr(A) [V,D] = eig(A) A2 = A.'*A; R = chol(A2) cond(A)^2 - cond(A2)
Berechnen Sie ein Matrix-Vektor-Produkt einer -Zufallsmatrix mit einem Zufallsvektor, indem Sie einerseits die eingebaute Funktion *, andererseits for-Schleifen verwenden. Vergleichen Sie die Rechenzeiten beider Lösungen.
A = rand(100); b = rand(100,1); t = cputime; v = A*b; t1 = cputime-t; w = zeros(100,1); t = cputime; for n = 1:100, for m = 1:100 w(n) = w(n)+A(n,m)*b(m); end end t2 = cputime-t; norm(v-w), t2/t1 ans = 0 ans = 577.00
Berechnen Sie alle Nullstellen des Polynoms
Zeichnen Sie diese Nullstellen in der komplexen Ebene als Punkte ein, und fügen Sie einen Einheitskreis hinzu (Hinweis: hold, real, imag).
bdf6 = [147/60 -6 15/2 -20/3 15/4 -6/5 1/6]; R = eig(compan(bdf6)); plot(R,'+'); hold on plot(exp(pi*i*[0:.01:2])); if any(find(abs(R)>1)) fprintf('BDF6 ist instabil\n'); else fprintf('BDF6 ist stabil\n'); end
Zeichnen Sie den Graphen der Funktion
x = -3:0.1:3; [xx,yy] = meshgrid(x,x); z = exp(-xx.^2-yy.^2); mesh(x,x,z); title('exp(-x^2-y^2)'); replot;
err = zeros(15,1); co = zeros(15,1); for k = 1:15 H = hilb(k); b = ones(k,1); err(k) = norm(H\b-invhilb(k)*b); co(k) = cond(H); end semilogy(1:15,err,'r',1:15,co,'x');
Berechnen Sie zu beliebig vorgegebenen Punkten (xj,yj), die durch zwei Vektoren x und y gegeben sind, die Ausgleichsgerade (im Sinne der kleinsten Fehlerquadrate). Zeichnen Sie die Punkte und die Gerade.
function coeff = ausgl(x,y) n = length(x); A = [x ones(n,1)]; coeff = A\y; plot(x,y,'x'); hold on interv = [min(x) max(x)]; plot(interv,coeff(1)*interv+coeff(2)); end
Schreiben Sie ein Programm, das beliebige Funktionen f in einer
Variablen auf einem Intervall [a,b] numerisch integriert. Verwenden
sie die Trapezregel (
h = (b-a)/N):
function S = trapez(fun,a,b,N) h = (b-a)/N; % fy = feval(fun,[a:h:b]); besser: fy = feval(fun,linspace(a,b,N+1)); fy(1) = fy(1)/2; fy(N+1) = fy(N+1)/2; S = h*sum(fy); end function y = f(x) y = exp(x); end for k=1:15; err(k) = abs(exp(1)-1-trapez('f',0,1,2^k)); end loglog(1./2.^[1:15],err); hold on; loglog(1./2.^[1:15],err,'x'); title('Trapezregel, f(x) = exp(x)'); xlabel('Schrittweite'); ylabel('Fehler'); replot;
This document was generated using the LaTeX2HTML translator Version 98.1p1 release (March 2nd, 1998)
Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
The command line arguments were:
latex2html -split 0 -no_navigation -show_section_numbers octave.tex.
The translation was initiated by Marcel Oliver on 2001-12-02