Skip to content

\bigtimes für LaTeX

In der Vorlesung Gruppentheorie wurde kürzlich das direkte Produkt von Gruppen definiert. Neben dem üblichen Produktzeichen ∏ verwendete der Vorlesende auch ein großes ×. Intuitiv verwendete ich bei meiner LaTeX-Mitschrift \bigtimes. Das resultierte im einem Fehler, da es dieses Zeichen in den eingebundenen Paketen nicht gab. Ein Blick in die The Comprehensive LaTeX Symbol List (PDF) sagte mir, dass es im Paket txfonts die Anweisung \varprod gibt und die Pakete MnSymbol sowie mathabx mein intuitiv gewähltes Zeichen vorrätig haben.

Da alle Varianten für mich mehr Nach- als Vorteile bringen, habe ein wenig gegoogelt und bin auf den Beitrag von Roland Illig gestossen. Seine Lösung baute ich mir zu \newcommand*{\bigtimes}{\mathop{\raisebox{-.5ex}{\hbox{\huge{$\times$}}}}} um. Das passt erstmal recht gut in meinen Text:

Symbol im Text

Falls jemand andere/bessere Lösungen weiß, dann immer her damit.

Das zwölfte Eulersche Problem

Meine Leser kennen sicher meine Vorliebe für das Project Euler. Bereits seit längerem beschäftigt mich das zwölfte Problem. Dort soll der Wert der ersten Dreieckszahl berechnet werden, die mehr als 500 Teiler hat. Im Rückblick betrachtet, ist diese Aufgabe relativ klar. Ich habe jedoch sehr viel Zeit daran verschwendet, das Problem zu verkomplizieren, theoretische Ober- und Untergrenzen zu berechnen. Nachdem ich nicht weiterkam, habe ich das Problem liegen lassen. Gerade eben kam es mir wieder in den Sinn. Als setzt ich mich hin und programmierte die Aufgabe einfach naiv und ohne Nachzudenken. Viola, das Ergebnis war richtig.

Code optimieren

Erathostenes lehrt in Alexandria

Bislang konnte ich die Eulerschen Probleme mit einem naiven Programmieransatz lösen. Das heißt, die erste Idee, die mir in den Kopf kam, schrieb ich runter und bekam eine Lösung. Das zehnte Problem warf mir einen Stock zwischen die Beine. Erstmals musste ich mir Gedanken über die Optimierung des Codes machen.

Das zehnte Problem klingt erstmal ganz harmlos: Finden Sie die Summen aller Primzahlen, die kleiner als 2 000 000 sind.. Ha, das ist ja eine einfache Fingerübung:

sieb = [ i for i in xrange(2,2000000) ]
for i in xrange(2,2000000):
  for j in xrange(2,2000000):
    if i*j in sieb:
      sieb.remove(i*j)

Die Werte in sieb müssen dann nur noch addiert werden und fertig. Jedoch kam ich gar nicht soweit. Denn das Programm lief und lief und lief.

Zahlenkolonnen

Das brachte mich zum Nachdenken, woran das liegen könnte. Letztlich ist die Ursache offensichtlich. Denn der Code berechnet jedes Produkt. Dafür werden schon 2 000 000 * 2 000 000 = 4 000 000 000 000 Berechnungen durchgeführt. Wenn man von der (viel zu optimistischen) Variante ausgeht, dass jede Berechnung ein CPU-Zyklus ist, würde das Programm auf aktuellen Architekturen länger als eine halbe Stunde laufen. In der Realität lief es 15 Stunden. Wie lässt sich die Laufzeit nun verbessern?

Es ist recht offensichtlich, dass das Programm zuviel berechnet. Im ersten Schleifendurchlauf gibt es die Multiplikationen: 2*2, 2*3, 2*4, ..., 2*1999999 = 3999998. Beim zweiten Schleifendurchlauf: 3*2, 3*3, 3*4, ..., 3*1999999 = 5999997. Am klarsten fällt es im letzten Durchlauf auf: 1999999*2, 1999999*3, ..., 1999999*1999999 = 3999996000001. Die Berechnung 3*2 wurde schon im ersten Schritt (nur umgekehrt mit 2*3) durchgeführt. Hier wirkt das Kommutativgesetz. Also kann die Schleife im zweiten Durchlauf erst bei drei beginnen. Im dritten Durchlauf würde nach obigem Algorithmus 4*2, 4*3, 4*4 usw. berechnet werden. Verallgemeinert lässt sich also sagen, dass die Variable der zweiten Schleife genausogroß oder größer als die erste Variable sein muss. Dieser Schritt halbiert die Zahl der Berechnungen.

In der obigen Darstellung wird klar ersichtlich, dass das Programm nicht in jedem Fall bis zum Maximum von 2 000 000 laufen muss. Schon im ersten Durchlauf werden Werte über 2 000 000 berechnet. Das heißt, das Produkt i*j muss kleiner oder gleich 2 000 000 sein. Umformen nach j ergibt: j?2 000 000/i. Eine weitere oft genutzte Optimierung ist es, die erste Schleifenvariable nur bis ?2000000 laufen zu lassen.

Weiterhin fiel mir auch ein, dass man schon die initiale Liste nicht mit Zahlen von 2 bis 2 000 000 füllen muss. Denn es ist bekannt, dass alle Vielfachen von 2 sofort ausfallen. Man kann sogar soweit gehen, dass man nur Zahlen nach dem Muster 6*n-1 und 6*n+1 aufnimmt. Denn die Zahlen 6*n+0, 6*n+2 und 6*n+4 sind gerade und damit keine Primzahlen. Die Zahl 6*n+3 entspricht 3(2*n+1) und ist somit durch drei teilbar. Es verbleibt das obige Muster.

Theoretisch hätetn die obigen Anpassungen schon reichen sollen, um die Laufzeit unter eine Minute zu drücken. Jedoch lief das Programm immer nach weitaus länger. Nach einigem Stöbern fiel mir dann auf, dass in Python die Listenoperationen in und remove die Listen von Beginn an durchsuchen. Das bringt natürlich nochmal eine extreme Pessimierung der Laufzeit. Stattdessen sollte man hier Sets oder Dictionaries nutzen. Ich habe es mit Sets probiert und prompt lief das Programm schnell genug.

sieb = {}
for i in xrange(2, 2000000):
  sieb[i] = True
for x in xrange(2,int(math.sqrt(2000000))+1):
  if sieb[x] == True:
    for y in xrange(2000000/x, x-1,-1):
      t = x * y
      sieb[t] = False

Grundsätzlich lassen sich weitere Möglichkeiten der Optimierung ausdenken. Jedoch reichte mir das obige Ergebnis, um das Ziel zu erreichen. Wahrscheinlich benötige ich in späteren Aufgabe noch eine weitere Verbesserung.

Lernen für höhere Analysis

Jetzt ist an den Unis Prüfungszeit ausgebrochen, so auch in Jena. Ich lerne gerade für die Vorlesung zu Funktionalanalysis oder, wie es hier heißt, Höhere Analysis. Zum Lernen habe ich mir ein paar Flashcards gebastelt. Wer das vielleicht ebenfalls zum Vorbereiten nutzen will, findet die Lernliste online.

Also dann: sei ε positiv und beliebig ... ;-)

Post aus Slovenien

SI-10289

Die Karte stammt aus der Nähe des Golfs von Triest, genauer aus Ajdovš?ina. Wier leicht zu sehen ist, kann man die Stadt auf der Karte nicht sehen. :-) Vielmehr sind da zwei Kinder, die wahrscheinlich gerade ein paar Vögel füttern.

Die Autorin der Karte ist eine begeisterte Ski- und Snowboardfahrerin. Auf der Karte ist etwas von ihrentrn diesbezüglichen Aktivitäten zu lesen. Weiterhin erzählt sie mir getreu dem Motto In Mathe war ich immer schlecht, dass sie in Mathe immer schlecht ist bzw. das nicht mag. Aber das kenn ich ja schon zur genüge.

Update: Zwei Tippfehler korrigiert und noch eine Erklärung zur obigen Bemerkung:
Lest am besten mal die Einleitung zu dem oben verlinkten Buch oder, wenn euch mal jemand nach eurem Beruf fragt, dann erzählt, dass ihr was mit Mathematik macht. In weit 90% aller Fälle wird man dann mit einem Blick gemustert und es folgen die Worte: In Mathe war ich immer schlecht. oder etwas äquivalentes. Beutelspacher schreibt in der Einleitung:

... Wenn ein Landrat oder ein Minister eine Mathematiktagung eröffnet, kokettiert er richtig damit, daß er schon in der Schule in Mathematik schlecht war und von unserer Wissenschaft rein gar nichts versteht. Ein Skandal! So ein Mann würde sich doch nie trauen, bei der Eröffnung eines Anglistenkongresses zuzugeben, daß er kein Englisch kann. ...

In dem Sinne war auch die obige Bemerkung zu verstehen. ;-)

Von Vögeln und Fröschen

Kürzlich stieß ich auf den Artikel Birds and Frogs von Freeman Dyson. Der sollte im Rahmen der AMS Einstein Lecture als Vortag erscheinen. Auf elf Seiten schreibt Dyson über verschiedene Arten von Mathematikern. Seiner Meinung nach gibt es nur zwei unterschiedliche Typen, nämlich Vögel und Försche. Die Mathematik-Vögel fliegen sehr hoch und überschauen weite Teile der Mathematik. Daher finden sie oft Verbindungen zwischen verschiedenen Fachgebieten. Als Beispiele nennt Dyson René Descartes, Erwin Schrödinger oder Hermann Weyl. Die mathematischen Frösche leben eher im Schlamm und sehen daher nur das, was in direkter Nähe zu ihnen ist. Sie freuen sich an kleinen Details und lösen Probleme Schritt für Schritt. Beispiele für diese Typen sind Francis Bacon oder John von Neumann. Der gesamte Artikel ist sehr schön geschrieben und gibt einen guten Überblick über diverse Mathematiker und Physiker. Gleichzeitig lernt ihr bei der Lektüre noch etwas über aktuelle Probleme der Fachgebiete. ich kann das nur zum Lesen empfehlen.

cronjob