圖姆-庫克算法

圖姆-庫克算法（Toom–Cook），有時也被稱為Toom-3算法，由安德魯·圖姆命名，他提出了這種算法的基本原理，而斯蒂芬·庫克則最先用簡潔的形式描述並改進了這種算法，將其作為大整數的乘法算法。
圖姆-庫克算法的原理是：對於給定的兩個大整數和 ，將和分成個較小的部分，每個部分的長度為 ，並對這些部分執行運算。隨著的增長，可以組合許多乘法子運算，從而降低算法的整體複雜度，然後再次使用圖姆-庫克算法遞歸計算乘法子運算，依此類推。Toom-3和圖姆-庫克兩個術語有時會被錯誤的混用，但事實上Toom-3只是圖姆-庫克算法在時的特例。
Toom-3將9次乘法降低至僅需5次，使其在的時間裡運行。通常，Toom-的時間複雜度為 ，其中。是在乘法子運算上花費的時間，則是花費在對小常數進行的加法和乘法運算上的時間。著名的Karatsuba算法實際上是圖姆-庫克算法的特例，在Karatsuba算法中，原始乘數被拆分成兩個較小的數，而原本的4次乘法運算縮減為3次，使之在的時間內完成運算。Toom-1等價於普通的長乘法，具有的複雜度。
儘管可以通過增加來使指數任意接近1，但函數增長速度非常快。混合級別圖姆-庫克算法的增長率直到2005年仍然是一個廣為研究的開放性問題。根據高德納所描述算法的一種實現，其複雜度可降低至。
由於工作時的開銷，當乘數包括較小的數時，圖姆-庫克算法會比長乘法更慢，因此它適用於中等規模的乘法。對於更大規模的數據，則有漸進更快的史恩哈格·施特拉森算法（複雜度為）。
這一算法由安德魯·圖姆1963年首次描述，並在斯蒂芬·庫克1966年的博士學位論文中得到漸進等效的改進。

**細節**
本節將討論對於任意給定  值， Toom-究竟是如何運作的，這是馬可·波德拉託對圖姆-庫克多項式乘法的簡化描述。這個算法包括五個主要步驟：
# 拆分
# 求值
# 點乘
# 插值
# 重組
在典型的大整數實現中，每個整數都表示為進制的數字序列（通常取較大的數）。在此示例中，，因此每個數字序列對應一組十進制數字（在實踐中，通常取的冪）。設要相乘的兩個大整數 、 分別是：
這對乘數實際上比圖姆-庫克算法通常要處理的數據小很多，在此使用學校裡學習的普通乘法可能會更快，但這個示例仍有助於說明圖姆-庫克算法的工作原理。

**拆分**
第一步是選擇基數，使得兩個數字和可以分成段大小不超過的數字（例如在Toom-3算法中，拆分段數應至多為3）。常常根據如下公式求得：
  
我們的示例將演繹Toom-3算法的運算過程，因此確定，接著把和拆分為3段，即和，則有：
  
然後，我們把這些數作為階多項式和的係數，with the property that    and  ：
  
  
定義這些多項式的目的在於：如果計算出它們的乘積，我們的答案就會是。
如果乘數位數不同，對於、分別取不同的值十分有用，我們將其稱為和。例如，算法“Toom-2.5”是指且時的圖姆-庫克算法。這時中的通常被確定為：
  

**求值**
圖姆-庫克算法包含一種常用的方法，來計算多項式、的乘積。注意，次數為的多項式可以通過個空間中的點確定（例如一次多項式是一條直線，它由兩個點確定）。這個方法是在各個點上求值和，然後把這些點相乘以獲得多項式乘積上的點，最後進行插值以找到其係數。
由於，我們將需要個點來確定最終結果。在Toom-3的情況下，。無論選擇什麼點，該算法都可以工作（有一些小例外，請參閱插值中的矩陣可逆性約束），但為了簡化算法，最好選擇較小的整數值，例如 、 、和。
無窮大是一個常被使用的不尋常點，其記作或。求多項式在無窮大時的值，實際上意味著令的上限為 且趨向無窮大。因此，總是其高階係數的值（是上文中的係數）。
在我們的Toom-3示例中，我們將使用點 、  、  、 和，這些選擇簡化了求值，如下式子：
  
對於也是如此。在示例中，我們得到的值是：
如上所示，這些值可以包括負值。
為了下文的闡述，把這個求值過程視作矩陣向量乘法較為有用。其中，矩陣的每一行都包含求值點之一的冪，且向量包含多項式的係數：
  
The dimensions of the matrix are    by    for    and    by    for  。除最後一列的  以外，無窮大的行總是。

**更快的求值**
與上述公式相比，多點求值可能會減少基本運算（加、減）的次數，更快獲得需要的結果。波德拉託 為Toom-3給出的序列如下所示，它是在運行示例的第一個操作數（多項式上進行的）：
此序列需要進行五次加/減運算，比簡單求值少一次，同時節省了在計算時乘以的開銷。

**點乘**
與對多項式和所進行的乘法不同，將 和被求出的值相乘僅涉及整數相乘——這是原始問題的較小實例。我們遞歸調用我們的乘法過程來使每對已求值的點相乘。在實踐中，隨著乘數減小，算法將逐漸過渡為教科書長乘法。令為多項式乘積，我們將得到：
如上所示，這些值也可以是負數。對於足夠大的數值，這裡是最昂貴的、唯一與、大小不成線性關係的步驟。

**插值**
這一步最為複雜。與求值相反：給定多項式乘積上的點，我們需要確定其係數。換句話說，我們要在右側求解其向量的矩陣方程：
  
此矩陣的構造與求值步驟中的矩陣相同，不過它是的。我們可以用高斯消元法來求出方程的解，但這樣非常昂貴。根據以下事實：只要求值點的選擇合適，這個矩陣就是可逆的。因此我們有：
  
接下來即要求得該矩陣的向量積。儘管矩陣中包含分數，但所得的係數卻是整數——因此所有這些都可以在整數算術中完成，僅僅是與小常數進行加減乘除。圖姆-庫克設計時面臨的一個困難挑戰就是找到有效的操作順序來計算該乘積。下面是波德拉託為Toom-3找到的一組順序，通過上面的示例演示：
現在我們知道多項式乘積：
  
如果我們使用不同的、或求值點，矩陣和我們的插值將改變。但是它不依賴於輸入，因此可以對任何給定的參數集進行硬編碼。

**重組**
最後，我們將求出的值以獲得最終結果。很顯然，由於是的冪，因此對的冪的乘法同樣也可以應用於所有以為底數的數值。在這個示例中，且。
這實際上是與的乘積。

**在其他取值時的插值矩陣**
這裡我們給出了幾種和取常見較小值的插值矩陣。

**Toom-1**
Toom-1（）需要一個求值點，這裡選擇。它退化為長乘法，並且使用恆等矩陣的插值矩陣。
  

**Toom-1.5**
Toom-1.5（）需要兩個求值點，這裡選擇和，且其插值矩陣就是恆等矩陣。
  
這裡亦退化為長乘法：一個因數的兩個係數都乘以另一個因數的兩個係數。

**Toom-2**
Toom-2（）需要三個求值點，這裡選擇、和。它與 Karatsuba 算法相同，其插值矩陣為：
  

**Toom-2.5**
Toom-2.5（）需要四個求值點，這裡選擇、、和。它的插值矩陣為：
 

**另見**
 乘法算法- 任意精度整數- 長乘法- Karatsuba 算法- 施特拉森算法- 富爾算法

**參考資料**

**引用**
 D. Knuth. The Art of Computer Programming, Volume 2. Third Edition, Addison-Wesley, 1997. Section 4.3.3.A： Digital methods, pg.294.- R. Crandall & C. Pomerance. Prime Numbers – A Computational Perspective. Second Edition, Springer, 2005. Section 9.5.1： Karatsuba and Toom–Cook methods, pg.473.- M. Bodrato.  Toward Optimal Toom-Cook date=20070706025358 . In WAIFI'07, Springer, 2007.

**外部鏈接**
 http://gmplib.org/manual/Toom-3_002dWay-Multiplication.htmldate=20180628233441