Rychlé násobení
je násobení se složitostí menší než násobení klasické. Snaha o zrychlení algoritmů se zesiluje ruku v ruce s rozvojem počítačů a speciálně snaha o maximální zrychlení násobení je dána potřebami kryptografie, kde je nutné násobit v přijatelném čase ohromná čísla (řádově 10
100).
My popíšeme dvě rychlá násobení -
Karacubovo násobení a
Schönhageovo násobení v modulární aritmetice - založená na důvtipných myšlenkách a poměrně jednoduše popsatelná. Mezi rychlými algoritmy patří k těm nejstarším, ovšem algoritmy ještě rychlejší už jsou příliš technické.
Zájemce o násobení přirozených čísel s binárním rozvojem délky n blížící se svou složitostí libovolně blízko až k nejnižší hranici O(n) si dohledá podrobnosti v D. E. Knuth,
The Art of Computer Programming volume 2: Seminumerical Algorithms, 3rd ed, Addison-Wesley Boston etc., 1998.
Poznamenejme, že jde o jednu z nejrespektovanějších publikací v oboru programování. Donald E. Knuth (na obrázku) je průkopníkem oboru matematické algoritmické analýzy a významnou osobností v mnoha dalších oborech teoretické počítačové vědy.
Karacubovo násobení
Karacubovo násobení vyvrátilo domněnku, že složitost násobení dvou přirozených čísel s binárním rozvojem délky n je O(n
2). Tento názor razil ještě v roce 1960 na semináři moskevské univerzity zakladatel teorie složitosti algoritmů Andrej N. Kolmogorov (na obrázku).
Semináře se účastnil jeho student Anatolij A. Karacuba, který navrhl a o dva roky později publikoval důvtipný algoritmus s nižší složitostí. Popíšeme algoritmus, který je založen na stejné myšlence jako původní Karacubův, ale je ještě trochu jednodušší.
Chceme násobit dvě 2n-bitová čísla
U s binárním zápisem u
2n-1...u
1u
0 a V s binárním zápisem v
2n-1...v
1v
0.
- Zapíšeme U, V následujícím způsobem U = 2nU1 + U0 a V = 2nV1 + V0. Platí tedy, že
U1 má binární zápis u2n-1...un a U0 má zápis un-1...u1u0, podobně V1 má binární zápis v2n-1...vn a V0 má zápis vn-1...v1v0.
- Následující formule redukuje problém na 3 násobení n-bitových čísel, několik sčítání, resp. odečítání a posouvání binární čárky:
U×V = (22n+2n)U1V1+2n(U1-U0)(V0-V1)+(2n+1)U0V0.
Ilustrujme Karacubův algoritmus pro U × V, kde U=210 a V=119. Binární zápis U je 11010010 a binární zápis V je 01110111.
Není těžké dokázat, že složitost Karacubova násobení je O(n
log23). Platí log
23 je přibližně 1,585, což je číslo menší než 2, a tedy jde skutečně o rychlé násobení podle naší definice.
Adaptací na desítkovou soustavu lze převést násobení 8-místných čísel na násobení čísel 4-místných, které už dobří počtáři zvládnou zpaměti. Kupodivu se nezdá, že by taková metoda byla známa před rokem 1962 a že by ji tedy používali "zázrační počtáři", kteří v minulosti bavili obecenstvo násobením obrovských čísel zpaměti.
Schönhageovo násobení v modulární aritmetice
Schönhageovo násobení v modulární aritmetice sice není rychlejší než Karacubův algoritmus, ale je založeno na odlišných myšlenkách a na neobvyklé reprezentaci čísel, takže je rozhodně zajímavé do jeho tajů proniknout.
Jeho základním stavebním kamenem je modulární aritmetika, u jejíhož zrodu stáli čeští vědci Antonín Svoboda (tvůrce prvního československého počítače SAPO a velmi významný průkopník informatiky nejen u nás - o jeho klikatých osudech se dočtete v článku Petra Vysokého
100 let od narození Antonína Svobody a jeho podobu vidíte na obrázku) a Miroslav Valach. Nezávisle na nich přišel se stejnou myšlenkou také L. H. Garner.
Modulární zápis
Dosud jsme se seznámili jen se zápisy přirozených čísel v pozičních
soustavách s přirozenou bází (případně jsme připustili záporné cifry).
Nyní přijde naprosto odlišný zápis přirozených čísel.
Nechť jsou dána přirozená čísla m
1, m
2, ..., m
r. Pak modulárním zápisem nezáporného celého čísla U nazveme (u
1,u
2,...,u
r,),
kde u
i je rovno U mod m
i pro každé i od 1 do r.
Připomeňme, že mod k znamená zbytek po celočíselném dělení číslem k a nabývá hodnot od 0 do k-1. (Například 13=3.4+1, a tedy 13 mod 4=1.)
Ukažme si na příkladu takovou modulární reprezentaci.
Aby takový zápis měl smysl, mělo by být možné původní číslo ze znalosti modulární reprezentace zrekonstruovat. To bez dodatečných podmínek možné není. Všimněme si, že čísla 56 a 26 mají stejný modulární zápis (0,2,1).
Naštěstí platí následující tvrzení, které je důsledkem známé
Čínské zbytkové věty:
Nechť a,u
1,u
2,...,u
r jsou nezáporná celá čísla a nechť m
1, m
2, ..., m
r jsou přirozená po dvou nesoudělná čísla. Pak existuje právě jedno U, které splňuje
- a - 1 < U < a + m = a + m1. m2. ... . mr,
- (u1,u2,,...,ur) je modulární reprezentace U.
Z této věty plyne, že když se omezíme na čísla od 0 do 2.3.5 = 30, pak mezi nimi právě jen číslo 26 má modulární reprezentaci (0,2,1).
Modulární aritmetika
V modulární aritmetice je možné paralelizovat sčítání a násobení.
Platí totiž, že pokud U a V jsou přirozená čísla s modulárními reprezentacemi
(u
1,u
2,...,u
r) a (v
1,v
2,...,v
r) a obě leží mezi 0 a m = m
1. m
2. ... . m
r,
pak
- U + V má modulární reprezentaci ((u1+v1) mod m1, (u2+v2) mod m2,...,(ur+vr) mod mr),
- U x V má modulární reprezentaci ((u1.v1) mod m1, (u2.v2) mod m2,...,(ur.vr) mod mr).
Nevýhodou je, že při pohledu na modulární reprezentace nepoznáme, které z čísel je větší. Navíc nepoznáme, zda výsledek operace nevypadl z intervalu 0 až m. Proto potřebujeme rychlou konverzi, která číslům přiřazuje modulární zápis a zejména z modulárního zápisu rychle vyrábí zpět reprezentovaná čísla.
Binární modulární aritmetika
Jak uvidíme, takovou rychlou konverzi poskytuje vhodná volba modulí m
1, m
2, ..., m
r. Následující nápad se zrodil v hlavě A. S. Fraenkela.
Volme modula m
i= 2
ei -1, kde e
1 < e
2 < ... < e
r jsou po dvou nesoudělná. Nesoudělnost takových modulí je zaručena následující větou:
Nechť e, f jsou přirozená čísla. Pak 2
e -1 a 2
f -1 jsou nesoudělná, právě když e a f jsou nesoudělná
Konverze U na (u1,u2,...,ur)
Zapišme U ve tvaru U = a
tA
t + a
t-1A
t-1 + ... +a
1A + a
0, kde A = 2
ei.
Uvědomme si, že binární zápis a
0 získáme tak, že vezmeme posledních e
i bitů v binárním zápisu U, pro získání a
1 vezmeme předposledních e
i bitů atd. Vlastně jen nasekáme binární zápis U od konce po e
i bitech. Protože A = 1 mod (2
ei-1), dostaneme u
i = (a
t + a
t-1 + ... + a
0) mod (2
ei-1).
V desítkové soustavě máme analogii (tzv. casting out nines - vyloučení devítek)
789 mod 9 = 7 + 8 + 9 mod 9 = 6, což skutečně platí, protože 789 = 87.9 + 6.
Ilustrujme tento algoritmus opět na příkladu.
Konverze (u1,u2,...,ur) na U
Je o něco složitější. Probíhá ve dvou krocích:
- Nejprve je třeba najít r(r-1)/2 konstant cij, indexy i,j nabývají hodnot od 1 do r, i < j a platí
cijmi=1 mod mj.
K tomu využijeme následující algoritmus.
- Poté položíme U = vr mr-1...m2m1 +...+ v3 m2m1 + v2 m1 + v1, kde
v1 = u1 mod m1
v2 = (u2-v1)c12 mod m2
v3 = ((u3-v1)c13-v2)c23 mod m3
...
vr = (((ur-v1)c1r-v2)c2r-...)cr-1r mod mr
Snadno se přesvědčíme, že takto spočtené U splňuje
- U je nezáporné číslo menší než m,
- U mod mi = ui pro každé i od 1 do r.
Ilustrujme i tento algoritmus na příkladu.
Schönhageovo násobení
Nyní máme vše připraveno k tomu, abychom pochopili fungování algoritmu, který Arnold Schönhage v roce 1966 navrhl.
Nejprve si všimněme, jak šikovně volí 6 modulí, která budou v jeho algoritmu vystupovat.
Pro posloupnost q
0=1 a q
k=3q
k-1-1,
tj. q
k=(3
k+1)/2 pro každé k přirozené, jsou modula po dvou nesoudělná.
Navíc platí, že při násobení p
k=(18q
k+8)-bitových čísel nedojde k přetečení,
tj. zůstaneme mezi 0 a m=m
1. m
2. ... . m
6,
protože m je větší než 2
2pk.
Teď již samotný
Schönhageův algoritmus. Chceme násobit přirozená čísla U a V, označme W = U x V. Najdeme nejmenší p
k
tak, že násobená čísla jsou nejvýše p
k-bitová. K p
k najdeme příslušná modula.
Tento algoritmus převádí úlohu násobit p
k-bitová čísla na násobení p
k-1-bitových čísel.
To je podobná myšlenka jako v Karacubově násobení vedoucí ke snížení složitosti.
Tentokrát je možné - i když pracné - dokázat, že složitost Schönhageova násobení je O(n
log36).
Platí log
36 je přibližně 1,63, což je číslo menší než 2, a tedy jde opět o rychlé násobení podle naší definice.