RegistrierenRegistrieren   LoginLogin   FAQFAQ    SuchenSuchen   
Numerische Berechnung von pi, sqrt, sin, cos
 
Neue Frage »
Antworten »
    Foren-Übersicht -> Sonstiges
Autor Nachricht
VeryApe



Anmeldungsdatum: 10.02.2008
Beiträge: 3247

Beitrag VeryApe Verfasst am: 01. Aug 2020 00:47    Titel: Antworten mit Zitat

Weil ihr gerade über PI und Wurzel 2 redets.
Ich habe zuvor ein Nullstellenfindungs Programm mit Javascript geschrieben, aber DoubleFloat64bit hat klarerweise nur ne beschränkte Genauigkeit, jetzt komme ich vom Regen in die Traufe und hantiere mit BigIntegers und zwar als Bruch, da kann mir erst alles selbst erarbeiten.

Jetzt habe ich Wurzel 2 Folge mit a[0]=1/2




realisiert, aber mit jeder Iteration komme ich nicht gerade schnell in tiefere Genauigkeit.

PI habe ich mit https://crypto.stanford.edu/pbc/notes/pi/ramanujan.html
realisiert, da gehts ab pro Itertation.
https://jsfiddle.net/Veryape/y3pe2L8d/58/

Aber was wäre die schnellste wurzel2 folge für die Berechnung?

Momentan arbeite ich an sinus und cosinus, da nehme ich die Taylor Reihe, oder gibts was schnelleres?

_________________
WAS IST LOS IN EUROPA? https://www.youtube.com/watch?v=a9mduhSSC5w
TomS
Moderator


Anmeldungsdatum: 20.03.2009
Beiträge: 18030

Beitrag TomS Verfasst am: 01. Aug 2020 09:25    Titel: Antworten mit Zitat

Generell:

Javascript im Browser? Such mal nach Algorithmen und Implementierungen der Numerical Recipes; zu meiner Zeit gab‘s die in FORTRAN und C++.

Dann: Geht es dir um eine größtmögliche Präzision, also um möglichst viele Stellen? Oder geht es dir um möglichst schnelle Konvergenz für eine feste Anzahl von Stellen? Das kann auf unterschiedliche Methoden rauslaufen.

Bzgl. numerischer Berechnungen: Es gibt ein paar allgemeingültige Fallen und Tricks. Eine Falle ist die Berechnung der Differenz kleiner Zahlen; das muss man auf jeden Fall vermeiden. Ein Trick ist das Hornerschema für Polynome und Taylorreihen:



Die iterative Berechnung erfolgt von innen nach außen:



Das einfachste Verfahren zur Quadratwurzelberechnung für allgemeine a, nicht nur speziell a = 2, ist das sogenannte Heron-Verfahren. Es gilt die Rekursion



Es konvergiert sehr schnell (recht langsam) bei guter (schlechter) Wahl des Startwertes.

Andere Verfahren findest du hier: https://en.m.wikipedia.org/wiki/Methods_of_computing_square_roots

Dein Verfahren zur Berechnung von pi nach Ramanujan ist vernünftig, wenn es um möglichst viele Stellen geht; weitere Methoden findest du hier: https://en.m.wikipedia.org/wiki/Pi#Rapidly_convergent_series

Die Berechnung von Winkelfunktionen ist die Taylorentwicklung des Sinus um x = 0 aufgrund der alternierenden Reihe geeignet. Dazu muss man mittels der Theoreme für Sinus und Cosinus dafür sorgen, dass die Berechnung einer Winkelfunktion f(a) zum Funktionswert a in die Form



mit



gebracht wird, wobei F ein Ausdruck ist, der nur von sin(x) sowie Konstanten abhängt, und wobei x möglichst nahe bei Null liegen sollte! sin(x) wird dann genau einmal numerisch berechnet.

_________________
Niels Bohr brainwashed a whole generation of theorists into thinking that the job (interpreting quantum theory) was done 50 years ago.
VeryApe



Anmeldungsdatum: 10.02.2008
Beiträge: 3247

Beitrag VeryApe Verfasst am: 01. Aug 2020 12:05    Titel: Antworten mit Zitat

Zitat:
Javascript im Browser?
nicht nur, die schnelle V8 Javascript Engine rennt auch auf Server NodeJS https://nodejs.org/en/ oder als Standalone APP https://nwjs.io/ , spidermonkey ist auch nicht so langsam.

Im Prinzip, nehmen wir die Seite von Wolfram alpha, da kannsd du ne Funktion eingeben und siehst den Plot, ich möchte mich in den Plot beliebig reinzoomen können, oder Nullstellen, Steigung mit höherer Genauigkeit berechnen.


Zitat:
Dann: Geht es dir um eine größtmögliche Präzision, also um möglichst viele Stellen? Oder geht es dir um möglichst schnelle Konvergenz für eine feste Anzahl von Stellen? Das kann auf unterschiedliche Methoden rauslaufen


Ja es geht um eine schnelle Konvergenz für eine vorher definierte Fehlergenauigkeit indem man einen Nenner (denominator) eines Ergebnis Bruches übergibt. der Fehler wäre dann <+- 1/denominator, weil ich im Zähler auch nur ganze Zahlen darstellen kann->BigInt

In Javascript habe ich bei DoubleFloat64bit 52bit Präzessionbits plus ein 1er bit für die Höchste Stelle also 53bit, der Rest ist das Vorzeichen und der Exponent.

der größte sichere Integer ist 2^53-1 =9007199254740991 da kann man klarerweise keine Kommastelle hinten mehr speichern.

wenn ich ein Bit fürs Komma lasse also 2^-1 =0.5 dann habe ich 2^52-1=
4503599627370495 da könnte ich dann 4503599627370495.5 darstellen, also die Kommagenauigkeit hängt stark vor Zahl vor den Komma ab.

Jetzt habe ich Big Integers Brüche..
der Zähler ist ein Big Integer und der Nenner=denominator ist ein BigInter, mit dem habe ich jetzt beliebige Genauigkeit, aber muß die ganzen mathematischen Funktionen erst selber integrieren.

Aber ich kann mit BigInt das integrierte Math Object nicht nützen, überhaupt kann man nicht einfach Javascript Numbers mit BigInts multiplizieren oder sonstige mathematische Operationen durchführen.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

Das Hornerschema werde ich mir anschauen.

Zudem was du über die Taylor Reihe sinus x geschrieben hast.

ich dachte an folgendes. n von 0 bis unendlich






wenn ich jetzt zum Beispiel zwei BigInt fraction übergebe





sehe ich jetzt nicht ganz wie ich da jetzt nur einmal numerisch einen sinus nach der Folge berechnen könnte, und den Rest dann einfach irgendwie umrechnen.

Ich hätte jetzt in diese Folge x1 eingesetzt und berechnet und dann x2 eingesetzt und dann berechnet.

wie genau berechnet wird bestimmt das zweite Argument
function sinus ( x, denominator) x ist irgendein BigInt fraction und denominator ist der Nenner in dem man das Ergebnis als Bruch zurück haben will, damit hat man dann einen Fehler <+- 1/denominator

_________________
WAS IST LOS IN EUROPA? https://www.youtube.com/watch?v=a9mduhSSC5w
TomS
Moderator


Anmeldungsdatum: 20.03.2009
Beiträge: 18030

Beitrag TomS Verfasst am: 01. Aug 2020 13:19    Titel: Antworten mit Zitat

JavaScript wird interpretiert, egal, wo‘s läuft. Wenn dir die Performance ausreicht, ist‘s OK, aber grundsätzlich ist eine compilierte Sprache immer noch schneller.

Bzgl. der Berechnung hatte ich dich wohl falsch verstanden. Ich sehe nicht, dass du die Berechungen sinnvollerweise mittels Integer-Arithmetik durchführen kannst.

Du benötigst eine Formel, die überhaupt mit Integern arbeitet. Das hast du i.A. nicht, pi ist ein Spezialfall. Selbst wenn du mit Integern und Brüchen arbeitest, hast du das Problem, dass dir Zähler und Nenner getrennt überlaufen, wenn du erst zuletzt den Bruch berechnest. Einfaches Bsp. wäre die Taylorreihe des Sinus. Und zuletzt sehe ich nicht, dass du bei deiner Berechnung mit x-Bit Integern besser sein wirst als die FPU mit x-Bit Float.

_________________
Niels Bohr brainwashed a whole generation of theorists into thinking that the job (interpreting quantum theory) was done 50 years ago.
VeryApe



Anmeldungsdatum: 10.02.2008
Beiträge: 3247

Beitrag VeryApe Verfasst am: 01. Aug 2020 13:55    Titel: Antworten mit Zitat

Zitat:

JavaScript wird interpretiert, egal, wo‘s läuft. Wenn dir die Performance ausreicht, ist‘s OK, aber grundsätzlich ist eine compilierte Sprache immer noch schneller


sicherlich, V8 compiliert Javascript mit einer Just in Time compilation optimiert, performance code wird vorcompiliert bevor er exekutiert wird.

Du kannsd es auch generell compilieren.

Zitat:
Und zuletzt sehe ich nicht, dass du bei deiner Berechnung mit x-Bit Integern besser sein wirst als die FPU mit x-Bit Float.


Ich will ja nicht besser sein als die Floating Point Unit. Ich möchte probieren eine höhere Genauigkeit unter Javascript zu erhalten, dafür habe ich mir ne fraction Pseudo klasse geschrieben und probiere jetzt, wie schnell ich da etwas berechnen kann. Die Performance ist bei PI bei 10000 berechnungen mit einem denominator von 2^1024 genauigkeit entspricht 1.79e+308 bei 1.2 sec.
Also 10000 mal hintereinander PI berechnen auf 5.65e-309
bei wurzel 2 ist sie bei 1000 mal hintereinander berechnen mit bei ca 1.2 sec.
Aber diese konstanten berechnet man sowieso nur einmal am Start mit einer gewissen Genauigkeit. Interessant wirds für mich jetzt bis sinx und cosinusx , wie schnell das geht.

Du meinst es geht gar nicht? probiere ich demnächst und vergleichs mit wolframalpha.

wenn der denominator durch die ganzen hochs zu groß wird, wird einfach der Zähler durch den überschuss dividiert.

wenn ich habe x= 900/10000 und ich errechne x² dann erhalte ich den denominator auf 10000 und errechne



dabei entsteht max 1/10000 Fehler in der Summierung der einzelnen Brüche muß ich dann darauf achten das der insgesamte Fehler nicht größer als 1/denominator gefordert wird.

_________________
WAS IST LOS IN EUROPA? https://www.youtube.com/watch?v=a9mduhSSC5w


Zuletzt bearbeitet von VeryApe am 01. Aug 2020 14:21, insgesamt einmal bearbeitet
TomS
Moderator


Anmeldungsdatum: 20.03.2009
Beiträge: 18030

Beitrag TomS Verfasst am: 01. Aug 2020 14:10    Titel: Antworten mit Zitat

Ok, dass V8 Javascript in nativen Maschinencode compiliert wusste ich nicht.

Zu meinem Einwand bzgl. Integer: Integer-Berechnungen haben zunächst den Vorteil, dass sie - wenn im Rahmen des Datenformats möglich - exakt sind. Ob sie auch schneller sind, ist eine Frage der Implementierung. Spätestens wenn das Datenformat nicht mehr zur Prozessorarchitektur passt, sehe ich das nicht unbedingt.

Zu pi: hier liegt ein Algorithmus vor, der speziell zur bitweisen Berechnung verwendet werden kann. Wenn ein derartiger Algorithmus bekannt ist, dann mag das natürlich Vorteile haben. Aber i.A. ist das ja nicht der Fall. Schau dir die Taylorreihe zum Sinus für beliebiges x an: die Reihe konvergiert für kleines x aufgrund der alternierenden Vorzeichen extrem schnell und liefert eine sehr hohe Genauigkeit, weil das Taylorsche Restglied sehr schnell klein wird. Wenn du aber Integer-Arithmetik verwendest, dann musst du Zähler und Nenner getrennt berechnen, was evtl. deutlich früher zu einem Überlauf führt.

_________________
Niels Bohr brainwashed a whole generation of theorists into thinking that the job (interpreting quantum theory) was done 50 years ago.
VeryApe



Anmeldungsdatum: 10.02.2008
Beiträge: 3247

Beitrag VeryApe Verfasst am: 06. Aug 2020 23:31    Titel: Antworten mit Zitat

ist überhaupt kein Problem

1000 mal sinus auf denominator 2^1024 hintereinander ausrechnen für PI/2 dauert 512ms.

dabei rechne ich das übergebene x (BigInt fraction z.B 12999212/1112121289) auf einen denominator_expanded=j*denominator (z.B j=1000) und erhalte diesen Nenner während der ganzen Berechnung, die Fehler habe ich abgeschätzt, pro Folgeglied mache ich ungefähr 1.2/denominator_expanded Fehler, da sollte für 500 Summierungen eine Erweiterung auf 1000 reichen.

für j=1000


Bei 2^1024 und PI/2 brauche ich 93 Schleifendurchgänge also 94 Folgeglieder

und PI/2 ist maximum Wert den ich für die Folge erlaube für x erlaube, größere x Werte kann man ja leicht in die Quartale umrechnen, ändert sich ja nichts ausser vielleicht das Vorzeichen.

_________________
WAS IST LOS IN EUROPA? https://www.youtube.com/watch?v=a9mduhSSC5w
Neue Frage »
Antworten »
    Foren-Übersicht -> Sonstiges