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:

In>

Ausgaben werden durch folgenden Prompt eingeleitet:

Out>

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

In> Sin(Pi/2);
Out> 1;

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:

In> ??

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:

In> ?Sum

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:

f(x):=2*x*x

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:

f(x):=Eval(x+x)

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

uu:={a,b,c,d,e,f};

hat

uu[2];

den Wert b und

uu[2 .. 4];

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:

u:={};

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;