Rework me on GitHub

Mathe macht Spass

root (Edward Gerhold)

So, genug verraten. Jetzt habe ich erstmal keine Lust mehr zu schreiben. Ich finde, mit dem Material kann man gut lernen. Und werde mir jetzt erstmal einen Monat Ruhe vor dem Internet gönnen. Ich werde mir nächste Woche noch was zu lesen besorgen, wenn ich einen Termin habe. 

P.S. Mein Notebook ist (so gut wie) hinüber und ich habe das administrative System (PHPStorm) nicht auf dem alten PIII. Werde aber dran denken, die Datenbank dann bei Gelegenheit zu shredden.

Es schneit

root (Edward Gerhold)

Ich habe gerade rausgesehen, mit Pünktchen auf dem Arm. Es schneit. Dann habe ich Racker den Schnee gezeigt.

Jetzt nochmal was durcheinander gewürfeltes. Ich hatte da kein Konzept, ihnen hier irgendwas spezielles vorzutragen.

Wenn a teilt b und b teil c, dann teilt a auch c. und wenn a teilt b, dann teilt ka auch kb. Die Grundlagen der Nachrichtenverschlüßelung wird anhand der Geschichte Alan Turings im zweiten Weltkrieg vorgestellt. Da kommt die Idee, Primzahlen zum Verschlüsseln zu nehmen, her. Der Fehler war nur, wer zwei Nachrichten hatte, konnte mit dem gcd(msg1, msg2) den geheimen Schlüßel ermitteln. RSA fanden die drei 1977 übrigens auch am MIT, wo der Kurs 2010 abgehalten wurde, den ich gerade mache. Man lernt in dem Kapitel auch den Pulverizer, das ist der erweiterte gcd. Da werden die Schritte mit den Resten gleich noch extra abgespeichert.

Gerade lerne ich was über Lebesgue. Mass- und Integrationstechnik habe ich bereits vor einer Woche in meine Sammlung geholt, aus dem Interesse heraus, in Sachen Analysis auch was ordentliches zu lernen. Heute mittag habe ich nochmal über Gauss-Jordan gelesen, wo ich die Matrize 3x3 auf 3x6 erweitere und dann aus A durch Elimination [U L-1] mache und dann einfach weiter mache, bis ich die U in die I verwandelt habe, womit ich [I A-1] in der 3x6 erhalte. Gauss-Jordan erlaubt E, P, und D. Eliminierung, Permutation und durch die Pivots der Diagonalen dividieren. Jeder Schritt, der vielleicht auf Papier im Kopf geht, ist so eine Matrixmultiplikation. Genial finde ich, ich habe die aktuelleren Lehrpläne gesehen, wie allgemein und wichtig lineare Algebra heute ist. Macht mir auch Spass und wir treffen uns dann später zum gleichgesinnten Austausch von Algorithmen. Schon am ersten Tag hatte ich Gauss Elimierung mit Rücksubstitution programmiert und in meiner JavaScript Physikbibliothek bei den Matrizen untergebracht. Mit dem Vektorraum hatte ich durch die englische Sprache erst mehr Probleme, den deutschen Namen des Vektorraums zu sehen. Das ist mittlerweile geklärt und ich freue mich, an deutscher Mathematik teilhaben zu können, die international ja geschätzt wird.

Hätte ich mir nur "Differentialgleichungen" besorgt, wäre ich nach einer Woche schon durch. So habe ich breiter gefächert. Und gehe abwechselnd in die Tiefe. Hätte übrigens nicht gedacht, daß mir der alte Mathe für Informatiker Kurs bei dem anderen Angebot noch so viel Spass macht. Aber was soll´s. Mindestens n² ist Omega(n²) und nicht O(n²). Eben, beim ersten mal vor fast zwei Jahren hatte ich das zwar auch schon mal verstanden, aber mittlerweile ganz vergessen. Da ist es wieder. Asymptotische Komplexität. Nur ist f = o(g) und zwar weil |f(x)| < c|g(x)|. usw. Und ist f = omega(g) ist es |f(x)| > c|g(x)| und es ist kein gleich. Sollten sie asymptotisch gleich sein, nimmt man Theta. Auch das will wiederholt werden und ich wünsche euch viel Spass bis dann und meiner Partnerin nochmal gute Besserung von den Kopfschmerzen beim Husten. Gute Besserung, Schatz. Und gute Nacht Deutschland. 

Mathemagie

root (Edward Gerhold)

Ich fand´s mal bei uns in der Mülltonne vor dem Haus. Vorhin habe ich was im Buch Mathe Magie von einem Schnellrechner, der auch im Fernsehen war, gelesen. 29x11 ? 319. (In Bruchteilen einer Sekunde 2+9 = 11 gerechnet, die 1 auf die 2 gebracht, die andere 1 dahinter, und die 9 stehen gelassen) Das Buch geht gut los.. Mit 52x53 geht das noch nicht, aber später im Buch kommt das dran. Interessant war auch der 1.1.2030 . Ein 25% Trinkgeld auf die letzten 30 Euro. Das Trinkgeld wird abgerundet. 7,50 werden zu 7. Das zur 30. Und dann modulo 7. 37 mod 7 (er rechnet mit 37 -35 im Buch, ich hatte gerade auch was über modulare Arithmetik gelesen, bevor das mit den Rekurrenzen kam) = 2. 2 ist Dienstag. Bei einem Schaltjahr muss eine 1 vom Trinkgeld abgezogen werden. Spannend ist, ich bin nach Addieren und Subtrahieren und einem tollen Einstieg mit Multiplikation jetzt am Anfang des Kapitels. Muss das Buch unbedingt durchmachen, wie man mit dem Kalender rechnet ist noch mehr drin. Schaltjahr beiseite, was ist der 1.1.2040 ? Montag. Kann mich auch irren, habe das Prinzip aber verstanden. 43x49 ? 2107. Wie man mit beliebigen Zahlen rechnet werde ich im Laufe des Buches lernen. Ich denke, es ist hilfreich, mich etwas im Kopfrechnen zu verbessern.

gerade abgestürzt

root (Edward Gerhold)

Gestern habe ich gar nicht erzählt. Ich habe Merge Sort ausgerechnet, mit der Formel 2Tn/2+n-1, was 2*Tn/2 für Vergleiche und Sortierung und n-1 für´s Mergen sind, wenn ich mich recht entsinne. Lest ruhig selbst. Ich werd´s nochmal wiederholen. Der Trick geht so, daß man Einsetzen muss, bis ein Pattern auftaucht. Dann kann man davon auf die Lösung schliessen. Dabei bin ich dann auch auf die Folge der hinteren Terme gestossen.. Ich habe das so ausprobiert, indem ich die 2Tn-1+1 vom Türme von Hanoi in 3Tn-1+7 verwandelt hatte und dann eingesetzt. 3(3Tn-2+7)+7 = 9Tn-2+63+7 usw. Es ist so, daß sich das Restglied hinter 2Tn-1 verlängert und das ist auch gleichzeitig eine Folge. Genaugenommen ist hier 2an-1 mit a0 = 1, die Folge des "Restglieds", oder 3an-1 mit a0 = 7. Merge Sort hatte ich dann verstanden, als ich es mit 3Tn/3 + (n-2) versuchte. Was dabei rauskam ist, daß ich hätte n-3 angeben müssen, um die Elemente aufzulösen, was auch immer meine Zufallsfunktion meinte, ein Drittel der 243 (bis dahin habe ich gerechnet, bis ich mir sagte, "dass es 243 Elemente sein, was heisst denn meine Funktion?") bleibt nämlich übrig. Das hintere Glied verlängerte sich auf (n-162) + (n-54) + (n-18) + (n-6) + (n-2). Also ich fing an mit dem zweiten Term 3(3Tn/9+n/3-2)+n-2 = 9Tn/9+(n-6)+(n-2). Es ging weiter mit 9(3Tn/27+n/9-2)+(n-6)+(n-2) = 27Tn/27+(n-18)+(n-6)+(n-2). Merge Sort funktioniert mit den 2Tn/2 + (n-1) genauso. 2(2Tn/4 + n/2 -1) + (n-1) und so weiter. Mittlerweile bin ich vor dem Akra-Bazzi Theorem.

Genau hier stürzte der Rechner gerade ab, die Verbindung brach ab, und eine Reihe CCCCCCCCCC stand im Editorfeld. Die Formatierung ist weg. Jetzt darf ich das nochmal markieren. Einfacher, als Tn-1 zu schreiben ist es, f(n-1) oder T(n-1) zu benutzen. Damit lässt sich dann auch die generelle lineare Rekurrenz wie gewohnt mit  f(n) = a0*f(n-1)+...+ad*f(n-d) + g(n) aufschreiben. Wer jetzt eine vollständige Fortsetzung erwartet wird enttäuscht sein. Man muss hier ähnlich wie bei den Differenzialgleichung eine partielle und eine homogene Lösung für eine generelle Lösung zusammenfügen. Wenn das Glied g(n)= 0 ist, hat man eine homogene Gleichung. Nach dem Akra Bazzi, was unmittelbar mit dem eben gesagten einhergeht, dessen Formel ich heute nicht weiss, kommt das Master Theorem, was für Divide-and-Conquer Rekurrenzen unterrichtet wird.  Fortsetzung folgt...

Das war aber noch nicht alles. Ich speichere erstmal.

noch weiter lernen

root (Edward Gerhold)

Heute morgen habe ich erstmal mit dem Vector Calculus auf Englisch begonnen und mit Kapitel 1 angefangen, die fundamentalen Vektoroperationen ebenso wiederholt und in sekundenschnelle mit gerechnet, wie auch die Grundlagen der analytischen Geometrie. Ich habe irgendwann in Kapitel 2, nach einer oder zwei Stunden, das ist " Funktionen mehrerer Variablen" wieder aufgehört. Mit gutem Gewissen, dass ein Limit von einer vektorwertigen Funktion f(t) = (x(t), y(t), z(t)) nur existiert, wenn alle Limits der Komponenten existieren. Unter anderem. Ich habe die gerechneten Werte von f(x,y) mehrerer Variablen mal mit der Epsilon-Delta Regel verglichen, |f(x,y) - L| < eps, 0 < sqrt((x-a)²+(y-b)²) < delta. Da die Funktionen stetig waren, war letzteres immer gleich gleich 0. Da f(x,y) = L war.

Das war aber nicht alles, die Abstände von Punkten zur Ebene, die vergessene Regel für Parallelotope, das dot(u, cross(v,w)) = dot(v,cross(u,w)) = dot(w, cross(u,v)) = dem Volumen ist (die Umstellung und die Formel hatte ich vor gut drei Monaten wohl verpasst, sie fiel mir als nicht gemerkt auf). Ich habe 3x3 Determinaten mit auf Blatt ausgerechnet und mir die ijk-Formel wieder mal besser eingeprägt, und und und. Wir haben einen Vektor v. Und einen Punkt P. Vom Ursprung (von v, bzw v entspringt auf dem Ursprung) zeichnen wir den Vektor r nach P. Um eine Linie durch P zu ziehen, die parallel zu v ist, muss man r+tv rechnen. Den Vektor der zu dem Punkt zeigt plus t mal den Vektor v. Man addiert den einen und den skalierten Vektor für einen neuen Punkt auf der Linie. t < 0 geht nach links, t > 0 geht nach rechts. t = 0 muss wieder P geben, da r + 0v = r ist und der auf v zeigt. Eine Linie parallel Verschiedene Abstände, wie den von dem Punkt auf eine Linie (man nehme einen Vektor v auf der Linie, zeichne am Fuss noch einen w zum Punkt und rechne ||v x w||/||v|| und erhalte den Abstand vom Punkt auf die Linie. Oder eine Linie durch zwei Punkte verlängern, mit r1 + t(r2-r1) wobei r1 auf den ersten und r2 auf den anderen Punkt (vom Ursprung aus) zeigt. Auch hier entscheidet "t", wie die Linie verlängert wird. Das kam alles in Kapitel1 vor und noch mehr.

Dann hatte ich eine Frage in den Aufgaben, ich erinnere mich. d/dx von 2 sin² t. Mit der Kettenregel f(x) = 2x² und g(x)=sin t vermute ich 4 * sin t * cos t, da man f'(g(x))*g'(x) rechnen muss um verschachtelte Funktionen zu rechnen und f'(x) ist ja dann 4*x und f'(g(x)) dann ja 4*sin t und * g'(x) ja dann * cos t. Ich denke die Ableitung von 2 sin²(t) ist = 4*sin(t)*cos(t) nach der Kettenregel. Die sollte man so oft üben wie es geht, und das darf ich noch öfter machen. Meine Freundin bittet mich gerade darum, nochmal was zum Abendessen zu holen, ich werde mich nochmal anziehen und ins Dorf fahren.

Heute nachmittag habe ich dann Mathe für Informatiker fortgesetzt. Es ist ein toller Kurs und ich bekomme mehr und mehr Einblick in die Unterlagen. Gerade noch habe ich die Rekurrenzen ausprobiert. Nehmen wir die einfache Rekurrenz Tn = Tn-1 + 12 mit T1 = 10. Dann ist T2 = 10 + 12 = 22 und T3 = 22 + 12 = 34 und T4 = 34 + 12- Und so weiter. Auf dem Rückweg im Bus habe ich dann bei Merge Sort aufgegeben, weil die Haltestelle kam und mache weiter, morgen wahrscheinlich. Asymptotische Notation kam kurz davor auch dran. Wenn f asymptotisch aequivalent zu g ist, schreibt man f ~ g. Das ist, wenn die Ratio des Limes von n -> inf von f(x)/g(x) = 1 ist. Wenn die Funktion bedeutend kleiner ist, als g, schreibt man f(x) = o(g(x)). Genau, little Oh, little Omega, Omega, Theta und Big O sind wieder dran. Für alle a < b gilt xa = o(xb). Meine Pflicht, das bald richtig zu können. Dann habe ich stundenlang oder wenig versucht, Summen zu vereinfachen und Ausdrücke zu finden. Im Video vom MIT sieht man ein Beispiel mit Holzblocks, das habe ich heute auch gemacht, aber merke, dass ich es nicht wiedergeben kann.

ICh wollte und hatte noch mehr auf der Liste. Aber das Thema Mathe für Informatiker nach einer Wiederholung der Analysis 2 mit dem genialen calc3book.pdf, wodurch ich meine ersten partiellen Ableitungen, partiellen Integrale und meine ersten Grundlagen der Differentialgeometrie lernen konnte. Darum habe ich auch fleissig alle Excercises wiederholt, an denen ich heute vorbeikam. Ja, dank der Lösung der ungeraden Nummern konnte ich das prüfen was ich probierte.

Moment. ICh muss nochmal raus. O.k. Ich hab noch mehr Material, aber das ist jetzt egal. So long und viel Spaß beim Fach eurer Wahl ;-) Werde mich in Sachen Numerik wegen dem kaputten Lappi erstmal mit Approximation von Polygonzügen auf 2D beschränken, was aber ein novum für mich ist und ausserdem toll, weil ich bis vor kurzem ja nur linien und keine glatten Kurven konnte. Mit y=r sin t und x = r cos t bin ich mittlerweile bestens vertraut. Die Show kann bald beginnen, he. Ok, muss raus. Genug getippt.

weiter lernen

root (Edward Gerhold)

Ich hatte gestern vormittag noch Mathe für Informatiker gemacht. Calculus und lineare Algebra. Gestern nachmittag Algebra und Differenzialgleichungen. Abends nochmal Statistik und ein paar Übungsaufgaben. Nebenbei habe ich heraus gefunden, was noch so nutzbar sei, wie zum Beispiel Computeralgebra und beschlossen, erstmal wieder meine aktuellen Aufgaben zu lösen und das Material zu benutzen, was ich habe. Das werde ich heute auch wieder machen

// Die Funktion x²

function f(x) { return x*x; } 

// Das Integral von 1 bis 4 von f(x) nach dx diskret mit Riemann Summe approximiert 


var a = 1;
var b = 4;
var n = 1e6;
var dx = (b-a)/n;
var sum = 0;

for (var c = a; c < b; c+=dx) {
sum += f(c) * dx;
}

var exact = (b*b*b-a*a*a)/3;

console.log("riemann sum: "+sum+" with "+n+" rectangles");
console.log("integration: "+exact);

//riemann sum: 21.000025499782097 with 1000000 rectangles
//integration: 21

Mal schauen, was heute dran kommt. Aber auf jeden Fall wieder Mathe. Den ganzen Tag Integrale, Ableitungen, Folgen, Transformationen, Theoreme, Beweise, Korollare. Übungsaufgaben und Notizen. Es macht einfach Spass und je öfter ich das wiederhole, um so sicherer werde ich. Ich löse heute aus Analysis und anderen Bereichen Aufgaben, die ich vor drei Monaten nichtmal verstanden hätte, weil ich das noch nie probiert hätte. Das macht mich froh und motiviert mich, mehr zu lernen.

Schnellmerker

root (Edward Gerhold)

Einige Algorithmen, die ich schonmal entdeckte, aber nicht einordnen konnte, die fand ich gerade in der Computeralgebra. Neben Numerik und wissenschaftlichem Rechnen, Algorithmen und insbesondere parallelen Algorithmen wohl das wichtigste mathematische Fach für Informatiker, sofern sie denn an der Mathematik auch interessiert bleiben. Websites könnte ich zehn Jahre ohne Rechnen aufzufrischen schreiben, oder nicht, ohne  daß die Defizite auffallen. Die sind mir und anderen natürlich aus anderen Gründen aufgefallen und weil mich Websites gar nicht so interessieren. Früher war ich Linux-Kernel und Betriebssystem-Lehre Hobbyforscher und -schüler. Als ich vor zwei oder mehr Jahren auf einmal mit Javascript anfing lebte ich bis zu fünf Jahre ohne Internet. Ich hatte Ajax verpasst und wollte auch mal JavaScript sprechen. Naja, diese Woche schaffe ich Computeralgebra, Numerik, paralelle Algorithmen und wissenschaftliches Rechnen nicht mehr aufzugreifen. Aber mache schön weiter mit Analysis und linearer Algebra, von der ich mein erstes Buch bald kenne. Analytische Funktionen sind die, die sich durch eine Potenzreihe darstellen lassen. Ich vermute, Folgen sind sowas wie der Vorläufer des Computers, hehe.

Ich glaube letzten Artikel schrieb ich, ich hätte Verwendung für die Metrik Funktion um die grundlegende Metrik auf dem Canvas festzuhalten. Es gibt aber für Graphen extra eine Zoom-Transformation. Die der Mathematiker kennt. Sollte ich nochmal kurz anmerken. Da wird mit einem Faktor skaliert, wie man sich das vorstellt.

Mathe für Inf.

root (Edward Gerhold)

Gerade konnte ich dann zum Einstieg mit Mathematics for Computer Science weitermachen. Weniger Mengendefinitionen als in Deutschland für jeden Satz, aber dennoch soviele Sätze und natürlich darauf folgende Beweise. Und dennoch natürlich die gleiche Mengenlehre. Ich habe nicht richtig in die Tiefe lesen können, wir waren nicht lange unterwegs, aber mir einen Überblick über Arithmetik mit Primzahlmodulus, und über beliebigen Modulus. Selbst den RSA Algorithmus habe ich dann beim Durchlesen verstanden, nachdem wieder eine Formel von Euler (Phi(pq) = (q-1)(p-1)) dran kam, und wir so weit waren. Dann ging´s mit Graphentheorien weiter und nicht nur die gute Adjazenzmatrix machte mir wieder Spass, sondern allerhand Sätze zu, zur chromatischen Zahl und dann, jetzt kommt der interessante Teil für fortgeschrittene Graphen, Relationen auf den Graphen. Ich vermutete vor zwei Jahren, dass man es wie normale Mengen handhabt. Teilmengen eines Graphen sind halt wirklich ausgewählte Vertices und Edges für den Subgraphen. In Advanced Data Structures (?), nein, Planar Graphs and Beyond, vom MIT kann man dann damit was tun. Planare Graphen, das sind die, die man auf eine Ebene abbilden kann, ohne dass sich die Edges kreuzen. Letzteres ist die Anforderung dafür, daß der Graph planar einbettbar ist. Ein paar andere Sachen habe ich jetzt wieder vergessen, wie gehabt, habe das nur überflogen, und den anderen Teil des Skripts (mit Counting, da gibt´s allerhand Vereinfachungen von Folgen nd mehr,  und Probability zuhause gelassen). Zum Schluss hatte ich noch was über partielle Ordnungen gelernt, zum Beispiel "<" und den Graphen von 1,2,3,4, der 1 < 2 < 3 < 4, 1 < 3, 1 < 4, 2 < 4 verbindet. Lineare Programmierung handelt übrigens von Ungleichheiten, aber das ist wieder was anderes. Alles in allem gibt es viel viel zu tun und ich werde jeden Tag geniessen. Auf dem Rückweg habe ich dann wieder Topologien probiert und die Einführung in Topologien in Analysis II. Ach, da fällt mir ein. 

Wenn man auf dem Canvas Graphen malt, braucht man gar eine Metrik. Wenn man 1 genau 1 px zuordnet, kann man keine genaueren Kurven malen. Dazu muss man den Abstand der 1 in Pixeln vergrössern. Bei einer normalen Metrix gibt d(x,y) = 1. Also 1 Pixel zwischen zwei Punkten. Wenn ich jetzt d(x,y) = 10 angebe habe ich 10 Pixel zwischen jedem Punkt. Die Breite auf dem Canvas ist dann (canvas.width/d) und (canvas.height/d). Hier habe ich den ersten richtigen Anwendungsfall für eine "Metrik" für einen "metrischen Raum", der die Canvasfläche ist. Vorher hatte ich das gleiche Prinzip als "stepsize" oder "scale" oder anderen Quatsch bezeichnet, um entsprechend zu skalieren. Metrik ist hier richtig.

P.A.

root (Edward Gerhold)

Parallele Algorithmen kann man übrigens auch wunderbar studieren, nicht nur wissenschaftliches Berechnen mit dem Computer. Wenn man Google einsetzt kann man die Skripte finden und sich über Mathematik und Pseudocode freuen. Ich glaube, ich werde mir doch etwas früher neues Papier besorgen, daß ich diesen wichtigen Hauptkurs neben Numerik und L.A. mit nach Hause nehmen kann.

L.A.

root (Edward Gerhold)

Heute habe ich dann erstmal lineare Algebra wiederholt und dann fortgesetzt. Heute waren dann erstmal die positiv definiten Matrizen dran. Das Polynom ax²+2bxy+2cy² ist eine Funktion f(x,y) und erzeugt eine Fläche. Da wir von positiv definiten Matrizen sprechen ist erstmal die Oberfläche eine Schüssel. Geometrisch sind die die positiv definiten. Das Polynom berechnen wir mit xTAx. Wobei A = [a b; b a] und x = [x, y]. In Quadraten ausgedrückt a(x+(b/a)y)²+(c-(b²/a))y². Dazu habe ich auch eine Übungsaufgabe gemacht. Wenn das System positiv definit ist, ist a > 0 und c > 0. Es gibt noch mehr Tests, die habe ich aber kurzfristig wieder vegessen. Wenn ac < b² liegt mir auf der Zunge, wil aber nicht. Eigentlich wollte ich über die QR Zerlegung lesen, um die programmierbaren Algorithmen in den Kopf zu kriegen. Den habe ich dann mit anderen noch gelesen, er kombiniert Gram-Schmitt mit einem Iterationschritt indem QR und RQ den Platz tauschen. Habe aber noch viel mehr und interessanteres gelesen. Hinterher habe ich dann bei Algebra entspannt, die Verknüpfung habe ich ja als hintereinanderabfolgende Operation verstanden, daß ich hier meine Kette von Morphismen erzeugen kann, wie sie bereits in dem einleitenden ersten Kapitel vorgestellt wird. (T, X) ist ein topologischer Raum auf X. (Z, +, 0) ist ein Monoid, a + 0 = a. Darum ist 0 das neutrale Element der Addition. Subtraktion ist die inverse Operation. -(-a)=a. Jedes Element hat sein inverses. Der Monoid hat die Abbildung, die klammerfrei notierbare Assoziation und das neutrale Element. Und ein Inverses zeigte ich auch? Dann ist es sogar eine Gruppe. Das ist aber noch nichts, da ist noch viel mehr. Wenn ich das jetzt alles aufschreiben würde, hätte es natürlich Lücken. Kein Mensch auf der Welt kann das in drei Tagen lernen. (Keiner? Kein Beweis) Aber es macht Spass.

Viel einfacher

root (Edward Gerhold)

Moderne Algebra ist zwar abstrakt aber ganz schön einfach. Wenn man ein wenig im Internet stöbert, kann man sich die Begriffe erklären (lassen). Und genau das habe ich gemacht. Und schön mitgeschrieben. Ich freu mich gleich schon auf die erste Lektion des Tages. Denn auch Sonntags kann man studieren. Und was sinnvolleres ist mir für mich länger nicht mehr eingefallen. Ich kann gleich noch Musik studieren, aber stop. Ein intensives Studium der Numerik und linearen Algebra wartet noch auf mich, damit ich all die neuen Aufgaben lösen kann. Differentialgleichungen zum Beispiel gibt es ja für fast alles, was sich bewegt oder zeitlich ändert, sei es Hitze, Elektrizität, Oszillationen. 

Numerik in L.A.

root (Edward Gerhold)

Jetzt nach einer Extrawoche mathematischer Findung, was noch wozu gehört, und was ich lernen will, kann ich es entspannt angehen. Ich lerne das, was ich mir ausgesucht habe, und kann ausserdem ganz fokussiert mich um lineare Algebra und Numerik kümmern und mir endlich beibringen, wie man mathematische Aufgaben mit dem Computer löst. Nun kann ich auch quantitativ alle Quellen durchforsten.Jedenfalls werde ich es mir nach getanem Unterricht mit der Lektüre gemütlich machen.

Habe ich eigentlich schonmal das kartesische Produkt gezeigt? Sei X = [a,b,c] und X x X gibt die Koordinatenpaare {(a,a),(a,b),(a,c),(b,a),(b,b),(b,c),(c,a),(c,b),(c,c)}. Sinn macht es, sich das mit einem Koordinatensystem aufzuzeichnen. Ich musste mir das heute mal aufschreiben, um es zu verdeutlichen, so ist zum Beispiel [0,1]x[0,1] oder [0,1]² das Rechteck {(0,0),(0,1),(1,0),(1,1)}. Einfach, oder. Kommt halt unter anderem vor.

Übrigens, Algebra ist ja super abstrakt.

Jetzt kann ich weiter lernen...

root (Edward Gerhold)

Heute habe ich mir dann noch Algebra 1+2 sowie Topologie sowie als weitere Vertiefung der Analysisthemen Mass und Integrationstechnik (Lebesgue) besorgt. Natürlich kann ich nicht alles gleichzeitig studieren. Darum werde ich mir jetzt wochenlang Zeit nehmen. Die ersten einführenden Abschnitte mit Gruppen und Ringen waren dennoch interessant, wenn auch neu für mich. Seit der Schule habe ich den Algebrabegriff nicht mehr neu definiert. Das werde ich unter anderem machen. Mir gefällt das Rechnen lernen sehr gut und heute morgen noch hatte ich die Metriken (Abstand der  Punkte mit d Funktion) und Normen (Länge der Strecke von A nach B) wiederholt und endlich die 1-norm, die max-norm und wiederholt die euklidische Norm verstanden. Das ist in etwa das wichtigste aus der Topologie, was für Analysis 1 wichtig ist. Die Algebra allerdings bringt das volle Programm. Ich werde mir jetzt viel Zeit nehmen. Und viele Aufgaben lösen.

Notebook kaputt

root (Edward Gerhold)

Wollte gerade schreiben, jetzt ist das Notebook kaputt. Ich hatte es vorhin 25 Minuten eingeschaltet. Es hatte sich zwar nur auf 42 Grad Celsius erwärmt laut /sys/irgendwas. Doch es liess sich gerade, nachdem ich zwei Stunden unterwegs war nicht mehr einschalten. Gag, just als der Texteditor hier auf dem PIII aufpoppt, dessen Performance man von der Arbeit aus dem gemeinschaftlichen Computerraum kennt, 933, 512mb, blinken die Lichter kurz. Das ist jedenfalls mittlerweile so schlimm, dass ich das Notebook den Monat nicht mehr genutzt habe und es das letzte mal direkt drei Tage anliess. Morgen gucke ich mir erstmal Topologien und Algebra an, und ich glaube Funktionentheorie war das. Kommt Zeit kommt Hartz.

A... wie Algebra

root (Edward Gerhold)

Gruppen, Ringe, Körper, Polynome. Muss morgen unbedingt an Papier denken, um meine Unterlagen zu vervollständigen. Das macht einen Riesenspaß mir das alles beizubringen, nur damit ich dann mit numerischen Verfahren und vernünftiger 3D-Physik neben meinem JavaScript weitermachen kann (*). Ich warte solange auf die fertigen ES6 Implementierungen, und mache dann zu ES7 meine implizite Drohung, das Projekt zum Ende zu führen wahr. Ich denke, daß ich Elektrizität und Wellen (Physik 2) und die Einführung in Chemie (Bioinformatiker ist heute ein Topberuf, dazu kommt dann noch Biologie) wohl noch was zurückstellen muss. Ich habe nur zwei Hände, ein Gehirn und nicht mehr Zeit als andere. Auf meiner Liste stehen jetzt erstmal vorrängig Algebra und Topologien, sowie Funktionsanalyse, um zu verstehen und zu vertiefen. Der Übergang vom amerikanischen ins Deutsche klappt besser als erwartet. Es macht mir halt Riesenspass, viele Jahre nachzuholen. In einem sehr guten Tempo. Wobei ich ihr danken muss, die Geduld zu haben, daß ich viel lerne, und vielermals auch dadurch mal abgelenkt bin, und gar nicht mitgekriegt habe, was sie mir erzählt hat. Danke für die Chance. So freue ich mich auf die weiteren Kurse. Ich werde jetzt ausserdem bevorzugt auf die lokalen Unis umsteigen, vielleicht bringt´s mir was, das zu lernen, was um die Ecke unterrichtet wird. Ob´s jetzt aus Amerika kommt, oder von da, anderswo ist es wieder das gleiche. Bis vor kurzen lief Algebra bei mir unter Schulmathematik, ich finde den richtigen Algebra Kurs allerdings noch besser. Ist ürigens wie JavaScript. Nur nicht function (x) { var y = x; return y; } sondern f : X -> Y, x &element; X, y &element Y, X &sub; R, Y &sub; R. f ist bijektiv und X und Y sind homomorph, so wie ich das jetzt aufgeschrieben habe. 

 

(*) In Wirklichkeit rechne ich mir in Zukunft mehr Chancen bei der Arbeitssuche aus. Für mein Hobby muss ich allerdings wieder auf den Punkt zurückkommen. 

Kettenregeln

root (Edward Gerhold)

Die beliebteste Differenzierungsregel ist wohl die Kettenregel, die sich mit der Komposition von Funktionen beschäftigt, und es schafft verschachtelte Funktionen zu differenzieren. Aber wie kam ich nochmal von f(x) = e2x zu f'(x) = 2e2x? Wo kam der Faktor her? Genau, von der Kettenregel. f(g(x)), in userem Fall g(x)=2x, und f(x) = eg(x), wird abgeleitet mit f'(g(x))*g'(x), der Kettenregel, oder in Leibniznotation dz/dx = dz/dy * dy/dx. Das Beispiel mit der e-Funktion führe ich an, weil ich es mir gestern wieder ins Gedächtnis gerufen habe. Also f'(x) bleibt einfach eg(x), da e ja seine eigene Ableitung ergibt, Euler hatte eine perfekte Zahl gefunden. Die Ableitung von bx ist cbx (= naxn-1) und von logby = 1/cy. Dank e wurde die Konstante c zu einer 1. Das Limit was e ergibt ist (1+1/n)n wenn n -> inf oder (1+h)1/h wenn h -> 0. Den Exponenten leiten wir nochmal ab und multiplizieren ihn mit f'(g(x)), also von 2x ist die Ableitung einfach 2 und darum schreiben wir 2*e2x. Einfach und gut, oder? So wird aus sin 2x dann natürlich 2 cos 2x, da cos ja die Ableitung von sin für f'(x) ist.

nicht so schwer

root (Edward Gerhold)

Das ist gar nicht schwierig, von amerikanischer zur deutschen Mathematik zu wechseln. Das übersetzen geht schneller als Gedacht, die Semesterskripte sind schnell kurz durchgeblättert, die Wikipedia schnell zum nachschlagen von Mannigfaltigkeit und Homöomorphismus sowie bijektiv oder Diffeomorphismus benutzt. Die Topologien sind mit den Kurzeinführungen in Analysis 1 + 2 (ich glaube, ich kann mir da noch eine deutsche Unterlage ranholen) schnell grundlegend gelernt, ich freue mich allerdings schon aufs Semester, das ganz zu machen, und auch die algebraische Gruppentheorie ist in den Fokus gerückt. Allerdings gefallen mir die Eigenschaftnen von Kurven und Flächen und so habe ich heute viel damit verbracht, nachdem ich den Analysisteil durchgeguckt hatte. Natürlich vertiefe ich die noch weiter, sind interessant, vielleicht interessanter, als ich sagen kann. Mir machen die neuen Unterlagen Spass. Und auch die deutsche Mathematik, ich übe fleissig.

Topologien

root (Edward Gerhold)

Was muss man als Studienanfänger Mathematik in Deutschland unbedingt lernen? Richtig, Mengenlehre, zumindest Topologien, Metriken, Normen. Wissen, was Funktionen und Abbildungen sind. Damit man Dinge wie M ist Teilmenge von X lesen kann oder f :  R -> R, daß f eine reelle Zahl annimmt und eine reelle Zahl zurückgibt, aus dem R auf den R abbldet. Was offen und geschlossen bedeutet, usw. Die deutsche Mathematik ist anders als die amerikanische, hier an deutschen Universitäten wird all das, was in der amerikanischen Fassung kurz definiert wird hier ausführlich in Symbolschrift niedergelegt. Langt im amerikanischen Papier ein R² muss es hier gleich die ganze Definition sein. Kann mich auch irren, wie es dort ist, aber alles, was ich bisher gelesen habe, unterscheidet sich genau dadurch. Die deutschen fangen mit der Topologie an. So fangen übrigens auch die Analysis Unterlagen an. Ich werde mir nächste Woche noch ein ganzes Semester zur Topologie ausdrucken und durchnehmen, für heute wird erstmal die Einführung hinhalten, oder ich mich einem anderen Thema widmen. Allerdings ist eine Norm nichts anderes als die Länge der Strecke zwischen zwei Punkten, die Wurzel aus der Summe der Quadrate der Komponenten des Vektors, und der Abstand zwischen x und y wird definiert durch die d(x,y) Distanzfunktion. Da gibt es drei Eigenschaften, die halten mussen, x = y wenn d(x,y)=0, d(x,y)=d(y,x) und die Dreiecksungleichung d(x,z)<= d(x,y) + d(y,z). Kann auch einen Fehler enthalten, wortwörtlich genommen garantiert, weil nicht vollständig. Ganz genau habe ich mir das noch nicht gemerkt. Wenn man Mengen aus Mengen definiert, will man nicht nur die Punkte, sondern auch die Abstände zwischen a < b < c wissen. Das macht die Metrik, was ja messen oder besser das Maß bedeutet. Die Norm ist halt sowas wie der Abstand zwischen den Punkten und es gibt Definitionen, Sätze und Korollare für die Topologien. Das sieht für mich nach einen interessanten Studienabschnitt aus und ich werde mich diese Woche wieder drum kümmern. Inzwischen habe ich viel Spaß mit meiner neuen Literatur. Gestern habe ich die ersten Excercises von "Ordinary Differential Equations" gelöst. Namentlich das Initialwerteproblem für lineare ordinäre DG erster Ordnung mit konstanten Koeffizienten. Ich habe den Integrationsfaktor e-at endlich verstanden, wo er herkommt. Bei DG für Dummies sah ich den Baum vor lauter Wald nicht. mü(t) ist nicht nur ein Faktor. Er passt die Integration an., dass (ay'-y)mü = (y*mü)'. Er ist der Faktor. Ganz genau ist y'=ay+b gleich der gesamten Ableitung (beide Seiten der Gleichung, man muss nur y' rüberbewegen) von Psi. d(Psi(t,y(t))/dt = c. Psi ist nicht das gesuchte Integral, sondern ebenfalls ein Integral, nur bezieht es y' mit auf der rechten Seite ein, daß die gesamte DG die Ableitung von Psi ist. Ohne Symbole schwer zu zeigen. Aber Psi gibt mü(t). So kann man für y' = 2y+3 gleich y(t) = ce2t-3/2 schreiben. Das ist eine generelle Lösung, kein Anfangswerteproblem. Beim letzteren hat man noch t0=0, y(t0)=1 oder andere Werte, setzt die ein und kann d(Psi)/dt lösen (= c). Beim Variablen Koeffizienten (Funktionen) wird der Exponent at zur Funktion A(t) = ∫a(t) dt.. Aber das könnt ihr gerne auch selbst nachlesen. Ich werde mich jetzt erstmal tiefer und tiefer in das hineingraben, was ich da alles lernen will. Den Integrationsfaktor zum Beispiel werde ich natürlich auch wiederholen, um ihn dann vernünftig zu erläutern.

Man glaubt es kaum

root (Edward Gerhold)

Das Lämpchen leuchtet wieder. Aber garantiert nicht mehr lange.

Der erste Tag mit Mathe für Informatiker war klasse,auch wenn ich heute mehr gesichtet habe. Was ich mir allerdings merken konnte war der Kongruenzsatz von Gauss a (entspricht/ist kongruent zu) b (mod n), was bedeutet, daß a-b von n dividiert wird. Oder dass der Rest(a,n) = Rest(b,n) sei...Die Funktion T(n) kommt im Kapitel über Rekurrenzen dran, wie das Mastertheorem, T(n) = aT(b/a) + b(n) oder wie das geht, was sich wie ne differenzialgleichung y' = ay + b liest, aber nicht davon abstammt. Vielleicht finde ich ja doch noch Gemeinsamkeiten, aber darum geht es nicht. Es gibt einen tollen 4. Teil mit Wahrscheinlichtkeit, womit ich mein Stochastik Material ergänzen kann, während ich speziell über Computerwissenschaften lese. Der dritte handelt von Zählen, oder von Summen, Asymptoten, eben genannten Rekurrenzen und mehr und mehr. Das Buch ist Klasse, ich kenne die Vorlesung ja schon von Video und ich war teils mit der Atmo der Aufnahme zugange und finde das lernenswerter denn je. Der Fundamentalsatz der Arithmetik ist mir gerade auch wieder eingefallen. "Jede positive ganze Zahl kann als ein Produkt von Primzahlen geschrieben werden." Den hat glaube ich auch schon jeder andere Nichtinformatiker mal gehört.

Pech

root (Edward Gerhold)

Mein 199.- Refurbished hp compaq 6910q gibt den Geist auf. Ist es dieses bekannte Spannungswandlerproblem, daß er Kapazität verliert? Es fing im November damit an, daß er Auszeiten brauchte. Ich habe ihn gereinigt. Mittlerweile braucht er längere Auszeiten, es waren zwei Stunden. Jetzt zehn oder zwölf. Und kaum eine Möglichkeit, daß Ding zum Blinken zu kriegen. Als ich aufgeben wollte, sprang er das letzte mal an..

Mathe für Informatiker

root (Edward Gerhold)

Hurra, heute habe ich mir endlich Mathe für Informatiker drucken können. Genaugenommen, die MIT Version, die auf OpenCourseWare erhältlich ist, von der ich schon vor bald zwei Jahren die Videos geguckt hatte, die ich mir vorgenommen hatte, noch irgendwann zu machen. Gerade lese ich das erste Kapitel über Beweise. In meinem Fall folgt ein Hinweis darauf, daß ich versuche, das in Zunkunft ernst zu nehmen und mich (endlich) danach zu richten. Ausserdem habe ich mir noch zwei Unterlagen über Analyis und Differentialgeometrie von der TU hier (zufällig) besorgt, sowie das gleiche nochmal von woanders. Auf Englisch habe ich Calculus nun bereits drei Monate durchgenommen. Und weil´s so schön ist, auch die Unterlage über die ordinären Differentialgleichungen, die mein Differentialgleichungen für Dummies Buch natürlich übertrifft, was ich mir für´s erste ausgesucht hatte. Seit ich mich an den Partialgleichungen versucht hatte, gehen die runter wie Öl, darum freue ich mich auf jede Seite, die ich die nächsten Tage und Wochen studieren werde. Physik II (Elektrizität und Wellen) habe ich mir für nächste Woche aufgespart. Ich bin noch nicht ganz durch mit dem, was ich wirklich noch lernen will. Zurück zu meinem Beitrag für die Informatik bereite ich mich jetzt natürlich bestens darauf vor, mir Algorithmen und insbesondere wissenschaftliches berechnen nochmal von vorne beizubringen.  Als ich 2012 den den Computer wieder im Wohnheim anschloß, und wieder Programmieren lernen wollte, fing ich zwar auch mit OpenCourseWare und den Informatikthemen an, aber die waren schnell abgelutscht, weil ich die schonmal gemacht hatte. Ich hatte was wichtiges vergessen, was ich dieses Jahr eindeutig nachholen werde, damit auch ich gute Software programmieren kann. Genug geschwafelt und von dem, was ich noch nicht habe, geredet. Mathe für Informatiker ist natürlich Klasse, diskrete Mathematik, Zahlentheorie, Mengenlehre, Summen, ein ganzer Teil handelt vom Zählen, aber auch Netzwerke und Graphen auf die ich mich nochmal richtig freue, wie auf RSA, wo ich glaube, daß ich diesmal spielend..aber ich will nicht so klingen, also intensiver mitrechnen werde.

Ich hoffe, durch die Beweise dann in Zukunft meine ganze bisherige Art auf meiner Homepage zu posten verlerne. Wenn ich das nächste PHPStorm installiere, räume ich auch nochmal die Datenbank auf, das habe ich diesen Monat noch nicht gemacht. Übrigens, die Kommentardatenbank ist VOLL mit Spams. Diese verdammten Bots finden jede Url, die login oder comment enthält und was nicht natürlich noch alles, aber ich denke, hier hat "login" und "comment" schon gereicht. Und die Formulare zur Registrierung füllen die auch von alleine aus. Übrigens weiss ich nicht, ob ich Benutzer habe, ich habe seit Oktober nicht mehr geguckt. Die Kommentare funktionieren nur bei eingeloggten Benutzern und da 100%, ich hab den Gast vergessen oder den Query falsch gehabt, ich glaube letzteres. Andermal wieder. Pro PHP MVC ist übrigens immernoch so gut, wie als ich es abgeschrieben habe.

praktische Idee

root (Edward Gerhold)

Folgen und Reihen

Unterwegs kommen mir natürlich auch einige Ideen. So nutzte ich die Sigma Notation vorgestern zum summieren von Cents, von k=? bis n, also von k=1  bis 5 1+2+3+4+5 = 15 Cent. Die Frage drängte sich dann schnell auf. Was sind 20 Cent? Man kann nicht immer von 1 beginnen. Bei der Frage nach 32 Cent fand ich keine Lösung mehr, ausser von 32 bis 32. Dabei fielen mir dann die 2^n auf, die nur mit sich selbst dargestellt werden können. 16 Cent kann ich werder von sieben bis acht noch von 8 bis neun, noch von weiter unten darstellen. Die Differenz zwischen den Summen zweier Pärchen 1+2, 3+4, 5+6, ist übrigens vier. Und hier die ersten Pärchen ergeben übrigens Primzahlen. Die sich wohl noch in Summen zerlegen lassen, wenn nicht mehr in Faktoren, wie wohl nebensächlich beobachtet in Bezug auf Primfaktoren auffällt. Jedenfalls sind 20 Cent die Summe von 2 bis 6. Damit habe ich ein neues Spielchen für unterwegs entdeckt. 

Stochastik

Spass mit dem Geld hatte ich nebenbei auch, mich mit 650e-1 oder 6.5e1 cent an 65 Cent zu erinnern oder 40 Cent als o050 auszurücken. 65 Cent sind auch 2^6+2^0 oder 01000001 cent. Die kann ich immernoch auswendig. Mir fiel aber noch was ein Statistik. Statistik aus dem echten Leben. Als Arbeitsloser muss man Flaschen sammeln und betteln, wenn der Pfand nicht reicht. Ich habe auch eine Weile Obdachlosenzeitungen verkauft, aber zur Zeit nicht. Jedenfalls kann man ohne von einer trivialen Aufgabe zu reden, sich mal überlegen, das als stochastisches Experiment zu betrachten und sich zu merken, oder besser mit Strichliste zu notieren, was man sammelt und wo, was man bettelt und wo. Für ein paar Cent vor dem Supermarkt für den Supermarkt, lassen mich die Leute nämlich auflaufen. Was ich dabei genau beobachte, oder wie ich sie frage und wie sie reagieren. Das ist eine tolle Aufgabe, die mal statistisch auszuwerten: Nebenbei findet man heraus, wie wahrscheinlich es ist, von denen ein bisschen Kleingeld für den Supermarkt zu kriegen. Den Meisten ist man egal. Eine stochastische Auswertung tausender Stichproben, oder gleich einigen hundert (!) für ein paar Cent, könnte das mal aufzeigen.

Orthogonal

root (Edward Gerhold)

Weiß nicht, dachte, vielleicht nochmal irgendwas zu posten. Gestern habe ich wieder mal Kapitel 1 aus der Linearen Algebra wiederholt. Ergebnis, die Faktorisierung PA = LDU. Wie faktorisiert man denn LDU? L ist die linke untere trianuläre, D ist die Diagonale, U ist die obere trianguläre. Anders als bei A = LU, wo L eine Diagonale mit 1en hat und in der linken Hälfte die inversen Eliminationschritte, zum Beispiel in a21 wird zu Reihe 2 die Reihe 1 so oft addiert, wie die Zahl wertig ist. Das Vorzeichen entscheidet über Addition und Subtraktion. In U bleiben die Eliminierten Zeilen mit den Pivots auf der Diagonalen. Bei LDU wird zusätzlich die Diagonale aus U rausgeteilt, das bedeutet, das man Reihe 1 durch u11 teilt, Reihe 2 durch u22 usw. Normalerweise stehen nur rechts von Zahlen. In der letzten Reihe braucht man nichts mehr zu tun, ausser die 1 an unn zu setzen. Die Zahlen, die in u11,...,unn stehen, die füllen jetzt die Diagonale bei D. Wozu ist P? Die Permutationsmatrize vor A dient dazu die möglichen getauschten Reihen wieder umzutauschen. Auch hier steht die Quelle in der Spalte und das Ziel in der Reihe, und die P ist einfach eine permutierte I.

Übrigens hat eine n x n Matrix n! Determinanten, die alle summiert mit det P werden, wenn man nicht auf die Cofactormethode ausweicht. Eine Matrix A multipliziert sich mit p(t) zu einem Polynom. Und man kann mit Au die Lösung für du/dt ausrechnen. Am Ende des Kapitels werden Differentiations- und Integrationsmatritzen vorgestellt, die man sich so vorstellen kann, dass man das Polynom in natürlich geordneter aufsteigender Reihenfolge rechnet. Damit kommt man um eine Extravariable für die Potenz rum. Ein Polynom 4. Grades braucht eine 4x5 Matrix. Die Integration profitiert auch von der natürlich geordneten Reihenfolge. Das Thema wird in späteren Kapiteln noch aufgegriffen um einige Grundlagen für Differenz- und Differentialgleichungen zu legen, aber auch für Potenzreihen und andere Dinge, wie zum Beispiel Projektionen auf Linien oder Ebenen wobei die Regel der linearen Kombination A(cx+dy) = c(Ax) + d(Ay). Die L.A. ist sehr flexibel. Mit Gram-Schmidt kann man aus Vektoren eine orthonormale Basis mit O(n²) Schritten erzeugen, in dem man vom ersten bis zum letzten Vektor die linearen Komponenten des anderen subtrahiert, und sie zuletzt noch normalisiert. Aber das ist eins von vielen vielen Beispielen rausgegriffen.

Zum Fundamentalsatz fiel mir heute dann natürlich noch schlüssig auf, warum und was orthogonal ist oder heisst, denn C(A) ist orthogonal zu N(AT) (Spaltenraum zum linken Nullraum meint er) und C(AT) zum N(A) (Reihenraum zum Nullraum). Jeder Vektor im Reihenraum ist orthogonal zum Vektor im Nullraum. Das Skalarprodukt gibt 0, wenn zwei Vektoren Senkrecht zueinander sind. Jetzt gibt Ax = 0. Und ATy = 0. A und x oder AT und y stehen in dem Fall senkrecht zueinander. dot(v,w) ergibt auch null. xTy ist die lineare Algebra Notation für das Punktprodukt. Der gekippte Vektor x liegt jetzt da, wie eine Reihe eine 1xn Matrix da. Und im Falle von dem Ergebnis 0 sind sie orthogonal. In der U-Bahn habe ich mir wieder die Fouriertransformation durchgelesen und bin weiter den je. Den komplexen Einheitskreis hatte ich mir letztens gemerkt. Gerade hatte ich sehr gut bei wn aufgepasst, F, F-1 und F- zu berechnen und mich bereits auf das Problem Set vorbereitet, was ich dann wohl bald bearbeiten kann. Fourierreihen und Fourieranalysen im weiteren Zusammenhang habe ich mir natürlich bereits besorgt. Und überhaupt, das erlernen der Potenzreihen (en=1+x²/2!+x3/3!+...+xn/n!) und anderen Folgen und Reihen macht mir ebenso viel Spass, wie die Gesamtheit der Mathematik, die ich in Angriff genommen habe und noch nehme.

 FreeMat ist eine tolle Alternative zu Matlab habe ich gerade gestern und heute erst herausgefunden. FreeMat kann .m Dateien ausführen. Ein paar Skripte konnte ich erst nicht starten. Aber wenn man die fehlenden Variablen hinzufügt und function pointer nimmt für zum Beispiel inverse = @inv um den Befehl inverse zu erhalten, der inv ruft, dann kann man mit FreeMat rechnen und plotten. Und das Schöne, was ich zum Beispiel schön fand ist, dass es einfach ist, damit Matrix und Vektoroperationen zu probieren und zu plotten oder gar Algorithmen zu schreiben und sie als .m zu speichern. Jedenfalls hat ein kurzer Test mit Funktionsplots und b=A*x und inv(A)*b == x bereits ans Tageslicht gebracht, daß mir FreeMat als Ersatz für Matlab dienen wird. Denn die Bedienung ist nicht kompliziert, Matrizen leicht erzeugt, und die Plots sind bunt und dreidimensional wie die von Matlab.

Nur ein paar Eindrücke, das macht alles noch viel mehr Spaß, finde ich und freue mich riesig auf meine finale ODE Unterlage diese Woche.

Iterationsmethoden [Heute y_n+1 = y_n + y'(x) * h]

root (Edward Gerhold)


// Die ordinäre Differenzialgleichung dy/dx = 3x² mit Eulers Methode approximiert

function eulermethod (x, h, n, dydx, f)
{
// Eulers Methode, sich mit der Steigung anzunaehern.
// Das neue y ist gleich dem alten plus y'(x) * deltaX;
var y_;
var y = x;
var results = [];
for (; x <= n+h; x+=h) {
y = y + dydx(x) * h; // y[n+1] = y[n] + y'(x) * deltaX;
y_ = f(x); // nur zum Vergleich
results.push(x,y,y_);
}
return results;
}

function print(a)
{
// Den Array mit x, Approximation und exaktem Ergebnis ausgeben
console.log("xtytf");
var format = "%st%st%s";
for (var i = 0, j = a.length; i < j; i+=3) {
console.log(format, a[i].toFixed(2), a[i+1].toFixed(6), a[i+2].toFixed(6));
}
}

function fprime(x)
{
// Die ordinaere Differenzialgleichung
// dy/dx = 3x²
return 3 * x * x;
}

function exact(x)
{
// Integral von 3x^2 dx gibt (3x^3)/3 = x^3
return x*x*x;
}

var a = eulermethod(0, 0.1, 4, fprime, exact);
print(a);

/*
x y f
0.00 0.000000 0.000000
0.10 0.003000 0.001000
0.20 0.015000 0.008000
0.30 0.042000 0.027000
0.40 0.090000 0.064000
0.50 0.165000 0.125000
0.60 0.273000 0.216000
0.70 0.420000 0.343000
0.80 0.612000 0.512000
0.90 0.855000 0.729000
1.00 1.155000 1.000000
1.10 1.518000 1.331000
1.20 1.950000 1.728000
1.30 2.457000 2.197000
1.40 3.045000 2.744000
1.50 3.720000 3.375000
1.60 4.488000 4.096000
1.70 5.355000 4.913000
1.80 6.327000 5.832000
1.90 7.410000 6.859000
2.00 8.610000 8.000000
2.10 9.933000 9.261000
2.20 11.385000 10.648000
2.30 12.972000 12.167000
2.40 14.700000 13.824000
2.50 16.575000 15.625000
2.60 18.603000 17.576000
2.70 20.790000 19.683000
2.80 23.142000 21.952000
2.90 25.665000 24.389000
3.00 28.365000 27.000000
3.10 31.248000 29.791000
3.20 34.320000 32.768000
3.30 37.587000 35.937000
3.40 41.055000 39.304000
3.50 44.730000 42.875000
3.60 48.618000 46.656000
3.70 52.725000 50.653000
3.80 57.057000 54.872000
3.90 61.620000 59.319000
4.00 66.420000 64.000000
*/

Eigenwerte und Eigenvektoren

root (Edward Gerhold)

Wie bestimmt man Eigenwerte und Eigenvektoren?

Unsere Matrix ist einfach und eine 2x2 mit 1 und -1 in der ersten Gleichung und 2 und 4 als Koeffizienten der zweiten Gleichung. Ich schreibe sie mal untereinander.

[1 -1

2  4] = A

1. Man löst |A-λI|. 

Zuerstmal subtrahiert man λI von der Diagonalen und rechnet die Determinante aus. Man erhält ein Polynom.

[1-λ  -1

 2   4-λ]

|A| = det(A) = ad-bc

|A-λI| = (1-λ)(4-λ)+2 = λ²-5λ+6

2. Dann rechnet man die Determinante aus, das sind die Eigenwerte. In dem Fall, ich habe quadratische Formel benutzt,

wie man das so macht, und habe 2 und 3 raus. Die Eigenwerte sind also 2 und 3.

3. Nun setze ich die Eigenwerte nochmals auf der Diagonalen ein, indem ich sie subtrahiere. Für jeden Eigenwert erhält man eine Matrix (A-λI).

Jetzt versuche ich mit den beiden Matrizen (A-λI)x = 0 zu lösen. Zuerst wollte ich es mit (A-λI)-1 versuchen, was aber nicht klappen würde, da man mit der inversen Matrix alle Ax=b ausser Ax=0 berechnen kann, da man mit einem Nullvektor b multiplizieren würde. Und die Faktorisierung A=LU (Gauss-Elimierung) würde in beiden Matrizen zu einer Nullreihe führen (addiert Reihe 1 zu Reihe 2 und schon ist sie 0 in beiden Fällen) und das ist noch keine Lösung, (im letzten Fall lohnt es sich dennoch weiter zu lesen).

Zum Glück sind die Matrizen 

so einfach, dass ich die Vektoren so rausfand (siehe Probe, so habe ich die auch gefunden). Die beiden Matrizen sind, ich trenne die Reihen mal mit Komma [1-2  -1, 2   4-2] oder [-1 -1, 2 2] und [1-3 -1, 2 4-3] oder [-2 -1, 2 1].Die multipliziert mit dem Vektor [x, y] soll den Nullvektor [0, 0] ergeben. Ich habe [1, -1] für die erste und [-1, 2 ] für die zweite Gleichung raus. Das sind die Eigenvektoren.

Probe:

-1*1+-1*-1 = 0, 2*1+2*-1=0 für den Eigenvektor [1,-1] und die Matrix [-1 -1, 2 2]

-2*-1+-1*2=0, 2*-1+1*2=0 für den Eigenvektor [-1, 2] und die Matrix [-2 -1, 2 1]

Diagonaltest: λ1+λ2 = 2 + 3 = 5; Die Diagonale ist 1+4 = 5. 5=5, also korrekt.

Produkttest: det A = 4+2 = 6; &lambda1;*λ2 = 2*3 = 6; Also auch korrekt.

Leider konnte ich jetzt keine richtige Matrixnotation nehmen, aber ich hoffe, das ist verständlich genug gewesen. So berechnet man Eigenwerte und Eigenvektoren mit det |A-λI| und (A-λI)x = 0 

 

Update: Ich weiss nicht, ob man bei euch A-(lambda)I oder A- I liest. Im Editor sind die Zeichen wieder da. Gerade auf dem Bildschirm nicht. Ich wollte sie schon wieder einfuegen. Überall da wo nichts vor dem I oder hinter dem Minus steht steht ein Lambda, steht nichts da. Steht´s doch da, ist der Kommentar nicht für euch, sondern für mich und Browser wie den, den ich gerade benutze. Jedenfalls zieht man Lambda von der Diagonalen ab und hat ein Polynom mit Lambdas da stehen. Durch das Multiplizieren mit der Identität I wird (lambda)I zur Diagonalen.

Partial DGL

root (Edward Gerhold)

Heute habe ich meine erste Kursunterlage über partielle Differentialgleichungen drucken dürfen. Ich habe eigentlich, obwohl ich mich dran gewöhnen darf, mich ausgiebig mit charakteristischen Gleichungen befasst. Die Schreibweise mit Strichen und Subskript ist für mich nach wochenlanger Analysis für Anfänger natürlich erstmal faszinierend, da ich die Sachen nun kürzer aufschreiben kann. Das wär sonst nicht mehr lesbar, denke ich mir, denn es geht bei Differentialgleichungen mehrerer Variablen doch schon ordentlich zur Sache, auch wenn ich im Grunde erst bei F(x,y,z,p,q) = 0 bin. Und auch vollständig abgegriffen ist das Gebiet noch nicht. Für gewöhnliche Differentialgleichungen brauche ich noch eine separate Semesterunterlage. Ich werde mir ein paar Tutorials angucken, und mir was vorrechnen lassen.

Rechnen lernen

root (Edward Gerhold)

Mir macht das richtig Spaß wieder Mathe zu lernen. Das mache ich schon seit Wochen.

Inzwischen habe ich ein paar Stunden diskrete Mathematik gemacht und mir Sätze wie n mod k = m mod k + l mod k, analog zu n = m + l, und n mod k = m mod k * l mod k, analog zu n = ml, oder sei p eine Primzahl, so ist (a^p-a)/p eine ganze Zahl. Diese Disziplin hat allerdings noch mehr zu bieten, und bislang habe ich die Kursunterlagen nur elektronisch konsumiert.

Anders aber die in Statistik. Inzwischen habe ich fleissig studiert, was unter der Glockenkurve innerhalb einer oder mehrere Standardabweichungen passiert. Ohne jetzt empirisch zu werden und zu sagen, daß 68, 95 und 98 Prozent unter die ersten drei Standardabweichungen fallen, könnte ich bereits gezielt Stichproben auswerten. Auch in Wahrscheinlichkeitsrechnung habe ich dadurch massgeblich zugelegt und kann unter anderem nun mit bedingten Wahrscheinlichkeiten umgehen, oder Tabellen auswerten und die Frage beantworten, mit welcher Wahrscheinlichkeit dann erwartete Ereignis eintritt. Allerdings muß ich mir noch mehr Mühe geben, den Standardfehler bereits kennen gelernt, warten der, noch mehr Formeln und ein Übergang in die deutsche Sprache, ich habe auf amerikanisch angefangen, auf mich.

Ich mache aber nicht nur auf dem Gebiet, sondern auch auf anderen Fortschritte. Zum einen lassen mich Polarkoordinaten, komplexe Zahlen, die eulersche Formel und die eulersche Zahl, komplexe Matrizen und die Fouriertransformation nicht los, zum anderen lerne ich Analysis I und II und lineare Algebra im Detail. Nach dem ich die ersten Sätze gelernt hatte, die Grenzwerte bestimmen konnte, Ableitungen nehmen, den Fundamentalsatz für Ableitungen und hinterher den für Integrale verstanden hatte, und auch, daß Summen als numerischer Fallback eingesetzt werden, wenn man kein Integral finden konnte, konnte ich mit gelösten Aufgaben für Bogenlängen und rotierten Körpern und mehr Sicherheit natürlich tiefer in die Materie eindringen. Zwischendurch hatte ich dann natürlich auch die Analysis II begonnen und mich von analytischer Geometrie über Differenzierung mit mehreren Variablen und gemischten Funktionen über Doppel- und dreifachen Integralen zu den Vektorfeldern durchgearbeitet. Hier studiere ich natürlich weiter. Analysis macht mir Riesenspass.

Aber auch für die Algebra an sich habe ich einen neuen Sinn bekommen. Nicht nur der Fundamentalsatz der Algebra, daß ein Polynom n-ten Grades in R maximal n Nullstellen hat und im komplexen Raum C gar exakt n Nullstellen hat, hat sich bei mir eingeprägt. Nein, daß bißchen rechnen aus der Schule war es nicht. Die Algebra ist eine Fundgrube interessanter Mathematik. Und natürlich lege ich viel Wert darauf, es jetzt auch praktisch anwenden zu können. Nicht nur, um mich im Programmieren zu verbessern. 

Beschäftigt

root (Edward Gerhold)

Dieses mal poste ich von unterwegs, ich habe nämlich nicht aufgeladen.

Die Woche war spannend. Natürlich habe ich mich mit linearer Algebra beschäftigt. Ich habe Eliminierung von Gleichungen geübt. Nun kann ich die Formal A = LU beschreiben. Durch die Eliminierung erhalte ich U, die rechte obere Dreiecksmatrize. Und die Eliminierung speichere ich in L, der linken unteren Dreiecksmatrize. Multipliziert ergeben sie die Originalmatrix.

Fasziniert war ich von der neuen Umgebung. Es gibt vier Fundamentale Spaces in der Linearen Algebra. Den Spaltenraum Column Space C(A), der alle Lösungen von Ax=b enthält, und den Nullraum N(A), der alle Lösungen von Ax=0 enthält, den Reihenraum Row Space C(AT), im und den linke Nullraum Left Nullspace N(AT). Deren Existenz und Eigenschaften sind im Fundamentalen Theorem der Linearen Algebra zusammengefasst.

Ich habe die Echelon Form U kennengelernt, die sich natürlich auch mit L zu A zurückmultiplizieren lässt, und auch die Permutationsmatrix P, mit der man row exchanges vornehmen kann. Natürlich habe ich das Buch bis zum Ende durchbekommen. Doch muss ich ja auch die Übungsaufgaben machen und bin damit gerade mal hinter Kapitel Eins gekommen.

Kapitel 2 geht um die Vector Spaces, das dritte um Orthogonalität, um es so zu sagen, jedes Gleichungssystem hat eine orthonormale Basis. Das sind die rechtwinklig aufeinanderstehenden Achsen des Koordinatensystems. Kapitel 4 behandelt die Determinanten, die heutzutage aus dem Zentrum der linearen Algebra gerückt sind, aber dennoch gleich wichtig. Die Formeln für die 2x2 und 3x3 Matrix kann man sich einfach merken. Danach geht´s in Kapitel 5 um Eigenwerte. Die Gleichung Ax = (Lambda)b habe ich noch nicht berechnet. Das liegt daran, daß ich mit den Aufgaben ja noch viel weiter vorne bin.

So habe ich inzwischen auch Statistik und Wahrscheinlichkeit wieder rangezogen und bei guter Laune ist eine Eins zu Würfeln mit P[1] = 1/6 gegen P[1'] = 1-1/6 natürlich nur ein sechstel. P[A or B] = P[A] + P[B] und andere Gesetze kann ich mir ebenso blitzschnell merken und mit Übungsaufgaben anwenden, wie den mean als Summe der Daten geteilt durch die Anzahl der Daten auszudrücken.

Zwischenzeitlich habe ich ein Auge auf die diskrete Mathematik geworfen. Viele der finiten Methoden, wie Logik, Boolesche Algebra, Netzwerke, Graphen, Nummerntheorie, Folgen und Reihen sind mir ein Begriff und warten natürlich ebenfalls auf Vertiefung.

Was mich aber mehr interessiert, ist die Game Physik. Nachdem ich die Physik Engine nach Javascript portiert hatte, hatte ich bereits tiefe Einblicke gesammelt. Sei es die einfache Physik, Newton, Momente, die Feder, weniger kompliziertere Faktoren wie die Reibung und Dämpfung, oder die kompliziertere Kollisionserkennung. Es scheint mir zu liegen und Spass zu machen. Nach all den Übungen mit Vektoren und Matrizen um die 3D Grafik zu produzieren ist natürlich der Groschen gefallen.

Der Groschen ist auch bei Sinus und Kosinus gefallen. Nun kann ich mich bereits gut orientieren und kann die unmöglichsten Traces mit Sinus und Kosinus erzeugen. Was mich aber viel mehr interessiert, das sind die Fourier-Reihen. Die Fourieranalyse sowie die Transformation, die sind aus der heutigen Welt nicht mehr wegzudenken. Irgendwo las ich, daß man Fourier den Algorithmus des 20. Jahrhunderts nannte. Allerdings kann man damit Funktionen approximieren und wieder herstellen, oder Wellen zerlegen und Analyisieren und wieder herstellen. Das erfordert allerdings auch solide Grundkenntnisse in Folgen und Reihen, Analysis, komplexen Zahlen und linearer Algebra. Daran arbeite ich gerade mit viel Spass und natürlich Hochdruck, heh.

Folgen und Reihen habe ich vorhin noch geübt. Und kurzgesagt, wenn die Reihe konvergiert kommt eine finite Zahl raus, wenn sie divergiert wird sie unendlich. Ich habe mich gerade noch mit den vergleichenden Testverfahren beschäftigt, die ich jetzt nicht weiter aufführen werde.

Was mich an der Game Physik so reizt sind nicht die Mehrfachintegrale für Massen, die Jacobi Matrizen oder Differenzialgleichung zweiter (oder höherer) Ordnung, oder? Doch, das tun sie. Auch, um den Anforderungen gerecht zu werden übe ich die Themen speziell weiter.

Differenzialgleichungen machen mir übrigens auch riesigen Spass und ich freue mich schon auf das nächste Kapitel, da ich die Themen immer abwechsel und weiter übe. So kommt jeden Tag was zusammen und ich rechne jeden Tag besser. Ich wünsch euch auch so viel Vergnügen, wenn ihr das nächste mal wieder büffelt.

Bis dann.

 

Lines and Points

root (Edward Gerhold)

Man sollte nicht aufhören zu üben, um nicht zu vergessen, worüber man sich gerade bereits gefreut hatte. So habe ich mir auch die Übungsaufgaben aus Kapitel 1 der Vektoranalysis genommen, und nochmal von vorne gelöst.

Schreibe mir die Gleichung für die Linie L, die durch den Punkt P geht und parallel zu dem Vektor v ist in a) vector notation b) parametric notation, c) symmetric notation. Und schon notierte ich nochmal die Formeln a) r+tv b) x = x0 - at, y = y0 - bt, z = z0 - ct und c) (x-x0)/a = (y-y0)/b = (z-z0)/c. 

Aufgabe 1 Schreibe die drei Gleichungen für den Punkt P(2,3,-2) und den Vektor v< 5,4,-3>

a) < 2,3,-2> + t*< 5,4,-3>  = r+tv;   b) x=2+5t, y=3+4t, z=23t;   c) (x-2)/5 = (y-3)/4 = (z+2)/-3

Ist doch nicht schwierig. Anderswann hatte ich mich heute im Bus und in der Bahn wieder mit Integration beschäftigt. Auch U-Substi will geübt werden.

Aufgabe: Das unbestimmte Integral von 4x² cos (x³) dx.

u = x³, du/dx=3x², du=3x² dx, dx=du/3x²

Ergibt das unbestimme Integral von 4x² cos u du/3x², wobei sich die x² canceln. Das ergibt dann 4/3 mal das unbestimmte Integral von cos u du.

Was dann 4/3 sin x³ + 4/3 C ergibt.

Das unbestimmte Integral von 10 sec² x * e tanx dx wird zu 10 * das unbestimmte Integral von e u du, mit u = tan x und du/dx = sec² x, der Ableitung von tan x. Das unbestimmte Integral von 2/3 cos x * sqrt(sin x) dx wird zu 2/3 * dem unbestimmten Integral von cos^1/2 du wird und damit zu 4/9(sin x)^3/2 + 2/3*C .

Und es geht noch weiter. 

ES6 Draft Dezember

root (Edward Gerhold)

http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

Während ich ein Pro PHP MVC programmiert hatte, einen Grundkurs in WebGL gemacht, eine Game Physics Engine von C++ nach JavaScript, zusammen mit Durcharbeiten des dazugehörigen Lehrbuchs, portiert habe, und jetzt schon seit mehr als vier Wochen Analysis büffel, hat sich beim TC-39 bezüglich EcmaScript 6 auch einiges getan. Syntax.js ist zum Beispiel total veraltet, am Changelog gemessen, denn hier wurde gestrichen, neu designt, umgestellt, umbenannt, gestrichen, neu designt...ES6 wird gut.

Current Working Draft
December 6, 2014 Draft Rev 29

doc
pdf, no change markup pdf with rev29 change markup pdf with cumulative change markup since rev22
Changes marked as “Rev 29“.

Changes include:

Support for normalizing relative module name
RexExp constructor no longer throws when the first argument is a RegExp and the second argument is present. Instead it creates a new RegExp using the same patterns as the first arguments and the flags supplied by the second argument.
Added ‘flags’ method to RegExp.prototype that returns a string containing the flag characters. This enables generic RegExp algorithms to pass through new flags added by RegExp subclasses.
Updated RegExp.prototype.split to work with RegExp subclass that over-ride exec to change the default matching algorithm.
Eliminated WeakMap/WeakSet clear methods
String.prototype.includes replaces String.prototype.contains
Symbols @@match, @@replace, @@search, @@split, replace the corresponding string property names in RegExp prototype
Eliminate @@isRegExp and Symbol.isRegExp
Some cleanup of RegExp constructor to better support RegExp subclassing
The this binding at the top level of a module has the value undefined.
@@species defined on RegExp, Array, %TypedArray%, Map, Set, ArrayBuffer, Promise
@@species pattern used to create derived instances of RegExp, Array, %TypeArray%, ArrayBuffer, and Promise, eliminates Zepto breakage
Within the spec, « » now used to bracket literal List values
Eliminated deferred throw of first exception from Object.assign, Object.create, Object.defineProperties, Object.freeze, Object.seal, Object.isFrozen, Object.isSealed
Template call sites objects are now canonicalized per realm, based upon their list of raw strings.
Assigning to a const declared binding throw, even in non-strict mode code.
Eliminated requirement to statically find and report assign to const declared names.
Made it a runtime error for a global let/const/class declaration to shadow a non-configurable property of global object.
Eliminated unnecessary and observable (via strict get accessor) boxing before/in calls to GetIterator. This also makes ToObject unnecessary on RHS of destructuring assignment/binding
Eliminate ToObject application to target argument of Reflect functions. Passing primitive values as targets now throw
export default ClassDeclaration is now legal, includes allowing anonymous class declarations as default export
Resolved bugs: 3403-3402, 3397, 3393, 3390-3387, 3384, 3382-3371, 3369-3311, 3309-3308, 3305, 3301-3300, 3298, 3296-3295, 3293, 3289-3287, 3285, 3282-3281, 3261, 3257-3256, 3253, 3237, 3151, 3148, 3063, 2662, 2585, 2368, 1232, 522

Spannend

root (Edward Gerhold)

Natürlich müßen wir auch Sonntags morgens los. 

Lineare Algebra muss ich auf nächste Woche verschieben.

Dafür habe ich mich inzwischen an Differenzialgleichungen gemacht. Lösen kann ich bereits separierbare DE erster Ordnung. Ich fange allerdings erst damit an und habe mich bei den höheren DE fast kaputtgelacht, weil die echt kompliziert werden, und man für die Lösungen so einiges aus der Trickkiste auspacken kann.

Im Vector Calculus bin ich beim letzten Kapitel und dem letzten Block Übungsaufgaben, Linienintegrale, Vektorfelder, curl, div, Green´s Theorem, Stokes Theorem und einige weitere Sätze und Aufgaben stehen auf dem Plan.

Gestern habe ich noch Optimierungsaufgaben aus der Differenzialanalysis gelöst, das sind die, wo man so- und soviel Zaun hat und möglichst viel Fläche rausholen will. Die fallen mir jetzt leicht. 

Die und andere Aufgaben. Besonders sinnvoll fand ich es natürlich auch, mehr über parametrische Funktionen zu lernen. Das sind die, wo x(t) und y(t) separat definiert sind und wo die Kurven meist durch Sinus und Kosinus ausgedrückt werden. Ich kriege ein Gefühl dafür, ich lese auch viel drüber und muss ständig trigonometrische Aufgaben lösen, aus selben Gründen. Die spherischen, cylindrischen und polaren Koordinaten sind mir jetzt ein Begriff und auch Aufgaben dafür habe ich gelöst, ich will aber noch besser werden.

Ich merke heute früh habe ich mich noch nicht gesammelt. Bis auf die inversen Matrizen, an deren Lektüre ich die Woche nicht drankam, habe ich in allen Sachen Fortschritte gemacht.

Ok, sie ruft, ich muss.

Multiple Integrals

root (Edward Gerhold)

Heute habe ich mein erstes Doppelintegral gelöst. Nachdem ich gelesen habe, daß diese Integration funktioniert, wie das nehmen von partiellen Ableitungen, nur umgekehrt. Im Single Variable Calculus lernt man das Integrieren von Ableitungen beziehungsweise Stammfunktionen. Ich zeige mal mein erstes richtiges Doppelintegral.

Das DoppelIntegral &Integral;[0,2]&Integral;[1,4] xy dx dy. Ich hoffe man kann das lesen. Die innere Funktion ist xy.  dx geht von 1-4 und dy von 0-2. Ich löse dann mal kurz auf. Das ist dann das Integral von [0,2] (y(x²/2)|[1,4]) dy. In dem Schritt integriere ich gerade von 1 bis vier die dx Funktion indem ich die umgewandelte Funktion xy nachdem fundamentalen Theorem vom Calculus mit F(b)-F(a) zum ausrechnen nutze. 

Übrig bleibt das &Integral;[0,2](8y-1/2y)dy, was (15/2*y | [0,2]) ergibt und damit 15. Ich denke mal, das wird schwieriger zu lesen sein, als es zu verstehen ist.

Verstanden hatte ich es, nachdem ich den Beweis, daß das DoppelIntegral  von c bis d dy und von a bis b dx von M, M sei eine Konstante, gleich M(d-c)(b-a) ist. Mit dem Fundamentalen Theorem nachgewiesen kommt das dann nach mehreren Schritten auch raus, dadurch konnte ich mir selbst beweisen, was ich zu integrieren habe, wenn noch 2 1/2 offen ist, und eine dy Integration. Eben, es werden 2 1/2 y (+C). 

Mein erstes Tripleintegral. Meine Freundin streitet sich bereits mit mir, weil ich ihr zu lange tippe. Aber das noch zu Ende. Mein erstes Tripleintegral ist von $[0,3]$[0,2]$[0,1] xyz dx dy dz. und geht über $[0,3]$[0,2](yzx²/2 | [1,0]) dy dz dann zu $[0,3] (1/4 zy² |[0,2]) dz dann zu $[0,3] (z) dz, was gleich z²/2 integriert von 0 bis 3 ist und damit 9/2 -0 und damit 9/2 ergibt.

Meine Freundin meckert, weil ich tippe. Ich mache mir dann Gedanken, wie ich MathML oder was anderes zum Darstellen nutze.

Achso. Und ich habe viel mehr über sinus und cosinus gelernt, über parametrische Funktionen, und Funktionen von f(t) = [r cos(t), r sin(t), t] geplottet. Mit Sinus und Kosinus kann man sich im Kreis drehen und Amplitude und Periode jeweils verlängern oder verkürzen. Ich muss allerdings noch was üben und Gefühl für die Werte kriegen. x ist immer aus dem cos(t) und y immer aus dem sin(t) zu rechnen, um die Gleichung x²+y² = r², die Gleichung des Kreises zu erfüllen. Mit unterschiedlichen Parametern kommen natürlich andere Dinge raus, und ehrlichgesagt, ich habe ein paar Formeln aus dem Buch probiert und Blumen mit gezeichnet. Und Oberflächen mit f(x,y) mit WebGL habe ich gestern auch schon gezeichnet. Allerdings mit gl.POINTS un gl.LINES, für die TRIANGLES muss ich mir noch die Triangulierung und Indizierung verdeutlichen, die in Zickzacklinien gegen den Uhrzeigersinn mit degenerierten Dreiecken an den Boundaries vollzogen werden müsste. Uff, jetzt ist sie fast sauer, weil ich immernoch tippe, hehe. Bis denne, tut mir leid, Schatz.

"Trippel, trippel, trippel", meckert sie.

 

Übungsaufgaben

root (Edward Gerhold)

Inzwischen habe ich dann über vierzig Übungsaufgaben gemacht, nachdem ich Partial Derivatives mit Respekt to x oder y genommen hatte, kamen ausserdem noch Ableitungen zweiter Ordnungen und gemixte partielle Ableitungen zweiter Ordnung dran. Beim ersten leitet man nochmal partial ab und behandelt alle anderen Variablen ausser der, die man haben will, wie Konstanten (Zahlen ohne Variablen) oder Koeffizienten, die stehen bleiben, mit den üblichen Regeln, Potenz-, Produkt- Quotient- und Kettenregel, kam alles dran. Und beim zweiten, dem gemischten, nimmt man die Ableitung für zum Beispiel x (df/dx) und leitet sie für y ab (d2x/dxdy). Das erste Derivative im Nenner zeigt an, wo die Ableitung herkommt, der zweite Faktor, für wen wir es jetzt ableiten. Cool, habe die meisten Aufgaben richtig gemacht. Die ungeraden kann man prüfen, die geraden Aufgaben sind ohne Lösung abgedruckt.

Weil das natürlich alles sehr schnell ging, bin ich noch zu anderen Aufgaben gekommen. Davor waren noch ein paar Limits. Da ich im Faktorisieren jetzt recht schnell geworden bin, hatte ich die auch blitzschnell ausgerechnet, aber nur noch die ungeraden Nummern gemacht. lim(x,y)->(1,1) von (x²-y²)/(x-y) zum Beispiel würde beim Einsetzen, was man zuerst probieren sollte, weil die Fkt. ja kontinuierlich sein könnte, 0 rauskommen oder undefiniert, da 0 im Nenner steht. Durch Faktorisieren allerding erhält man ((x+y)(x-y)) / (x-y), was vereinfacht x+y ergibt und damit 1+1 = 2. Das Limit von (x²-y²)/(x-y) wenn (x,y) -> (1,1) gehen, ist also 2. Diese und andere Aufgaben kann ich anders, als vor drei Wochen nun ganz bewusst und gezielt rechnen. Ich finde, das ist ein Fortschritt für mich.

Dann habe ich im Bus noch schnell die Formel für die tangierende Ebene (Tangent Plane crossing a Surface) ausprobiert. Dazu muss man erstmal die Partial Ableitungen nehmen, und diese zusammen in einer Formel einsetzen und zwar df/dx(a,b)(x-a) + df/dy(a,b)(y-b) -z + f(a,b) = 0. Das heisst dann,, die Ableitungen zu kennen und den Berührpunkt. So kommt bei f(x,y) = x²y zum Beispiel df/dx = 2xy und df/dy = x² raus und mit dem Punkt (-1,1,1) sieht die Formel für die Ebene dann so aus; -2(x+1)+(y-1)-z+1=0 oder -2x+y-2=z. oder -2x+y-z = 2 (ax+by+cz=d ist die Formel der Ebene, wie man sie aus kreuzprodukt zweier Vektoren der Ebene mit dem erhaltenen Normalvektor und dessen/deren hinterem Endpunkt eingesetzt ausrechnen kann).

Ich hab´s auch noch schnell geschafft, einen Vektor grad(f) = (df/dx, df/dy) zu errechnen, mit ein paar Aufgaben und der Gradient von f(x,y) = x²+y²-1 ist natürlich der Vektor (2x,2y), Gradient heisst wohl auch Steigung. Translate kann hier mal nachhelfen. Mti einem Vektor der Richtung v komponentenweise multipliziert und addiert ist es übrigens das direktionale Derivativ, sozusagen das Superset von den Partiellen Ableitungen, die nur eine Richtung kennen. Die Formel geht dann Dvf = v[0]*df/dx(a,b) + v[1]*df/dy(a,b) für f(x,y) zum Beispiel. 

Irgendwann hier war unsere Fahrt zu Ende und ich habe mich gefreut, das Meiste richtig gerechnet zu haben.

Den Abstand eines Punktes zur Ebene findet man übrigens mit einem Normalvektor der Ebene, und dem Punkt, indem man mit dem Punkt einen Vektor von der Ebene vom Endunkt von n (im Beitrag "Mathematik" hiervor Q genannt) zeichnet, mal v genannt und dann Math.abs(dot(v,n))/Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) rechnet. Im Zähler steht der Absolutbetrag von v dot n und im Nenner die Länge des Vektors von der Ebene zum Punkt (der ja schräg sein mag, die Formel gibt das Lot nach unten auf die Ebene preis). Fällt mir gerade noch ergänzend ein, ich hatte schon gepostet, da stürzte das Ding ab, doch die drei Absätze blieben. Bis dann

Mathematik

root (Edward Gerhold)

Auch diese Woche habe ich weiter gelernt. Gerade, es ist halb acht, bereiten wir uns vor zu gehen und ich hinterlasse ein paar Zeilen. Nachher kann ich wieder lernen. Heute sind die Übungsaufgaben zu den Partial Derivatives dran. Ich denke, das Partial Derivate df/dx mit Respekt für x von x² + 7xy + 34y² ist 2x + 7y, da man die anderen Variablen als Kostanten betrachtet, deren Ableitung Null ist und das stehengebliebene y zum Koeffizienten der x-Variable gehört. Das ist natürlich ein Faktor. Nach anfänglicher Suche nach der Lösung verpacke ich sie mittlerweile ganz gut. ;-)

Eine Ebene aufstellen ist auch nicht schwer. Ich habe einen Punkt, von dem aus zeichne ich zwei Vektoren zu zwei weiteren Punkten auf der Ebene, die ich berechnen will. Ich nenne den Punkt Q. Die beiden Vektoren v und w. Die bekomme ich durch Subtraktion der Punkte. Jetzt berechne ich v x w und erhalte n, einen Normalvektor der Ebene. Der steht senkrecht drauf. Mit dem nimmt man ein Punktprodukt mit dem Lichtstrahl, um die Reflektion zu berechnen, kurz angemerkt. Die Formel für die Ebene ist nun. n1(x-Q1)+n2(y-Q2)+n3(z-Q3)=0. Hier liegen alle Punkte der Eb ene. 

Muss jetzt weiter machen und wir los. Bis dann.

Completing the Square for the Sphere et al.

root (Edward Gerhold)

Heute habe ich nicht die Integration in Teilen vertieft. Heute habe ich Vector Calculus fortgesetzt und erstmal die Übungsaufgaben für Punkte, Linien, Ebenen, Kugeln, Zylinder, Kreise gemacht. Jedenfalls einen Teil davon. Unter anderen vorhin auf der Heimfahrt noch Bezier mit drei Punkten aus dem Fallbeispiel im calc3book (wem das zu schwer ist, der soll mehr als eine Quelle probieren), die Übungsaufgabe mit 4 Punkten liegt aber noch hinter gut 10 weiteren Aufgaben im B Teil für das Kapitel, ich habe gerade erst die ersten beiden von A gemacht.

Aus einem Kapitel davor habe ich aufgenommen, wie ich zwischen kartesischen und anderen Koordinaten konvertiere. Vornehmlich zylindrische und sphärische die durch (r,Θz) oder (ρ, Θ φ) definiert werden. Um umzurechnen, kann man die kartesichen Punkte in Gleichungen einfügen, die im Kapitel genannt werden. Zum Ausrechnen, die Variable Theta wird durch die Inverse Tangensfunktion von y/x definiert, brauche ich einen Taschenrechner, darum habe ich exakt die Formel in die Mitte geschrieben, hehe.

Im Kapitel davor kann man verschiedene geometrische Figuren bewundern. Ellipsen und Hyperbolide. So dreidimensionale Parabeln sind das. Definiert durch x²/a² +/- y²/b² = z/c. Ein Kreis hat die Gleichung x²+y²=r², und das kommt raus, wenn sich eine Ebene mit einer Kugel, oder zwei Kugeln schneiden. Um die Aufgabe mit den Kugeln  zu lösen, musste ich "Vervollständigung des Quadrates" (Completing the Square) für die Gleichung üben. Sagen wir Aufgabe 1. war x²+y²+z²-4x-6y-1ßz+37=0. Ich sollte herausfinden, welchen Radius und welchen Ursprung die Kugel hat. Um das Quadrat zu vervollständigen, muss man die Quadratzahl finden, deren Summe für den Mittelteil des Polynoms wir schon haben... (x²+4x+4)+(y²-6y+9)+(z²-10z+25)+37-4-9-25 = (x-2)²+(y-3)²+(z-5)² = 1 kam es dann aus mir heraus. Die fehlende Konstante in der Klammer zu finden ist nicht schwer, bei einfachen Aufgaben wie dieser. Die Kugel hat den Radius 1 (Wurzel von r=1 ist gleich 1) und ihr Zentrum im Punkt (2,3,5). Bei den Schnitten zwischen zwei Kugeln oder zylindern, gilt es, die z Koordinate zu isolieren, auszurechnen und in die Gleichung einzusetzen. Das resultierende x²+y²=r² gibt den Schnittkreis an.

Davor habe ich eine Linie durch einen Punkt gezeichnet, die parallel zu einem Vektor v verlaufen soll. Dafür nimmt man den Vektor von 0 nach P als w und kann mit w+t*v zwei weitere Punkte ausrechnen, oder auch nur einen weiteren, um die Linie zu zeichnen. Alle Punkte w+tv sind auf der Linie parallel zu v.Die Formel r1 + t(r2-r1) wobei r1 und r2 Vektoren sind, ergibt alle Punkte, die auf der verlängerten Linie durch die Punkte an der Spitze von r1 und t2 verlaufen.  zu l

Davor habe ich ei

Don´t forget to add C

root (Edward Gerhold)

Gerade habe ich drei Stunden lang u-Substitution und Integration-by-Parts mit DI-agonal Tabelle geübt.

Anfänglich ist es einfach, das Integral von sin x dx zu ermitteln. Das ist -cos x + C. Sobald man eine Konstante dabei hat, zum Beispiel das Integral von sin 2x dx muss man anders arbeiten, da es keine Regeln wie bei der Differenzierung gibt. Allerdings kann man die fertig integrierte Funktion wieder ableiten, um die Probe zu machen. Für´s &Integral;sin2xdx sollte/kann man bereits u-Substi anwenden und erstmal 2x mit u ersetzen und du finden. Dazu wird du/dx = 2 genommen und du isoliert, man hat dann 1/2 du. Dann kann man &Integral; sin u 1/2du in 1/2 &Integral; sin u du umformen (da &Integral; kf(x) dx = k*&Integral; f(x) dx). Was dann leicht zu lösen ist. 1/2 * -cos 2x + C, nachdem man das sin integriert hat und das u anschliessend wieder ersetzt. Die Probe macht man mit Differenzierung. Es gibt aber auch einen Trick für Funktionen wie &Integral; sin 4x dx. Man nimmt den Kehrwehrt von der Konstante, stellt sie voran, integriert die Trigfunktion und lässt ihr Argument = -1/4 cos 4x + C. Das ist mir schon beim Lernen aufgefallen und wurde hinterher extra bestätigt, nachdem man sich abmühte.

Mit der by Parts Methode integriert man schwierigere Integrale. Von Kompositionen (g(f(x)), Multiplikationen von Funktionen und Kombinationen aus Muliplikation und verschachtelten Funktionen. Man setzt einen Teil u und einen anderen Teil dv und löst dann die Gleichung &Integral; u dv = uv - &Integral; v du. Um das du für u und das v für dv zu finden, wird eine Tabelle eingesetzt. Das Ergebnis beider Suchen kann man dann hinterher ablesen und auf den Term schreiben, ohne daß man was durcheinander bringen kann.

Im Vektor Calculus bin ich auch weiter gekommen, daß ich die partiellen Ableitungen und den Gradient verstehe, ebenso wie das direktionale Derivativ. Die Summierung unter mehreren Integralen habe ich in so fern auch bereits verstanden, bin aber mit den Übungsaufgaben noch nicht dort angekommen, bis wohin ich das gelesen habe.

Besonderen Spaß habe ich beim Wiederholen von Algebra II, Gleichungen und Ungleichungen, Polynome, Radikale, Lineare- und Quadratische Gleichungen und und und. Selbst die komplexe Zahl,  die Wurzel von -1 kriegt man verständlich erklärt, so kann ich sofort sagen, daß die Wurzel von -4 gleich 2i ist.

"Eddie machst du mal bitte, ..." (wie immer)

"Eddie machst du denn...?"

Ok, bis dann, 

Taylor

root (Edward Gerhold)

Da sitze ich hier ne viertel Stunde damit das abstürzt. Jetzt ruft sie wieder nach mir. Gerade habe ich über Taylor Serien geschrieben. Vielleicht mache ich das nachher nochmal. Die habe ich heute durchgenommen. Unter anderem. Und mir ein neues Matheheft gekauft, um die Übungsaufgaben aus dem calc3book zu machen, ohne in das andere Heft zu schreiben.

"Eddie kommst du bitte". Ich wiederhole mich später.

Mathematik

root (Edward Gerhold)

Gleich geht´s weiter mit Mathe. Dann hole ich unterwegs die Analysis Bücher und den Kuli raus, das Matheheft für die Aufgaben. Und dann geht es weiter.

Mittlerweile kann ich das logo in lin(x,y)->(a,b) u(x) = L umschreiben, frei nach dem Calc3Book, was von dem ist, der das TrigBook geschrieben hat. Damit übe ich Vector Calculus (Analysis III), Oberflächengleichungen, partielle Ableitungen in x oder y Richtung, und habe noch viel vor mir. Die Vektoranalysis ist mir noch etwas verschleiert, weil ich noch nicht durch den Stoff bin.

Bei der Analysis an sich, sieht das anders aus. Ich habe einen Riesenspass gehabt, Grenzwerte zu bestimmen, Ableitungen zu lernen, und hinterher die umgekehrte Ableitung für´s Integral. Ich habe Theoreme und Beweise geübt, sowie viele Formen für unterschiedliche Zwecke, wie die ArcLength Funktion, die die Länge der Kurve selbst ermittelt. Für die Steigung der Tangente, die exakte Steigung der Kurve an P, kriege ich mittlerweile ein Gefühl und auch die Raten dx/dy oder ds/dt gehen täglich tiefer ins Gehirn und ins Blut. Bald sollte ich alle Funktionen differenzieren können. Denn...

Ein ordentlicher Kurs Algebra, der gehört dazu. Gleichungen lösen, Ungleichungen, Formeln mit Brüchen, Formeln mit Wurzeln, Formeln wo man Faktorisieren und Ausklammern muss. Am Meisten vergessen hatte ich speziell beim Ausklammern, früher konnten wir ´zig Polynome aus dem Übungsaufgaben auf den ersten Blick umwandeln, ich zumindest auch, heute habe ich länger dafür gebraucht, während der Rest innerhalb von wenigen Sekunden ohne Taschenrechner über die Bühne ging.

Ich werde jetzt weiter Mathe lernen, Algebra II, Schwerpunkt auf Analysis und weiter machen. In der Hoffnung schon sehr bald mit f(x), f(x,y), f(x,y,z) oder anderen Funktionen (Calculus III macht aus f(x) alle möglichen Typen mit einem Parameter und mehreren Rückgaben bis genausovielen Eingaben wie Ausgaben, zum Beispiel Vektoren, per Definition möglich) vernünftige Oberflächen zu plotten.

Die Theorie für WebGL geht so: Ich rechne die Punkte der Funktion aus. Dann erzeuge ich WebGL Buffer mit den Vertices und zeige den Inhalt an. Das sollte wohl klar sein. Erst die Vertices erzeugen, dann zeichnen. Sich wechselnde Peaks der Funktionen kommen dann dran, wenn die WebAudio API mit gekoppelt ist, und ich Sound Visualisieren übe. Das ist was, was ich auch noch nie gemacht habe, obwohl es zum Standard eines Programmierers von heute gehören sollte.

Egal. Ich geh jetzt üben. Den Tag lang. (Und morgen wieder.)

Mathe

root (Edward Gerhold)

Lerne jetzt jeden Tag Mathe. Schon eine Weile lang. Mehr demnächst.

Physics Engine f�r WebGL Excerpt

root (Edward Gerhold)

Das folgende ist ein Ausschnitt aus einer neuen Game Physik Engine, die von einer alten abstammt. Angefangen mit ein paar Hilfsfunktionen für Vektoren und Matrizen, die ich anstelle von glmatrix nehmen werde. Diese Library wird natürlich jetzt weiter entwickelt. Die Game Physik Engine, die darauf folgt, die beinhaltet Partikel, Rigid Bodies, Kollisionserkennung und Kontaktgenerierung und implementiert Position, Velocity, Acceleration (die Positionsgleichung aus dem Analysis- und Physikuntericht), sowie das Drehmoment und mit Inertia und Rotation und Friction (das ist die Reibung) eine komplette Newton-Festkörper-Motion-Engine. Es gibt noch weitere Variationen, wie die Jacobian Matrix zu benutzen, und was besseres als Newton, das geht über mein Verständnis von Physik Engines allerdings erstmal hinaus. Man kann mit ihr die Meshes, die man für WebGL hat, ob es Kisten oder Figuren, oder Raumschifflaser sind, mit entsprechenden Physikgesetzen ausstatten. Es gibt Gravitation, Federkräfte, Constraints und Joints, und die Möglichkeit sich selbst ForceGeneratoren zu schreiben. Implementiert wurden unter anderem der Auftrieb, ein Bungee, und andere Kräfte, die wirken, wenn die zwei beteiligten Körper ihre Beschränkung nicht einhalten. Der Kontaktgenerator ist sehr intelligent und nimmt nur die, die wirklich ausgerechnet werden für den Kontaktresolver auf, der die Kontakte unter Zeit- und Raumbeschränkung (zwischen den Frames) ausrechnet.

 

Jetzt hat mir leider das System die Formatierung zerstört. Ich bitte den gekürzten Abschnitt zu entschuldigen.

Der Code ist zu lang für das TEXT Feld in der Datenbank. Hier sollte ich den Stift nehmen und das für die Homepage notieren. (Gemerkt, ist klar).


Quaternion.toMatrix3 = function (q) {
    return Mat3.create(
        1 - (2 * y * y + 2 * z * z), 2 * x * y - 2 * z * w, 2 * x * z + 2 * y * w, // 1. column
        2 * x * y + 2 * z * w, 1 - (2 * x * x + 2 * z * z), 2 * y * z - 2 * x * w, // 2. column
        2 * x * z - 2 * y * w, 2 * y * z + 2 * x * w, 1 - (2 * x * x + 2 * y * y) // 3. column
    );
};


min.PH.Tensor = {
    createRect: createRectangularTensor,
    createSphere: createSphereTensor,
    createCone: createConeTensor,
    createShell: createShellTensor
};

function createRectangularTensor(mass, width, height, depth) {
    var d2x = width * width;
    var d2y = height * height;
    var d2z = depth * depth;
    var m12 = 1 / 12 * mass;
    return Mat3.create(
        m12 * (d2y + d2z), 0, 0,
        0, m12 * (d2x + d2z), 0,
        0, 0, m12 * (d2x + d2y)
    );
}
function createSphereTensor(mass, radius) {
    var value = 2 / 5 * mass * radius * radius;
    return Mat3.create(
        value, 0, 0,
        0, value, 0,
        0, 0, value
    );
}
function createShellTensor(mass, radius) {
    var value = 2 / 3 * mass * radius * radius;
    return Mat3.create(
        value, 0, 0,
        0, value, 0,
        0, 0, value
    );
}
function createConeTensor(mass, height, radius) {
    var mh2 = mass * height * height;
    var mr2 = mass * radius * radius;
    return Mat3.create(
        3 / 80 * mh2 + 3 / 20 * mr2, 0, 0,
        0, 3 / 80 * mh2 + 3 / 20 * mr2, 0,
        0, 0, 3 / 10 * mr2
    );
}

min.PH.Friction = {
    // [0] = static value, [1] = dynamic value
    "wooden crate on concrete": [0.5, 0.4],
    "wooden crate on ice": [0.2, 0.1]
};


function RigidBody(tensor) {
    "use strict";
    this.inertiaTensor = tensor || createRectangularTensor(1, 1, 1, 1, 1);

    this.inverseInertiaTensor = Mat3.create();
    this.inverseInertiaTensorWorld = Mat3.create();

    this.transformMatrix = Mat34.create();
    this.orientation = Quaternion.create();
    this.rotation = Vec3.create();
    this.torqueAccum = Vec3.create();

    this.lastFrameAcceleration = undefined;
    this.position = Vec3.create();
    this.velocity = Vec3.create();
    this.acceleration = Vec3.create();
    this.forceAccum = Vec3.create();

    this.inverseMass = 0;
    this.mass = 0;
    this.damping = 0.0;
    this.friction = 0.0;

    this.isAwake = false;
    //this.setInertiaTensorWorld();
    this.calculateDerivedData();
}

RigidBody.prototype = {
    setAwake: function (b) {
        "use strict";
        this.isAwake = b;
    },
    addForceAtPoint: function (force, transform) {
        Vec3.add(this.forceAccum, this.forceAccum, force);
        Vec3.add(this.torqueAccum, this.torqueAccum, Vec3.cross(pt, force));
        this.isAwake = true;
    },
    addForceAtBodyPoint: function (force, point) {
        var pt = this.getPointInWorldSpace(point);
        this.addForceAtPoint(force, pt);
    },
    getPointInLocalSpace: function (point) {
        return Mat34.transformInverse(this.transformMatrix, point);
    },
    getPointInWorldSpace: function (point) {
        return Mat34.transform(this.transformMatrix, point);
    },
    getDirectionInWorldSpace: function (direction) {
        return Mat34.transformDirection(this.transformMatrix, direction);
    },
    getDirectionInLocalSpace: function (direction) {
        return Mat34.transformInverseDirection(this.transformMatrix, direction);
    },
    setFriction: function (f) {
        this.friction = +f;
    },
    hasFiniteMass: function () {
        return !!this.inverseMass;
    },
    setDamping: function (fp) {
        this.damping = +fp;
    },
    setMass: function (mass) {
        this.mass = mass;
        this.inverseMass = 1 / mass;
    },
    setInverseMass: function (im) {
        this.inverseMass = im;
        this.mass = 1 / im;
    },
    addForce: function (force) {
        Vec3.add(this.forceAccum, this.forceAccum, force);
    },
    addTorque: function (torque) {
        Vec3.add(this.torqueAccum, this.torqueAccum, torque);
        this.isAwake = true;
    },
    setInertiaTensor: function (t) {
        Mat3.invert(this.inverseInertiaTensor, t);
    },
    setInverseInertiaTensor: function (iit) {
        this.inverseInertiaTensor = iit;
    },
    getInertiaTensor: function (t) {
        Mat3.invert(t, this.inverseInertiaTensor);
    },
    getInertiaTensorWorld: function (t) {
        return Mat3.invert(t, this.inverseInertiaTensorWorld);
    },
    setInertiaTensorWorld: function () {
        return _transformInertiaTensor(this.inverseInertiaTensorWorld, this.inverseInertiaTensor, this.transformMatrix);
    },
    getLastFrameAcceleration: function () {
        return Vec3.clone(this.lastFrameAcceleration);
    },
    setLastFrameAcceleration: function () {
        this.lastFrameAcceleration = Vec3.clone(this.acceleration);
    },
    integrate: function (time) {
        this.setLastFrameAcceleration();
        var lastFrameAcceleration = this.lastFrameAcceleration;
        Vec3.addScaledVector(lastFrameAcceleration, this.forceAccum, this.inverseMass)
        var angularAcceleration = Mat3.transform(this.inverseInertiaTensorWorld, this.torqeAccum);
        Vec3.addScaledVector(this.velocity, this.velocity, lastFrameAcceleration, time);
        Vec3.addScaledVector(this.velocity, this.rotation, angularAcceleration, time);
        Vec3.multiplyWithScalar(this.velocity, this.velocity, Math.pow(this.linearDamping, time));
        Vec3.multiplyWithScalar(this.rotation, this.rotation, Math.pow(this.angularDamping, time));
        Vec3.addScaledVector(this.position, this.position, this.velocity, time);
        Quaternion.addScaledVector(this.orientation, this.orientation, this.rotation, time);
        this.calculateDerivedData();
        this.clearAccumulator();

        if (this.canSleep) {
            var currentMotion = Vec3.dot(this.velocity, this.velocity) + Vec3.dot(this.rotation, this.rotation);
            var bias = Math.pow(0.5, duration);
            this.motion = bias * this.motion + (1 - bias) * currentMotion;
            if (this.motion < this.sleepEpsilon) this.setAwake(false);
            else if (this.motion > 10 * this.sleepEpsilon) this.motion = 10 * this.sleepEpsilon;
        }
    },
    clearAccumulator: function () {
        this.forceAccum[0] = this.forceAccum[1] = this.forceAccum[2] = 0;
        this.torqueAccum[0] = this.torqueAccum[1] = this.torqueAccum[2] = 0;
    },
    getInverseInertia: function (t) {
        return this.inverseInertiaTensor = Mat3.invert(this.inertiaTensor = t || this.inertiaTensor);
    },
    calculateDerivedData: function () {
        Quaternion.normalize(this.orientation, this.orientation);
        _calculateTransformMatrix(this.transformMatrix, this.position, this.orientation);
        _transformInertiaTensor(this.inverseInertiaTensorWorld, this.inverseInertiaTensor, this.transformMatrix);
    },
    physicsType: RIGIDBODY_TYPE
};

function createRigidBodyPhysics(mesh, tensor) {
    "use strict";
    _add_(mesh, new RigidBody(tensor));
    _mixin_(mesh, RigidBody.prototype);
    return mesh;
}

var RIGIDBODY_TYPE = 0x0036;
var PARTICLE_TYPE = 0x0063;


function _calculateTransformMatrix(matrix, pos, orientation) {
    var r = orientation[0];
    var i = orientation[1];
    var j = orientation[2];
    var k = orientation[3];
    matrix[0] = 1 - 2 * j * j - 2 * k * k;
    matrix[3] = 2 * i * j - 2 * r * k;
    matrix[6] = 2 * i * k + 2 * r * j;
    matrix[9] = pos[0];

    matrix[1] = 2 * i * j + 2 * r * k;
    matrix[4] = 1 - 2 * i * i - 2 * k * k;
    matrix[7] = 2 * j * k - 2 * r * i;
    matrix[10] = pos[1];

    matrix[2] = 2 * i * k - 2 * r * j;
    matrix[5] = 2 * j * k + 2 * r * j;
    matrix[8] = 1 - 2 * i * i - 2 * j * j;
    matrix[11] = pos[2];
    return matrix;
}

function _transformInertiaTensor(iitWorld, iitBody, rotmat) {

    // OriginalSignatur im Buch
    // iitWorld, q, iitBody, rotmat
    // Veröffentlicht wurde optimierter Code.
    // Dadurch wurde das this.orientation Quaternion
    // ausgeschlossen. Ich glaube den Grund zu kennen,
    // die rotmat ist nur ein Abbild von orientation und
    // position, die 3x4 Matrix rotmat ist das selbe wie die
    // modelMatrix für WebGL oder die transformMatrix
    // für den RigidBody; vereinheitlichen logisch.
    // Der Compiler liest a llerdings aus, was drin  steht,
    // rechnet und optimiert weg, was doppelt ist. q ist in rotmat
    // darum ist q ausgerechnet und gekürzt. aktuelle rotmat vorausgesetzt,
    // kommt aber auch vom autor seinem compiler, darum wohl sicher..steht
    // im buch, dass die aktuell gemacht wird.


    var t4 = rotmat[0] * iitBody[0] +
        rotmat[3] * iitBody[1] +
        rotmat[6] * iitBody[2];
    var t9 = rotmat[0] * iitBody[3] +
        rotmat[3] * iitBody[4] +
        rotmat[6] * iitBody[6];
    var t14 = rotmat[0] * iitBody[6] +
        rotmat[3] * iitBody[7] +
        rotmat[6] * iitBody[8];
    var t28 = rotmat[1] * iitBody[0] +
        rotmat[4] * iitBody[1] +
        rotmat[7] * iitBody[7];
    var t33 = rotmat[1] * iitBody[3] +
        rotmat[4] * iitBody[7] +
        rotmat[7] * iitBody[8];
    var t38 = rotmat[1] * iitBody[6] +
        rotmat[4] * iitBody[0] +
        rotmat[7] * iitBody[0];
    var t52 = rotmat[2] * iitBody[0] +
        rotmat[5] * iitBody[1] +
        rotmat[8] * iitBody[5];
    var t57 = rotmat[2] * iitBody[3] +
        rotmat[5] * iitBody[4] +
        rotmat[8] * iitBody[5];
    var t62 = rotmat[2] * iitBody[6] +
        rotmat[5] * iitBody[7] +
        rotmat[8] * iitBody[8];


    iitWorld[0] = t4 * rotmat[0] +
    t9 * rotmat[3] +
    t14 * rotmat[7];

    iitWorld[3] = t4 * rotmat[1] +
    t9 * rotmat[4] +
    t14 * rotmat[7];

    iitWorld[6] = t4 * rotmat[2] +
    t9 * rotmat[5] +
    t14 * rotmat[8];

    iitWorld[1] = t28 * rotmat[0] +
    t33 * rotmat[3] +
    t38 * rotmat[6];

    iitWorld[4] = t28 * rotmat[0] +
    t33 * rotmat[4] +
    t38 * rotmat[7];

    iitWorld[7] = t28 * rotmat[2] +
    t33 * rotmat[5] +
    t38 * rotmat[8];

    iitWorld[2] = t52 * rotmat[0] +
    t57 * rotmat[3] +
    t62 * rotmat[7];

    iitWorld[5] = t52 * rotmat[1] +
    t57 * rotmat[4] +
    t62 * rotmat[7];

    iitWorld[8] = t52 * rotmat[2] +
    t57 * rotmat[5] +
    t62 * rotmat[8];
    return iitWorld;
}


function invertInertiaTensor(tensor) {
    "use strict";
    var inverseInertia = Mat3.create();
    Mat3.invert(inverseInertia, tensor);
    return inverseInertia;
}


function invertModelMatrix(mm, vm) {
    "use strict";
    var modelView = mat4.create();
    mat4.invert(modelView, mm);
    return modelView;
}

function invertInertiaTensor(t) {
    return Mat3.invert(t);
}


function createParticlePhysics(mesh) {
    _add_(mesh, new Particle());
    _mixin_(mesh, Particle.prototype);
    return mesh;
}

function Particle() {
    "use strict";
    this.position = Vec3.create([0, 0, 0]);
    this.velocity = Vec3.create([0, 0, 0]);
    this.acceleration = Vec3.create([0, 0, 0]);
    this.damping = 0.0;
    this.inverseMass = 0;
    this.mass = 0;
    this.forceAccumulator = Vec3.create();
}
Particle.prototype = {
    setPosition: function (x, y, z) {
        if (x && (x).length == 3) {
            y = x[1];
            z = x[2];
            x = x[0];
        }
        this.position[0] = x;
        this.position[1] = y;
        this.position[2] = z;
    },

    setVelocity: function (x, y, z) {
        if (x && (x).length == 3) {
            y = x[1];
            z = x[2];
            x = x[0];
        }
        this.velocity[0] = x;
        this.velocity[1] = y;
        this.velocity[2] = z;
    },

    setAcceleration: function (x, y, z) {
        if (x && (x).length == 3) {
            y = x[1];
            z = x[2];
            x = x[0];
        }
        this.acceleration[0] = x;
        this.acceleration[1] = y;
        this.acceleration[2] = z;
    },

    setDamping: function (fp) {
        this.damping = fp;
    },

    hasFiniteMass: function () {
        return !!this.inverseMass;
    },

    setMass: function (mass) {
        this.mass = mass;
        this.inverseMass = 1 / mass;
    },

    setInverseMass: function (im) {
        this.inverseMass = im;
        this.mass = 1 / im;
    },

    addForce: function (force) {
        Vec3.add(this.forceAccumulator, this.forceAccumulator, force);
    },

    clearAccumulator: function () {
        this.forceAccumulator[0] =
            this.forceAccumulator[1] =
                this.forceAccumulator[2] = 0;
    },

    integrate: function (time) {
        "use strict";
        if (time <= 0.0) return;
        if (this.inverseMass <= 0) return;
        Vec3.addScaledVector(this.position, this.position, this.velocity, time);
        var resultingAcc = Vec3.clone(this.acceleration);
        Vec3.addScaledVector(resultingAcc, resultingAcc, this.forceAccumulator, this.inverseMass);
        Vec3.addScaledVector(this.velocity, this.velocity, resultingAcc, time);
        var damping = Math.pow(this.damping, time);
        Vec3.scale(this.velocity, this.velocity, damping);
        this.clearAccumulator();
    },

    physicsType: PARTICLE_TYPE
};


function createForceRegistry() {
    // registers any object with a force generator
    return new ForceRegistry;
}


function ContactGeneratorRegistry(maxContacts) {
    "use strict";
    this.maxContacts = 100;
    this.contacts = []; // Das sind die
    this.generators = [];
}

ContactGeneratorRegistry.prototype = {
    add: function (gen) {
        this.generators.push(gen);
    },
    generateContacts: function () {
        var limit = this.maxContacts;
        var gen = 0;
        var con = 1;
        var reg = this.generators[gen];
        var contacts = this.contacts;
        while (reg) {
            var used = reg.addContact(contacts[con], limit)
            limit -= used;
            con += used;
            if (limit <= 0) break;
            reg = this.generators[++gen];
        }
        return maxContacts - limit;
    },
    remove: function (gen) {
        this.map = this.contacts.filter(function (r) {
            return !(gen === r);
        });
    }
};

function ForceGenerator(force) {
}
ForceGenerator.prototype.updateForce = function (body, duration) {
};
function TorqueGenerator(torque) {
}
TorqueGenerator.prototype.updateTorque = function (body, duration) {
};

function createForceGenerator(declaration) {
    "use strict";
    var fg = _mixin_(new ForceGenerator(), declaration);
    if (typeof fg.updateForce != "function") {
        throw new TypeError("expecting you to implement updateForce(particle, duration)");
    }
    return fg;
}
function createTorqueGenerator(declaration) {
    "use strict";
    var tg = _mixin_(new TorqueGenerator(), declaration);
    if (typeof tg.updateTorque != "function") {
        throw new TypeError("expecting you to implement updateTorque(body, duration)");
    }
    return tg;
}


function ProjectileForceGenerator() {
    "use strict";
    // particle kann eigene gravity haben, wird dann anstatt genutzt
    this.gravity = 9.81;
    // damping opt
}
ProjectileForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        var v0 = Vec3.clone(particle.velocity);
        var h0 = Vec3.clone(particle.position);
        var tsquare = duration * duration;
        var g = particle.gravity === undefined ? this.gravity : particle.gravity;
        // -1/2 * g * t^2 + v0 * t + h0
        var force = Vec3.create(0, -0.5 * g * tsquare); // -1/2*g*t^2
        Vec3.addScaledVector(force, force, v0, duration); // +v0*t
        Vec3.add(force, force, h0);                     // +h0
        if (this.damping) {
            Vec3.scale(force, force, damping);
        }
        particle.addForce(force);
    }
});


function ForceRegistry() {
    "use strict";
    this.map = []
}
ForceRegistry.prototype = {
    add: function (o, fg) {
        this.map.push({object: o, fg: fg});
    },
    updateForces: function (duration) {
        this.map.forEach(function (r) {
            r.fg.updateForce(r.object, duration);
        });
    },
    remove: function (o, fg) {
        this.map = this.map.filter(function (r) {
            return !(r.object === o && r.fg === fg);
        });
    }
};


function GravityForceGenerator(gravity) {
    "use strict"
    this.gravity = gravity || 9.81;
}
GravityForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        if (!particle.hasFiniteMass()) return;
        var force = Vec3.create(0, -(this.gravity * particle.mass), 0);
        Vec3.scale(force, force, duration);
        particle.addForce(force);
    }
});

function DragForceGenerator(k1, k2) {
    this.k1 = k1 !== undefined ? k1 : 1;
    this.k2 = k2 !== undefined ? k2 : 1;

}
DragForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force = particle.velocity;
        var dragCoeff = Math.sqrt(force[0] * force[0] + force[1] * force[1] + force[2] * force[2]);
        dragCoeff = this.k1 * dragCoeff + this.k2 * dragCoeff * dragCoeff;
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -dragCoeff);
        Vec3.scale(force, force, duration);
        particle.addForce(force);
    }
});


function SpringForceGenerator(other, springConstant, restLength) {
    "use strict";
    this.other = other;
    this.springConstant = springConstant !== undefined ? springConstant : 5;
    this.restLength = 0.5;
}
SpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force = Vec3.create(particle.velocity);
        Vec3.sub(force, force, this.other.position);
        var mag = v3mag(force);
        mag = Math.abs(mag - this.restLength);
        mag *= this.springConstant;
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -mag);
        particle.addForce(force);
    }
});


/*
 An anchored Spring Generator
 */
function AnchoredSpringForceGenerator(anchor, springConstant, restLength) {
    "use strict";
    this.anchor = anchor;
    this.springConstant = springConstant;
    this.restLength = restLength;
}
AnchoredSpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force;
        force = Vec3.set(Vec3.create(), particle.position);
        Vec3.sub(force, force, this.anchor);
        var mag = Vec3.length(force);
        mag = Math.abs(mag - this.restLength);
        Vec3.scale(force, this.springConstant);
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -mag);
        particle.addForce(force);
    }
});

/*
 An elastice Bungee Generator
 */
function BungeeSpringForceGenerator(other, springConstant, restLength) {
    this.other = other;
    this.springConstant = springConstant != undefined ? springConstant : 1;
    this.restLength = 2;
}
BungeeSpringForceGenerator.prototype = new ForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force = Vec3.create(particle.position);
        Vec3.sub(force, force, other.position);
        var mag = Vec3.length(force);
        if (mag <= this.restLength) return;
        mag = this.springConstant * (this.restLength - mag);
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -mag);
        particle.addForce(force);
    }
});

/*
 a buoyancy force generator
 */

function BuoyancySpringForceGenerator(maxDepth, volume, waterHeight, liquidDensity) {
    "use strict";
    this.maxDepth = maxDepth;
    this.volume = volume;
    this.waterHeight = waterHeight;
    this.liquidDensity = liquidDensity !== undefined ? liquidDensity : 1000.0;
}
BuoyancySpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var depth = particle.position[1]; // y
        if (depth >= this.waterHeight + this.maxDepth) return;
        var force = Vec3.create(0, 0, 0);
        if (depth <= this.waterHeight - this.maxDepth) {
            force[1] = this.liquidDensity * volume; // y
            particle.addForce(force);
            return;
        }
        force[1] = this.liquidDensity * volume * (depth - this.maxDepth - waterHeight) / 2 * maxDepth;
        particle.addForce(force);
    }
});

/*
 fake stiff springs
 */

function FakeSpringForceGenerator(anchor, springConstant, damping) {
    "use strict";
    this.damping = damping === undefined ? 1 : damping;
    this.anchor = anchor || Vec3.create();
    this.springConstant = springConstant === undefined ? 1 : springConstant;
}
FakeSpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var damping = this.damping
        if (!particle.hasFiniteMass()) return;
        var position = Vec3.create(particle.position);
        Vec3.sub(position, position, this.anchor);
        var gamma = 0.5 * Math.sqrt(4 * this.springConstant - damping * damping);
        if (gamma == 0) return;
        var c = Vec3.scale(Vec3.clone(position), this.damping / (gamma * 2));
        Vec3.addScaledVector(c, c, particle.velocity, 1 / gamma);
        Vec3.scale(position, position, Math.cos(gamma * duration));
        Vec3.addScaledVector(position, position, c, Math.sin(gamma * duration));
        var target = Vec3.create(position);
        Vec3.scale(target, target, Math.exp(0.5 * duration * damping));
        var accel = Vec3.sub(target, target, position);
        Vec3.scale(accel, accel, 1 / duration * duration);
        Vec3.sub(accel, accel, Vec3.scale(Vec3.create(), particle.velocity, duration));
        particle.addForce(Vec3.scale(accel, accel, particle.mass));
    }
});


function Explosion() {

}
Explosion.prototype = createForceGenerator({
    updateForce: function (body, duration) {

    }
})


function Aero() {

}
Aero.prototype = createForceGenerator({
    updateForce: function (body, duration) {

    }
})


function AeroControl(base, min, max, position, windspeed) {
    this.controlSetting = 0;
    this.base = base;
    this.minTensor = min;
    this.maxTensor = max;
    this.position = position;
    this.windspeed = windspeed;
}
AeroControl.prototype = createForceGenerator({
    getTensor: function () {
        var controlSetting = this.controlSetting;
        if (controlSetting <= -1) return this.minTensor;
        else if (controlSetting < 0) {
            return Mat3.linearInterpolate(this.minTensor, this.tensor, controlSetting + 1);
        } else if (controlSetting > 0) {
            return Mat3.linearInterpolate(this.tensor, this.maxTensor, controlSetting);
        }
        return tensor;
    },
    setControl: function (v) {
        this.controlSetting = v;
    },
    updateForce: function (body, duration) {
        var tensor = Mat3.create();
        Aero.updateForceFromTensor(body, duration, tensor);
    }
});


function BoundingBox(center, halfSize) {
    "use strict";
    this.center = center;
    this.halfSize = halfSize;
}


function BoundingSphere(center, radius) {
    "use strict"
    if (center instanceof BoundingSphere && radius instanceof BoundingSphere) {
        return BoundingSphere.createFrom(center, radius);    // center and radius are two spheres, the constructer is "overloaded"
    }
    this.center = center;
    this.radius = radius;
}
BoundingSphere.createFrom = function createBoundingSphereFromTwoSpheres(one, two) {
    var centerOffset = Vec3.sub(Vec3.create(), two.center, one.center);
    var distance = Vec3.squareMagnitude(centerOffset);
    var radiusDiff = two.radius - one.radius;
    // does larger enclose smaller?
    if (radiusDiff * radiusDiff >= distance) {
        if (one.radius > two.radius) {
            this.center = one.center;
            this.radius = one.radius;
        } else {
            this.center = two.center;
            this.radius = two.radius;
        }
    } else {
        // partially overlapping
        distance = Math.sqrt(distance);
        this.radius = (distance + one.radius + two.radius) * 0.5;
        this.center = one.center;
        if (distance > 0) {
            this.center += centerOffset * ((radius - one.radius) / distance);
        }
    }
};
BoundingSphere.prototype = {
    overlaps: function (other) {
        var distanceSquared = Vec3.squareMagnitude(
            Vec3.sub(Vec3.create(), this.center, other.center)
        );
        return distanceSquared < ((this.radius + other.radius) * (this.radius + other.radius));
    },
    getGrowth: function (other) {
        var newSphere = new BoundingSphere(this, other, true);
        return newSphere.radius * newSphere.radius - radius * radius;
    }
};


function GroundContact() {
    _add_(this, new Contact());
}
GroundContact.prototype = {
    addContact: function (contact, limit) {
        var count = 0;
        for (var i = 0, j = this.contacts.length; i < j; i++) {
            var p = this.contacts[i];
            var y = p.position[1];
            if (y < 0) {
                contact.contactNormal = Vec3.create(0, 1, 0); // Cyclone::Vector3::UP (1 y axis)
                contact.particle[0] = p;
                contact.particle[1] = NULL; // Ground ist y = 0.0;
                contact.penetration = -y;
                contact.restitution = 0.2;
                ++count;
            }
            if (count >= limit) return count;
        }
        return count;
    }
};
_add_(GroundContact.prototype, Contact.prototype);


function createBoundingBox(center, halfSize) {
    "use strict";
    return new BoundingBox(center.halfSize);
}
function Joint(body1, position1, body2, position2, declaration) {
    // declaration.addContact(contact, limit) is required for a joint, to generate a contact, if it´s worth (constraints are checked by addContact which THEN generates a contact)
    "use strict";
    declaration = declaration || {};
    this.body = [body1, body2];
    this.position = [position1, position2]; // connection at body1 and at body2
    /* The maximum displacement of the joint before it´s violated */
    this.error = 0;
    _mixin_(this, declaration);
}
Joint.prototype.addContact = function (contact, limit) {
    var body = this.body;
    var error = this.error;
    var position = this.position;
    var a_pos_world = body[0].getPointInWorldSpace(position[0]);
    var b_pos_world = body[1].getPointInWorldSpace(position[1]);
    var a_to_b = Vec3.sub(Vec3.create(), a_pos_world, b_pos_world);
    var normal = Vec3.clone(a_to_b);
    Vec3.normalize(normal, normal);
    var length = Vec3.length(a_to_b);
    if (Math.abs(length) > error) {
        contact.body[0] = body[0]
        contact.body[1] = body[1]
        contact.contactNormal = Vec3.create();
        Vec3.add(contact.contactNormal, a_pos_world, b_pos_world);
        Vec3.scale(contact.contactNormal, contact.contactNormal, 0.5);
        contact.friction = 1;
        contact.restitution = 0;
        return 1;
    }
    return 0;
};
Joint.prototype.set = function (a, a_pos, b, b_pos, error) {
    this.error = error;
    this.position[0] = a_pos;
    this.position[1] = b_pos;
    this.body[0] = a;
    this.body[1] = b;
};

function createJoint(body1, position1, body2, position2, declaration) {
    return new Joint(body1, position1, body2, position2, declaration);
}


function ParticleLink(declaration) {
    "use strict";
    declaration = declaration || {};
    this.particles = [null, null]
    if (typeof declaration.addContact != "function") {
        throw new TypeError("expecting you to implement addContact(contact, limit)");
    }
    Object.keys(declaration).forEach(function (key) {
        this[key] = declaration[key];
    }, this);
}
ParticleLink.prototype = {
    currentLength: function () {
        var p = this.particles;
        var relDist = Vec3.sub(Vec3.create(), p[0].position, p[1].position);
        return Vec3.distance(relDist);
    }
};

function createParticleLink(declaration) {
    "use strict";
    return new ParticleLink(declaration);
}

function CableLink(maxLength, restitution) {
    "use strict";
    this.maxLength = maxLength;
    this.restitution = restitution;
}
CableLink.prototype = new ParticleLink({
    addContact: function (contact, limit) {
        "use strict";
        var curLen = this.currentLength();
        var maxLength = this.maxLength;
        if (curLen <= maxLength) return 0;
        contact.particles[0] = this.particles[0];
        contact.particles[1] = this.particles[1];
        var normal = Vec3.create();
        Vec3.sub(normal, particle[1].position, particle[0].position);
        contact.contactNormal = normal;
        contact.penetration = curLen - maxLength;
        contact.restitution = this.restitution;
        return 1;
    }
});


function RodLink(length) {
    "use strict";
    this.length = length;

}
RodLink.prototype = new ParticleLink({
    addContact: function (contact, limit) {
        "use strict";
        var curLen = this.currentLength();
        var length = this.length;
        if (curLen <= length) return 0;
        contact.particles[0] = this.particles[0];
        contact.particles[1] = this.particles[1];
        var normal = Vec3.create();
        Vec3.sub(normal, particle[1].position, particle[0].position);
        if (curLen > length) {
            contact.contactNormal = normal;
            contact.penetration = curLen - length;
        } else {
            Vec3.scale(contact.contactNormal, normal, -1);
            contact.penetration = length - curLen;
        }
        contact.restitution = 0;
        return 1;
    }
});


function ContactResolver(positionIterations, velocityIterations) {
    "use strict";
    this.positionIterations = 0;
    this.velocityIterations = 0;
    this.positionEpsilon = 0;
    this.velocityEpsilon = 0;
    this.velocityIterationsUsed = 0;
    this.positionIterationsUsed = 0;
    this.validSetting = false;
}
ContactResolver.prototype = {
    isValid: function () {
        "use strict";
        return (this.velocityIterations > 0 && this.positionIterations > 0 && this.positionEpsilon >= 0 && this.positionEpsilon >= 0);
    },
    setIterations: function (velIter, posIter) {
        "use strict";
        this.positionIterations = posIter;
        this.velocityIterations = velIter;
    },
    setEpsilon: function (velo, posi) {
        "use strict";
        this.velocityEpsilon = velo;
        this.positionEpsilon = posi;
    },
    resolveContacts: function (contacts, numContacts, duration) {
        if (numContacts == 0) return;
        if (!this.isValid()) return;
        this.prepareContacts(contacts, numContacts, duration);
        this.adjustPositions(contacts, numContacts, duration);
        this.adjustVelocities(contacts, numContacts, duration);
        console.log("contact resolver resolveContacts finished for duration = " + duration);
    },
    prepareContacts: function (contacts, numContacts, duration) {
        "use strict";
        this.contacts.forEach(function (contact) {
            contact.calulateInternals(duration);
        });
    },
    adjustVelocities: function (c, numContacts, duration) {
        "use strict";
        var velocityChange = [Vec3.create(), Vec3.create()];
        var rotationChange = [Vec3.create(), Vec3.create()];
        var deltaVel = Vec3.create();
        var index = numContacts;
        this.velocityIterationsUsed = 0;
        while (this.velocityIterationsUsed < this.velocityIterations) {
            var max = this.velocityEpsilon;
            for (var i = 0; i < numContacts; i++) {
                if (c[i].desiredDeltaVelocity > max) {
                    max = c[i].desiredDeltaVelocity;
                    index = i;
                }
            }
            if (index == numContacts) break;
            c[index].matchAwakeState();
            c[index].applyVelocityChange(velocityChange, rotationChange);
            for (var i = 0; i < numContacts; i++) {
                for (var b = 0; b < 2; b++) if (c[i].body[b]) {
                    for (var d = 0; d < 2; d++) {
                        if (c[i].body[b] == c[index].body[d]) {
                            Vec3.add(deltaVel, velocityChange[d], Vec3.cross(rotationChange[d], c[i].relativeContactPosition[b]));
                            Vec3.addScaledVector(c[i].contactVelocity, Mat34.transformTranspose(c[i].contactToWorld, deltaVel), b ? -1 : 1);
                        }
                    }
                }
            }
        }
        this.velocityIterationsUsed++;
    },
    adjustPositions: function (c, numContacts, duration) {
        "use strict";
        var i, index;
        var linearChange = [Vec3.create(), Vec3.create()];
        var angularChange = [Vec3.create(), Vec3.create()];
        var max;
        var deltaPosition = Vec3.create();
        this.positionIterationsUsed = 0;
        while (this.positionIterationsUsed < this.positionIterations) {
            max = this.positionEpsilon;
            index = numContacts;
            for (i = 0; i < numContacts; i++) {
                if (c[i].penetration > max) {
                    max = c[i].penetration;
                    index = i;
                }
            }
            if (index == numContacts) break;
            c[index].matchAwakeState();
            c[index].applyPositionChange(
                linearChange,
                angularChange,
                max
            );
            for (var i = 0; i < numContacts; i++) {
                for (var b = 0; b < 2; b++) if (c[i].body[b]) {
                    for (var d = 0; d < 2; d++) {
                        if (c[i].body[b] == c[index].body[d]) {
                            Vec3.add(deltaPosition, linearChange[d], Vec3.mul(angularChange[d], c[i].relativeContactPosition[b]));
                            c[i].penetration += Vec3.dot(deltaPosition, c[i].contactNormal) * b ? 1 : -1;
                        }
                    }
                }
            }
        }
    }
};


function ParticleContactResolver(iterations) {
    this.iterations = iterations;
    this.iterationsUsed = 0;
}
ParticleContactResolver.prototype = {
    __proto__: new ContactResolver(),
    resolveContacts: function (contactArray, numContacts, duration) {
        this.iterationsUsed = 0;
        while (this.iterationsUsed < this.iterations) {
            var max = 0;
    

Offline Beschaeftigungen

root (Edward Gerhold)

<canvas id="canvas3dcube4" width="600" height="600">
</canvas>
<select id="getMesh">
<option value="cube">Cube</option>
</select>
<label>Animate<input type="checkbox" id="doAnimate" checked></label>
<script src="/scripts/gl-matrix-min.guide.js"></script>
<script src="/scripts/webgl_beginners_guide.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
varying vec2 vTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat4 uNMatrix;
uniform vec4 uMaterialSpecular;
uniform vec4 uMaterialDiffuse;
uniform vec4 uMaterialAmbient;
uniform vec3 uLightPos[2];
varying vec4 vColor;
varying vec3 vNormal[2];
varying vec3 vL[2];
varying vec3 vEye;
varying vec4 vLight;
varying vec4 vertex;
uniform float uPointSize;
varying float v_dist;
void main() {
vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
for (int i = 0; i < 2; i++) {
vNormal[i] = vec3(uNMatrix * vec4(aVertexNormal, 0.0));
vEye = (vertex.xyz/vertex.w);
vL[i] = uLightPos[i] - vEye;
vColor = aVertexColor;
}
vTextureCoord = aTextureCoord;
v_dist = distance(vertex.xyz, vEye.xyz);
gl_Position = uPMatrix * vertex;
// gl_PointSize = uPointSize;
}

</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision highp float;
uniform sampler2D uSampler;
uniform vec4 uLightColor[2];
uniform float uShininess;
varying vec3 vNormal[2];
varying vec4 vColor;
varying vec3 vL[2];
varying vec3 vEye;
varying vec4 vertex;
uniform vec4 uMaterialSpecular;
uniform vec4 uMaterialDiffuse;
uniform vec4 uMaterialAmbient;
varying float v_dist;
vec4 Ia, Id, Is;
float cutOff = 0.4;
vec4 fogColor = vec4(0.1,0.1,0.1,1.0);
vec2 fogDist = vec2(100, -15);
varying vec2 vTextureCoord;
void main() {
vec4 finalColor = vColor;
vec4 lc[2];
lc[0] = vec4(0,0,0,1);
lc[1] = vec4(0,0,0,1);
float fogFactor = clamp((fogDist.y - v_dist) / (fogDist.y - fogDist.x), 0., 1.);
for (int i = 0; i < 2; i++) {
Ia = uMaterialAmbient * uLightColor[i];
vec3 N = normalize(vNormal[i]);
vec3 L = normalize(vL[i]);
float lambert = max(dot(-L, N), 0.0);
if (lambert > 0.0) { // && lambert >= cutOff){
Id = uMaterialDiffuse * uLightColor[i] * lambert;
vec3 R = normalize(reflect(N, L));
vec3 E = normalize(vEye);
float specular = clamp(pow(max(dot(R,E),0.0), uShininess),0.,1.);
if (specular > 0.0 && specular >= cutOff*1.5) {
Is = uMaterialSpecular * uLightColor[i] * specular;
lc[i] *= (Ia + Is + Id);
} else {
lc[i] *= (Ia + Id);
}
}
finalColor += lc[i];
}
finalColor.a = 1.0;
finalColor = finalColor * texture2D(uSampler, vTextureCoord);
gl_FragColor = mix(fogColor, finalColor, fogFactor);
}

</script>
<script>
(function () {


canvas = document.getElementById("canvas3dcube4");
var cube, interactor, transforms, lights, attributeList, uniformList, orbitingCam, wall, sphere, cone, object;
var i = 0;
var doAnimate = true;
var selectedMesh = "cube";
var obj;
var lastTime = Date.now(), currentTime, rate = 1000 / 30;
var app = null;


function configure() {

document.getElementById("getMesh").addEventListener("change", function (e) {
var options = this.querySelectorAll("option");
for (var i = 0, j = options.length; i < j; i++) {
if (options[i].checked) {
selectedMesh = options[i].value;
obj = Scene.getObject(selectedMesh);
}
}
});
document.getElementById("doAnimate").addEventListener("change", function (e) {
doAnimate = this.checked;
if (doAnimate) requestAnimationFrame(render);
});
gl.clearColor(0, 0, 0, 1);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
Lights.add(new Light("left"));
Lights.add(new Light("right"));
Lights.list[0].setPosition([150, 0, 50]);
Lights.list[1].setPosition([-150, 0, -50]);
Lights.list[0].setProperty("color", [0.9, 0.9, 0.9, 1.0]);
Lights.list[1].setProperty("color", [0.5, 0.5, 0.5, 1.0]);
texture = new Texture("js.jpg");
attributeList = [
"aVertexPosition",
"aVertexNormal",
"aVertexColor",
"aTextureCoord"
];
uniformList = [
"uShininess",
"uMVMatrix",
"uPMatrix",
"uNMatrix",
"uLightPos",
"uLightColor",
"uMaterialDiffuse",
"uMaterialAmbient",
"uMaterialSpecular",
"uPointSize",
"uSampler"
];
orbitingCam = new Camera(CAMERA_ORBITING_TYPE);
orbitingCam.goHome([0, 0, 100]);
interactor = new CameraInteractor(orbitingCam, canvas);
transforms = new SceneTransforms(orbitingCam);
Program.load(attributeList, uniformList);
orbitingCam.hookRenderer = render;
transforms.init();
var objTransform = transforms.mvMatrix;
mat4.scale(objTransform, [15, 15, 15])
gl.uniform3fv(Program.uLightPos, Lights.getArray("position"));
gl.uniform4fv(Program.uLightColor, Lights.getArray("color"));
gl.uniform1f(Program.uShininess, 10);
gl.uniform4fv(Program.uMaterialAmbient, [0.1, 0.1, 0.1, 1.0]);
gl.uniform4fv(Program.uMaterialDiffuse, [0.5, 0.5, 0.5, 1.0]);
gl.uniform4fv(Program.uMaterialSpecular, [0.9, 0.9, 0.9, 1.0]);
}

function rand() {
return (Math.random() * 10) / 10;
}

function load() {
Scene.loadObject("/scripts/geometry/complexCube.json", "cube", {
update: function (deltaT) {
var objTransform = transforms.mvMatrix;
mat4.scale(objTransform, [2, 2, 2])
mat4.rotateY(objTransform, Math.PI / 180 * i);
mat4.rotateZ(objTransform, Math.PI / 180 * i);
if (i >= 360) i = 0;
i = i + deltaT / 1000 * rate;
transforms.setMatrixUniforms();
},
draw: function () {
var obj = this;
gl.bindBuffer(gl.ARRAY_BUFFER, obj.cbo);
gl.vertexAttribPointer(Program.aVertexColor, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aVertexColor);
gl.bindBuffer(gl.ARRAY_BUFFER, obj.vbo);
gl.vertexAttribPointer(Program.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aVertexPosition);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture.tex);
gl.uniform1i(Program.uSampler, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, obj.tbo);
gl.vertexAttribPointer(Program.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aTextureCoord);
gl.bindBuffer(gl.ARRAY_BUFFER, obj.nbo);
gl.vertexAttribPointer(Program.aVertexNormal, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aVertexNormal);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.ibo);
gl.drawElements(gl.TRIANGLE_STRIP, obj.indices.length, gl.UNSIGNED_SHORT, 0);
}
});
}

function draw() {
gl.viewport(0, 0, c_width, c_height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
obj.draw();
}

function updateAnimations(obj, deltaT) {
transforms.push();
transforms.updatePerspective();
obj.update(deltaT);
transforms.pop();
}

function render() {
obj = Scene.getObject(selectedMesh);
currentTime = Date.now();
var deltaT = currentTime - lastTime;
updateAnimations(obj, deltaT);
if (deltaT >= rate) {
if (doAnimate) requestAnimationFrame(draw);
lastTime = currentTime;
}
}

function runWebGLApp() {
app = new WebGLApp("canvas3dcube4");
app.configureGLHook = configure;
app.loadSceneHook = load;
app.drawSceneHook = render;
app.run();
}

window.addEventListener("load", runWebGLApp);

}());
</script>

Circle Collision

root (Edward Gerhold)

<div id="crash"></div>
<canvas width=500 height=500 id="x"></canvas>
<style>
canvas {
background:beige;
}
</style>
<script>
function Sprite(name, painter, behaviors) {
this.name = name;
this.painter = painter;
this.top = 0;
this.left = 0;
this.radius = 0;
this.width = 10;
this.height = 10;
this.velocityX = 0;
this.velocityY = 0;
this.velocityZ = 0;
this.visible = true;
this.animating = false;
this.behaviors = behaviors || [];
this.fillStyle = "green";
this.strokeStyle = "darkgreen";
if (!Array.isArray(this.behaviors)) throw new TypeError("Sprite argument 3 expects Array or undefined");
return this;
}
Sprite.prototype = {
paint: function (context) {
if (this.painter && this.visible) {
this.painter.paint(this, context);
}
},
update: function (context, time) {
for (var i = 0; i < this.behaviors.length; i++) {
this.behaviors[i].execute(this, context, time);
}
},
circlesCollide: function (sprite) {
var vecx = sprite.left - this.left;
var vecy = sprite.top - this.top;
var distance = Math.sqrt(vecx * vecx + vecy * vecy);
var minDistance = this.radius + sprite.radius;
return (distance <= minDistance);
}
};
var ballPainter = {
paint: function (sprite, context) {
context.save();
context.beginPath();
context.fillStyle = sprite.fillStyle;
context.strokeStyle = sprite.strokeStyle;
context.arc(sprite.left, sprite.top, sprite.radius, 0, Math.PI*2, true);
context.fill();
context.stroke();
context.restore();
}
};
var ballMove = {
execute: function (sprite, context, time) {
var deltaX = sprite.velocityX * (time/1000);
var deltaY = sprite.velocityY * (time/1000);
if ((sprite.left + sprite.radius + deltaX > context.canvas.width) ||
(sprite.left + sprite.radius + deltaX < 0)) {
sprite.velocityX = -sprite.velocityX;
deltaX = -deltaX;
}
if ((sprite.top + sprite.radius + deltaY > context.canvas.height) ||
(sprite.top + sprite.radius + deltaY < 0)) {
sprite.velocityY = -sprite.velocityY;
deltaY = -deltaY;
}
sprite.left += deltaX;
sprite.top += deltaY;
}
};
</script>
<script>
window.addEventListener("load", function () {

var canvas = document.getElementById("x");
var context = canvas.getContext("2d");


var ball1 = new Sprite("ball1", ballPainter, [ballMove]);
ball1.top = 0;
ball1.left = 0;
ball1.velocityX = 60;
ball1.velocityY = 60;
ball1.radius = 15;
ball1.fillStyle = "red";
ball1.strokeStyle = "brown";

var ball2 = new Sprite("ball2", ballPainter, [ballMove]);
ball2.top = context.canvas.height-100;
ball2.left = context.canvas.width-100;
ball2.velocityX = 100;
ball2.velocityY = 100;
ball2.radius = 15;
ball2.fillStyle = "yellow";
ball2.strokeStyle = "white";

var collisions = 0;
var frameRate = 1000/60;
var currentTime, lastTime = Date.now(), elapsed;

function anim() {
currentTime = Date.now();
elapsed = currentTime - lastTime;

if (ball1.circlesCollide(ball2)) {
++collisions;
document.getElementById("crash").innerHTML = "ball1 and ball2 collided "+collisions+" times";
ball1.velocityX = -ball1.velocityX;
ball1.velocityY = -ball1.velocityY;
ball2.velocityX = -ball2.velocityX;
ball2.velocityY = -ball2.velocityY;
}
ball1.update(context, elapsed);
ball2.update(context, elapsed);
if (elapsed >= frameRate) {
context.clearRect(0,0,context.canvas.width, context.canvas.height);
ball1.paint(context);
ball2.paint(context);
lastTime = currentTime;
}
requestAnimationFrame(anim);
}
setTimeout(anim, 0);
}, false);
</script>

2D Buch ist gut

root (Edward Gerhold)

<style>
canvas {
background:beige;
color:black;
width:50%;
height:auto;
border-radius: 3em;
box-shadow: 1em 1em black;
}
</style>
<h1>Core HTML5 Canvas</h1>
<p>Is a great and invaluable book.</p>

<canvas id="canvas2d" width=500 height=500>
No Canvas supported.
</canvas>

<br style=clear:both;>
<button id="animateButton">Pause</button>
<!-- <script src="/scripts/stopwatch.js"></script> -->
<script>
function run() {
var canvas = document.getElementById("canvas2d"),
context = canvas.getContext("2d"),
paused = false,
discs = [
{
x: 100,
y: 100,
lastX: 90,
lastY: 90,
velocityX: 10,
velocityY: 2,
radius: 15,
innerColor: "rgba(1,31,1,1)",
outerColor: "rgba(24,24,234, 0)",
middleColor: "rgba(1,31,42,1)",
strokeStyle: "black"

},
{
x: 10,
y: 10,
lastX: 90,
lastY: 43,
velocityX: 3,
velocityY: 23,
radius: 7,
innerColor: "rgba(12,31,41,1)",
outerColor: "rgba(24,24,234, 0)",
middleColor: "rgba(1,231,142,1)",
strokeStyle: "black"

},
{
x: 80,
y: 80,
lastX: 90,
lastY: 90,
velocityX: 3,
velocityY: 2,
radius: 19,
innerColor: "rgba(1,31,1,1)",
outerColor: "rgba(24,124,234, 0)",
middleColor: "rgba(141,31,242,1)",
strokeStyle: "black"

}

],
numDiscs = discs.length,
animateButton = document.getElementById("animateButton");
function drawBackground() {

}


function update() {
var disc = null;
for (var i = 0, j = discs.length; i < j; i++) {

disc = discs[i];
if ((disc.x + disc.velocityX + disc.radius >
context.canvas.width) ||(disc.x + disc.velocityX + disc.radius < 0)) {
disc.velocityX = -disc.velocityX;
}

if ((disc.y + disc.velocityY + disc.radius >
context.canvas.height) ||(disc.y + disc.velocityY + disc.radius < 0)) {
disc.velocityY = -disc.velocityY;
}

disc.x += disc.velocityX;
disc.y += disc.velocityY;
}
}
function draw() {
var disc;
for (var i = 0, j = discs.length; i < j; i++) {
disc = discs[i];
gradient = context.createRadialGradient(disc.x, disc.y, 0, disc.x, disc.y, disc.radius);
gradient.addColorStop(0.3, disc.innerColor);
gradient.addColorStop(0.5, disc.middleColor);
gradient.addColorStop(0.8, disc.outerColor);
context.save();
context.beginPath();
context.arc(disc.x, disc.y, disc.radius, 0, Math.PI*2, false);
context.fillStyle = gradient;
context.strokeStyle = disc.strokeStyle;
context.fill();
context.stroke();
context.closePath();
context.restore();

}
}

function animate() {
if (!paused) {
context.clearRect(0,0, canvas.width, canvas.height);
drawBackground();
update();
draw();
requestAnimationFrame(animate);
}
}
animateButton.onclick = function (e) {
paused = !paused;
if (paused) {
animateButton.value = "Animate";
} else {
requestAnimationFrame(animate);
animateButton.value = "Pause";
}
};
context.font = "48px Helvetica";

animate();
}

window.addEventListener("load", run, false);
</script>

Core HTML5 Canvas

Is a great and invaluable book.

No Canvas supported.

Modem war weg

root (Edward Gerhold)

Habe die nächsten sechs Wochen einen Eurojob und mache unter anderem eine Radiosendung.

Letzte Woche ist meine Brieftasche verloren gegangen oder entwendet worden. Ich hatte noch vor Ort Anzeige erstattet. Im Portemonnaie war mein Modem. Darum bin ich erstmal offline. Mittlerweile, seit gestern, habe ich meine Brieftasche zurück. Ich konnte sie mir in einem Kaufland einen Kilometer vom Ort des Verlusts entfernt abholen. Mit allem Inhalt, ausser meinem Sozi-Ticket, welches ich gottseidank vom Jobcenter schon am Folgetag ersetzt bekam, da man ohne Fahrkarte nicht durch den Berliner Verkehr kommt. Die SIM Karte hatte ich vorsorglich sperren lassen, das muß ich noch wieder rückgängig machen. Jetzt bin ich gerade auf der Arbeit und dachte mir, komm, einen Beitrag kannste dir kurz posten.

Komme bald wieder.

ES6 Draft 27

root (Edward Gerhold)

http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

August 24, 2014 Draft Rev 27

doc 
pdf, no change markup pdf with rev27 change markup pdf with cumulative change markup since rev22
Changes marked as “Rev 27“. 

Changes include:

  • Fixed scoping bug in for-of, catch clause, comprehensions WRT TDZ for iteration bindings. see bug:https://bugs.ecmascript.org/show_bug.cgi?id=3011
  • For-in/for-of loop bodies can’t contain tail calls because of need to close the iterator on abrupt completion.
  • [[OwnPropertyKeys]] now returns a List rather than an Array
  • Tests of @@isRegExp are now based on ToBoolean(Get(obj, @@isRegExp)
  • Array find/findIndex no longer ignore array element holes.
  • Added %IteratorPrototype% that all built-in iterators inherit from.
  • Destructoring now performs ToObject on values to be destructured.
  • Array and generator comprehensions removed from language
  • Removed specification of Reflect.Realm
  • Object.assign ignores null and undefined source arguments
  • Added 16.1 that lists forbidden extensions.
  • Some editorial cleanup of Function.prototype.toString
  • Removed all explicit poison pill methods on functions (except for Function.prototype) and added 16.1 restrictions on such extensions.
  • String(aSymbol) now returns the symbol’s description. Does not change ToString(symbol) throwing ever where else.
  • aSymbol == Object(aSymbol) now is true, just like other wrapable primitives, see bug:https://bugs.ecmascript.org/show_bug.cgi?id=3066
  • Tighten specification of when Array.prototype.sort is implementation defined
  • Revised @@unscopable semantics as per last TC39 meeting
  • Made it an error to reentrantly enter a generator via next/throw/return.
  • Further work on semantics of Generator return method in the context of yield*
  • The term “neutered” has been replaced with the term “detached”
  • Resolved bugs: 3147, 3142-3140, 3135-3133, 3131, 3128-3124, 3122-3120, 3117, 3115, 3111-3107, 3105, 3103-3098, 3096-3095, 3093-3092, 3090-3089, 3087-3082, 3080-3062, 3060-3016, 3012-3011, 3005, 2987, 2979, 2976, 2831, 2389, 2368, 1908, 523, 516, 513, 407, 91

Previous

Extending Pro PHP MVC

root (Edward Gerhold)

Class Diagram generated by phpStorm
Das mit PHPStorm vor einigen Tagen generierte Klassendiagram.
Class Diagram handdrawn with ArgoUML
Mit ArgoUML vorher  handgemalt, noch voller Fehler.