Tôi đã cố gắng thực hiện thuật toán nhân số nguyên Schönhage, nhưng đã gặp phải một vấp ngã trong bước đệ quy.
Tôi có một giá trị với bit và tôi muốn tính x ^ 2 \ pmod {2 ^ n + 1} . Ban đầu tôi nghĩ ý tưởng là chọn một k sao cho 4 ^ k \ geq 2n , chia x thành 2 ^ k mỗi mảnh có 2 ^ {k-1} bit, áp dụng tích chập của SSA trong khi làm việc modulo 2 ^ {2 ^ k} +1 , một vòng có 2 ^ k bit dung lượng cho mỗi giá trị, sau đó đặt các mảnh lại với nhau. Tuy nhiên, đầu ra của tích chập có hơn 2n bit (nghĩa là > 2 ^ kbit trên mỗi giá trị đầu ra, lớn hơn dung lượng của vòng, do mỗi giá trị đầu ra là tổng của một số sản phẩm) nên điều này không hoạt động. Tôi đã phải thêm vào một yếu tố phụ của 2 phần đệm.
Đó là yếu tố thêm 2 trong phần đệm làm hỏng sự phức tạp. Nó làm cho bước đệ quy của tôi quá đắt. Thay vì thuật toán , tôi kết thúc với thuật toán .
Tôi đã đọc một vài tài liệu tham khảo được liên kết từ wikipedia, nhưng tất cả chúng dường như che đậy các chi tiết về cách giải quyết vấn đề này. Ví dụ: tôi có thể tránh được phần đệm thêm trên đầu bằng cách làm việc modulo cho một không phải là sức mạnh của 2 ... nhưng sau đó mọi thứ chỉ dừng lại sau đó, khi tôi chỉ không có sức mạnh- còn lại 2 yếu tố và không thể áp dụng Cooley-Tukey mà không nhân đôi số lượng mảnh ghép. Ngoài ra, có thể không có modulo nghịch đảo nhân . Vì vậy, vẫn còn các yếu tố bắt buộc của 2 được giới thiệu.
Làm cách nào để chọn vòng để sử dụng trong bước đệ quy, mà không thổi vào độ phức tạp tiệm cận?
Hoặc, ở dạng mã giả:
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);
...