Hệ thức truy hồi tuyến tính với hệ số hằng
Giới thiệu
Dãy truy hồi tuyến tính thuần nhất hệ số hằng (còn gọi là C-finite hoặc C-recursive) là một lớp dãy cơ bản.
Với dãy \(\left(a_j\right)_{j\geq 0}\) và truy hồi
trong đó \(c_j\) không đồng thời bằng 0, mục tiêu là khi cho \(a_0,\dots ,a_{d-1}\) và \(c_1,\dots ,c_d\) thì tính \(a_k\). Nếu \(k\gg d\), ta cần thuật toán nhanh hơn.
Dãy \(\left(a_j\right)_{j\geq 0}\) gọi là dãy truy hồi tuyến tính thuần nhất hệ số hằng bậc \(d\).
Thuật toán Fiduccia
Thuật toán Fiduccia dùng modulo đa thức và lũy thừa nhanh để tính \(a_k\), thời gian \(O(\mathsf{M}(d)\log k)\), với \(O(\mathsf{M}(d))\) là thời gian nhân hai đa thức bậc \(O(d)\).
Thuật toán: Xây đa thức \(\Gamma(x):=x^d-\sum_{j=0}^{d-1}c_{d-j}x^j\) và \(A(x):=\sum_{j=0}^{d-1}a_jx^j\), khi đó
với \(\left\langle \left(\sum_{j=0}^{n-1}f_jx^j\right),\left(\sum_{j=0}^{n-1}g_jx^j\right) \right\rangle :=\sum_{j=0}^{n-1}f_jg_j\) là tích vô hướng.
Chứng minh: Định nghĩa ma trận đồng hành của \(\Gamma(x)\):
Định nghĩa \(b(x):=\sum_{j=0}^{d-1}b_jx^j\) và
Quan sát:
và
Biểu diễn truy hồi dưới dạng ma trận:
Suy ra hàng đầu của \(\left(\left(C_\Gamma\right)^{k}\right)^{\intercal}\) là \(B_{x^k\bmod{\Gamma}}\), theo định nghĩa nhân ma trận là đúng.
Biểu diễn dưới dạng hàm hữu tỉ
Với dãy \(\left(a_j\right)_{j\geq 0}\) trên, luôn tồn tại hàm hữu tỉ
với \(Q(x)=x^d\Gamma\left(x^{-1}\right)\), \(\deg{P}<d\). Gọi là “hàm hữu tỉ” vì \(P(x),Q(x)\) là “đa thức”.
Chứng minh: Với \(P(x)=\sum_{j=0}^{d-1}p_jx^j\) và \(Q(x):=\sum_{j=0}^{d}q_jx^j\), xét định nghĩa hệ số của \(\dfrac{P(x)}{Q(x)}=\sum_{j\geq 0}\tilde{q}_jx^j\) (tương ứng phép “chia” của chuỗi lũy thừa):
Chỉ cần lấy
thì theo định nghĩa \(\tilde{q}_N\) sẽ có \(\dfrac{P(x)}{Q(x)}=\sum_{j\geq 0}a_jx^j\).
Thuật toán Bostan–Mori
Tính một hệ số
Mục tiêu: cho \(P(x),Q(x)\) như trên, tính \(\left\lbrack x^k\right\rbrack\dfrac{P(x)}{Q(x)}\).
Bostan–Mori dựa trên lặp Graeffe:
Vì mẫu \(V(x^2)\) là hàm chẵn, nên chỉ cần xét một nửa:
Chi phí hai phép nhân đa thức để giảm ít nhất một nửa bài toán; khi \(k=0\) thì \(\left\lbrack x^0\right\rbrack \dfrac{P(x)}{Q(x)}=\dfrac{P(0)}{Q(0)}\). Độ phức tạp tương tự.
Tính một đoạn liên tiếp
Mục tiêu: cho \(P(x),Q(x)\), tính \(\left\lbrack x^{\left\lbrack L,R\right)}\right\rbrack\dfrac{P(x)}{Q(x)}\). Ta chỉ xét các hệ số “có ảnh hưởng”.
Giả sử \(\deg{P}<\deg{Q}\), nếu không thì dùng phép chia đa thức để đưa về dạng này.
Xét bài toán đơn giản:
Cần tính \(\left\lbrack x^{\left\lbrack L-\deg{Q},R\right)}\right\rbrack\dfrac{1}{Q(x)Q(-x)}\), rồi nhân và lấy \(x^L,\dots ,x^{R-1}\). Đặt \(V(x^2)=Q(x)Q(-x)\), khi đó chỉ cần
để khôi phục \(\left\lbrack x^{\left\lbrack L-\deg{Q},R\right)}\right\rbrack\dfrac{1}{Q(x)Q(-x)}\). Tiếp theo chỉ cần tính \(\left\lbrack x^{\left\lbrack L-\deg{P},R\right)}\right\rbrack\dfrac{1}{Q(x)}\) rồi nhân với \(P(x)\) để ra \(\left\lbrack x^{\left\lbrack L,R\right)}\right\rbrack\dfrac{P(x)}{Q(x)}\).
Tuy nhiên thuật toán này còn phụ thuộc \(R-L\) ở mỗi bước; ta muốn giảm. Hãy tính \(\left\lbrack x^{\left\lbrack L,L+\deg Q+1\right)}\right\rbrack \dfrac{1}{Q(x)}\):
Cần:
Với \(V(x^2)=Q(x)Q(-x)\), chỉ cần:
bởi vì:
Ta biết \(L+\deg Q\) và \(L-\deg Q\) cùng parity, nên:
Mã giả:
Nhưng chỉ vậy chưa đủ; cần tìm một biểu diễn hữu tỉ mới để lấy thêm hệ số.
Tìm biểu diễn hữu tỉ mới
Biết \(Q(x)\) và một đoạn hệ số của \(Q(x)^{-1}\) như \(\left\lbrack x^{\left\lbrack L,L+\deg Q\right)}\right\rbrack Q(x)^{-1}\) với \(L\geq 0\), ta muốn tính \(\left\lbrack x^{\left\lbrack L+\deg Q,L+2\deg Q\right)}\right\rbrack Q(x)^{-1}\). Tức là cần tìm \(P(x)\), \(\deg P<\deg Q\), sao cho \(\dfrac{P(x)}{Q(x)}\) có \(\deg Q\) hệ số đầu giống \(\left\lbrack x^{\left\lbrack L,L+\deg Q\right)}\right\rbrack Q(x)^{-1}\). Nói cách khác: quan hệ truy hồi (mẫu) giữ nguyên, chỉ thay đổi điều kiện đầu.
Cụ thể:
Muốn dịch tiến \(n\) bước:
Ta dùng \(\operatorname{Slice-Coefficients}(Q,L-\deg{P})\) để tính \(\left\lbrack x^{\left\lbrack L-\deg{P},L-\deg{P}+\deg{Q}+1\right)}\right\rbrack Q(x)^{-1}\), rồi ghép thành \(\left\lbrack x^{\left\lbrack L-\deg{P},L+\deg{Q}\right)}\right\rbrack Q(x)^{-1}\). Sau đó tính lại tử số sao cho
Cuối cùng dùng phép chia chuỗi lũy thừa để tính \(\left\lbrack x^{\left\lbrack 0,R-L\right)}\right\rbrack\dfrac{\widetilde{P}(x)}{Q(x)}\), thời gian \(O(\mathsf{M}(d)\log L+\mathsf{M}(R-L))\).
Tài liệu tham khảo
- Alin Bostan, Ryuhei Mori.A Simple and Fast Algorithm for Computing the \(N\)-th Term of a Linearly Recurrent Sequence.
Last updated on this page:, Update history
Found an error? Want to help improve? Edit this page on GitHub!
Contributors to this page:OI-wiki
All content on this page is provided under the terms of the CC BY-SA 4.0 and SATA license, additional terms may apply