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)k4k≥2nx2k2k−122k+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)=nlg⁡n+nF(2n)=Θ(nlg⁡nlg⁡lg⁡n) algoritması, bir sona bir F(n)=nlg⁡n+nF(4n)=Θ(nlg2⁡n) 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=(p−1)2ss≤p≤2s

  • 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 .s2p2s2≤p2≤2s22m2s2p2≥2n+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(p2−1)2s2s

F(s)(≤)(p-1)2sm+2mF(⌈s/2⌉+1)(≤)2s2s(⌊s/2⌋+1)+2⌊s/2⌋+1F(⌈s/2⌉+1)(≤)s22s+2⋅2s/2F(s/2+1)(≤)s22s+4(s/2)22s+16(s/4)22s+...(≤)2ss2lg⁡(s)(≤)nlg⁡n(lg⁡nlg⁡n)2lg⁡lg⁡nlg⁡n(≤)nlg⁡n(lg2⁡n)lg⁡lg⁡n(≤)n(lg⁡n)lg⁡lg⁡n

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ük⁡nps

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.