Forum: PC-Programmierung Rechnen mit rationalen Zahlen begrenzter Grösse, beste Approximation für Bruch gesucht


von 🐧 DPA 🐧 (Gast)


Lesenswert?

GCC und C-Lang haben einen uint128_t Datentyp. Ich habe ein paar 
Berechnungen & Konstanten, für die das gerade so ausreichen müsste.
Einige der Berechnungen will ich mit Rationalen Zahlen bestehend aus 2 
int128_t machen. Die 2 Komponenten wachsen bei so ziemlich jeder 
Operation, ist halt so bei Rationalen Zahlen. Wenn ich glück habe, kann 
ich dann durch den grössten gemeinsamen Teiler teilen, aber ich kann 
mich nicht darauf verlassen, dass das immer geht.

Für den Fall suche ich nun die Beste Approximation a'/b' für a/b mit 
a'<m und b'<m. Dabei geht es mir nicht darum, a'/b' - a/b zu minimieren, 
mir ist die Präzision beider Komponenten gleich wichtig. Vorerst 
definiere ich das zu minimierende deshalb so. Mit dem nächste Punkt X 
auf die Linie a'b/a, die Distanz vom Punkt  (a'/b') zu X im Verhältnis 
zur Distanz vom Punkt (0/0) zu X.

Wenn ich das ausrechne komme ich auf:
1
f(n) = (a^3 (a^2 + b^2))/(2 (a + b) (2 a^2 n + a b + 2 b^2 n))
2
3
0 < b < a
4
0 < n < m <= a
5
6
g(m) = n with smallest f(n) for m
(btw. n ist hier a'). Das 0 < b < a ist da, um das ganze etwas zu 
vereinfachen, die beste Approximation für a'/b' und b'/a' ist ja 
eigentlich die Selbe, nur die Zahlen sind vertauscht, daher kann ich das 
immer umtauschen so das b'<a', und nachher zurück tauschen.

Was ich herausfinden muss ist g(m). In meinem konkreten fall wäre 
m=2**127, aber eine Allgemeine Lösung wäre mir lieber, falls ich die 
Präzision später mal ändern will.

Ich brauche eine Effiziente Formel für g(m), aber ich stehe hier absolut 
auf dem Schlauch. Wie gehe ich sowas überhaupt an?

Was ich bisher herausgefunden habe, ist, dass g(a) >= a/2 aber das hilft 
mir nicht wirklich weiter. Wolframalpha hat mich bisher auch nicht 
weiter gebracht...

von (Gast)


Lesenswert?

Habs leider gerade nicht zur Hand, aber in "Concrete Mathematics" [1] 
sollten sich da Hinweise finden. Google spuckt das aus: 
https://github.com/alidasdan/best-rational-approximation

[1] R.L. Graham, D.E. Knuth, and O. Patashnik, Concrete Mathematics, 2nd 
Edition, Addison-Wesley Longman, 1994.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

rµ schrieb:
> https://github.com/alidasdan/best-rational-approximation
> A fraction n/d, where d is at most a given limit l, is the best rational
> approximation to a target real number t if the absolute difference (the
> absolute error) between n/d and t is the smallest among all the fractions
> each of whose denominator is at most l.

Hmm... Da wird also einfach die Differenz der Brüche minimiert? Aber ist 
die beste Lösung für min a'/b'-a/b wirklich immer die beste Lösung für 
min b'/a'-b/a, oder ist das ein anderes Problem?

von (Gast)


Lesenswert?

Ehrlich gesagt hab ich die Rechnung nach diesem Satz

🐧 DPA 🐧 schrieb:
> Dabei geht es mir nicht darum, a'/b' - a/b zu minimieren,
> mir ist die Präzision beider Komponenten gleich wichtig.

nicht mehr weiter nachvollzogen. Wenn mit Komponenten die Zahlen a', a, 
b' und b gemeint sind, das sind ganze Zahlen, und die sind per Defintion 
exakt, haben also keine "Präzision". Rationale Zahlen ditto.

Was die "Operationen" angeht die die Koeffizienten "aufblasen", dazu 
gibts bei Knuth z.b. in TeX auch Algorithmen zumindest für die 
Grundrechenarten.

von Alexander S. (alesi)


Lesenswert?

🐧 DPA 🐧 schrieb:
> Dabei geht es mir nicht darum, a'/b' - a/b zu minimieren,
> mir ist die Präzision beider Komponenten gleich wichtig.

Was genau meinst Du mit "mir ist die Präzision beider Komponenten gleich 
wichtig"? Suchst Du nun die beste rationale Approximation zu a/b mit a', 
b' < m = 2^127 oder gibt es eine weitere Nebenbedingung?

Was ist Dein g(m)?

von Alexander S. (alesi)


Lesenswert?

🐧 DPA 🐧 schrieb:
> Wie gehe ich sowas überhaupt an?

Bei besten Näherungen spielen auch Kettenbrüche eine Rolle: 
https://de.wikipedia.org/wiki/Kettenbruch#Beste_N%C3%A4herungen

von 🐧 DPA 🐧 (Gast)


Lesenswert?

Alexander S. schrieb:
> 🐧 DPA 🐧 schrieb:
>> Dabei geht es mir nicht darum, a'/b' - a/b zu minimieren,
>> mir ist die Präzision beider Komponenten gleich wichtig.
>
> Was genau meinst Du mit "mir ist die Präzision beider Komponenten gleich
> wichtig"?

Stell dir ein Raster a x b breit vor. Nun stell dir eine Linie von 0,0 
zu a,b vor. a',b' wäre der Punkt, der am nächsten an der Linie liegt, 
wobei 0<a'<m und 0<b<m

> Suchst Du nun die beste rationale Approximation zu a/b mit a',
> b' < m = 2^127 oder gibt es eine weitere Nebenbedingung?
>
> Was ist Dein g(m)?

Die Funktion suche ich ja.

von Ui große Zahl (Gast)


Lesenswert?

https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library

Wieso nicht einfach "die" Standardbibliothek für mathematische 
Operationen verwenden?

Generell für das Rechnen mit großen Zahlen ist auch die OEIS immer einen 
Blick wert, dort findet man viele Algorithmen usw.

Boost und die Bibliotheken in C++ sind auch einen Blick wert.

von (Gast)


Lesenswert?

🐧 DPA 🐧 schrieb:
> Wenn ich das ausrechne komme ich auf:f(n) = (a^3 (a^2 + b^2))/(2 (a + b)
> (2 a^2 n + a b + 2 b^2 n))
> 0 < b < a
> 0 < n < m <= a
> g(m) = n with smallest f(n) for m

ich versteh zwar noch immer nicht was die rechnung da genau soll, aber 
minimum von f(n) rechnet man aus indem man nach n ableitet und die 
ableitung 0 setzt und ausrechnet. f(n) ist von der struktur her ja recht 
einfach (konstante faktoren herausheben, dann bleibt die ableitung von 
sowas wie 1/(x+const)), ableitung 0 setzen ergibt quadratische 
Gleichung. Man nimmt dann die Lösung wo 2te Ableitung <0 ist.

von (Gast)


Lesenswert?

Bei weiterem Nachdenken fällt mir ein dass n vermutlich ganzzahlig sein 
soll, das macht das dann zu einer diophantischen Gleichung, und da 
beisst man sich dann vermutlich direkt die Zähne aus.

von Yalu X. (yalu) (Moderator)


Lesenswert?

🐧 DPA 🐧 schrieb:
> Dabei geht es mir nicht darum, a'/b' - a/b zu minimieren,
> mir ist die Präzision beider Komponenten gleich wichtig. Vorerst
> definiere ich das zu minimierende deshalb so. Mit dem nächste Punkt X
> auf die Linie a'b/a, die Distanz vom Punkt  (a'/b') zu X im Verhältnis
> zur Distanz vom Punkt (0/0) zu X.

Das verstehe ich überhaupt nicht.

> Wenn ich das ausrechne komme ich auf:
> f(n) = (a^3 (a^2 + b^2))/(2 (a + b) (2 a^2 n + a b + 2 b^2 n))

Wie du auf diese wilde Formel kommst, verstehe ich auch nicht.

🐧 DPA 🐧 schrieb:
> Stell dir ein Raster a x b breit vor. Nun stell dir eine Linie von 0,0
> zu a,b vor. a',b' wäre der Punkt, der am nächsten an der Linie liegt,
> wobei 0<a'<m und 0<b<m

Das verstehe ich schon eher :)

Du willst also nicht den auf den Wert des Bruchs bezogenen Fehler

minimieren (was IMHO am naheliegendsten wäre), sondern stattdessen den
auf den Nenner des Bruchs bezogenen Fehler

Habe ich das richtig verstanden?

Falls ja: Wenn es zwei Paare (a', b') gibt, die zum gleichen Fehler e2
führen, welcher der beiden Alternativen gibst du dann den Vorzug?

Noch eine Frage zum Sinn des Ganzen:

Rationale Arithmetik verwendet man üblicherweise dann, wenn man mit
gebrochenen Zahlen exakt rechnen möchte, was mit Fest- oder
Gleitkommaarithmetik nicht immer möglich ist (schon 1/3 führt dort zu
Rundungsfehlern). Dafür nimmt man den zusätzlichen Rechenaufwand (Finden
des kleinsten gemeinsamen Nenners bei Additionen und Subtraktionen und
Kürzen der Ergebnisse bei allen Rechenoperationen) in Kauf.

Du möchtest jetzt mit noch höherem Rechenaufwand Näherungslösungen für
die einzelnen Rechenoperationen finden, womit der Vorteil der rationalen
Arithmetik zunichte gemacht und ihr Nachteil noch verstärkt wird. Warum
verwendest du stattdessen nicht einfach Fest- oder Gleitkommaarithmetik?

: Bearbeitet durch Moderator
von (Gast)


Lesenswert?

Yalu X. schrieb:
> Falls ja: Wenn es zwei Paare (a', b') gibt, die zum gleichen Fehler e2
> führen, welcher der beiden Alternativen gibst du dann den Vorzug?

Wenn man die zwei Varianten gleichsetzt umstellt und ausrechnet ergibt 
sich

das sollte eigentlich nicht vorkommen, da ja
, oder?

von Daniel A. (daniel-a)


Lesenswert?

Wenn man von (0/0) Linien nach (a/b) und (a'/b') zeichnet, den Winkel 
dazwischen, den will ich minimieren.

Mir ist aufgefallen, bei der Formel f(n) oben hatte ich einen Fehler 
beim umformen gemacht, die sollte eigentlich so aussehen:

Da ist b' schon eingesetzt. Andernfalls wäre es
https://www.geogebra.org/graphing/xryhkcbh

Das kommt von:
d ist die Distanz vom 0 Punkt, e ist die Distanz zur Linie b/a: 
https://www.geogebra.org/graphing/ptmpy6ad

von Daniel A. (daniel-a)


Lesenswert?

Yalu X. schrieb:
> Du möchtest jetzt mit noch höherem Rechenaufwand Näherungslösungen für
> die einzelnen Rechenoperationen finden, womit der Vorteil der rationalen
> Arithmetik zunichte gemacht und ihr Nachteil noch verstärkt wird. Warum
> verwendest du stattdessen nicht einfach Fest- oder Gleitkommaarithmetik?

Das ganze ist eigentlich nur eine Spielerei. Ein versuch, eine kleine 
Physiksimulation aufzubauen, basierend auf Plank Einheiten. Die sind 
teils sehr gross / klein, deshalb nehme ich int128_t. Der Grundgedanke 
dabei war, wenn ich beim Rechnen etwas aufpasse, kann ich den Fehler so 
halten, dass der eh kleiner ist als eine Plank länge/zeit bleibt usw. 
bleibt. Beim Relativitätszeugs gibt es aber ein paar fiese Sachen, die 
man beachten muss. z.B. wenn man 2 Geschwindigkeiten addiert:
Das +1 ist bei floats fies. Und wenn man bei allen Variablen 1/x macht, 
kommt wieder das selbe raus. Also je nachdem, ob es schnelle oder 
langsame Geschwindigkeiten sind, ändert sich der Zähler oder der Nenner 
quasi linear. Also kann ich nicht sagen, dass mir die Genauigkeit beim 
einen oder beim anderen wichtiger wäre. Aber ich hoffe, es mit 
Rationalen Zahlen ganz gut abbilden zu können.

Und deshalb der Versuch, den Fehler bei beiden Komponenten klein zu 
halten.

Vermutlich wird aus dem ganzen am Ende nichts. Ich bin mir noch nicht 
einmal sicher, was ich überhaupt simulieren möchte. Aber was auch immer 
dabei raus kommt, ist wieder eine neue Erfahrung. Es geht ja nur um den 
Spass an der Freude.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.