23 stycznia 2020

Faktoryzacja z podstawy systemu, przygotowanie do implementacji

Przejrzałem wręcz, co się dzieje, gdy najpierw szukamy postaci kanonicznej podstawy systemu, a z jego pomocą rozkładu liczby.

Założenia:
- pamiętać jak najmniej; wymagana jest jednak znajomość wszystkich liczb pierwszych mniejszych niż pierwiastek czwartego stopnia z liczby rozkładanej n. Wystarczy zapamiętać parę, na którą składają się dzielnik i jego odpowiednia wielokrotność;
- każda liczba pierwsza jest testowana dokładnie raz.

Drugi z warunków w pierwszej wersji sugerował zapamiętanie dodatkowych przedziałów, ale bliższe obserwacje wskazały, że nie są one potrzebne. Są niezbędne z kolei, kiedy chcemy sprawdzić dzielnik jak nakszybciej, zaraz przy jego pierwszym pojawieniu się, nie czekając na odpowiednią wartość.
Jeśli poczekamy, liczby pierwsze będą się spokojnie ujawniać wielokrotnie, a będziemy badać tylko występujące przy potęgach dwójki. 

Znowu mamy dwa kierunki przeglądu zupełnego. Od pierwiastka kwadratowego z liczby rozkładanej n do połowy tej liczby, lub na odwrót.
Przy pierwiastku kwadratowym niezmiennik 
n = (a+b)*a + c
ma wartości a=sqrt n; b równe 0, 1 albo 2; c jest na moduł ograniczane przez a. Zmiana a o 1 powoduje w tym zakresie zmianę b o 2,
np. 8934053 = (2988+2)*2988-67.
Przy połowie pierwiastka kwadratowego c dalej jest ograniczone na moduł przez a, a = 1/2 sqrt n, zaś b jest bliskie 3/2 sqrt n. Zmianie a o 1 tutaj towarzyszy zmiana b o 4:
np. 8934053 = (1494+4486)*1494-67.
Modyfikacje są na tyle małe, że robimy mały błąd nadając zazwyczaj a~3*b dla szacunku c jak najbliższego zeru. Potem korekta postaci: b+1 oznacza c-a.   

Pierwiastek czwartego stopnia z 8934053 to 54. Czyli do rozkładu potrzebujemy zapamiętywać wielokrotności następujących liczb pierwszych: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 37, 41, 43, 47, 53. Warto mieć je posortowane po wartościach, wystarczy jedna wartość na jedną liczbę pierwszą jak najbliżej pobieranej do testu.  
Zaczynając od pierwiastka kwadratowego, zapisujemy (2988; 2), (2988; 3), co można złączyć w (2988; 2, 3); (2985; 5), (2982; 7), itd.
Wbrew początkowym oczekiwaniom, nie musimy znać rozkładu kanonicznego, nawet tej jego części korzystajacej z wymienionych liczb pierwszych. Wystarczy nam liczba oraz jej dzielniki.

Algorytm:
1. k = 1+sqrt n ;
2. pętla, bierzemy wartość o 1 mniejszą (k--);
3. jeśli liczba nie jest zapamiętana, sprawdzamy ją pod kątem pierwszości
jeśli liczba jest zapamiętana, sprawdzamy, czy ma dzielnik większy od 2, jeśli nie, sprawdzamy liczbę pod kątem pierwszości;
4. liczba złożona (k, p) wskazuje, że liczba (k-p, p) też jest złożona, zapamiętujemy ją (dla każdej czynnika pierwszego p), przy czym, jeśli dana wartość k-p już jest zapamiętana, tylko dopisujemy doń kolejny dzielnik;
5. jeśli k<1/2 sqrt n, liczba jest pierwsza; w przeciwnym przypadku wracamy do 2;

Sprawdzenie pod kątem pierwszości, trafiają tu liczby pierwsze oraz postaci k=2^i*p, gdzie p jest pierwsza.
Obliczamy wartość c niezmiennika n=(k+b)*k+c, oraz sprawdzamy |c|%p. Podzielność oznacza znalezienie dzielnika p|n (bo p|k). Dla większości wartości sprowadza się do porównania takiego jak 157<881. Rzadko kiedy trzeba dzielić modulo. Oczywiście wtedy należy zakończyć algorytm.

Dlaczego to działa.
Potęgi dwójki dzielą nam przedział (1, sqrt n)  na rozłączne przedziały
(2^{-i}*n, 2^{1-i}*n);
każda liczba pierwsza trafia do dokładnie jednego z nich.

Jeśli dopuścimy inne liczby pierwsze lub rozkład kanoniczny, zakresy przedziałów będą często miały części wspólne. Owszem, początkowo szybko będziemy sprawdzać i eliminować liczby pierwsze, korzystając z dzieleń. Choć wtedy część liczb będzie sprawdzanych wielokrotnie, o ile ich nie zapamiętamy. I tak musimy przejrzeć cały przedział. W dotatku mamy nadmiarowe dzielenia przy szukaniu liczb pierwszych większych niż zapamiętane, gdyż nie znamy wykladników potęg tych liczb pierwszych w rozkładach.

Brak komentarzy: