Inhaltsverzeichnis

  1. Sage als Taschenrechner
  2. Symbolisches Rechnen
  3. Plotten von Funktionen
  4. Interaktive Programme
  5. Datentypen
  6. Kontrollstrukturen
  7. Definieren von Funktionen

Sage als Taschenrechner

Man kann Sage einfach als sehr mächtigen Taschenrechner verwenden. Es werden dabei Zahlen mit beliebiger Genauigkeit unterstützt, ebenso Brüche und komplexe Zahlen. Für viele Berechnungen werden exakte Ergebnisse geliefert.

Um eine Rechnung auszuführen, geben wir die Rechnung in eine Zelle ein und drücken dann Umschalt + Enter um die Berechnung zu starten.

{{{id=1| 1 + 1 /// 2 }}} {{{id=3| (2 * 2 + 5)/3 /// 3 }}}

Exponentation

{{{id=5| 2^10 /// 1024 }}}

Langzahlarithmetik

{{{id=175| 2^1000 /// 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376 }}}

Bruchrechnen

{{{id=7| 1/6 + 7/12 /// 3/4 }}}

Komplexe Zahlen

{{{id=12| sqrt(-4) /// 2*I }}} {{{id=17| I^2 /// -1 }}}

Realteil

{{{id=13| real((1 + I)/(1 - I)) /// 0 }}}

Imaginärteil

{{{id=177| imag((1 + I)/(1 - I)) /// 1 }}}

Exakte Auswertung mathematischer Funktionen

{{{id=178| sin(pi/2) /// 1 }}} {{{id=179| sin(pi/3) /// 1/2*sqrt(3) }}} {{{id=182| sin(pi/4) /// 1/2*sqrt(2) }}}

Um Ungeleichungen exakt auszuwerten, müssen wir sie in einen Wahrheitswert umwandeln.

{{{id=176| bool(sqrt(2) < 2 * sin(pi/3)) /// True }}}

Gleitkommaarithmetik mit beliebiger Genauigkeit

{{{id=30| numerical_approx(pi, digits = 400) /// 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609 }}}

Dasselbe in objektorientierter Notation

{{{id=31| (pi + e^2).n(digits = 1000) /// 10.53064875252044346569307084385451069737748496992695314506207241483039020236526676201234731042123886275590124777876117277097844830233185560620375162152655889235040699830934927480795097557049963701696378469845884387433766711073088310952924570668588183727498045499422364962979222638894338056735555244878904540583029101038120479507969240851237801498812897048093035647254337983403014542652297161592863442315991833510138597124827441396033036719792839281241506021438151270971542695772401826064679018024083176608964530353652283456589289927479291800180093729617333369278105300058305767541627736043428953362070924906013833879518199973750309002758643851883702926331707287258181290037567515935461189742948294037381966476375511412614298109036235160131324605658645832842067385414023361513679088972798600438648896389142901008412490961373517244673668998768162507274864289812079578153923518660991290853999013639314329067156430539000857850175309296293268346866917304865948408910465623063448527807274335625240795500791 }}}

Bei längeren Berechnungen ist es sinnvoll sich zuerst einen geeigneten Datentyp zu definieren.

{{{id=34| R = RealField(1000) # Praezision in Bits /// }}} {{{id=35| a = R(pi + 2 * cos(sqrt(2))) # ist aequivalent zu # a = (pi + 2*cos(sqrt(2))).n(prec=1000) a /// 3.45348004312054218537193934109668216744606390015771653475576512778581944853927991583839488586037872127640744221244934330297809724069799196701472904141229851345704604036901163048293103154488672423994678507761079241574053184885496625498252454523664605727741827887817599528269501839305499660252464797407 }}}

Der Typ einer Variable lässt sich mit der Funktion type() ermitteln.

{{{id=239| type(a) /// }}}

Genauere Informationen für mathematische Typen gibt der Befehl parent().

{{{id=39| parent(a) /// Real Field with 1000 bits of precision }}}

Achtung: Kommen Zahlen unterschiedlicher Präzision in einer Rechnung vor, dann hat das Ergebnis immer die kleinste Präzision. Konstanten müssen also manuell zu einer Zahl mit hoher Präzision konvertiert werden.

{{{id=217| parent(0.1) /// Real Field with 53 bits of precision }}} Falsch: {{{id=36| a1 = 2 * a + 0.1 print a1 parent(a1) /// 7.00696008624108 Real Field with 53 bits of precision }}}

Falsch: Hier wird mit $2a+0.1$ mit niedriger Präzision berechnet, und danach das Ergebnis zu einer Zahl mit 1000 Bit Präzision konvertiert

{{{id=37| b = R(2 * a + 0.1) print b parent(b) /// 7.00696008624108390705487181548960506916046142578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Real Field with 1000 bits of precision }}} Richtig: {{{id=40| c = 2 * a + R(0.1) print c parent(c) /// 7.00696008624108437074387868219336433489212780031543306951153025557163889707855983167678977172075744255281488442489868660595619448139598393402945808282459702691409208073802326096586206308977344847989357015522158483148106369770993250996504909047329211455483655775635199056539003678610999320504929594815 Real Field with 1000 bits of precision }}}

Symbolisches Rechnen

Symbolische Variablen müssen deklariert werden.

{{{id=51| var('x, y, z') /// (x, y, z) }}} {{{id=49| expr1 = (x + y + z)^3 expr1 /// (x + y + z)^3 }}} {{{id=243| parent(expr1) /// Symbolic Ring }}}

Anzeige in mathematischer Notation. (Dafür müssen die jsMath Schriften installiert sein)

{{{id=65| show(expr1) ///
{(x + y + z)}^{3}
}}}

Ausmultiplizieren

{{{id=47| show(expand(expr1)) ///
x^{3} + 3 \, x^{2} y + 3 \, x^{2} z + 3 \, x y^{2} + 6 \, x y z + 3 \, x z^{2} + y^{3} + 3 \, y^{2} z + 3 \, y z^{2} + z^{3}
}}}

Faktorisieren

{{{id=219| expr2 = (x^2 - 2 * x * y + y^2) show(expr2) ///
x^{2} - 2 \, x y + y^{2}
}}} {{{id=53| show(factor(expr2)) ///
{(x - y)}^{2}
}}}

Substitution von Variablen und Termen

{{{id=62| expr3 = expr2.substitute(y = sin(z^2)) show(expr3) ///
x^{2} - 2 \, x \sin\left(z^{2}\right) + \sin\left(z^{2}\right)^{2}
}}} {{{id=72| expr3.subs_expr(sin(z^2) == y).show() ///
x^{2} - 2 \, x y + y^{2}
}}}

Differentialrechnung

{{{id=180| diff(x * sin(x), x).show() ///
x \cos\left(x\right) + \sin\left(x\right)
}}}

Polynome

Wir konstruieren einen Datentyp für Polynome in der Variablen t, und Koeffizienten aus den Rationalen Zahlen ($\mathbb{Q}$).

{{{id=184| P. = QQ[] /// }}}

gen() gibt die Variable des Polynoms zurück

{{{id=189| P.gen() /// t }}} Wir definieren uns einige Polynome {{{id=195| p1 = (1/2 * t - 3/2) * (t - 1/4) show(p1) parent(p1) ///
\frac{1}{2} t^{2} - \frac{13}{8} t + \frac{3}{8}
Univariate Polynomial Ring in t over Rational Field }}}

roots() berechnet die Nullstellen eines Polynoms zusammen mit ihren Vielfachheiten.

{{{id=199| p1.roots() /// [(3, 1), (1/4, 1)] }}} Probe durch Einsetzen. {{{id=196| p1(3); p1(1/4) /// 0 0 }}}

degree() berechnet den Grad des Polynoms.

{{{id=194| p1.degree() /// 2 }}}

Polynome werden immer automatisch expandiert.

{{{id=191| p2 = (1 - 5*t + t^2) * (1+7*t+t^3) show(p2) ///
t^{5} - 5 t^{4} + 8 t^{3} - 34 t^{2} + 2 t + 1
}}}

Standardmäßig berechnet roots() nur Nullstellen in der selben Grundmenge in der die Koeffizienten des Polynoms liegen. In unserem Fall $\mathbb{Q}$. Unser Polynom hat keine rationalen Nullstellen.

{{{id=201| p2.roots() /// [] }}}

Wir können die Grundmenge aber auch explizit angeben. Hier berechnen wir alle reellen Nullstellen.

{{{id=202| p2.roots(ring = RR) /// [(-0.142444250604287, 1), (0.208712152522080, 1), (4.79128784747792, 1)] }}}

Um sämtliche Nullstellen zu bekommen, brauchen wir komplexe Zahlen.

{{{id=204| html.table(p2.roots(ring = CC)) ///
-0.142444250604287 1
0.208712152522080 1
4.79128784747792 1
0.0712221253021442 - 2.64862563859026i 1
0.0712221253021442 + 2.64862563859026i 1
}}}

Plotten von Funktionen

Sage verfügt über vielfältige High-level Funktionen zum Plotten von Funktionen.

Wir plotten das Polynom $p_2 = -t^6 + 3 t^5 - 5 t^3 + 3 t + 1$ im Intervall $[-1,2]$.

{{{id=206| p3 = (1+t-t^2)^3 plot(p3, -1, 2) /// }}} Plot einer Funktion mit Polstellen. Es sind leider keine Details sichtbar. {{{id=209| f(x) = (sin(5 * x) - 1)/(2 * x^2 - 3 * x - 2) p = plot(f(x), (x, -3, 3), rgbcolor = 'red') p.show() /// }}}

Für ein besseres Ergebnis müssen wir den den Bildbereich explizit auswählen.

{{{id=210| plot2 = plot(f(x), (x, -3, 3), rgbcolor = 'red', detect_poles = 'show') plot2.show(ymin = -5, ymax = 5) /// }}}

Interaktive Programme

Sage bietet die Möglichkeit kleine interaktive Progamme in das Notebook einzubinden (Siehe die Dokumentation zu interact). Weitere Beispiele für interact finden Sie im Sage-Wiki.

Das folgende Beispiel visualisiert die Taylorpolynome der Funktion $f(x) = \sin(x)\cdot e^{-x}$.

{{{id=221| var('x') f(x) = sin(x) * e^(-x) p = plot(f, -1, 5, thickness = 2) html('

Taylor Polynome

') @interact def _(x0 = input_box(0, label = "x0="), order = slider(0, 12, 1, label = "Ordnung: ", default = 3)): ft = f.taylor(x, x0, order) pt = plot(ft, -1, 5, color = 'green', thickness = 2) dot = point((x0, f(x0)), pointsize = 80, rgbcolor = (1, 0, 0)) html('$f(x) = %s$' % latex(f(x))) html('$\hat{f}(x;%s) = %s + \mathcal{O}(x^{%s})$' % (latex(x0), latex(ft(x)), order + 1)) (dot + p + pt).show(ymin = -.5, ymax = 1) /// }}}

Datentypen

Die wichtigsten Datentypen in Python sind:

Weitere Informationen finden Sie in der Python Dokumentation.

Tupel

Tupel sind ähnlich wie Listen, nur können einmal erstellte Tupel nicht mehr verändert werden (immutable). Tupel sind besonders nützlich, um mehrere Werte gleichzeitig von einer Funktion zurückzugeben.

{{{id=226| a = 1, 2, 3 a /// (1, 2, 3) }}} {{{id=102| a[0]; a[1]; a[2] /// 1 2 3 }}}

Die Funktion xgcd(a, b) berechnet den kleinsten gemeinsamen Teiler von a und b mit Hilfe des erweiterten Euclidschen Algrithmus und gibt das Ergebnis als Tupel von drei Zahlen zurück.

{{{id=225| t = xgcd(14, 25) t /// (1, 9, -5) }}} Man kann die Elemente des Tupels auch direkt einzelnen Variablen zuweisen (Tupel unpacking). {{{id=103| a1, a2, a3 = xgcd(14, 25) a2 /// 9 }}} Simultanes vertauschen zweier Variablen {{{id=222| t1 = 10 t2 = cos(x) t1; t2 /// 10 cos(x) }}} {{{id=183| t1, t2 = t2, t1 t1; t2 /// cos(x) 10 }}}

Listen

Listen sind wahrscheinlich der wichtigste Datentyp in Sage/Python. Der wichtigste Unterschied zu Tupeln ist dass Listen veränderbar (mutable) sind. Sie können Elemente zu Listen hinzufügen, löschen, verändern. Das ist bei Tupeln nicht möglich.

Einige Operationen auf Listen:

 

{{{id=107| L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] L /// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }}} {{{id=108| len(L) /// 10 }}}

Slices

{{{id=111| print L[0] # erstes Element print L[1] # zweites Element print L[-1] # letztes Element print L[2:5] # ein Teil der Liste print L[::3] # jedes dritte Element /// 1 2 10 [3, 4, 5] [1, 4, 7, 10] }}}

Hinzufügen von Elementen

{{{id=109| L.append(11) print "Liste:", L print "Anzahl der Elemente:", len(L) /// Liste: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] Anzahl der Elemente: 11 }}} Ersetzen von Elementen und Teillisten {{{id=119| L[0] = "Hallo" L /// ['Hallo', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] }}} {{{id=228| L[1:3] = 1/2 L /// ['Hallo', 1/2, 4, 5, 6, 7, 8, 9, 10, 11] }}} {{{id=237| L[2] = [pi/6, e] L /// ['Hallo', 1/2, [1/6*pi, e], 5, 6, 7, 8, 9, 10, 11] }}}

Sehr nützlich ist die Funktion zip, die ein Tupel von Listen in eine Liste von Tupeln verwandelt.

{{{id=118| zip([1, 2, 3], ['a', 'b', 'c'], [sin, cos, tan]) /// [(1, 'a', sin), (2, 'b', cos), (3, 'c', tan)] }}}

Erzeugen von Listen

{{{id=133| range(10) /// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }}} {{{id=134| range(0, 101, 20) /// [0, 20, 40, 60, 80, 100] }}} {{{id=139| range(10, 0, -1) /// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }}}

srange ist ähnlich wie range, aber für Fließkommazahlen

{{{id=135| srange(0, 1, 0.1, include_endpoint = True) /// [0.000000000000000, 0.100000000000000, 0.200000000000000, 0.300000000000000, 0.400000000000000, 0.500000000000000, 0.600000000000000, 0.700000000000000, 0.800000000000000, 0.900000000000000, 1.00000000000000] }}} {{{id=137| R = RealField(prec = 200) srange(R(0), R(0.5), R(0.1)) /// [0.00000000000000000000000000000000000000000000000000000000000, 0.10000000000000000000000000000000000000000000000000000000000, 0.20000000000000000000000000000000000000000000000000000000000, 0.30000000000000000000000000000000000000000000000000000000000, 0.40000000000000000000000000000000000000000000000000000000000] }}}

Kurznotation für arithmetische Progressionen

Achtung: Diese Notation ist Sage spezifisch und funktioniert nicht in Standard Python.

{{{id=138| [1..100] /// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100] }}} {{{id=136| [1,3..10] /// [1, 3, 5, 7, 9] }}} {{{id=131| [0,0.2..1] /// [0.000000000000000, 0.200000000000000, 0.400000000000000, 0.600000000000000, 0.800000000000000, 1.00000000000000] }}}

List Comprehensions

List Comprehensions orientieren sich an mathematischer Mengenschreibweise, und sind eine Elegante Art um komplexe Listen zu generieren.

Die Liste der ersten 10 Quadratzahlen

{{{id=157| [x^2 for x in range(10)] /// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] }}}

Liste von Ableitungen der Sinus Funktion

{{{id=174| var('x') [sin(x).diff(i) for i in [0..4]] /// [sin(x), cos(x), -sin(x), -cos(x), sin(x)] }}}

Liste von geraden Quadratzahlen

{{{id=156| [x^2 for x in [1..20] if 2.divides(x)] /// [4, 16, 36, 64, 100, 144, 196, 256, 324, 400] }}} {{{id=155| [(x,y) for x in [-3..3] for y in [-2..2] if -1 <= x-y <= 1] /// [(-3, -2), (-2, -2), (-2, -1), (-1, -2), (-1, -1), (-1, 0), (0, -1), (0, 0), (0, 1), (1, 0), (1, 1), (1, 2), (2, 1), (2, 2), (3, 2)] }}}

Strings

Strings sind im wesentlichen Listen von Buchstaben, allerdings sind Strings aus Performencegründen nicht mutable, genauso wie Tupel.

{{{id=229| s1 = "computer" s2 = "mathematik" s3 = "informatik" /// }}}

Strings können mit dem + Operator aneinandergehängt werden.

{{{id=230| s4 = s1.capitalize() + s2 s4 /// 'Computermathematik' }}}

Mit dem % Operator können String Formatierungen vorgenommen werden. Die Syntax ist ähnlich wie bei der printf() Funktion in C.

{{{id=231| s = s4 + " (%s) WS %d" % (s3.capitalize(), 2009) s /// 'Computermathematik (Informatik) WS 2009' }}}

Die Länge der Zeichenkette

{{{id=115| len(s) /// 39 }}}

Teilwörter funktionieren gleich wie bei Listen:

{{{id=114| s[8:18].capitalize() /// 'Mathematik' }}} {{{id=113| s.split() /// ['Computermathematik', '(Informatik)', 'WS', '2009'] }}} {{{id=129| s.upper() /// 'COMPUTERMATHEMATIK (INFORMATIK) WS 2009' }}}

Suchen in Strings

{{{id=146| suchstring = "Informatik" istart=s.find(suchstring) istart /// 20 }}} {{{id=148| s[istart:istart + len(suchstring)] /// 'Informatik' }}}

Dictionaries

Ein Dictionary speichert Zuordnungen von je einem Wert zu einem Schlüsselwert

Einige nützliche Funktionen:

{{{id=101| huss = {'name': 'Wilfried Huss', 'office': 'C305', 'email': 'huss@finanz.math.tugraz.at' } huss /// {'name': 'Wilfried Huss', 'office': 'C305', 'email': 'huss@finanz.math.tugraz.at'} }}} {{{id=96| huss['name'] /// 'Wilfried Huss' }}} {{{id=95| huss.keys() /// ['name', 'office', 'email'] }}} {{{id=94| huss.values() /// ['Wilfried Huss', 'C305', 'huss@finanz.math.tugraz.at'] }}} {{{id=93| huss.items() /// [('name', 'Wilfried Huss'), ('office', 'C305'), ('email', 'huss@finanz.math.tugraz.at')] }}} {{{id=92| huss.has_key('name'), huss.has_key('nachname') /// (True, False) }}}

Iteration über alle Schlüssel-Wert Paare in einem Dictionary

{{{id=233| for (key, value) in huss.iteritems(): print key, ":", value /// name : Wilfried Huss office : C305 email : huss@finanz.math.tugraz.at }}}

Im nächsten Beispiel speichern wir Primzahlen in einem Dictionary

{{{id=161| primzahlen = {} p = 1; for i in [1..30]: p = next_prime(p) primzahlen[p] = i primzahlen /// {2: 1, 3: 2, 5: 3, 7: 4, 11: 5, 13: 6, 17: 7, 19: 8, 23: 9, 29: 10, 31: 11, 37: 12, 41: 13, 43: 14, 47: 15, 53: 16, 59: 17, 61: 18, 67: 19, 71: 20, 73: 21, 79: 22, 83: 23, 89: 24, 97: 25, 101: 26, 103: 27, 107: 28, 109: 29, 113: 30} }}} {{{id=159| p = 109 print "%d ist die %d. Primzahl" % (p, primzahlen[p]) /// 109 ist die 29. Primzahl }}}

Mengen

{{{id=169| s1 = set([1..10]) s2 = set([5..15]) s3 = set([1, 1, 1, 1]) s1; s2; s3 /// set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) set([5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) set([1]) }}} {{{id=170| s1.union(s2) /// set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) }}} {{{id=171| s1.intersection(s2) /// set([5, 6, 7, 8, 9, 10]) }}} {{{id=172| s1.symmetric_difference(s2) /// set([1, 2, 3, 4, 11, 12, 13, 14, 15]) }}}

Kontrollstrukturen

Python die Programmiersprache von Sage verwendet Einrückungen zur Definition von Blöcken.

If-Statement

{{{id=83| a = -4 if a > 0: print a, "ist positiv" elif a < 0: print a, "ist negativ" else: print a, "ist null" /// -4 ist negativ }}}

For-Schleife

{{{id=80| for i in [1,2,3,4]: j = i^2 print j /// 1 4 9 16 }}}

While-Schleife

{{{id=78| html("Primzahlen:") i = 1 while i < 20: if i.is_prime(): print "%2d ist eine Primzahl" % i i += 1 /// Primzahlen: 2 ist eine Primzahl 3 ist eine Primzahl 5 ist eine Primzahl 7 ist eine Primzahl 11 ist eine Primzahl 13 ist eine Primzahl 17 ist eine Primzahl 19 ist eine Primzahl }}}

Definieren von Funktionen

{{{id=76| def absolutbetrag(x): if x < 0: return -x else: return x /// }}} {{{id=86| print absolutbetrag(-3) print absolutbetrag(6) /// 3 6 }}}

Selbstdefinierte Funktionen funktionieren automatisch für Typen, die alle in der Funktion verwendeten Methoden und Operationen unterstützen.
In unserem Beispiel:

{{{id=84| R = RealField(prec = 200) absolutbetrag(R.random_element(-10, -5)) /// 7.2426847053181090955843240493633989023140419883530090480303 }}} {{{id=238| /// }}}