Nhân hai đa thức là một thao tác cơ bản trong lập trình, nhất là trong mật mã. Giả sử chúng ta có hai đa thức bậc :
Cách tiếp cận tự nhiên nhất mà chúng ta được học ở trường phổ thông là phép nhân phân phối (Elementary Multiplication). Để tìm hệ số của đa thức tích , ta lấy từng hạng tử của nhân với mọi hạng tử của . Nếu mỗi đa thức có hệ số, chúng ta cần thực hiện phép nhân số thực/số phức. Trong khoa học máy tính, đây là độ phức tạp . Với (trong các bài toán xử lý tín hiệu hoặc mã hóa), số phép toán lên tới 1.000 tỷ, khiến các hệ thống hiện đại cũng phải "đầu hàng" về mặt thời gian thực.
Sự xuất hiện của FFT (Fast Fourier Transform), cụ thể là thuật toán Cooley-Tukey, đã thay đổi hoàn toàn cuộc chơi này bằng cách đưa độ phức tạp về mức , biến những bài toán không thể thành có thể.
Thông thường, chúng ta định nghĩa đa thức qua các hệ số của nó. Nhưng thực ra, chúng ta vẫn có thể định nghĩa một đa thức thông qua các điểm phân biệt mà đồ thị của nó đi qua. Theo định lý cơ bản về đa thức: Một đa thức bậc được xác định duy nhất bởi tập hợp cặp điểm phân biệt.
Ví dụ:
Qua 2 điểm, ta xác định được duy nhất 1 đường thẳng (bậc 1).
Qua 3 điểm, ta xác định được duy nhất 1 đường parabol (bậc 2).
Hãy tưởng tượng bạn có hai đa thức và đã được chuyển sang dạng điểm tại cùng một tập hợp các giá trị .
Để tìm đa thức tích ở dạng điểm, chúng ta chỉ cần tính:
Phép toán này chỉ tốn đúng phép nhân, tức là độ phức tạp , yeah!!!
Vậy tại sao nhanh như vậy mà ta không dùng nó ngay từ đầu? Đó là vì chi phí chuyển đổi:
Chuyển từ Hệ số Điểm (Evaluation): Nếu tính toán thông thường (thế vào đa thức), ta mất .
Chuyển từ Điểm Hệ số (Interpolation): Dùng các phương pháp như Newton hay Lagrange cũng mất .
FFT cho phép chúng ta thực hiện cả hai quá trình chuyển đổi trên chỉ với độ phức tạp .
Để chuyển một đa thức từ dạng Hệ số sang dạng Điểm trong , thuật toán Cooley-Tukey sử dụng chiến lược Chia để trị (Divide and Conquer) dựa trên một lựa chọn toán học cực kỳ thông minh: Căn đơn vị phức (Complex Roots of Unity).
Căn đơn vị phức
Nếu ta chọn các điểm ngẫu nhiên, ta vẫn mất để tính giá trị đa thức. Tuy nhiên, nếu ta chọn là các nghiệm của phương trình , chúng ta có những tính chất đối xứng tuyệt vời. Các điểm này nằm trên vòng tròn đơn vị trong mặt phẳng phức, được xác định bởi công thức:
Với .
Tính chất: . Điều này cho phép ta thu nhỏ bài toán kích thước thành bài toán kích thước một cách đồng nhất.
Giả sử ta có đa thức bậc (với là lũy thừa của 2). Ta tách các hệ số của thành hai đa thức con bậc :
(Chứa các hệ số ở vị trí chẵn)
(Chứa các hệ số ở vị trí lẻ)
Khi đó, đa thức ban đầu có thể biểu diễn qua hai đa thức con như sau:
Nhờ tính chất chu kỳ của số phức (), khi ta tính giá trị của tại các điểm , chúng ta nhận thấy một sự lặp lại thú vị:
Với nửa đầu ():
Với nửa sau (, đặt ):
Kết quả: Mỗi bước tính toán ở tầng dưới cung cấp dữ liệu cho hai giá trị ở tầng trên chỉ bằng một phép nhân và hai phép cộng/trừ. Đây chính là cấu trúc Butterfly nổi tiếng giúp giảm số lượng phép tính từ xuống còn .

Bức ảnh này giải thích chính xác cơ chế "phép màu" đã được đề cập:
Đầu vào (bên trái): Hai giá trị và từ tầng tính toán trước đó.
Hệ số xoay (Twiddle Factor - ): Giá trị phức được nhân với đầu vào thứ hai trước khi kết hợp.
Điểm kết hợp (Cánh bướm):
Phép cộng (trên): Tạo ra đầu ra thứ nhất: .
Phép trừ (dưới): Tạo ra đầu ra thứ hai: .
Cấu trúc đối xứng này cho phép máy tính tái sử dụng các kết quả tính toán trung gian, biến đổi độ phức tạp từ thành .
Để nhân hai đa thức và , quy trình gồm 3 bước:
Bước 1: Mở rộng và Biến đổi (Padding & Forward FFT)
Trước khi bắt đầu, có một chi tiết kỹ thuật cực kỳ quan trọng: Xử lý bậc của đa thức kết quả.
Nếu có bậc và có bậc , thì đa thức tích sẽ có bậc .
Zero Padding: Chúng ta phải thêm các hệ số vào và sao cho tổng số hệ số của mỗi đa thức ít nhất bằng bậc của , và phải là một lũy thừa của 2 (ví dụ: ).
Thực thi: Áp dụng FFT Cooley-Tukey để chuyển và từ dạng hệ số sang dạng điểm (tại các căn đơn vị ).
Bước 2: Nhân trong miền giá trị (Point-wise Multiplication)
Với các giá trị điểm đã có, ta tính giá trị của đa thức tích tại từng điểm tương ứng:
Chỉ cần đúng phép nhân số phức, chúng ta đã có đầy đủ đại diện dạng điểm của đa thức tích.
Bước 3: Biến đổi ngược (Inverse FFT - IFFT)
Bây giờ, chúng ta đang có các giá trị , nhưng mục tiêu là phải xác định kết quả là các hệ số . Lúc này, ta cần đến quá trình biến đổi ngược Inverse FFT. Thú vị thay, thuật toán cho IFFT gần như y hệt FFT. Sự khác biệt duy nhất nằm ở hai điểm:
Thay thế hệ số xoay bằng nghịch đảo của nó (tương đương với việc đổi dấu phần ảo trong số phức).
Sau khi tính xong, tất cả kết quả phải được chia cho
Hãy nhìn lại toàn bộ hành trình:
FFT cho A và B:
Nhân điểm:
IFFT cho C:
Tổng cộng: .
Để cài đặt FFT Cooley-Tukey, chúng ta sử dụng cấu trúc đệ quy chia mảng hệ số thành hai nửa: vị trí chẵn và vị trí lẻ.
Hàm FFT (Hệ số Điểm)
HÀM FFT(Mảng_Hệ_Số A):
N = Độ dài của A
NẾU N == 1:
TRẢ VỀ A // Trường hợp cơ bản: Đa thức bậc 0 là chính nó
// BƯỚC 1: CHIA (Divide)
A_chẵn = [A[0], A[2], ..., A[N-2]]
A_lẻ = [A[1], A[3], ..., A[N-1]]
// BƯỚC 2: TRỊ (Conquer - Đệ quy)
Y_chẵn = FFT(A_chẵn)
Y_lẻ = FFT(A_lẻ)
// BƯỚC 3: KẾT HỢP (Combine - Cấu trúc Cánh bướm)
Mảng_Kết_Quả Y = Mảng rỗng kích thước N
Hệ_số_xoay_gốc = e^(i * 2π / N)
w = 1
CHO k CHẠY TỪ 0 ĐẾN N/2 - 1:
// Tính toán dựa trên tính đối xứng và chu kỳ
Y[k] = Y_chẵn[k] + w * Y_lẻ[k]
Y[k + N/2] = Y_chẵn[k] - w * Y_lẻ[k]
w = w * Hệ_số_xoay_gốc // Xoay dần trên vòng tròn đơn vị
TRẢ VỀ Y
Quy trình nhân hai đa thức và
HÀM NHÂN_ĐA_THỨC(P1, P2):
1. Padding: Thêm các số 0 vào P1, P2 sao cho độ dài N là lũy thừa của 2
(N phải đủ lớn để chứa bậc của đa thức kết quả).
2. Chuyển đổi sang dạng điểm:
Điểm_P1 = FFT(P1)
Điểm_P2 = FFT(P2)
3. Nhân trực tiếp (Point-wise):
Điểm_Kết_Quả = Mảng chứa (Điểm_P1[i] * Điểm_P2[i]) với mọi i từ 0 đến N-1
4. Chuyển ngược về dạng hệ số:
Hệ_Số_Kết_Quả = IFFT(Điểm_Kết_Quả)
(IFFT dùng thuật toán y hệt FFT nhưng đổi dấu số phức và chia kết quả cho N)
TRẢ VỀ Hệ_Số_Kết_QuảNo comments yet. Be the first to comment!