Forum: HF, Funk und Felder Oszillator / Frequenz Quadrieren?


von Daniel C. (Gast)


Lesenswert?

Hallo ich habe eine Frage an euch.

Ich brauche eine Möglichkeit große Zahlen sehr schnell zu quadrieren. 
Die Implementierungen auf Computern mit Rechenoperationen dauern trotz 
guten Implementierungen auf Grafikprozessoren bei Werten um 
(10Millionen)^2 mehrere Mikrosekunden. Das ist für meine zwecke zu 
langsam, ich möchte gerne im Nano oder Picosekundenbereich arbeiten.

Ich brauche eine folgende Berechnung
p*p mod p
also das Moduloergebnis.

Meine Idee war es irgendwie mit Schwingungen / Oszillatoren zu 
berechnen.
Sogar wenn ich 10 Millionen quadriere wird das Ergebnis wegen der 
Modulooperation wieder im Bereich 10 Millionen (10 Megahertz) liegen.

Jetzt seid ihr gefragt:
Kann man irgendwie Frequenzen (bis 10 Mhz z.B.) einfach - vielleicht 
Anhand der harmonischen Oberwellen - modulo quadrieren?

Habt ihr eine Idee?

von Martin O. (ossi-2)


Lesenswert?

Das kann ich mir jetzt nicht verkneifen:

p*p mod p = 0

Wieviele (Dezimal-) Stellen sollen die Zahlen denn haben 9 oder 10^9

von Daniel C. (Gast)


Lesenswert?

Nun ja, streng genommen wäre es eine Berechnung wie

(k*k) mod p

mit k<p

8 Dezimalstellen reichen aus für p, also kann man annehmen p<99.999.999 
(fast 100 Millionen)

Danke für deine Hilfe,
Daniel

von Daniel C. (Gast)


Lesenswert?

Vielleicht kann man das ganze aber auch mit High-Speed Logikgattern (mit 
einer Scheitzeit von ca. 0,4 ns) realisieren. Hast du da eventuell 
erfahrung mit? (Wobei ich immernoch glaube dass der Oszillatoransatz 
schneller als 0,4 ns ist)

von Murkser (Gast)


Lesenswert?

Ich kann mir Deine "mehrere Mikrosekunden" noch nicht ganz erklären. Bei 
etwa 3GHz eines modernen Prozessors solltest Du eine 
Integer-Multiplikation und eine Integer-Division in weniger als 3000 
Takten hinkriegen, selbst bei Werten um 100 Mio. Wenn jetzt Dein "p" 
auch noch konstant ist, gibt es noch ein paar kleine 
Optimierungsmöglichkeiten.

Du solltest uns mal sagen/zeigen, was Du schon versucht hast, um zu 
sehen, warum Dein Ansatz so grottig lahm ist.

Murkser

von Helmut L. (helmi1)


Lesenswert?

Daniel C. schrieb:
> Meine Idee war es irgendwie mit Schwingungen / Oszillatoren zu
> berechnen.

Wie immer hier im Forum sagt doch mal was du vor hast dann kann man dir 
besser helfen.

von Daniel C. (Gast)


Lesenswert?

Also, ich möchte einen Lucas Lehmer Test möglichst schnell durchführen.

Die beste Implementierung rechnet für p ~ 40MIO auf einem 
Grafikprozessor rund 3 Tage, das liegt an der Quadratur und 
Modulooperation die selbst auf der Teuersten Floating Point Unit einfach 
zu lange braucht.

Der Lucas Lehmer Test ist wie folgt definiert:
Es sei folgende Reihe gegeben:
S(1) = 4, S(k+1) = S(k)^2–2.

Um zu testen ob 2^50000-1 eine Mersenne Primzahl ist, reicht es zu 
wissen ob
S(49999) mod 2^50000 = 0

Um allerdings S(49999) zu berechnen muss man 49999 Quadrate rechnen.

Diese Quadratur dauert sogar mit den besten FFT Operationen mehrere 
Mikro bis Millisekunden, was zur folge hat das der Lucas Lehmer Test für 
p ~ 40 MIO unendlich lange dauert.

Ich bin mir überzeugt dass man diesen Test schneller durchführen kann, 
wenn man nicht "Rechnet" sondern die Gesetze der Physik für sich 
arbeiten lässt :-)

von Murkser (Gast)


Lesenswert?

Primzahltests und damit explizit Integer-Arithmetik auf Floating-Point 
Operationen abzubilden scheint mir erstmal ein etwas "ungewöhnlicher 
Ansatz". Lucas-Lehmer auf GPUs haben schon andere vor Dir versucht. Lies 
mal folgendes Paper: Fast Mersenne Prime Testing on the GPU, Andrew 
Thall, GPGPU 2011

Murkser

von Murkser (Gast)


Lesenswert?

Korrigiere mich. Primzahltest mit FP Operationen ist doch nicht so 
ungewöhnlich!

Murkser

von Daniel C. (Gast)


Lesenswert?

Ich möchte eben keinen GPU einsatz, da GPUs für diese zwecke zu langsam 
sind.

Ich suche nach einem Ansatz die Gesetze der Physik zu nutzen 
(Schwingungen, Wellen, etc.)

Simples Beispiel:
10.000.000 * 3/2 zu berechnen dauert viel länger,
als die dritte harmonische Oberwelle von 10 MHZ durch einen 
Frequenzteiler zu jagen (diese Berechnung erfolgt nämlich in 
Lichtgeschwindigkeit)

von Alexander S. (esko) Benutzerseite


Lesenswert?

Daniel C. schrieb:
> Diese Quadratur dauert sogar mit den besten FFT Operationen mehrere
> Mikro bis Millisekunden, was zur folge hat das der Lucas Lehmer Test für
> p ~ 40 MIO unendlich lange dauert.

Angenommen das Quadrieren dauert 1 µs, dann braucht man für 40e6 
Operationen 40 s. In Wirklichkeit etwas länger, weil die anderen 
Operationen auch noch durchgeführt werden müssen. Die letzte entstandene 
Zahl sollte man sich merken, um das nächste Mal direkt dort starten zu 
können.
Edit: Du liegst falsch. Nicht p liegt bei 40 Mio, sondern dies ist die 
Zahl der Stellen in Binärschreibweise. Somit ist p = 2^40e6 = 
~6e12041199

> Ich suche nach einem Ansatz die Gesetze der Physik zu nutzen
> (Schwingungen, Wellen, etc.)

Der Ansatz ist interessant!

Allerdings für diese Anwendung unbrauchbar, weil sich der Zahlenbereich 
so stark ändert.
Man wird kaum eine physikalische Anordnung bauen können, die mit 50 kHz 
genauso gut funktioniert, wie mit 50 MHz.
Und wenn sie einmal benutzt wurde kann man sie hier auch "wegwerfen", 
wenn man sich die Ergebnisse gemerkt hat.

von Murkser (Gast)


Lesenswert?

Daniel C. schrieb:
> Simples Beispiel:
> 10.000.000 * 3/2 zu berechnen dauert viel länger,
> als die dritte harmonische Oberwelle von 10 MHZ durch einen
> Frequenzteiler zu jagen (diese Berechnung erfolgt nämlich in
> Lichtgeschwindigkeit)

Dein Beispiel hinkt. Hier multiplizierst Du mit einer Konstante und zur 
Genauigkeit schweigst Du Dich auch aus. Und Du vergißt, daß Du noch 
einen Frequenzzähler brauchst, um Dein Ergebnis abzulesen. Dieser 
braucht auch ein wenig Zeit dazu.

Bei der GPU verlangst Du Multiplikationen usw. über einen großen 
Wertebereich und exakte (Integer) oder doch einigermaßen exakte (FP) 
Ergebnisse.

Ich denke, daß Dein Ansatz mit der Abbildung der Operationen auf analoge 
HF-"Operationen" zwar interessant ist, aber vermutlich nicht 
weiterführt.

Schau Dir dennoch mal das Paper mit Lucas-Lehmer auf GPU an.

Murkser

von Plasmon (Gast)


Lesenswert?

Daniel C. schrieb:
> Kann man irgendwie Frequenzen (bis 10 Mhz z.B.) einfach - vielleicht
> Anhand der harmonischen Oberwellen - modulo quadrieren?

Oberwellen sind ganzzahlige Vielfache, keine Potenzen! Oberwellen 
entstehen zwar durch Potenzieren des Zeitsignals, damit erhältst du aber 
keine Potenzen der Frequenz.

Wenn du 10 MHz quadrierst bist du bei 100 THz. Das ist Infrarot.

Und dann ist noch das Problem zu lösen, wie du die Eingangsfrequenz 
einstellst und die Ausgangsfrequenz misst - jeweils auf 1 Hz (!) genau, 
und das in einer Zeit, die den Stand der Technik bei Prozessorarithmetik 
schlägt.

Ich sehe da kein Land.

von Plasmon (Gast)


Lesenswert?

Plasmon schrieb:
> Und dann ist noch das Problem zu lösen, wie du die Eingangsfrequenz
> einstellst und die Ausgangsfrequenz misst - jeweils auf 1 Hz (!) genau,
> und das in einer Zeit, die den Stand der Technik bei Prozessorarithmetik
> schlägt.

Da springt mir jetzt auch die grundsätzliche Begrenzung direkt ins Auge: 
Um eine Frequenz auf 1 Hz genau zu bestimmen, braucht man auch 1 s 
Messzeit. Da führt kein Weg daran vorbei. Eventuell kann man ein 
bisschen was holen, wenn man ein optimales Schätzverfahren und hohen 
Störabstand hat. Aber du wirst sicher nicht um Größenordungen von dieser 
Messzeit wegkommen.

von Joe (Gast)


Angehängte Dateien:

Lesenswert?

Lies mal den beiliegenden Text.

von Plasmon (Gast)


Lesenswert?

Plasmon schrieb:
> Wenn du 10 MHz quadrierst bist du bei 100 THz. Das ist Infrarot.

Der nächste Show-Stopper: Selbst wenn man diese Quadrierung realisieren 
würde, du würdest durch Frequenzmessung keine Integer-Genauigkeit 
kriegen, weil kein Oszillator der Welt eine hinreichende 
Frequenzstabilität hat. Selbst wenn der 10-MHz-Oszillator ein guter 
Quarz-Synthesizer ist, möchte ich nicht wissen, wie das daraus 
abgeleitete 100-THz-Signal jittert. Das ist ja ein Faktor 10^7 in der 
Frequenz und damit auch in der Phase. Das heißt, das Phasenrauschen des 
10-MHz-Oszillators erschiene bei 100 THz um 140 dB höher.

von Joe (Gast)


Lesenswert?

Erinnerungen aus meiner Jugend sagen, dass es Hardwaremultiplizierer mit 
Gattern gibt. So was hab ich dann auch mal mit SN74xxx und Erfolg 
gebaut.

Siehe:

http://de.wikipedia.org/w/index.php?title=Datei:4bit_multiplizierer.png&filetimestamp=20080316140412

von Murkser (Gast)


Lesenswert?

Joe schrieb:
> Erinnerungen aus meiner Jugend sagen, dass es Hardwaremultiplizierer mit
> Gattern gibt. So was hab ich dann auch mal mit SN74xxx und Erfolg
> gebaut.

Und Du glaubst, daß diese antiken Dinger schneller sind als die 
HW-Multiplizierer, die in aktuellen CPUs verbaut sind?

Murkser

von Johannes E. (cpt_nemo)


Lesenswert?

Daniel C. schrieb:
> 10.000.000 * 3/2 zu berechnen dauert viel länger,
> als die dritte harmonische Oberwelle von 10 MHZ durch einen
> Frequenzteiler zu jagen (diese Berechnung erfolgt nämlich in
> Lichtgeschwindigkeit)

Das ist ein relativ schlechtes Beispiel.

Du musst die 3. Oberwelle erst mal erzeugen, z.B. mit einem 
nichtlinearen Bauteil und einem Filter. Je nach Filterbandbreite dauert 
es eine gewisse Zeit, bis der Filter eingeschwungen ist; vorher liefert 
der Frequenzteiler kein richtiges Ergebnis.

Dann muss die Ausgangsfrequenz des Frequenzteilers gemessen werden. Hier 
gibt es einen Zusammenhang zwischen der Mess-Dauer und der 
Genauigkeit/Auflösung. Eine Periode bei 15 MHz dauert 66ns, so lange 
muss man mindestens messen. Für eine Auflösung von 10-7 (also eine 
Genauigkeit von 1 Hz bei 10 MHz) dauert so eine "Berechnung" vermutlich 
einige 100µs.

In einem FPGA kann man so etwas in wenigen ns berechnen, also wesentlich 
schneller als mit Oberwellen und Frequenzteiler.

von Hagen R. (hagen)


Lesenswert?

Daniel C. schrieb:
> Der Lucas Lehmer Test ist wie folgt definiert:
> Es sei folgende Reihe gegeben:
> S(1) = 4, S(k+1) = S(k)^2–2.
>
> Um zu testen ob 2^50000-1 eine Mersenne Primzahl ist, reicht es zu
> wissen ob
> S(49999) mod 2^50000 = 0
>
> Um allerdings S(49999) zu berechnen muss man 49999 Quadrate rechnen.

Das ist falsch. Der Lucas Lehmer Test, sprich dessen Algorithmus, 
benötigt Ln2(k) Iterationen und pro Iteration 1 Mul + 1 Sqr + 2 Add. 
Ln2(49999) = 16 ergibt 16 Multiplikationen + 16 Quadrierungen + 32 
Subtraktionen.
Da dein Modul mit 2^50000 eine Potenz zur Basis 2 ist können alle 
modularen Reduktionen (Divisonen) durch simple UND Verknüpfungen 
erfolgen. Eine gute Bibliothek kann das unterscheiden und so können 
Mersenne Primes sehr schnell verifiziert werden. Simple UND Verküpfung 
mit solch großen Zahlen sind einfach nur eine Truncation dieser zahlen 
im Speicherbereich. Also selbst das UND-Verküofen mit jedem Bit der 
Zahlen kann entfallen, sondern man verkürzt einfach den Speicherbereich 
der die Zahl speichert.

Gruß hagen

PS: hier mal meine Implementierung der verschiedenen Lucas Lehmer 
Varianten aus meinem DEC (Delphi Bibliothek zur Berechnung mit großen 
Zahlen). Ich weiß das dir das jetzt nicht 1 zu 1 weiterhelfen wird aber 
vielleicht kannst du ja Hinweise in die richtige Richtung raus ziehen.
1
resourcestring
2
  sNLucasMod = 'NLucasMod(), requiere K >= 0, Q <> 0, P <> 0 and M > 2 and odd M';
3
4
procedure NLucasMod(var V: IInteger; const K,P,M: IInteger);
5
// compute V_k(P, 1) mod M of a lucas sequence, normal and montgomery domain
6
var
7
  I: Integer;
8
  P1,V0,V1,T: IInteger;
9
  Inv2k: Cardinal;
10
begin
11
  I := NSgn(K, True);
12
  if (I < 0) or (NSgn(M, True) < 3){ or not NOdd(M)} then NRaise(@sNLucasMod);
13
  if I = 0 then NSet(V, 2) else
14
    if I = 1 then NMod(V, P, M) else
15
    begin
16
      Inv2k := NMont(M);
17
      NMont(T, NTwo, M, Inv2k);   // T = 2
18
      NMont(P1, P, M, Inv2K);     // P1 = P
19
      NSet(V0, P1);               // V0 = P
20
      BSqrMnt(V1, P1, M, Inv2k);  // V1 = P^2 - 2 mod M
21
      NSubMod(V1, T, M);
22
      for I := NSize(K) -2 downto 0 do
23
        if NBit(K, I) then
24
        begin
25
          BMulMnt(V0, V0, V1, M, Inv2k);  // V0 = (V0 * V1 - P) mod M
26
          NSubMod(V0, P1, M);
27
          BSqrMnt(V1, V1, M, Inv2k);      // V1 = (V1^2 - 2) mod M
28
          NSubMod(V1, T, M);
29
        end else
30
        begin
31
          BMulMnt(V1, V1, V0, M, Inv2k);  // V1 = (V1 * V0 - P) mod M
32
          NSubMod(V1, P1, M);
33
          BSqrMnt(V0, V0, M, Inv2k);      // (V0 = V0^2 - 2) mod M
34
          NSubMod(V0, T, M);
35
        end;
36
      NRedc(V0, M, Inv2k);       // V = V0
37
      NSwp(V0, V);
38
    end;
39
end;
40
41
procedure NLucasMod(var V: IInteger; const K,P,Q,M: IInteger);
42
// compute V_k(P, Q) mod M of a lucas sequence
43
var
44
  P1,Q1,V0,V1,U0,T: IInteger;
45
  I: Integer;
46
  Inv2k: Cardinal;
47
begin
48
  I := NSgn(K, True);
49
  if (I < 0) or (NSgn(M, True) < 3) {or not NOdd(M)} then NRaise(@sNLucasMod);
50
  if I = 0 then NSet(V, 2) else
51
    if I = 1 then NMod(V, P, M) else
52
    begin
53
      NMod(Q1, Q, M);
54
      if NSgn(Q1, True) = 1 then NLucasMod(V, K, P, M) else
55
      begin
56
        Inv2k := NMont(M);
57
        NMont(Q1, M, Inv2k);    // Q1 = Q mod M
58
        NMont(P1, P, M, Inv2k); // P1 = P mod M
59
        NSet(V0, P1);
60
        NSet(U0, Q1);
61
        NAddMod(T, Q1, Q1, M);      // T = 2Q mod M
62
        BSqrMnt(V1, P1, M, Inv2k);  // V1 = (P^2 - 2Q) mod M
63
        NSubMod(V1, T,  M);
64
        for I := NSize(K) -2 downto 1 do
65
        begin
66
          BMulMnt(T, U0, P1, M, Inv2k);
67
          if NBit(K, I) then
68
          begin
69
            BMulMnt(V0, V0, V1, M, Inv2k);
70
            NSubMod(V0, T, M);
71
            BSqrMnt(V1, V1, M, Inv2k);
72
            BMulMnt(T, U0, Q1, M, Inv2k);
73
            NAddMod(T, T, M);
74
            NSubMod(V1, T, M);
75
            BSqrMnt(U0, U0, M, Inv2k);
76
            BMulMnt(U0, U0, Q1, M, Inv2k);
77
          end else
78
          begin
79
            BMulMnt(V1, V1, V0, M, Inv2k);
80
            NSubMod(V1, T, M);
81
            BSqrMnt(V0, V0, M, Inv2k);
82
            NSubMod(V0, U0, M);
83
            NSubMod(V0, U0, M);
84
            BSqrMnt(U0, U0, M, Inv2k);
85
          end;
86
        end;
87
        if NOdd(K) then
88
        begin
89
          BMulMnt(V0, V0, V1, M, Inv2k);
90
          BMulMnt(U0, U0, P1, M, Inv2k);
91
        end else
92
        begin
93
          BSqrMnt(V0, V0, M, Inv2k);
94
          NAddMod(U0, U0, M);
95
        end;
96
        NSubMod(V, V0, U0, M);
97
        NRedc(V, M, Inv2k);
98
      end;
99
    end;
100
end;
101
102
procedure NLucasMod(var U,V: IInteger; const K,P,Q,M: IInteger);
103
// compute V_k(P, Q) mod M, U_k(P, Q) mod M of a lucas sequence
104
var
105
  P1,U0,V0,V1,T: IInteger;
106
  I: Integer;
107
  Inv2k: Cardinal;
108
begin
109
  I := NSgn(K, True);
110
  if (I < 0) or (NSgn(M, True) < 3) or not NOdd(M) then NRaise(@sNLucasMod);
111
  if I = 0 then
112
  begin
113
    NSet(U, 0);
114
    NSet(V, 2);
115
  end else
116
    if I = 1 then
117
    begin
118
      NSet(U, 1);
119
      NMod(V, P, M);
120
    end else
121
    begin
122
      Inv2k := NMont(M);
123
      NMont(P1, P, M, Inv2k);
124
      NShl(T, Q, 2);
125
      NMont(T, M, Inv2k);
126
      NMont(U0, NOne, M, Inv2k);
127
      NSet(V0, P1);
128
      BSqrMnt(V1, P1, M, Inv2k);
129
      NSubMod(V1, T, M);
130
      for I := NSize(K) -2 downto 0 do
131
      begin
132
        BSqrMnt(T, U0, M, Inv2k);
133
        BMulMnt(T, T, V1, M, Inv2k);
134
        BMulMnt(U0, V0, U0, M, Inv2k);
135
        BSqrMnt(V0, V0, M, Inv2k);
136
        NAddMod(V0, T, M);
137
        if NOdd(V0) then NAdd(V0, M);    // V0 = V0 div 2
138
        NShr(V0, 1);
139
        if NBit(K, I) then
140
        begin
141
          BMulMnt(T, U0, V1, M, Inv2k);
142
          BMulMnt(U0, U0, P1, M, Inv2k);
143
          NAddMod(U0, V0, M);
144
          if NOdd(U0) then NAdd(U0, M);
145
          NShr(U0, 1);
146
          BMulMnt(V0, V0, P1, M, Inv2k);
147
          NAddMod(V0, T, M);
148
          if NOdd(V0) then NAdd(V0, M);
149
          NShr(V0, 1);
150
        end;
151
      end;
152
      NRedc(V0, M, Inv2k);
153
      NSwp(V0, V);
154
      NRedc(U0, M, Inv2k);
155
      NSwp(U0, U);
156
    end;
157
end;
158
159
function NInvLucasMod(var A: IInteger; const K,N,P,Q: IInteger): Boolean;
160
// see below
161
var
162
  U: IInteger;
163
begin
164
  Result := NInvMod(U, P, Q);
165
  if Result then NInvLucasMod(A, K, N, P, Q, U);
166
end;
167
168
function NInvLucasMod(var A: IInteger; const K,N,P,Q,U: IInteger): Boolean;
169
// calculate the inverse of a lucas sequence of V_k(N, 1) mod (P * Q)
170
// U = P^-1 mod Q are precomputed
171
// returns success
172
var
173
  N1,P1,Q1: IInteger;
174
begin
175
  NSqr(N1, N);                    // N1 = N^2 -4
176
  NDec(N1, 4);
177
  NSet(P1, P);                    // P1 = P - Jac(N^2 -4, P)
178
  NSub(P1, NJacobi(N1, P));
179
  NSet(Q1, Q);                    // Q1 = Q - Jac(N^2 -4, Q)
180
  NSub(Q1, NJacobi(N1, Q));
181
  Result := NInvMod(P1, K, P1);   // P1 = V[K^-1 mod (P - Jac(N^2 -4, P))](N, 1) mod P
182
  if Result then
183
  begin
184
    NLucasMod(P1, P1, N, P);
185
    Result := NInvMod(Q1, K, Q1); // Q1 = V[K^-1 mod (Q - Jac(N^2 -4, Q))](N, 1) mod Q
186
    if Result then
187
    begin
188
      NLucasMod(Q1, Q1, N, Q);
189
      Result := NCRT(A, NInt([P1, Q1]), NInt([P, Q]), NInt([U]));
190
    end;
191
  end;
192
end;

von Hagen R. (hagen)


Lesenswert?

Fazit: du versucht mit eckigen Rädern und dafür mit enormen Power eine 
so hohe Geschwindigkeit zu erreichen wie derjenige der cleverer Weise 
mit runden Rändern fährt.

von Hagen R. (hagen)


Lesenswert?

Hagen Re schrieb:
> Also selbst das UND-Verküofen mit jedem Bit der
> Zahlen kann entfallen, sondern man verkürzt einfach den Speicherbereich
> der die Zahl speichert.

Hm, im Beispiel von 2^50000+1 ist es also so das man nur an den 50000 
niederwertigsten Bits interessiert ist. Die größten Zahlen in den 
Zwischenergebnissen sind also 100000 Bits groß und nur die unterere 
Hälfte muß real berechnet werden am Ende. Bei jedem Rechenschritt der 
ein Ergenis > 2^50000 ergibt müssen nur die obersten Bits abgeschnitten 
werden.

Aber das kann man mit einer speziellen internen Zahlendarstellung noch 
viel weitergehend optimieren. Das geht soweit das man überhaupt nicht 
mher mit super großen Zahlen rechnen muß sondern man rechnet maximal mit 
32-64Bit großen Integern.

Gruß Hagen

PS: du bist hier im falschen Forum, ein mathematik Forum wäre 
geeigneter.

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.