วงแหวนด้านในถูกเลือกในอัลกอริทึมSchönhage – Strassen อย่างไร


9

ฉันพยายามที่จะใช้อัลกอริทึมการคูณจำนวนเต็มของSchönhage - Strassen แต่กด stumbling block ในขั้นตอนวนซ้ำ

ฉันมีค่าด้วยบิตและฉันต้องการที่จะคำนวณ1} ฉันคิดว่าแนวคิดดั้งเดิมคือการเลือกที่แยกเป็นชิ้นแต่ละชิ้นด้วยบิตใช้การโน้มน้าวใจของ SSA ขณะทำงานโมดูโล , แหวนที่มีความจุบิตต่อค่าจากนั้นนำชิ้นส่วนกลับมารวมกัน อย่างไรก็ตามเอาต์พุตของการบิดมีมากกว่าบิตเล็กน้อย(เช่นxnx2(พอควร2n+1)k4k2nx2k2k-122k+12k2n>2kบิตต่อค่าเอาต์พุตซึ่งมากกว่าความจุของวงแหวนเนื่องจากแต่ละค่าเอาต์พุตเป็นผลรวมของผลิตภัณฑ์หลายตัว) จึงไม่ทำงาน ฉันต้องเพิ่มปัจจัยพิเศษอีก 2 อย่างของการเติมเต็ม

นั่นคือปัจจัยพิเศษของ 2 ในการทำลายที่ซับซ้อน มันทำให้ขั้นตอนแบบเรียกซ้ำของฉันแพงเกินไป แทนที่จะเป็นอัลกอริทึมฉันท้าย ด้วยF (n) = n \ lg n + \ sqrt {n} F (4 \ sqrt {n}) = \ Theta (n \ lg ^ 2 n)อัลกอริทึมF(n)=nLGn+nF(2n)=Θ(nLGnLGLGn)F(n)=nLGn+nF(4n)=Θ(nLG2n)

ฉันได้อ่านเอกสารอ้างอิงสองสามฉบับที่เชื่อมโยงจากวิกิพีเดีย แต่พวกเขาดูเหมือนจะล้วงลึกถึงรายละเอียดว่าปัญหานี้ได้รับการแก้ไขอย่างไร ตัวอย่างเช่นฉันสามารถหลีกเลี่ยงค่าใช้จ่ายในการเสริมกำลังพิเศษได้ด้วยการทำงาน modulo 2พี2k+1สำหรับpที่ไม่ใช่พลังของ 2 ... แต่จากนั้นสิ่งต่าง ๆ ก็พังทลายในภายหลังเมื่อฉันไม่มีพลัง - เหลือเพียงปัจจัย 2 และไม่สามารถใช้ Cooley-Tukey ได้โดยไม่ต้องเพิ่มจำนวนสองเท่า นอกจากนี้pไม่อาจมีผกผันแบบโมดูโล2p+1 1 ดังนั้นยังคงมีปัจจัยบังคับจากการแนะนำ 2 อย่าง

ฉันจะเลือกแหวนที่จะใช้ในระหว่างขั้นตอนแบบเรียกซ้ำโดยไม่ทำให้เกิดความซับซ้อนเชิงซีมโทติคได้อย่างไร?

หรือในรูปแบบโค้ดหลอก:

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);
  ...

กรุณาอย่าโพสต์คำถามเดียวกันบนเว็บไซต์ต่างๆ แต่ละชุมชนควรมีความจริงใจในการตอบคำถามโดยไม่เสียเวลาไปกับใคร ฉันแนะนำให้คุณลบหนึ่งในสองชุด
DW

@DW เรียบร้อยแล้ว ฉันโพสต์ข้ามหลังจาก cs ​​ไม่ได้ให้คำตอบใด ๆ เป็นเวลาหนึ่งสัปดาห์โดยคิดว่ามันยากเกินไปสำหรับไซต์นั้น จะเชื่อมโยงคำตอบกลับอย่างชัดเจน
Craig Gidney

ฉันเข้าใจ. หากเกิดขึ้นในอนาคตคุณสามารถตั้งค่าสถานะโพสต์ของคุณเพื่อขอความสนใจจากผู้ดูแลและขอให้ย้ายข้อมูลและเราสามารถย้ายไปที่ CSTheory ได้ ขอขอบคุณสำหรับความเข้าใจของคุณ!
DW

3
มีรุ่นของอัลกอริทึมที่ใช้งานหมายเลขโมดูโลในรูปแบบ : A. Schönhage อัลกอริธึมที่รวดเร็วแบบไม่เชิงเส้นสำหรับการคูณเชิงตัวเลขและการหารของพหุนามด้วยค่าสัมประสิทธิ์ที่ซับซ้อน ใน EUROCAM '82: การประชุมพีชคณิตคอมพิวเตอร์ยุโรป, การบรรยาย หมายเหตุประกอบ วิทย์ 144, 3-15 iai.uni-bonn.de/~schoe/publi39.dvi2ν2n
Markus Bläser

IIRC คุณได้รับคำตอบบางส่วนจากคำถาม CS ที่ถูกลบตอนนี้ ดูเหมือนว่าน่าละอายที่จะสูญเสียสิ่งนั้น คุณสามารถรวมไว้ที่นี่ (ในคำถามเพื่อไม่ให้มีการทำเครื่องหมายคำถามว่าตอบแล้ว)
Peter Taylor

คำตอบ:


4

คำตอบนี้นำมาจากบทความเรื่อง"Asymptotically fast algorithm สำหรับการคำนวณเชิงตัวเลขและการหารของ polynomials ด้วยสัมประสิทธิ์ที่ซับซ้อน"ซึ่ง Markus เชื่อมโยงในความคิดเห็น


คุณต้องการที่จะตารางจำนวนบิต, โมดูโล1 นี่คือสิ่งที่คุณทำ:n2n+1

  • ค้นหาและที่ตอบสนองและ2spsn=(p1)2ssp2s

  • เลือกจำนวนชิ้นเพื่อแบ่งบิตเป็นและพารามิเตอร์ที่เกี่ยวข้องสำหรับขนาดชิ้น:2mn

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

    โปรดทราบว่าและยังคงตอบสนองความคงที่ โปรดทราบว่ามีความพึงพอใจดังนั้นอินพุตจึงเหมาะกับห้องสำหรับพกพาs2p2s2p22s22m2s2p22n+m+1

  • ดำเนินการ convolutions negacyclic-based FFT บนชิ้นส่วนและส่วนที่เหลือตามปกติ

เพื่อให้เป็นความคิดที่ครอบคลุมกลอการิทึม padding ปัจจัยPตอนนี้สำหรับการวิเคราะห์ความซับซ้อน FFT จะใช้งานที่ต้องทำและเรา recursing อยู่บนชิ้นส่วนของขนาดดังนั้นตอนนี้เราสามารถทำคณิตศาสตร์หยาบมากกับการกลับมาอีกความสัมพันธ์ WRT :pnm2m(p21)2s2s

F(s)()(p1)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

ซึ่งดูเหมือนว่าถูกต้องถึงแม้ว่าฉันจะโกงในขั้นตอนเหล่านั้นมากทีเดียว

'หลอกลวง' ดูเหมือนจะเป็นความจริงที่ว่าเราลงท้ายด้วยแทนที่จะในราคาฐาน ยังคงมีสองคูณสองต่อระดับ recursive เหมือนฉันถูกบ่นเกี่ยวกับในคำถาม แต่ตอนนี้ลดลงครึ่งหนึ่งของจะจ่ายเงินปันผลสองครั้งเพื่อให้มันทั้งหมดออกไปทำงาน จากนั้นในตอนท้ายเรายกเลิกปัจจัยพิเศษของ (ซึ่งอันที่จริงแล้วเป็นปัจจัย ) ขอบคุณที่ทำให้มีขนาดใหญ่เมื่อเทียบกับในเบื้องต้นลอการิทึมs2ssslognps

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.