Aus dem Ankündigungsposter zur Spring School:
Mit einer Förderung durch die Exzellenzinitiative des Bundes und der Länder führt die RWTH Aachen die Spring School »Mathematik mit SAGE« durch.
SAGE ist ein neues Computer-Algebra-System. Die drei Haupteigenschaften dieses Systems sind:
In diesem Kompaktkurs wollen wir uns mit dem Gebrauch von SAGE bekannt machen, indem wir in sechs 90-minütigen Sitzungen an verschiedenen Projekten arbeiten.
def show_partitions(N): """ Print the partitions of all natural numbers <=N. """ for n in range(1,N+1): print partitions_list(n) def list_red_pols(b): """ Print all reducible polynomials of degree <= 3 over ZZ whose coefficients are nonnegative and < b. """ R.= PolynomialRing (QQ) for c in mrange([b,b,b]): f = R(c) if f != 0 and false == f.is_irreducible(): print factor(f) # Allgemeine Hinweise: # -------------------- # An die Leute, die von Windows kommen: # unbedingt im emacs im Menue unter Options, C-x/C-c/C-v Cut and Paste (CUA) aktivieren # auf "M-/" (aka "ALT+SHIFT+7" ) als dynamische Word-Ergaenzung hinweisen (spart Tipparbeit) # # .__K ohne get und set Methode ist innerhalb dieser Datei moeglich # in der laufenden Sage-Console erzeugt eine abb1.__K die Fehlermeldung ... # siehe http://www.python.org/doc/faq/programming/#i-try-to-use-spam-and-i-get-an-error-about-someclassname-spam # in der laufenden Sage-Console kommen wir nur mit den get und set Methoden an __K # Zeichenketten, die von drei Anfuehrungszeichen, also """ """ oder ''' ''' # begrenzt sind, duerfen Zeilenumbruech enthalten. # Es gibt einen Patch fuer eine kommende Version von SAGE, der auch # Umlaute ermoeglicht. # Wie arbeitet man mit mehreren Leuten an einem gemeinsamen Projekt? # Eine Datei pro Objekt und ein Objekt wird nur von einer Person programmiert # Alternative eine Datei pro Person und darin nur die Objekte die von dieser # Person bearbeitet werden # Ansonsten verliert ihr den Ueberblick # (CVS und Subversion fuehren zu weit, waeren aber die Loesung.) class Abbildung(SageObject): """ A class describing a map from a finite field into itself. EXAMPLE sage: K. = GF(5^3) sage: P. = PolynomialRing (K) sage: abb = Abbildung ( t^4+a*t+3) sage: abb Abbildung von Finite Field in a of size 5^3 nach Finite Field in a of size 5^3 sage: abb.valueAt (K(4)) 4*a + 4 """ def __init__(self, object): """ INPUT: object -- a dictionary or a polynomial describing the map. """ if isinstance( object, dict): d = {} for x in object.keys(): v = object[x] if v != 0: d[x] = v elif isinstance( object, sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field): d = {}; f = object; self.__K = f.base_ring() for x in self.__K: v = f(x) if v != 0: d[x] = v else: raise TypeError, "%s: neither a dict nor or polynomial" %object self.__d = d def _repr_(self): return "Abbildung von %s nach %s" %(self.__K,self.__K) def valueAt( self, x): "" if self.__d.has_key(x): return self.__d[x] return K(0) # --------------------------------------------------------------- def __add__(self, g): """Punktweise Addition einer Abbildung g zu self. INPUT: g -- Abbildung ueber dem gleichen Ring, wie self EXAMPLES: sage: K. = GF(5^3) sage: P. = PolynomialRing (K) sage: f = Abbildung ( t^4+a*t) sage: g = Abbildung ( t+3 ) sage: h = f + g """ if self.__K != g.__K: raise ValueError, "Die beiden Abbildungen sind ueber unterschiedlichen Ringen." else: d = {} for x in K: v = self.valueAt(x) + g.valueAt(x) if v != K(0): d[x] = v A= Abbildung(d) A.__K= self.__K # obige Zeile kommt noch oft. wir koennten __init__ erweitern, so # dass wir auch K als Argument uebergeben koennen. # Dann koennten wir in einer Zeile zusammenfassen: # return Abbildung(d, K) return A # end of __add__() # nur rechts-Mul mit Skalaren def __mul__(self, g): # self ist self """Punktweise Multiplikation einer Abbildung g zu self oder Multiplikation der Abbildung self mit einem Skalar g. Die Multiplikation mit einem Skalar funktioniert NUR VON RECHTS. (Sonst: siehe Kapitel 11: http://www.sagemath.org/doc/html/ref/node61.html auch die Kapitel ueber die anderen Strukturen, Gruppen, Ringe, etc.) INPUT: g -- Abbildung ueber dem gleichen Ring, wie self oder ein Skalar aus self.__K EXAMPLES: sage: K. = GF(5^3) sage: P. = PolynomialRing (K) sage: f = Abbildung ( t + 1) sage: g = Abbildung ( 2 * t ) sage: h = f * g sage: f2= f * 2 """ if not (isinstance(g, Abbildung) or (g in self.__K) ): raise ValueError, "Abbildungen duerfen nur mit Abbildungen oder Ringelementen multipliziert werden" # nun haben wir eine Abbildung oder einen Skalar auf der rechten Seite: d= {} A= None if g in self.__K: # Wahr, falls rechts ein Skalar aus dem richtigen Ring steht # Unwahr, falls rechts eine Abbildung steht for x in K: v = self.valueAt(x) * g if v != K(0): d[x] = v A= Abbildung(d) else: # ab hier stehen links und rechts Abbildungen if self.__K != g.__K: raise ValueError, "Die beiden Abbildungen sind ueber unterschiedlichen Ringen." else: for x in K: v = self.valueAt(x) * g.valueAt(x) if v != K(0): d[x] = v A= Abbildung(d) A.__K= self.__K # hier heisst self, ja self return A # end of __mul__() def composition(self, g): r"""Komposition einer Abbildung g mit self: self \circ g. INPUT: g -- Abbildung ueber dem gleichen Ring, wie self EXAMPLES: sage: K. = GF(5^3) sage: P. = PolynomialRing (K) sage: f1 = Abbildung ( t+1) sage: g1 = Abbildung ( t ) sage: h1 = f.composition(g) sage: f2 = Abbildung ( t*2) sage: g2 = Abbildung ( t + 1 ) sage: h2 = f.composition(g) """ if not self.__K == g.__K: raise ValueError, "Die beiden Abbildungen sind ueber unterschiedlichen Ringen." else: d={} A=None for x in K: y= g.valueAt(x) z= self.valueAt(y) if z != 0: d[x]= z A=Abbildung(d) A.__K= self.__K return A # endo of composition() def is_bijective(self): r"""Prueft, ob self bijektiv ist. OUTPUT: boolean -- True, falls die Abbildung self bijektiv ist, sonst False EXAMPLES: sage: K. = GF(5^3) sage: P. = PolynomialRing (K) sage: f= Abbildung(t*2) sage: g= Abbildung((t+1)*(t-1)) sage: f.is_bijective() True sage: g.is_bijective() False NOTES: self ist eine Abbildung ueber einem endlichen Koerper in sich selbst. self ist eine Liste x_i -> y_i (es fehlen nur die Paare, fuer die y_i = 0 ist). Wir vergleichen die Laenge der Liste uniq( [... y_i ... ] ) (die Hilfe von uniq? anschauen) mit der Anzahl der Elemente im Ring self.__K. """ AnzahlElementeInK = len(self.__K) # oder auch len(list( self.__K )) oder self.__K.order() ListeDerWerte= list( self.__d.itervalues() ) UniqueListe=uniq(ListeDerWerte) # uniq? mal anschauen if len(UniqueListe) + 1 == AnzahlElementeInK : # in ListeDerWerte fehlen die Nullen return True else: return False # oder auch: "return (len(UniqueListe) + 1) == AnzahlElementeInK" # end of is_bijective() def inverse(self): r"""Die Umkehrabbildung von self. OUTPUT: Abbildung -- die Umkehrabbildung von self EXAMPLES: sage: K. = GF(5^3) sage: P. = PolynomialRing (K) sage: f= Abbildung(t + 2) sage: g= f.inverse() sage: r= K.random_element() sage: g.valueAt(f.valueAt( r )) == r True """ if not self.is_bijective(): raise ValueError, "In inverse(), die Abbildung ist aber nicht bijektiv." else: d={} A=None for x in K: if x != 0: v= self.valueAt(x) # valueAt und damit v nimmt auch den Wert 0 an d[v] = x A= Abbildung(d) A.__K = self.__K return A # end of inverse() # end of class Abbildung # wir koennen die EXAMPLES Abschnitte aus obigen Dokumentations-String # automatisch testen lassen: # # ~/SpringSchool] sage -t example.sage # sage -t example.sage # Example 0 (line 37) # Example 1 (line 89) # Example 2 (line 125) # Example 3 (line 173) # Example 4 (line 208) # Example 5 (line 243) # [11.0 s] # # ---------------------------------------------------------------------- # All tests passed! # Total time for all tests: 11.0 seconds # wenn sage die Datei neu einliest (Return auf leerer Zeile) dann # werden diese Anweisungen ausgefuehrt, dadurch spare ich mir das # wiederholte anlegen von abb1 und abb2, etc if __name__ == "__main__": print "Tests fuer die Abbildungsklasse:" K. = GF(5^3) P. = PolynomialRing (K) abb1 = Abbildung ( t^4+a*t+3) abb2 = Abbildung ( t^3+2*a*t+1) abb3 = abb1 + abb2 abb4 = abb1 * abb2 abb5 = abb2 * K(3) abb6= Abbildung(2*t) abb7= Abbildung(t+1) abb8= abb7.composition(abb6) #for x in K: #print abb3.valueAt(x) == abb1.valueAt(x) + abb2.valueAt(x) #print abb4.valueAt(x) == abb1.valueAt(x) * abb2.valueAt(x) #print abb5.valueAt(x) == abb2.valueAt(x) * 3 #print x, ':', abb6.valueAt(x),',', abb8.valueAt(x) abb9= Abbildung(t*2) abb10=Abbildung((t+1)*(t-1)) print "Abbildung 9:" , abb9.is_bijective() print "Abbildung 10:", abb10.is_bijective() inv=abb9.inverse() for x in K: print x == inv.valueAt(abb9.valueAt(x))