Ganzzahliger Quadratwurzel-Algorithmus mit beliebiger Genauigkeit?

9

Gibt es bekannte subquadratische Algorithmen zur Berechnung des Quadratwurzelbodens einer nBit-Ganzzahl?

Der naive Algorithmus wäre so etwas wie

def sqrt(x):
    r = 0
    i = x.bit_length() // 2
    while i >= 0:
        inc = (r << (i+1)) + (1 << (i*2))
        if inc <= x:
            x -= inc
            r += 1 << i
        i -= 1
    return r

Dies erfordert O(n)Iterationen, die jeweils O(n)zeitliche Ergänzungen beinhalten , also ist es O(n^2)insgesamt Zeit. Gibt es etwas schnelleres? Ich weiß, dass es für den Fall der Multiplikation spezielle Algorithmen gibt, die besser als die quadratische Zeit sind, aber ich kann nichts für Quadratwurzeln finden.

Antimon
quelle
Meine Antwort auf etwas Ähnliches könnte cs.stackexchange.com/a/37338/12052 helfen . Das einzige Problem ist, dass Sie einen Teil der notwendigen Gleichung empirisch finden müssen, um ihre Genauigkeit zu optimieren.
Francesco Gramano
@FrancescoGramano: Entschuldigung, ich glaube nicht, dass das hilft.
Aryabhata
Übrigens, ist diese subquadratische Anforderung Teil eines größeren Problems? Weil der Unterschied zwischen dem einfachen Quadrat und dem komplizierten Subquadrat in der Praxis möglicherweise nicht so groß ist. Oder ist es nur von theoretischem Interesse?
Aryabhata
@Aryabhata Entschuldigung, ich habe Ihren Kommentar vorher nicht gesehen. Nein, es ist nicht Teil eines größeren Problems, nur Neugier.
Antimon

Antworten:

5

Sie können die Newtonsche Methode oder eine Reihe anderer Methoden verwenden, um Annäherungen an Wurzeln des Polynoms .p(x)=x2c

Die Konvergenzrate für die Newtonsche Methode ist quadratisch, was bedeutet, dass sich die Anzahl der korrekten Bits in jeder Iteration verdoppelt. Dies bedeutet, dass -Iterationen der Newtonschen Methode ausreichen.O(lgn)

Jede Iteration der Newtonschen Methode wird berechnet

xj+1=xj(xj2c)/(2xj)=0.5xj+c2xj.

Die Bitkomplexität der Multiplikation ist O ( b lg b ) , um zwei b- Bit-Ganzzahlen zu multiplizieren (wobei lg lg b- Faktoren ignoriert werden). Die Bitkomplexität für die Division (auf b Bits der Genauigkeit) ist dieselbe. Daher kann jede Iteration in O ( n lg n ) -Operationen berechnet werden. Multipliziert man mit O ( lg n ) -Iterationen, so ergibt sich, dass die Gesamtlaufzeit zur Berechnung der Quadratwurzel mit n Genauigkeitsbits O ( n ( lg n) beträgtO (blgb)blglgbbO (nlgn)O(lgn)n . Dies ist subquadratisch.O (n(lgn)2)

Ich denke, eine genauere Analyse zeigt, dass dies auf die Laufzeit von O ( n lg n ) verbessert werden kann (indem berücksichtigt wird, dass wir jedes x j nur mit einer Genauigkeit von etwa j und nicht mit einer Genauigkeit von n kennen müssen ). . Selbst die grundlegendere Analyse zeigt jedoch bereits eine Laufzeit, die eindeutig subquadratisch ist.O (nlgn)xjjn

DW
quelle
In binären Eins hat auch eine große anfängliche Vermutung , die Identität mit . Anstatt das Protokoll zu berechnen, kann man log 2 x als Anzahl der Stellen in x approximieren . ZB log 2 101011 6 . x1/2=21/2log2xlog2xxlog21010116
Nick Alger
@ DW: Aber suchen wir nicht nach einer ganzzahligen Quadratwurzel? Wenn Sie die Methodeniteration des Newton nur mit ganzzahliger Arithmetik durchführen, müssen wir den -Anspruch zusätzlich begründen, nicht wahr? Ansonsten gehen wir bereits von einer ausreichend großen Präzision aus ... Entschuldigung, wenn mir etwas Offensichtliches fehlt. O(logn)
Aryabhata
@ DW: "Die Konvergenzrate für Newtons Methode" ist nicht quadratisch, wenn , und ich weiß nicht, was für Werte von c passiert, die keine nicht negativen Realwerte sind.c=0cIhre Schätzung für die Bitkomplexität der Multiplikation ist enger als Ihre folgende Bemerkung vermuten lässt .Außerdem müssen wir "jedes auf ungefähr 2 kennen "xj "Präzisionsbits".2j
@ Aryabhata: Wir sind nicht ganz "auf der Suche nach einer ganzzahligen Quadratwurzel"; Wir suchen nach "dem Boden der Quadratwurzel". Sie haben Recht mit dem Problem der Ganzzahlarithmetik, obwohl für Gleitkommaoperationen die gleichen Bitkomplexitäten gelten.
1
@RickyDemer ja, ist ein Sonderfall, da dann die Wurzel von p ( x ) Multiplizität 2 hat, aber , wenn c > 0 , die Wurzel Multiplizität 1 hat so die Newton-Verfahren ist quadratische Konvergenz aufweist. Ich gehe davon aus, dass niemand Newtons Methode verwenden würde, um die Quadratwurzel von c = 0 zu berechnen (weil die Quadratwurzel von Null offensichtlich Null ist). Also, was versuchst du zu sagen? Ist Ihr Kommentar ein trivialer Kommentar, der durch Hinzufügen von etwas zu meiner Antwort mit der Aufschrift "Sonderfall Quadratwurzel Null" angesprochen wird, oder gibt es hier etwas Tieferes, das mir fehlt? c=0p(x)c>0c=0
DW
6

Eines der Probleme bei der Newtonschen Methode besteht darin, dass in jeder Iteration eine Divisionsoperation erforderlich ist, die die langsamste grundlegende Ganzzahloperation ist.

Newtons Methode für die reziproke Quadratwurzel tut dies jedoch nicht. Wenn die Zahl ist, für die Sie 1 finden möchtenx , iteriere:1x

ri+1=12ri(3xri2)

Dies wird oft ausgedrückt als:

wi=ri2
di=1wix
ri+1=ri+ridi2

Das sind drei Multiplikationsoperationen. Die Division durch zwei kann als Rechtsverschiebung implementiert werden.

r

x

x=22ex

x1xxr=1xx=2erx

r

ri=2eiri

riei

Wir wissen, dass Newtons Methode die Anzahl der genauen signifikanten Stellen ungefähr verdoppelt. So können wir wählen:

ei+1=2ei

Mit ein wenig Manipulation finden wir:

ei+1=2ei
wi=ri2
xi=x22eei+1
di=2ei+1wixi2ei+1
ri+1=2eiriridi2ei+1

Bei jeder Iteration:

xrix2e+ei

x=263231212231e=31r0=3e0=23412

Dann:

e1=4,r1=11
e2=8,r2=180
e3=16,r3=46338
e4=32,r4=3037000481

eieei>2e

2633037000481×263231+32=3037000481

3037000499ei

bO(blogb)ri<2eiwieiei+1ei+12ei+1-bit Nummer.

O(eilogei)O(loge)O(2elog2e)O(elog2e)x

Diese Analyse verbirgt jedoch ein wichtiges Prinzip, das jeder, der mit großen ganzen Zahlen arbeitet, berücksichtigen sollte: Da die Multiplikation in der Anzahl der Bits superlinear ist, sollten Multiplikationsoperationen nur mit ganzen Zahlen durchgeführt werden, die ungefähr die Größe der aktuellen Genauigkeit (und) haben Ich möchte hinzufügen, dass Sie versuchen sollten, Zahlen mit einer ähnlichen Größenordnung zu multiplizieren. Die Verwendung größerer Ganzzahlen ist eine Verschwendung von Aufwand. Konstante Faktoren sind wichtig, und für große ganze Zahlen sind sie sehr wichtig.

ab2cabc

Pseudonym
quelle
Das ist großartiges Zeug. Ein Kommentar: Ist die Bitkomplexität der Division nicht asymptotisch ungefähr gleich der Bitkomplexität der Multiplikation? Sie sprechen also von etwas, das eine konstante Faktorverbesserung bewirkt, keine asymptotische Verbesserung, oder? Das war aus Ihrer Antwort nicht ganz klar.
DW
bO(blgb)O(blgb(lglgb)O(1))
1
@ DW: bO(blogb)Das Wort "Bit" kommt darin nur einmal vor; sonst hätte ich schon darauf hingewiesen.
Es geht um konstante Faktoren, ja. Die besten Algorithmen für große Ganzzahldivisionen verwenden eine Technik, die dem gesamten Algorithmus sehr ähnlich ist, wie beispielsweise die Newton-Raphson-Iteration und die Verdoppelung der effektiven Genauigkeit bei jeder Iteration. Eine Newton-Raphson-Schleife innerhalb einer Newton-Raphson-Schleife stapelt sich auf die konstanten Faktoren! Ricky Demer ist richtig; Ich dachte an das Wort RAM-Modell. Ich hätte das wahrscheinlich erwähnen sollen.
Pseudonym