Schönhage-Strassen algoritmasında iç halka nasıl seçilir?


9

Schönhage – Strassen tamsayı çarpma algoritmasını uygulamaya çalışıyorum, ancak yinelemeli adımda bir tökezleyen bloğa çarptı.

Benim bir değerim var xile bit ve hesaplamak istiyorum . Başlangıçta fikir almaya olduğunu düşündüm k öyle ki 4 ^ k \ geq 2n , split x içine k ^ 2 ile her adet 2 ^ {k-1} bit modül çalışırken, SSA en konvolüsyonunu uygulamak 2 ^ {2 ^ k} +1 , değer başına 2 ^ k bit kapasiteli bir halka , daha sonra parçaları tekrar bir araya getirin. Bununla birlikte, evrişim çıkışı 2n bitten biraz daha fazladır (yani > 2 ^ knx2(mod2n+1)k4k2nx2k2k122k+12k2n>2kHer çıkış değerinin birkaç ürünün toplamı olması nedeniyle halkanın kapasitesinden daha fazla olan çıkış değeri başına bit sayısı), bu işe yaramaz. Ben 2 dolgu ekstra bir faktör eklemek zorunda kaldı.

Dolgudaki 2 ekstra faktör karmaşıklığı bozar. Yinelemeli adımımı çok pahalı yapıyor. Bunun yerine, bir F(n)=nlgn+nF(2n)=Θ(nlgnlglgn) algoritması, bir sona bir F(n)=nlgn+nF(4n)=Θ(nlg2n) algoritması ile.

Vikipedi ile bağlantılı birkaç referans okudum, ancak hepsi bu sorunun nasıl çözüldüğüne dair ayrıntılar üzerinde parlak görünüyor. Örneğin, 2 gücü olmayan bir p2p2k+1 için modulo 2 ^ {p 2 ^ k} + 1 çalıştırarak ekstra dolgu yükünü önleyebilirim ... ama sonra sadece güç olmayan- -2 faktör kaldı ve parça sayısını iki katına çıkarmadan Cooley-Tukey'i uygulayamaz. Ayrıca, p çarpımsal bir ters modülo 2 ^ p + l'e sahip olmayabilir . Yani hala zorla kabul edilen 2 faktör var.pp2p+1

Asimptotik karmaşıklığı üflemeden özyinelemeli adımda kullanılacak halkayı nasıl seçerim?

Veya sözde kod biçiminde:

multiply_in_ring(a, b, n):
  ...
  // vvv                          vvv //
  // vvv HOW DOES THIS PART WORK? vvv //
  // vvv                          vvv //
  let inner_ring = convolution_ring_for_values_of_size(n);
  // ^^^                          ^^^ //
  // ^^^ HOW DOES THIS PART WORK? ^^^ //
  // ^^^                          ^^^ //

  let input_bits_per_piece = ceil(n / inner_ring.order);
  let piecesA = a.splitIntoNPiecesOfSize(inner_ring.order, input_bits_per_piece);
  let piecesB = b.splitIntoNPiecesOfSize(inner_ring.order, input_bits_per_piece);

  let piecesC = inner_ring.negacyclic_convolution(piecesA, piecesB);
  ...

Lütfen aynı soruyu birden fazla sitede yayınlamayın . Her topluluğun, kimsenin vaktini boşa harcamadan dürüstçe cevap vermesi gerekir. İki kopyadan birini silmenizi öneririm.
DW

@DW Tamamlandı. Ben cs bir hafta boyunca herhangi bir cevap vermedi sonra çapraz posta, bu site için çok zor olduğunu düşündüm. Açıkça herhangi bir cevap geri bağlantı olacaktı.
Craig Gidney

Anlıyorum. Gelecekte ortaya çıkarsa, yayınınızı her zaman moderatörlerin dikkatini çekmek için işaretleyebilir ve taşınmasını isteyebilirsiniz ve sizin için CSTheory'ye taşıyabiliriz. Anlayışınız için teşekkür ederiz!
DW

3
Algoritmanın formunun modulo sayılarını çalıştıran bir sürümü var : A. Schönhage. Polinomların karmaşık katsayılarla sayısal çoğaltılması ve bölünmesi için asimptotik olarak hızlı algoritmalar. EUROCAM '82'de: Avrupa Bilgisayar Cebir Konferansı, Öğr. Notlar Comp. Sci. 144, 3-15. iai.uni-bonn.de/~schoe/publi39.dvi2ν2n
Markus Bläser

IIRC, şimdi silinmiş CS sorusu üzerinde kısmi bir kendi cevabınız vardı. Bunu kaybetmek utanç verici görünüyor. Buraya buraya ekleyebilir misiniz (soruda, sorunun zaten yanıtlanmış olarak işaretlenmemesi için)?
Peter Taylor

Yanıtlar:


4

Bu cevap, Markus'un yorumlarda bağladığı "Karmaşık katsayılara sahip polinomların sayısal muitipi ve bölünmesi için asimptotik olarak hızlı algoritmalar" makalesinden alınmıştır .


Bir bitlik sayının karesini almak istiyorsunuz , modulo . İşte yapmanız gerekenler:n2n+1

  • ve karşılayan ve bulun .psn=(p1)2ssp2s

  • biti bölmek için parça sayısını ve parça boyutları için karşılık gelen parametreleri seçin:2mn

    m=s/2+1s2=s/2+1p2=p/2+1

    ve değişmezini karşılamaya devam ettiğini unutmayın . Ayrıca , bu nedenle girişin olduğuna dikkat edin .s2p2s2p22s22m2s2p22n+m+1

  • Her zamanki gibi, parçalar ve geri kalanı üzerinde FFT tabanlı negasiklik konveksiyon gerçekleştirin.

İşte bu kapsayıcı fikir: logaritmik dolgu faktörü . Şimdi karmaşıklık analizi için. FFT alacak yapacak işi ve biz üzerinde konum recursing büyüklükte parçalara , şimdi biz nüks ilişki wrt ile son derece kaba matematik yapabilirsiniz :pnm2m(p21)2s2s

F(s)()(p-1)2sm+2mF(s/2+1)()2s2s(s/2+1)+2s/2+1F(s/2+1)()s22s+22s/2F(s/2+1)()s22s+4(s/2)22s+16(s/4)22s+...()2ss2lg(s)()nlgn(lgnlgn)2lglgnlgn()nlgn(lg2n)lglgn()n(lgn)lglgn

Bu adımlarda oldukça fazla aldatmış olmama rağmen, bu doğru görünüyor.

'Hile' , temel maliyette yerine ile sonuçlandığımız gibi görünüyor . Sorunda şikayetçi olduğum gibi, yinelemeli seviye başına iki çarpma hala iki çarpım var, ama şimdi yarıya bölünmesi çift ​​temettü ödüyor, bu yüzden her şey işe yarıyor. Sonra, sonunda biz ekstra faktör iptal (aslında bir faktör olan ) yapım sayesinde için logaritmik büyük göreli başlangıçta.s2sssgünlüknps

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.