ฉันพยายามที่จะใช้อัลกอริทึมการคูณจำนวนเต็มของSchönhage - Strassen แต่กด stumbling block ในขั้นตอนวนซ้ำ
ฉันมีค่าด้วยบิตและฉันต้องการที่จะคำนวณ1} ฉันคิดว่าแนวคิดดั้งเดิมคือการเลือกที่แยกเป็นชิ้นแต่ละชิ้นด้วยบิตใช้การโน้มน้าวใจของ SSA ขณะทำงานโมดูโล , แหวนที่มีความจุบิตต่อค่าจากนั้นนำชิ้นส่วนกลับมารวมกัน อย่างไรก็ตามเอาต์พุตของการบิดมีมากกว่าบิตเล็กน้อย(เช่นบิตต่อค่าเอาต์พุตซึ่งมากกว่าความจุของวงแหวนเนื่องจากแต่ละค่าเอาต์พุตเป็นผลรวมของผลิตภัณฑ์หลายตัว) จึงไม่ทำงาน ฉันต้องเพิ่มปัจจัยพิเศษอีก 2 อย่างของการเติมเต็ม
นั่นคือปัจจัยพิเศษของ 2 ในการทำลายที่ซับซ้อน มันทำให้ขั้นตอนแบบเรียกซ้ำของฉันแพงเกินไป แทนที่จะเป็นอัลกอริทึมฉันท้าย ด้วยF (n) = n \ lg n + \ sqrt {n} F (4 \ sqrt {n}) = \ Theta (n \ lg ^ 2 n)อัลกอริทึม
ฉันได้อ่านเอกสารอ้างอิงสองสามฉบับที่เชื่อมโยงจากวิกิพีเดีย แต่พวกเขาดูเหมือนจะล้วงลึกถึงรายละเอียดว่าปัญหานี้ได้รับการแก้ไขอย่างไร ตัวอย่างเช่นฉันสามารถหลีกเลี่ยงค่าใช้จ่ายในการเสริมกำลังพิเศษได้ด้วยการทำงาน modulo สำหรับที่ไม่ใช่พลังของ 2 ... แต่จากนั้นสิ่งต่าง ๆ ก็พังทลายในภายหลังเมื่อฉันไม่มีพลัง - เหลือเพียงปัจจัย 2 และไม่สามารถใช้ Cooley-Tukey ได้โดยไม่ต้องเพิ่มจำนวนสองเท่า นอกจากนี้ไม่อาจมีผกผันแบบโมดูโล 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);
...