Làm thế nào là vòng trong được chọn trong thuật toán Schönhage Sàn Strassen?


9

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 ^ kxnx2(mod2n+1)k4k2nx2k2k122k+12k2n>2kbit 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 F(n)=nlgn+nF(2n)=Θ(nlgnlglgn) , tôi kết thúc với thuật toán F(n)=nlgn+nF(4n)=Θ(nlg2n) .

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 2p2k+1 cho một p 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, p có thể không có modulo nghịch đảo nhân 2p+1 . 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);
  ...

Xin vui lòng không đăng cùng một câu hỏi trên nhiều trang web . Mỗi cộng đồng nên có một cú đánh trung thực để trả lời mà không có ai lãng phí thời gian. Tôi đề nghị bạn xóa một trong hai bản sao.
DW

@DW Xong. Tôi đã đăng chéo sau khi cs không đưa ra bất kỳ câu trả lời nào trong một tuần, cho thấy trang web đó quá khó. Sẽ liên kết lại bất kỳ câu trả lời rõ ràng.
Craig Gidney

Tôi hiểu. Nếu nó xuất hiện trong tương lai, bạn luôn có thể gắn cờ bài đăng của mình để người điều hành chú ý và yêu cầu di chuyển nó, và chúng tôi có thể chuyển nó cho bạn qua CSTheory. Cảm ơn bạn đã hiểu biết của bạn!
DW

3
Có một phiên bản của thuật toán hoạt động các số modulo có dạng : A. Schönhage. Các thuật toán nhanh không có triệu chứng cho phép nhân số và chia đa thức với các hệ số phức tạp. Trong EUROCAM '82: Hội nghị đại số máy tính châu Âu, Bài giảng. Ghi chú Comp. Khoa học. 144, 3-15. iai.uni-bonn.de/~schoe/publi39.dvi2ν2n
Markus Bläser

IIRC bạn đã có một phần tự trả lời cho câu hỏi CS hiện đã bị xóa. Có vẻ xấu hổ khi mất điều đó. Bạn có thể đưa nó vào đây không (trong câu hỏi để câu hỏi không được đánh dấu là đã trả lời)?
Peter Taylor

Câu trả lời:


4

Câu trả lời này được lấy từ bài báo "Các thuật toán nhanh không có triệu chứng cho phép ghép số và phân chia đa thức với các hệ số phức tạp" mà Markus đã liên kết trong các bình luận.


Bạn muốn bình phương một số -bit, modulo . Đây là những gì bạn làm:n2n+1

  • Tìm và thỏa mãn và .psn=(p1)2ssp2s

  • Chọn số lượng mảnh để chia bit thành các tham số tương ứng cho kích thước mảnh:2mn

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

    Lưu ý rằng và tiếp tục thỏa mãn bất biến . Cũng lưu ý rằng được thỏa mãn, do đó, đầu vào phù hợp với chỗ để mang.s2p2s2p22s22m2s2p22n+m+1

  • Thực hiện tích chập negacyclic dựa trên FFT trên các mảnh và phần còn lại, như thường lệ.

Vì vậy, đó là ý tưởng bao quát: một yếu tố đệm logarit . Bây giờ cho các phân tích phức tạp. FFT sẽ mất việc phải làm, và chúng tôi đang recursing trên mảnh kích thước , vì vậy bây giờ chúng ta có thể làm toán vô cùng khó khăn với tái phát liên quan 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

Điều đó có vẻ đúng, mặc dù tôi đã gian lận khá nhiều trong các bước đó.

'Bí quyết' dường như là việc chúng ta kết thúc với thay vì trong chi phí cơ bản. Vẫn còn hai phép nhân với hai mức đệ quy, như tôi đã phàn nàn trong câu hỏi, nhưng bây giờ, một nửa số đang trả cổ tức gấp đôi để mọi việc đều ổn. Sau đó, cuối cùng, chúng tôi hủy bỏ hệ số phụ của (thực sự là một yếu tố của ) nhờ làm cho logarit lớn tương đối so với ban đầu.s2ssslognps

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.