Vorlesung 16.11.01 Inhaltsverzeichnis 1.. 3. 4. 5. 6. Einfache Rechnungen Hilfe! Gleitkommazahlen Formales Rechnen Polynome Endliche Körper Einfache Rechnungen Sage kann alles was ein Taschenrechner kann, und das entweder mit Gleitkommazahlen beliebiger Genauigkeit oder exakt mit ganzen Zahlen, Brüchen und "formalen Ausdrücken". Die Auswertung einer Eingabe erfolgt mit Shift+Enter. 1+1 (*3+5)/ ^10 ^100 11/ 104 1676506008940149670305376 1/6 + 7/13 55/78 sqrt(4) Wenn nicht explizit gewünscht, werden irrationale Zahlen nicht ausgewertet, sondern symbolisch weitergeführt. sqrt() sqrt() und zwar so, daß soweit wie möglich die Rechenregeln erhalten bleiben; (allerdings nicht uneingeschränkt, weil bewiesen werden kann, daß es keinen Algorithmus gibt, der jeden Ausdruck zu einer eindeutigen "Normalform" vereinfachen kann). sqrt()^ 1 of 9 01-11-6 09:33
Intern werden Irrationalzahlen anders behandelt als Rationalzahlen oder ganze Zahlen. Sage ist wie Python objektorientiert und jedes Objekt gehört einem eindeutig definierten Typ an, der die notwendigen Operationen bereitstellt. Den Typ kann man sich mit parent oder type anzeigen lassen: parent() type() Integer Ring <type 'sage.rings.integer.integer'> print(parent(1/)) type(1/) Rational Field <type 'sage.rings.rational.rational'> parent(sqrt()) Symbolic Ring Gleitkommazahlen; zur verwendeten Rechengenauigkeit siehe unten sqrt(1.) 1.09544511501033 parent(1.) Real Field with 53 bits of precision Komplexe Zahlen sqrt(-4) *I Die imaginäre Einheit ist vorab in der Variable I angelegt: I^ -1 Weitere mathematische Konstante: pi pi Numerische Approximation: numerical_approx(pi) 3.1415965358979 Zwischenergebnisse können in Variablen abgespeichert werden. In diesem Fall wird nichts auf den Bildschirm ausgegebe, weil das Ergebnis ja in der of 9 01-11-6 09:33
zugewiesenen Variable zur Verfügung steht. a=sqrt() a^ Hilfe! parent(pi) Symbolic Ring Die zur Verfügung stehenden Methoden kann man sich durch pi. und anschließendes Drücken von TAB anzeigen lassen. pi.n() 3.1415965358979 Information über eine Methode erhält man durch ein Fragezeichen pi.n?; will man es noch genauer wissen, macht man zwei Fragezeichen pi.n?? und erhält den Quellcode der Funktion Gleitkommazahlen R = RealField(300) Umwandlung in den gewünschten Typ R(1) 1.000000000000000000000000000000000000000000000000000000000000000000\ 00000000000000000000000 a = R(1.1) a 1.100000000000000000000000000000000000000000000000000000000000000000\ 00000000000000000000000 parent(a) Real Field with 300 bits of precision Zu beachten ist, daß Precision sich auf das Binärsystem bezieht, mit dem intern gerechnet wird. Das sind bei gleicher Genauigkeit in etwa dreimal soviele wie im Dezimalsystem 3 of 9 01-11-6 09:33
pi100= pi.n(digits=100) pi100.parent() Real Field with 336 bits of precision Beim Addieren von Zahlen unterschiedlicher Genauigkeit wird das Resultat in der jeweils kleinsten Genauigkeit berechnet a+1..30000000000000 a+r(1.).300000000000000000000000000000000000000000000000000000000000000000\ 00000000000000000000000 Rechnen mit formalen Ausdrücken Um mit formalen Ausdrücken zu rechnen, muß man entsprechende Variablennamen deklarieren var('x,y,z') x+y (x, y, z) x + y wenn man das nicht tut, dann kommt ein Fehler x+u Traceback (click to the left of this block for traceback)... NameError: name 'u' is not defined Die Ausdrücke werden vorerst nicht ausmultipliziert p1=(x+y+z)^ p1 (x + y + z)^ man mache sich den prinzipiellen Unterschied zwischen der "Variable" p1 und der "Variable" x klar: p1 bezeichnet einen Platz im Speicher des Computers, in dem ein gewisser Wert abgelegt ist, während x eine Variable im Sinne der Analysis ist, d.h., ein Platzhalter, für den verschiedene Werte eingesetzt werden können. nur die elementarsten Vereinfachungen werden gemacht p1+y + y 4 of 9 01-11-6 09:33
(x + y + z)^ + *y alles weitere muß explizit angefordert werden expand(p1) x^ + *x*y + *x*z + y^ + *y*z + z^ das gleiche in oo (=objektorientierter) Notation p1.expand() x^ + *x*y + *x*z + y^ + *y*z + z^ die inverse Operation zum ausmultiplizieren ist factor p= x^-*x*y+y^ p x^ - *x*y + y^ factor(p) (x - y)^ Zum Vergleich: Wenn man factor auf eine ganze Zahl anwendet, wird trotz gleichen Namens der Funktion eine ganz andere Methode aufgerufen: factor(104) ^10 Das Multiplikationszeichen muß immer explizit angeführt werden: x Traceback (click to the left of this block for traceback)... SyntaxError: invalid syntax Wie in der Vorlesung erklärt, werden formale Ausdrücke als Baum angelegt. Beim Substitutieren wird dieser Baum durchsucht und ggf. ein gefundener Teilausdruck ersetzt p.substitute(y=sin(z)) x^ - *x*sin(z) + sin(z)^ Lösen von Gleichungen solve(x^+1 == 0,x) [x == -I, x == I] solve(x^+x+1==0, x) [x == -1/*I*sqrt(3) - 1/, x == 1/*I*sqrt(3) - 1/] solve(x^3+x+1==0,x) 5 of 9 01-11-6 09:33
[x == -1/*(I*sqrt(3) + 1)*(1/18*sqrt(3)*sqrt(31) - 1/)^(1/3) + 1/6*(-I*sqrt(3) + 1)/(1/18*sqrt(3)*sqrt(31) - 1/)^(1/3), x == -1/*(-I*sqrt(3) + 1)*(1/18*sqrt(3)*sqrt(31) - 1/)^(1/3) + 1/6*(I*sqrt(3) + 1)/(1/18*sqrt(3)*sqrt(31) - 1/)^(1/3), x == (1/18*sqrt(3)*sqrt(31) - 1/)^(1/3) - 1/3/(1/18*sqrt(3)*sqrt(31) - 1/)^(1/3)] Für die Gleichung 5.Ordnung gibt es keine allgemeine Lösungsformel solve(x^5+*x^3+x^-3*x+1==0,x) [0 == x^5 + *x^3 + x^ - 3*x + 1] Polynome Wenn man von vorneherein weiß, daß man es nur mit Polynomen zu tun hat, ist es effizienter, in einem Polynomring zu arbeiten. Hier die Polynome in der Variable t über dem Körper der rationalen Zahlen P.<t> = QQ[] Exkurs in andere Zahlenbereiche RealField(100) Real Field with 100 bits of precision RR Real Field with 53 bits of precision QQ Rational Field ZZ Integer Ring P Univariate Polynomial Ring in t over Rational Field t muß nicht mehr deklariert werden, es weiß jetzt, wo es zu Hause ist: parent(t) Univariate Polynomial Ring in t over Rational Field t^+1 t^ + 1 Nullstellen findet man jetzt nicht mit solve solve(t^+1==0,t) Traceback (click to the left of this block for traceback) 6 of 9 01-11-6 09:33
... TypeError: The first argument must be a symbolic expression or a list of symbolic expressions. sondern mit der Methode roots (t^+1).roots() [] Allerdings werden Lösungen nur im zugrundegelegten Körper gesucht (siehe t.roots?), man kann aber den Suchbereich ausweiten, indem man einen größeren Ring angibt. (t^+1).roots(ring=cc) CC [(-1.00000000000000*I, 1), (1.00000000000000*I, 1)] Complex Field with 53 bits of precision Oder aber das Polynom selbst in einen anderen Typ umwandeln "Cast" SR Symbolic Ring p=sr(t^+1) p t^ + 1 parent(p) Symbolic Ring und die Gleichung dort lösen solve(p==0,sr(t)) [t == -I, t == I] manchmal geht das automatisch, z.b. enthält der Symbolic Ring alle rationalen Polynome. x+t t + x Endliche Körper heißen auf Englisch Galois field, so erhät man den Restklassenkörper Z/5Z durch GF(5) Finite Field of size 5 7 of 9 01-11-6 09:33
Z5=GF(5) a = Z5() a a*a*a 3 Auch lineare Algebra kann über beliebigen Körpern betrieben werden, davon später mehr v=vector([a,a,-a]) v 3*v (,, 3) (1, 1, 4) Vektoren sind streng von Listen zu unterscheiden l=[1,,3] l 3*l [1,, 3] [1,, 3, 1,, 3, 1,, 3] dieses seltsame Verhalten erklärt sich dadurch, daß die Addition von Listen durch Aneinanderhängen erklärt ist. [1,,3] + [4,5,6] [1,, 3, 4, 5, 6] Außerdem können Listen beliebige Objekte enthalten, während Vektoren nur über Ringen erklärt werden können (und nicht nur Körpern wie in der linearen Algebra) [1,[],"c"] [1, [], 'c'] vector(1,,"c") Traceback (click to the left of this block for traceback)... ValueError: incompatible degrees in vector constructor Manchmal geht es doch, aber mit unvorhergesehenen Konsequenzen v=vector([a,x]) v (, x) 8 of 9 01-11-6 09:33
parent(v) Vector space of dimension over Symbolic Ring d.h. die Zahl hat den endlichen Körper verlassen. Die Variable a ist davon natürlich nicht betroffen. parent(a) Finite Field of size 5 9 of 9 01-11-6 09:33