Modulo einer Potenz aus reeller Basis und ganzzahligem Exponenten

Neue Frage »

Torsten_Straeter Auf diesen Beitrag antworten »
Modulo einer Potenz aus reeller Basis und ganzzahligem Exponenten
Meine Frage:
Gegeben sei eine reelle Zahl a (als Basis), eine ganze Zahl e (als Exponent) sowie eine ganze Zahl m (als Modulus).
Gesucht ist floor(a^e) mod m.

Meine Ideen:
Sofern e kleinere Werte annimmt, sehe ich keine Probleme, die Aufgabe mit bspw. Python oder auch Mathematica zu lösen. Wenn der Exponent e aber in Sphären > 10^7 gelangt, wird es schwierig.
Z. B. floor((3,7253526)^135792468) mod 100000007
Ich hatte überlegt, ob ich die Potenz mit einem Logarithmus bearbeite, kam allerdings nicht wirklich weiter.
HAL 9000 Auf diesen Beitrag antworten »

Mit Logarithmen kann man in etwa abschätzen, welche Genauigkeit man für die Floating-Point-Rechnung benötigt, damit das ganze überhaupt funktionieren kann:

Es ist , d.h. man benötigt mindestens Bit Mantisse für die Floatingpointrechnung - hübsch anspruchsvoll. Augenzwinkern


Die ganzen Mechanismen, welche bekanntermaßen bei mit ganzzahligen (!) Basen greifen, kann man hier weitestgehend vergessen. Selbst wenn rational ist mit , so kann man bei der Bestimmung von



das ganze allenfalls auf zurückführen, was einem wohl so gut wie gar nichts nützt.


Erklär doch mal, in welchem Zusammenhang dir diese ziemlich seltsame Problemstellung begegnet ist.
Torsten_Straeter Auf diesen Beitrag antworten »

Gefragt, gejagt. Mein Bruder hatte die Frage über Weihnachten aufgeworfen. Ich habe jetzt nochmal nachgehakt. Er meinte, es gibt wohl bei Projekt Euler (ja, ich weiß...) die Problemstellung, dass zu einer kubischen Gleichung die Nullstellen gefunden werden sollen. Die Lösung stellt dann die Basis (siehe oben) dar, der Exponent ist ziemlich groß und der ganzzahlige Teil der Potenz soll dann per modulo reduziert werden.
Falls Interesse besteht, kann ich sicher auch den Index des Problems herausfinden.
HAL 9000 Auf diesen Beitrag antworten »

Du meinst aber nicht https://projecteuler.net/problem=251 ? Das war vor langer Zeit mal hier im Forum aufgeschlagen...

EDIT: Vermutlich meinst du https://projecteuler.net/minimal=324. Hast du denn eine Rekursionsgleichung für dieses dort aufstellen können? Ich denke, hier über Potenzen reeller Zahlen mit gigantischem Exponenten zum Ziel kommen zu wollen, ist ein Irrweg.
Torsten_Straeter Auf diesen Beitrag antworten »

Guten Morgen, es soll sich um Nr. 356 handeln. Wie es sich liest, ist eine Funktion gegeben, zu der die größte Nullstelle gesucht wird. Die bildet dann den reellen Wert der Basis und soll potenziert und die Potenz danach reduziert werden.
Torsten_Straeter Auf diesen Beitrag antworten »

Als Zusatz.... Ich hatte überlegt, ob man die Lösung über das Newton Raphson Verfahren annähern könnte, zum Beispiel in Python als Bruch, und dann bestmöglich zu berechnen. Die Zahlen dürften aber auch hier einiges groß werden. Auch finde ich fraglich, ob die Genauigkeit ausreicht.
 
 
HAL 9000 Auf diesen Beitrag antworten »

Auch wenn nun schon über vier Monate ins Land gegangen sind, und der Fragesteller sich wohl nicht wieder blicken lassen wird:

Ich hab mir dieses Problem 356 jetzt mal richtig angesehen, und es ist wie bei vielen anderen dieser Eulerprojekt-Probleme: Man muss erstmal einiges an Überlegung investieren, um mit diesen Vorabeiten am Ende dann doch auch noch einiges rechnen (ohne Computerunterstützung hoffnungslos).

Im vorliegenden Fall resultiert das am Ende in reinen Integerrechnungen, was meine obige Einschätzung

Zitat:
Original von HAL 9000
Ich denke, hier über Potenzen reeller Zahlen mit gigantischem Exponenten zum Ziel kommen zu wollen, ist ein Irrweg.

bestätigt.

Zitat:
Eulerprojekt Problem 356

Sei die größte reelle Nullstelle der kubischen Polynomfunktion .

Man bestimme die letzten 8 Dezimalstellen von .


Abschnitt 1) Sei zunächst fest gewählt.

Abschnitt 1.1) Wir diskutieren als erstes die Nullstellen von :

Im Fall haben wir mit den drei reellen Nullstellen . Für gilt







Unter Anwendung des Zwischenwertsatzes für sowie Einbeziehung des Spezialfalls gilt demnach für alle folgendes:

besitzt genau drei reelle Nullstellen, und zwar , sowie .

Darüber hinaus lässt sich noch feststellen, dass wegen Vieta die Ungleichung gefolgert werden kann, und damit .

Abschnitt 1.2) Befassen wir uns nun mit den Potenzen einer solchen Nullstelle :

Durch sukzessives Anwenden von kann man jede Potenz darstellen als Linearkombination (mit ganzzahligen Faktoren) von .

Das kann man formalisieren als Skalarprodukt mit . Start ist offenbar , und für die Iteration betrachtet man bei Wahl von Matrix .

Damit haben wir bzw. explizit .

Abschnitt 1.3) Es gilt also einzeln für , was in der Summe bedeutet.

Nun wissen wir aber laut Vieta sowie auch , beides zusammen bewirkt

.

Damit haben wir als Potenzsumme eine ganze (!) Zahl. Nun erinnern wir uns dran, dass die größte Nullstelle das aus der Problemstellung ist, außerdem gilt für ungerade Exponenten die Ungleichung , das bedeutet . Für bedeutet letzteres bei Anwendung der Gaußklammer schlussendlich

,

und ja, rechts steht ein Term, der durch reine Integerarithmetik ermittelt werden kann.


Abschnitt 2) Wir wollen nun für die letzten 8 Dezimalstellen der nunmehr so schreibbaren Summe



bestimmen. Dieses enthält exorbitant große ganze Zahlen, aber mit Modul (für die letzten 8 Dezimalstellen) kann man ja bei der Berechnung nutzen



und kann somit effizient in maximal Matrixmultiplikationsschritten der Dimension und mit ganzzahligen Einträgen in die Matrix berechnen - bei unserem sind übrigens exakt 47 solche Schritte. Damit ist die Berechnung von (*) modulo auf halbwegs aktuellen PC in Sekundenbruchteilen zu bewältigen, selbst mit einem Python-Programm (Interpreter).

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
import numpy as np

def matrix_power_mod(A, exponent, modul):
    B = np.identity(A.shape[0], dtype = A.dtype)
    while True:
        if exponent & 1:
            B = np.dot(B, A) % modul
        exponent //= 2
        if exponent == 0:
            break
        A = np.dot(A, A) % modul
    return B        

def root_power_floor(n, exponent, modul):
    pow2 = (1 << n) % modul
    A = np.array([[0,0,-n],[1,0,0],[0,1,pow2]], dtype = np.int64)
    Ae = matrix_power_mod(A, exponent, modul)
    pow4 = (pow2 * pow2) % modul
    return (3 * Ae[0][0] + pow2 * Ae[1][0] + pow4 * Ae[2][0] - 1) % modul
            
if __name__ == '__main__':
    modul = 10**8
    digits = sum(root_power_floor(n, 987654321, modul) for n in range(1, 31)) % modul
    print(digits)
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »