मैं शॉनहाज-स्ट्रैसेन पूर्णांक गुणन एल्गोरिथम को लागू करने की कोशिश कर रहा हूं, लेकिन पुनरावर्ती चरण में एक ठोकर मारा।
मेरा एक मूल्य है साथ में बिट्स और मैं गणना करना चाहते हैं । मैंने मूल रूप से सोचा था कि इस तरह के एक कश्मीर को चुनने के लिए 4 ^ k \ geq 2n , x को 2 ^ k टुकड़ों में 2 ^ {k-1} बिट्स के साथ विभाजित करें, modulo 2 ^ {2 ^ k} काम करते हुए SSA के कनवल्शन को लागू करें। +1 , मूल्य के अनुसार क्षमता के 2 ^ k बिट के साथ एक अंगूठी , फिर टुकड़ों को वापस एक साथ रखें। हालाँकि, कनवल्शन का आउटपुट 2n बिट्स से अधिक है (अर्थात > आउटपुट बिट्स प्रति आउटपुट मूल्य, जो कि रिंग की क्षमता से अधिक है, क्योंकि प्रत्येक आउटपुट वैल्यू कई उत्पादों का योग है) इसलिए यह काम नहीं करता है । मुझे पैडिंग के 2 के अतिरिक्त कारक पर जोड़ना था।
पैडिंग में 2 का वह अतिरिक्त कारक जटिलता को नष्ट कर देता है। यह मेरे पुनरावर्ती कदम को बहुत महंगा बनाता है। इसके बजाय का एक एल्गोरिथ्म, मैं अंत एक साथ एल्गोरिथ्म।
मैं विकिपीडिया से जुड़े हुए कुछ संदर्भों को पढ़ता हूं, लेकिन वे सभी इस बात पर गौर करते हैं कि यह समस्या कैसे हल होती है। उदाहरण के लिए, मैं modulo को लिए काम करके अतिरिक्त पैडिंग ओवरहेड से बच सकता हूं जो कि 2 की शक्ति नहीं है ... लेकिन तब चीजें बस बाद में टूट जाती हैं, जब मेरे पास केवल गैर-शक्ति होती है- शेष -2 कारक शेष और टुकड़ों की संख्या को दोगुना किए बिना Cooley-Tukey को लागू नहीं कर सकते। इसके अलावा, में एक बहुपरत व्युत्क्रम modulo नहीं हो सकता है । इसलिए अभी भी 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);
...