herunterladen - Clavius

Werbung
Regionale Begabtenförderung Oberfranken
Computeralgebra mit MuPAD
Dr. Rainer Dietrich
Clavius-Gymnasium Bamberg
20. Oktober 2005
Kapitel 1
Grundlegende Fähigkeiten von MuPAD
MuPAD ist ein Computer-Algebra-System. Das bedeutet, dass seine Fähigkeiten weit über die eines
herkömmlichen Taschenrechners hinaus gehen. Während dieser nur mit Zahlen rechnet (numerische
Berechnungen), kann MuPAD auch mit Variablen umgehen (symbolische Berechnungen) und beispielsweise Terme vereinfachen oder Gleichungen lösen. Daneben besitzt MuPAD auch sehr weit
reichende Möglichkeiten zur Erstellung von Graphiken.
1.1
Numerische Berechnungen
Wir beginnen mit einfachen Zahlenrechnungen. Im Gegensatz zum Taschenrechner gibt MuPAD nicht
automatisch Ergebnisse in Dezimaldarstellung an, sondern rechnet soweit wie nur möglich exakt.
Dies schließt auch mathematische Konstanten wie π oder e ein, die deshalb nicht weiter vereinfacht
werden.
• 1/2+1/3
• sqrt(12)
• (2*PI)ˆ2
Die Dezimaldarstellung kann auf zwei Arten erzwungen werden: Entweder mit dem Befehl float
oder indem bereits die Eingabe als Dezimalbruch erfolgt.
• float(5/6)
2
1.2. Symbolische Berechnungen
3
• sqrt(12.0)
Die vorgegebene Einstellung sind dabei 10 gültige Ziffern; das lässt sich aber ändern.
• DIGITS:=50
• float(1/7)
• float(PI)
Zum Schluß setzen wir die Anzahl der Dezimalstellen auf den Ursprungswert zurück. Der Wert von
DIGITS ist dann also wieder 10.
• delete DIGITS
• float(1/7)
• DIGITS
1.2
Symbolische Berechnungen
MuPAD rechnet mit Variablen nach den üblichen Rechenregeln, wichtig (und leicht vergessen!) ist
allerdings die explizite Angabe auch des Mal punktes“.
”
• 5*a+3*a
Natürlich kann MuPAD nicht erraten, in welcher Form wir einen Ausdruck gerne hätten; das müssen
R. Dietrich, CG Bamberg
4
1. Grundlegende Fähigkeiten von MuPAD
wir dem Programm mitteilen.
• expand((a+b)ˆ2)
Genauso wie sich Ausdrücke ausmultiplizieren lassen, können sie auch wieder faktorisiert werden.
• factor(xˆ3-1)
Aufgabe: Faktorisieren Sie und finden Sie die Nullstellen des Funktionsterms x4 − 4x2 + 3.
Auch Summen (sogar unendliche) sind möglich.
• sum(xˆk, k=0..10)
Variablen kann man mit := einen Zahlenwert zuweisen; dabei ist der Doppelpunkt besonders wichtig.
• a:=4
• 2*a
Aufgabe: Was geschieht, wenn man im obigen Beispiel den Doppelpunkt vergisst?
Mit := wird in MuPAD eine Zuordnung definiert. Es wird dabei zunächst die rechte Seite ausgerechnet und dieses Ergebnis dann unter dem Namen der linken Seite gespeichert. Der folgende Befehl ist
also durchaus sinnvoll (und wird auch häufig verwendet):
• a:=a+1
Hingegen macht die Gleichung a=a+1 keinen großen Sinn.
Den Wert einer Variablen löscht man mit delete. Das Zurücksetzen der Stellenzahl oben bedeutet
also lediglich, dass der (vom Benutzer eingegebene) Wert der internen Variablen DIGITS gelöscht
wird (und durch den Standardwert ersetzt wird; das ist nötig, um kein Chaos entstehen zu lassen.
Wie sollte sonst die nächste Ausgabe aussehen?)
• delete a
R. Dietrich, CG Bamberg
1.3. Funktionen
5
• 2*a
MuPAD kann auch Gleichungen lösen.
• solve(xˆ2=4)
Wenn in der Gleichung mehrere Variable auftreten, muss man dem Programm mitteilen, nach welcher
davon es auflösen soll. Bezüglich der anderen Variablen (den Parametern“) trifft MuPAD eine
”
Fallunterscheidung.
• solve(a*xˆ2+b*x+c=0, x)
Als weiteres Beispiel betrachten wir die Nullstellen der Sinus-Funktion.
• solve(sin(x)=0)
Zusätzlich zum exakten Ergebnis ist hier die Mengenschreibweise auffällig: MuPAD gibt wirklich die
komplette Lösungsmenge an!
Zum Abschluß noch eine etwas kompliziertere quadratische Gleichung:
• solve((3*xˆ2+9)/(xˆ2-1)-3=1/100)
Aufgabe: In welchen Punkten schneidet der Graph zu f (x) = −5x3 + 8x2 − 3 die Koordinatenachsen?
1.3
Funktionen
Funktionen werden in MuPAD am besten (mathematisch korrekt) als Zuordnungen definiert; für die
Quadratfunktion schaut das z.B. so aus:
R. Dietrich, CG Bamberg
6
1. Grundlegende Fähigkeiten von MuPAD
• f:=x->xˆ2
Wichtig ist dabei wieder der Doppelpunkt; er zeigt MuPAD an, dass hier keine Gleichung steht
(Lösungsmenge??), sondern eben eine Zuordnung.
Neben den Potenzen kennt MuPAD noch viele weitere Funktionen, z.B. den Betrag abs(x) , die
Quadratwurzel sqrt(x) , die gebräuchlichen trigonometrischen Funktionen sin(x), cos(x),
tan(x) und andere mehr.
In die Funktionsgleichung können verschiedene x-Werte eingesetzt werden.
• f(2.5)
Mit dem $-Befehl lässt sich eine Wertetabelle anlegen.
• f(x) $ x=0..5
Wir können den Funktionsgraphen zeichnen lassen; dabei ist es sinnvoll, den
Definitionsbereich auf der x-Achse vorzugeben. Der Befehl funktioniert allerdings auch ohne diese
Vorgabe; MuPAD wählt dann selbstständig einen mehr oder weniger sinnvollen Bereich aus.
• plotfunc2d(f(x), x=0..5)
Man kann auch mehrere Funktionsgraphen gleichzeitig zeichnen.
• plotfunc2d(sin(x), cos(x), x=-6..6)
R. Dietrich, CG Bamberg
1.3. Funktionen
7
Aufgabe: Zeichnen Sie die Graphen von f (x) = −x + 2 sowie g(x) = −2x − 3 in ein Koordinatensystem und berechnen Sie ihren Schnittpunkt.
Häufig begegnet man Funktionsgleichungen, die noch einen Parameter enthalten, wie z.B.
• g:=x->k*xˆ2
Der Befehl subs ersetzt ( substituiert“) diesen Parameter durch eine Zahl; an der ursprünglichen
”
Funktionsgleichung ändert sich dabei aber nichts.
• subs(g(x), k=3)
• g(x)
Die entsprechende Funktionenschar lässt sich zeichnen, indem für g(x) zuerst eine Liste von Funktionen mit verschiedenen Parameterwerten erzeugt wird; diese Liste wird dann gezeichnet.
• plotfunc2d((subs(g(x), k=j) $ j=-2..2), x=-3..3)
R. Dietrich, CG Bamberg
8
1.4
1. Grundlegende Fähigkeiten von MuPAD
Graphik
Außer den gerade besprochenen Funktionsgraphen lassen sich auch weitere Graphiktypen erzeugen.
Die meisten der spezielleren Befehle sind in sog. Bibliotheken“ enthalten, die von MuPAD erst bei
”
Gebrauch geladen werden. Uns interessiert hier die Grafik-Bibliothek, erkennbar am Vorsatz plot::
. Zunächst betrachten wir Graphiken in Parameterdarstellung.
Im ersten Beispiel nimmt x alle Werte t zwischen 0 und 2π an; y jeweils den Sinus davon.
• plot(plot::Curve2d([t,sin(t)], t=0..2*PI))
Das ist natürlich einfach der Graph der Sinus-Funktion. Aber was passiert, wenn x selbst wieder,
z.B., der Kosinus einer Variablen t ist?
• plot(plot::Curve2d([cos(t),sin(t)], t=0..2*PI))
R. Dietrich, CG Bamberg
1.4. Graphik
9
Es ergibt sich ein Kreis, der allerdings auf den ersten Blick nicht danach ausschaut. Die nötige gleiche
Skalierung der beiden Achsen lässt sich mit der Graphikoption Scaling=Constrained erreichen.
• plot(plot::Curve2d([cos(t),sin(t)], t=0..2*PI),Scaling=Constrained)
Mit etwas Spielerei kann man eine Menge interessanter Figuren erzeugen (der Fachausdruck dafür
heißt Lissajous-Figuren). U.U. ist es sinnvoll, die Anzahl der Stützstellen, an denen die Funktionen
berechnet werden, mit der Graphikoption Grid=[...] zu erhöhen; die gezeichnete Kurve wird
dadurch glatter“.
”
• plot(plot::Curve2d([cos(3*t),sin(7*t)], t=0..2*PI, Grid=[300]),
Scaling=Constrained)
R. Dietrich, CG Bamberg
10
1. Grundlegende Fähigkeiten von MuPAD
Häufig braucht man auch eine graphische Darstellung von Datenpunkten, beispielsweise aus einer Wertetabelle oder aus einem physikalischen Experiment. Dazu wird eine Liste von x- und yKoordinaten mit plot::Pointlist in eine druckbare“ Form gebracht und dann geplottet.
”
• plot(plot::Pointlist([x,sin(3.9*x)] $ x=0..20))
Will man die Punkte verbinden, so braucht man die Option DrawMode=Connected.
• plot(plot::Pointlist([x,sin(3.9*x)] $ x=0..20,DrawMode=Connected))
R. Dietrich, CG Bamberg
1.4. Graphik
11
R. Dietrich, CG Bamberg
Kapitel 2
Programmieren mit MuPAD
Bis jetzt hatten wir für jeden Befehl eine neue Zeile begonnen. Es lassen sich aber auch mehrere
Rechnungen in eine Zeile schreiben, dann muss jede mit einem Semikolon ;“ abgeschlossen werden.
”
Soll eine Rechnung zwar durchgeführt werden, die Ausgabe aber nicht erscheinen, so muss ein Doppelpunkt :“ stehen. Eine Eingabe darf sich auch über mehrere Zeilen erstrecken; auf diese Weise
”
entsteht bereits eine einfache Programmstruktur.
• 2+3; 3+4: 4+5;
5+6; 6+7
2.1
Schleifen
Die einfachste Form einer Schleife lässt sich mit dem for-Befehl realisieren. Das folgende Programm
druckt eine Liste der Quadrate der Zahlen von 1 bis 4 aus.
• for i from 1 to 4 do
print(iˆ2)
end_for:
1
4
9
16
Dabei kann auch rückwärts gezählt oder die Schrittweite verändert werden.
• for i from 20 downto 2 step 4 do
print(iˆ2)
end_for:
400
256
12
2.1. Schleifen
13
144
64
16
Der oben bereits für die Wertetabelle verwendete $-Befehl stellt in vielen Fällen eine elegante Alternative zu einer for-Schleife dar, z.B.
• iˆ2 $ i=1..4
Dabei kann die Zählvariable auch aus einer beliebigen Liste gewählt werden.
• iˆ2 $ i in [2,4,6,8,10]
Als weiteres Beispiel betrachten wir die Fakultät einer natürlichen Zahl n. Man versteht darunter das
Produkt aller natürlichen Zahlen kleiner oder gleich n und schreibt dafür n!. Zur Berechnung können
wir eine for-Schleife benutzen, wie im folgenden Beispiel für 5!:
• n:=5:
x:=1:
for i from 1 to n do
x:=x*i
end_for
Flexibler wird unser Programm, wenn wir ihm einen Namen geben, unter dem es später wieder
aufgerufen werden kann. Das leistet der Befehl proc. Zunächst wird die Variable angegeben, die
eingegeben werden muss, bei uns also n. Dann kommen sog. lokale Variable, d.h. solche, die nur
innerhalb des Programms verwendet werden, wie der Zählindex i. Das eigentliche Programm befindet
sich zwischen den Befehlen begin und end proc .
• fakultaet:=proc(n) local i;
begin
x:=1:
for i from 1 to n do
x:=x*i
end_for
end_proc:
• fakultaet(5)
Als weitere Anwendung wollen wir die Quadratwurzel einer Zahl x von Hand“ berechnen. Eine der
”
ältesten bekannten Methoden, das Heron-Verfahren oder Babylonische Wurzelziehen“ lässt sich sehr
”
schön geometrisch veranschaulichen: Endziel ist ein Quadrat mit Flächeninhalt x und Seitenlängen
√
x. Ausgehend von einem beliebigen Rechteck mit Seitenlängen a und xa (also mit richtigem“
”
R. Dietrich, CG Bamberg
14
2. Programmieren mit MuPAD
Flächeninhalt) kommen wir dem Quadrat näher, wenn die neue Rechteckseite das (arithmetische)
Mittel der beiden alten ist: aneu = (a + xa )/2. Natürlich müsste noch gezeigt werden, dass sich dieses
Verfahren tatsächlich auf ein Quadrat zubewegt, d.h. konvergiert.
Um unseren Erfolg zu kontrollieren setzen wir zunächst die Anzahl der angezeigten
Stellen hoch, z.B. auf 30.
• DIGITS:=30
Gemäß dem Heron-Algorithmus rechnen wir eine feste Anzahl von Schritten durch. Das Ergebnis
unseres Programms vergleichen wir anschließend mit dem exakten Wert, wie er z.B. vom MuPADBefehl sqrt geliefert wird.
• wurzel:=proc(x) local a,aneu,i;
begin
a:=1;
for i from 1 to 4 do
aneu:=(a+x/a)/2.0;
a:=aneu
end_for
end_proc:
• wurzel(12)
• sqrt(12.0)
Für vier Schritte schon nicht schlecht. Um genauer zu werden, muss offensichtlich die Anzahl der
Schritte erhöht werden. Allerdings sollte man auch nicht mehr Schritte ausführen, als gebraucht
werden um das Ergebnis garantiert bis auf z.B. 6 Nachkommastellen genau anzugeben.
Dabei hilft die while-Schleife. Sie prüft zunächst, ob die geforderte Bedingung erfüllt ist. Solange
das der Fall ist, führt sie die dann folgenden Befehle aus, z.B.
• y:=13:
while y>=10 do
print(y,yˆ2);
y:=y-1
end_while:
13, 169
12, 144
11, 121
10, 100
Ersetzen wir also im obigen Programm wurzel die for-Schleife durch eine while-Schleife. Dabei
R. Dietrich, CG Bamberg
2.2. Verzweigungen
15
brauchen wir eine neue Variable d, die den Unterschied zwischen a und aneu misst (am besten nimmt
man den Betrag abs(a-aneu) ). Das Programm soll abbrechen, wenn d einen vorgegebenen Wert
unterschreitet.
• wurzel:=proc(x) local a,aneu,d;
begin
a:=1;
d:=1;
while d>=10ˆ-6 do
aneu:=0.5*(a+x/a);
d:=abs(a-aneu);
a:=aneu
end_while
end_proc:
• wurzel(12)
• sqrt(12.0)
Aufgabe: Lassen Sie sich vom Programm nicht nur das Endergebnis, sondern alle
Zwischenwerte von aneu ausgeben.
2.2
Verzweigungen
Häufig soll ein Programm unterschiedliche Befehle ausführen, je nachdem ob eine bestimmte Bedingung erfüllt ist oder nicht. Mit dem if-Befehl lassen sich solche Verzweigungen realisieren.
Als Beispiel dazu ein einfaches Ratespiel: Ein Spieler gibt eine natürliche Zahl zwischen 1 und 1000
ein, der andere schaut weg.
• x:=721
Diese Zeilen müssen natürlich wieder gelöscht werden, aber MuPAD merkt“ sich die Zahl. Der
”
andere Spieler ruft dann das folgende Programm auf, bis er die Zahl erraten hat.
R. Dietrich, CG Bamberg
16
2. Programmieren mit MuPAD
• raten:=proc(y)
begin
if y<x then print("zu klein")
else print("zu groß oder richtig")
end_if
end_proc:
• raten(800)
“zu groß oder richtig“
Natürlich bräuchte man eigentlich drei Alternativen: zu groß, zu klein und genau richtig. Das lässt
sich erreichen, indem man die Verzweigungen ineinander schachtelt.
• raten:=proc(y)
begin
if y=x then print("richtig")
else
if y<x then print("zu klein")
else print("zu groß")
end_if
end_if
end_proc:
• raten(721)
“richtig“
Verzweigungen sind auch oft nützlich, um unerwünschte Eingaben zu verhindern. So macht (zumindest nach unserer Definition) die Fakultätsfunktion n! nur für natürliche
Zahlen n Sinn. Ergänzen wir daher unser Programm aus dem letzten Abschnitt durch eine entsprechende Abfrage. Der Test kann mit einem Befehl wie is(4, Type::PosInt) durchgeführt
werden. Die Antwort ist entweder TRUE“, falls die Zahl nach der Klammer wie hier tatsächlich eine
”
natürliche Zahl ist, oder FALSE“ falls nicht.
”
• fakultaet:=proc(n) local i;
begin
if is(n, Type::PosInt) then
x:=1:
for i from 1 to n do
x:=x*i
end_for
else print("falsche Eingabe")
end_if
end_proc:
• fakultaet(1.8)
“falsche Eingabe“
R. Dietrich, CG Bamberg
2.3. Listen
17
Aufgabe: Ergänzen Sie das Programm zum Heron-Algorithmus um eine Abfrage, die verhindert,
dass die Wurzel aus einer negativen Zahl gezogen wird.
2.3
Listen
Ein großer Vorteil von MuPAD liegt im Umgang mit komplexeren Datenstrukturen. Davon steht eine
Vielzahl zur Verfügung; wir beschränken uns hier auf den Umgang mit Listen und Matrizen.
Unter einer Liste versteht man eine geordnete Folge beliebiger Objekte; sie ist in eckigen Klammern
eingeschlossen. Am einfachsten lässt sich eine Liste durch Aufzählen angeben
• liste:=[1,6,"a",89.7]
oder mit dem Folgenoperator $ erzeugen.
• quadrate:=[xˆ2 $ x=0..10]
Der Zugriff geschieht über den Index, d.h. die Nummer in der Liste. Wichtig dabei ist,
dass die Zählung immer mit 1 beginnt, auch wenn die Liste anders erzeugt wurde (siehe oben bei
den Quadratzahlen).
• liste[4]
• quadrate[5]
Die Listenelemente selbst (d.h. ohne die umschließende Klammer) nennt man Operanden; man erhält
sie mit dem Befehl op . Auf diese Weise lassen sich ebenfalls einzelne Listenelemente anzeigen.
• op(liste)
• op(quadrate,5)
Folgerichtig ist die Anzahl der Listenelemente die number of operands“ nops :
”
• nops(quadrate)
R. Dietrich, CG Bamberg
18
2. Programmieren mit MuPAD
Listen lassen sich beliebig verschachteln; die entsprechende Indizierung läuft von außen nach innen.
Bei der Schreibweise unterscheiden sich die oben bereits vorgeführten Möglichkeiten geringfügig.
• doppelliste:=[["a","b","c"],["d","e","f"],["g","h","i"]]
• doppelliste[2][3]; op(doppelliste,[2,3])
Listen lassen sich um einzelne Elemente erweitern oder verkürzen.
• append(liste,"neu")
• delete(liste[2]); liste
Beide Befehle funktionieren etwas unterschiedlich: Während delete tatsächlich die Liste verändert
(das Ergebnis selbst aber nicht darstellt) erzeugt append eine neue, noch unbenannte Liste. Diese
könnte dann natürlich durch die Zuordnung liste:= wieder unter dem alten Namen gespeichert
werden.
Auch das Suchen nach bestimmten Elementen ist möglich.
• contains(liste,"a")
Die Ausgabe ist die Position, an der das gesuchte Element zum ersten Mal auftritt; ist es überhaupt
nicht vorhanden, gibt MuPAD die Zahl 0 zurück.
Im Zusammenhang mit graphischen Darstellungen hatten wir im letzten Kapitel bereits mit Listen
gearbeitet. Jetzt können wir das Ganze in ein etwas anspruchsvolleres
Beispiel einbetten: Wir schreiben die Zwischenwerte aus dem Programm zur Wurzelbestimmung mit
append in eine Liste und stellen sie graphisch dar. (Zur Erinnerung: Das geht mit plot(plot::Polygon2d())
.
R. Dietrich, CG Bamberg
2.4. Rechnen mit Listen
19
• wurzel:=proc(x) local a,aneu,d,l;
begin
a:=1;
l:=[];
d:=1;
while d>=10ˆ-6 do
aneu:=0.5*(a+x/a);
l:=append(l,aneu);
d:=abs(a-aneu);
a:=aneu
end_while;
plot(plot::Pointlist([i,l[i]] $ i=1..nops(l),DrawMode=Connected));
a
end_proc:
• wurzel(500)
2.4
Rechnen mit Listen
Sollen auf Listen Rechenoperationen angewendet werden, so ist dies grundsätzlich mit (evtl. mehrfachen) for-Schleifen möglich. Z.B. lässt sich eine Verdreifachung unserer Quadratzahl-Liste folgendermaßen erreichen:
• dreifach:=[0 $ i=1..nops(quadrate)]:
for i from 1 to nops(quadrate) do
dreifach[i]:=3*quadrate[i]
end_for:
dreifach
Es gibt jedoch in MuPAD eine Reihe spezieller Operationen für Listen, die häufig wesentlich eleganter
zu programmieren sind. map wendet eine Funktion (definiert durch den Zuordnungspfeil) der Reihe
R. Dietrich, CG Bamberg
20
2. Programmieren mit MuPAD
nach auf jedes Element einer Liste an:
• dreifach:=map(quadrate,x->3*x)
Sollen hingegen die Elemente einer Liste miteinander verknüpft werden, so kann die entsprechende
Rechenanweisung vorangestellt werden. Die Summe aller unserer Quadratzahlen erhält man so ganz
schnell mit
• _plus(op(quadrate))
Entsprechendes funktioniert auch mit mult für die Multiplikation aller Listenelemente. Dass es
Elemente sind, die miteinander verknüpft werden, wird durch den eingeschalteten op-Befehl berücksichtigt. Ohne ihn erhält man eine Fehlermeldung.
Die Verknüpfung von zwei Listen miteinander ist dagegen ohne Weiteres möglich; gemeint ist dabei
die paarweise Verknüpfung von Elementen jeder der beiden Listen. Das Verfahren erinnert an einen
Reissverschluß und trägt daher den Namen zip. Für die Addition beispielsweise sieht das so aus:
• zip(quadrate,dreifach,_plus)
Falls die beiden Listen verschieden lang sind, stoppt der Reissverschluß mit dem Ende der kürzeren
Liste.
Die zuletzt vorgestellten Konstruktionen sind zunächst wohl etwas ungewohnt, stellen
sich aber bald als sehr mächtig heraus. Insbesondere helfen sie, den Programmieraufwand zu reduzieren und die Programme dadurch übersichtlicher zu halten.
2.5
Matrizen
Der Datentyp der Matrix schließt sich sehr eng an verschachtelte Listen an, als Elemente dürfen
allerdings nur Zahlen vorkommen.
• mat1:=matrix([[1,2,3],[4,5,6],[7,8,9]])
• mat2:=matrix([[2,0,0],[0,2,0],[0,0,2]])
R. Dietrich, CG Bamberg
2.5. Matrizen
21
• matrix(quadrate)
Die einzelnen Einträge werden mit Zeilen- und Spaltennummer angesprochen; die
Schreibweise ist etwas anders als bei verschachtelten Listen.
• mat1[2,3]
Matrizen können direkt (komponentenweise) addiert, multipliziert (im Sinne einer Matrix-Multiplikation)
oder potenziert werden:
• mat1+mat2; mat1*mat2; mat2ˆ2
Aufgabe: Führen Sie die obige Addition der Listen quadrate und dreifach als Additon geeigneter Matrizen aus.
R. Dietrich, CG Bamberg
Herunterladen