Yacas im Überblick
Einführung
Yacas (Yet Another Computer Algebra System) ist ein hochflexibles, universell
einsetzbares Computer Algebra System. Yacas enthält eine kleine Bibliothek
mathematischer Funktionen, die eigentliche Stärke ist jedoch die eingebaute
Programmiersprache, mit der auf einfache Weise eigene Algorithmen implementiert
werden können. Numerische Berechnungen können mit beliebiger Genauigkeit ausgeführt
werden.
Yacas Installation
Hinweise zum Kompilieren des Yacas-Quellcodes finden sich in der Datei
INSTALL. Erforderlich ist ein C++-Compiler wie z.B.
g++.
Yacas erwartet als Eingabe reinen ascii-Text und liefert als Ausgabe ebenfalls
ascii-Text. Damit ist das Programm weitestgehend plattformunabhängig. Yacas ist
lauffähig unter UNIX, Windows und EPOC32 (Psion).
Unter UNIX erfolgt das Kompilieren und die Installation nach dem üblichen Schema:
./configure
make
make install
|
Yacas kann mit Unterstützung für die "libgmp"-Bibliothek kompiliert werden
(configure-Option --enable-gmp). Damit werden math. Berechnungen mit hoher
Genauigkeit deutlich beschleunigt.
Bedienung im Textmodus
Yacas läuft auf der Textkonsole oder im Terminalfenster (z.B. xterm) und wird durch
Eingabe von yacas gestartet. Yacas meldet sich daraufhin mit dem
Prompt:
Ausgaben werden durch folgenden Prompt eingeleitet:
Beendet wird Yacas durch Eingabe von Exit() oder quit
oder ^C. Drücken von ^C während einer längeren Berechnung beendet nur die aktuelle
Berechnung.
Im Normalfall wird eine Anweisung pro Zeile eingegeben, z.B.:
Anweisungen werden mit einem Semikolon (;) abgeschlossen. Fehlt das
Semikolon in der Eingabe, wird es automatisch eingefügt.
Die gesamte Dokumentation ist über den Yacas-Prompt zugänglich. Nach Eingabe von:
kann auf die Funktionsreferenz und die verschiedenen Handbücher zugegriffen werden.
Als Browser ist lynx voreingestellt, so dass die Hilfetexte auch auf der
Textkonsole lesbar sind.
Der Hilfetext für eine bestimmte Yacas-Funktion kann folgendermaßen angezeigt werden:
Einige zufällige Beispiele können mit der Funktion Example();
angezeigt werden.
Die zuletzt eingegebenen Anweisungen werden in einer "history"-Liste gespeichert.
Mit Hilfe der Cursortasten kann diese Liste durchlaufen werden. Werden nur die
ersten Zeichen einer Anweisung eingegeben und danach die TAB-Taste gedrückt, dann
wird die letzte Anweisung angezeigt, die mit dieser Zeichenfolge beginnt.
Gehen Anweisungen über mehrere Zeilen, dann muss jede Zeile mit einem Backslash "\"
abgeschlossen werden, z.B.:
In> a:=2+3+
Error on line 1 in file [CommandLine]
Line error occurred on:
>>>
Error parsing expression
In> a:=2+3+ \
In> 1
Out> 6;
|
Fehlermeldungen werden ohne Out>-Prompt ausgegeben.
Yacas als symbolischer Rechner
Nun zu den ersten einfachen Berechnungen. Die Yacas-Syntax ist C-ähnlich und
unterscheidet Groß- und Kleinschreibung. Das erste Beispiel zeigt eine exakte
Berechnung mit Brüchen:
In> 1/14+5/21*(30-(1+1/2)*5^2);
Out> -12/7;
|
Für symbolische Berechnungen enthält Yacas eine Bibliothek mit Regeln für die
Vereinfachung algebraischer Ausdrücke. Namen wie z.B. x werden als
unabhängige Variablen interpretiert und nicht numerisch berechnet.
In> 0+x;
Out> x;
In> x+1*y;
Out> x+y;
In> Sin(ArcSin(alpha))+ArcCos(Cos(beta));
Out> alpha+beta;
In> (x+y)^3-(x-y)^3
Out> (x+y)^3-(x-y)^3;
In> Simplify(%)
Out> 6*x^2*y+2*y^3;
|
Der Operator % symbolisiert das Ergebnis der vorangegangenen
Berechnung. Die Funktion Simplify vereinfacht algebraische
Ausdrücke. Funktionsnamen in Yacas beginnen mit einem Großbuchstaben. Der
Unterstrich _ hat eine besondere Bedeutung und darf in Variablen- und
Funktionsnamen nicht verwendet werden.
Yacas kann Berechnungen mit beliebiger Genauigkeit durchführen:
In> 20!;
Out> 2432902008176640000;
|
Mit dem Befehl Precision(n); lässt sich die Genauigkeit von
Fließkommazahlen auf n Nachkommastellen fest einstellen:
In> Precision(30);
Out> True;
In> 1.0/243;
Out> 0.004115226337448559670781893004;
|
Der Zähler wurde hier explizit als Fließkommazahl eingegeben, um die numerische
Berechnung zu erzwingen.
Auch Ableitungen von Funktionen können berechnet werden:
In> D(x) Sin(x);
Out> Cos(x);
In> D(x) D(x) Sin(x);
Out> -Sin(x);
|
Brüche, deren Zähler und Nenner ganze Zahlen sind, werden in einer Berechnung nicht
in Fließkommazahlen umgewandelt. Beispielsweise ist das Ergebnis von 55/10
der Bruch 11/2. Die Umwandlung in eine Fließkommazahl kann jedoch
mit der Funktion N() erzwungen werden. Das Ergebnis von
N(55/10) ist dann 5.5. Dieses Verhalten gilt für fast
alle mathematischen Funktionen. Yacas versucht immer, Ergebnisse als exakte
Bruchzahlen anzugeben. Für die Kreiszahl sollte immer Pi verwendet
werden. Yacas kann damit auch trigonometrischen Ausdrücke vereinfachen.
Die imaginäre Einheit i wird mit I bezeichnet. Komplexe
Zahlen können als Ausdrücke mit I geschrieben werden oder explizit
als Complex(a,b) für a+i*b.
Zum Lösen von Gleichungen sind einige Algorithmen enthalten:
In> Solve(a+x*y==z,x);
Out> (z-a)/y;
In> Solve({11*x+3*y==1,2*x+y==0},{x,y})
Out> {{1/5,-2/5}};
|
Gleichungen müssen mit dem == Operator formuliert werden. Zurzeit
können mit Solve nur Gleichungen gelöst werden, in denen die
Variable nur einmal vorkommt.
Taylor Reihen können folgendermaßen berechnet werden:
In> Taylor(x,0,3) Exp(x)
Out> 1+x+(1/2)*x^2+(1/6)*x^3
In> PrettyForm(%);
/ 1 \ 2 / 1 \ 3
1 + x + | - | * x + | - | * x
\ 2 / \ 6 /
Out> True;
|
Die Funktion PrettyForm() gibt das schwer lesbare Ergebnis in einer
übersichtlicheren Form an.
Variables
Yacas unterstützt das Rechnen mit Variablen:
In> Set(a,Cos(0));
Out> True;
In> a:=a+1;
Out> 2;
|
Der globalen Variablen a wurde der Wert 2 zugewiesen. Für
Wertzuweisungen können die Funktion Set() oder der Operator
:= verwendet werden.
Die Bindung einer Zahl an eine Variable kann mit der Funktion Clear(a);
aufgehoben werden. a; wird dann einfach zu a berechnet.
In der Wertzuweisung mit Set() oder := gibt es keinen
Unterschied. Mit dem Operator := können jedoch auch Listen zugewiesen
und Funktionen definiert werden.
Funktionen
Funktionen werden mit dem := Operator definiert:
Damit wurde eine neue Funktion "f" definiert.
Ein Funktionsname wie z.B. "f" kann für unterschiedliche Funktionen verwendet werden,
wenn diese sich in der Anzahl der Argumente unterscheiden.
In> f(x):=x^2;
Out> True;
In> f(x,y):=x*y;
Out> True;
In> f(3)+f(3,2);
Out> 15;
|
Funktionen können auch boolsche Werte (True oder False)
zurückgeben. Solche Funktionen heißen boolsche Funktionen:
In> IsNumber(2+x);
Out> False;
In> IsInteger(15/5);
Out> True;
|
Vor einer Wertzuweisung wird der zuzuweisende Ausdruck ausgewertet, d.h.
a:=2*2 |
setzt a auf den Wert 4. Dies gilt allerdings nicht für
Funktionen. In der Definition f(x):=x+x wird die rechte Seite
x+x nicht ausgewertet. Mit Hilfe der Funktion Eval
kann die Auswertung jedoch erzwungen werden:
x+x wird hier zunächst in 2*x umgeformt und dann der
Funktion f zugewiesen. Die Verwendung von Eval macht in diesem
speziellen Beispiel keinen Sinn. Ist jedoch die rechte Seite ein komplizierter
Ausdruck wie z.B. eine Taylorentwicklung, dann muss diese bei Verwendung von
Eval nur einmal berechnet werden und nicht bei jedem Aufruf von f
erneut.
Strings und Listen
Neben den schon besprochenen Zahlen und Variablen unterstützt Yacas auch Strings
und Listen. Strings sind einfache, in Anführungszeichen eingeschlossene Zeichenketten,
z.B. "Dies ist ein String, der \"Anführungszeichen\" enthält".
Listen sind geordnete Mengen von Elementen. Die Listenelemente werden durch Komma
getrennt in geschweiften Klammern eingeschlossen. Eine Liste mit den Elementen a, b
und c wird als {a,b,c} geschrieben. Vektoren sind Listen, Matrizen
sind Listen von Listen. Tatsächlich kann jeder Ausdruck in eine Liste umgewandelt
werden.
Auf Listenelemente kann mit dem [ ] Operator zugegriffen werden.
In der folgenden Liste
hat
den Wert b und
liefert die Liste {b,c,d}. Der Operator .. muss von Leerzeichen
eingeschlossen sein.
Ein Spezialfall sind Schlüssellisten. In Yacas sind Schlüssellisten einfache Listen
von Schlüssel-Wert Paaren. Schlüssel müssen Strings sein, die Werte können beliebige
Objekte sein. Das folgende Beispiel zeigt, wie eine einfache Datenbank mit Hilfe
einer Schlüsselliste realisiert werden kann. Zunächst wird eine leere Liste
definiert:
dann erfolgt die Eingabe der Schlüssel-Wert Paare:
u["name"]:="Isaia";
u["occupation"]:="prophet";
u["is alive"]:=False;
|
Der Ausdruck u["name"] liefert dann "Isaia". Die
Liste u enthält jetzt drei Teillisten:
In> u;
Out> { {"is alive", False}, {"occupation", "prophet"}, {"name", "Isaia"} };
|
Listen können auch für mehrfache Wertzuweisungen verwendet werden. Beispielsweise
wird mit {x,y}:={2!,3!} der Variablen x der Wert 2 und y der Wert 6
zugewiesen.
Die Elemente einer Liste werden ausgewertet und als neue Liste zurückgegeben. Die
Liste {1+2,3}; ergibt somit {3,3}.
Die Idee, Ausdrücke durch Listen zu repräsentieren, geht zurück auf die Programmiersprache
LISP, die in den 70er Jahren entwickelt wurde. Zusammen mit einigen Operatoren für
Listen können sehr leistungsfähige Algorithmen implementiert werden.
Argumente von Funktionen können auch Listen sein. Dies erlaubt Funktionen mit einer
variablen Anzahl von Argumenten.
Die folgenden Beispiele zeigen einige Operationen mit Listen:
In> m:={a,b,c};
Out> True;
In> Length(m);
Out> 3;
In> Reverse(m);
Out> {c,b,a};
In> Concat(m,m);
Out> {a,b,c,a,b,c};
In> m[1]:="blah blah";
Out> True;
In> m;
Out> {"blah blah",b,c};
In> Nth(m,2);
Out> b;
|
Weitere Operationen mit Listen werden in der Yacas Funktionsreferenz beschrieben.
Lineare Algebra
Vektoren werden als Listen ihrer Komponenten dargestellt. Die Liste {1,2,3} ist ein
dreidimensionaler Vektor mit den Komponenten 1, 2 und 3. Matrizen werden als Listen
von Listen dargestellt.
Der Zugriff auf die Komponenten eines Vektors erfolgt wie der Zugriff auf die Elemente
einer Liste:
In> l:=ZeroVector(3);
Out> True;
In> l;
Out> {0,0,0};
In> l[ 2 ]:=2;
Out> True;
In> l;
Out> {0,2,0};
|
Die Multiplikation von Matrizen, Vektoren und Skalaren erfolgt nach den Regeln der
linearen Algebra:
In> v:={1,0,0,0}
Out> {1,0,0,0};
In> E4:={ {0,u1,0,0},{d0,0,u2,0},{0,d1,0,0},{0,0,d2,0}}
Out> {{0,u1,0,0},{d0,0,u2,0},{0,d1,0,0},{0,0,d2,0}};
In> CharacteristicEquation(E4,x)
Out> x^4-x*u2*d1*x-u1*d0*x^2;
In> Expand(%,x)
Out> x^4-(u2*d1+u1*d0)*x^2;
In> v+E4*v+E4*E4*v+E4*E4*E4*v
Out> {1+u1*d0,d0+(d0*u1+u2*d1)*d0,d1*d0,d2*d1*d0};
|
Die mathematische Bibliothek von Yacas enthält u.a. Funktionen zum Berechnen von
Determinanten, des Inversen einer Matrix, von Eigenvektoren und Eigenwerten und zum
Lösen von linearen Gleichungssystemen. Weitere Matrixoperationen werden ausführlich
in der Yacas Funktionsreferenz beschrieben.
Verzweigungen, Schleifen, Blöcke
Die in Yacas enthaltene Programmiersprache umfasst verschiedene Befehle zur Steuerung
des Ablaufs von Programmen. Schleifen können mit den Funktionen ForEach()
oder While() realisiert werden.
Für bedingte Verzweigungen steht die Funktion If() zur Verfügung.
absx := If( x>=0, x, -x );
|
Mehrere Yacas-Anweisungen können mit Hilfe der Funktion Prog() oder
durch Setzen von eckigen Klammern zusammengefasst werden.
Im folgenden Beispiel wird eine Liste der geraden Zahlen von 2 bis 20 erzeugt und
dann das Produkt dieser Zahlen mit Ausnahme der durch 3 teilbaren berechnet. (Das ist
nicht unbedingt die eleganteste Lösung in Yacas.)
In> L := {};
Out> {};
In> i := 2;
Out> 2;
In> While(i<=20) [ L:= Append(L, i); i := i+2; ]
Out> True;
In> L;
Out> {2,4,6,8,10,12,14,16,18,20};
In> answer := 1;
Out> 1;
In> ForEach(i, L) If (Mod(i, 3)!=0, answer := answer * i);
Out> True;
In> answer;
Out> 2867200;
|