**톰–쿡 알고리즘**은 안드레이 톰과 스테픈 쿡이 제안한 곱셈 알고리즘으로 큰 두 정수를 곱할 때 사용된다.

톰-쿡 알고리즘에서는 큰 정수 ''a''와 ''b''를 곱하기 위해, 두 수를 작은 조각으로 나눈다. 조각의 수를 ''k''라고 할때, ''k''가 커질수록 곱셈의 내부 연산법은 복잡해지지만, 전체 시간 복잡도는 낮아진다. 이 곱셈 방법은 나눠진 각각의 조각에 대해서도 다시 적용할 수 있기 때문에, 조각이 작아질때까지 재귀적으로 사용할 수 있다.

톰-3 알고리즘은 ''k''가 3일 경우를 가리키며, 9번의 곱셈을 5번으로 단축시켜, Θ(''n'')가 된다.

''k''값을 증가시켜서 ''e''값을 거의 1에 가깝게 낮출수 있지만, 이 경우 ''c''의 값이 급속하게 커져 소용이 없다. 이런 부가적인 연산 때문에 톰-쿡 알고리즘은 작은 정수의 곱셈에 적용하면 일반 곱셈법보다 느려지기에 이 알고리즘은 적당히 큰 정수에 사용되며, 정수 크기가 훨씬 더 커질 경우는 시간복잡도가 Θ(''n''&nbsp;log&nbsp;''n''&nbsp;log&nbsp;log&nbsp;''n'')인 쇤하게-슈트라센 알고리즘이더빠 르게 된다.

톰은 1963년에 처음 이 알고리즘을 제시하였고, 쿡은 1966년에 그의 박사 논문에서 이 알고리즘을 개량시켰다.

## 상세
이 단락은 톰-''k'' 알고리즘이 어떻게 작동하는지를 간략하게 설명한다. 알고리즘은 크게 5단계를 거쳐 완료된다.

큰 정수를 구현하는데 있어서, 대개 위치 기수법으로 각 자리의 정수를 표현하는 방법이 자주 사용된다. 이 때의 밑을 ''b''라고 하자. 이 예시에서는 ''b'' = 10000을 사용할 것이므로, 한 자리에는 4개의 10진 정수가 들어가게 된다. (실제 컴퓨터 구현에서는 연산의 효율성을 위해 ''b''값으로 2의 거듭제곱이 사용된다.) 두 큰 정수를 다음과 같다고 하자.

물론 이 정수들은 톰-쿡 알고리즘을 사용하기엔 작아서, 그냥 일반 곱셈법이 훨씬 빠르다. 하지만 설명을 위해 이 값을 사용하도록 한다.

### 분할
첫번째 단계는 정수를 ''k''개의 조각으로 자르기 위한 적절한 단위인 ''B'' = ''b''를 찾는 것이다. 일반적으로 ''i''는 다음과 같이 구할 수 있다.

이 예제에서는 톰-3 알고리즘을 사용할 것이므로, ''B'' = ''b''

우리는 이 수를 계수로 하는 ''k''−1차 다항식을 만들것이다.

다항식을 이렇게 정의하면 ''p''(''B'')&nbsp;=&nbsp;''m'', ''q''(''B'')&nbsp;=&nbsp;''n''이 된다. 이렇게 정의한 목적은 두 다항식의 곱인 ''r''(''x'')&nbsp;=&nbsp;''p''(''x'')''q''(''x'')를 구하기 위해서이다. 즉 우리가 구하고자 하는 결과는 이 다항식에 ''B''를 대입함으로써 얻을 수 있다. ''r''(''B'')&nbsp;=&nbsp;''m''×''n''

''m''과 ''n''을 일반적인 곱셈법으로 곱하면 (여기서는 3 조각으로 나누었으므로), 조각 간의 곱셈이 9번 필요하다. 하지만, ''r''(''x'')는 2(''k''−1)차 다항식(''k''가 3이므로 4차 다항식)이므로, 2''k''−1개의 미지 계수를 구하기 위해서는 2''k''-1개의 방정식만 있으면 된다. 이 방정식은 선형 대수를 이용하여 간단한 방법으로 풀어낼 수 있으므로, 결과적으로 일반 곱셈법보다 적은 수의 곱셈을 사용하여 결과를 얻을 수 있게 된다.

만약 곱하는 두 수의 자리수가 다를 경우 ''k''값을 ''m''과 ''n''에 따라 다르게 주는 것이 유용하다. ''톰-2.5'' 알고리즘에서는 ''k''

''q''에 대해서도 마찬가지. 예시의 값을 실제로 대입하면 다음과 같다:

위에 보이는대로 결과값이 음수가 될 수도 있다.

다음과 같이 행렬로 간단하게 표현할 수 있다. 이 표현은 보간 과정에서도 유용하게 쓸 수 있다.

\left(\begin{matrix}p(0) \\ p(1) \\ p(-1) \\ p(-2) \\ p(\infty)\end{matrix}\right) =
\left(\begin{matrix}
0^0 & 0^1 & 0^2 \\
1^0 & 1^1 & 1^2 \\
(-1)^0 & (-1)^1 & (-1)^2 \\
(-2)^0 & (-2)^1 & (-2)^2 \\
0 & 0 & 1
\end{matrix}\right)
\left(\begin{matrix}m_0 \\ m_1 \\ m_2\end{matrix}\right) =
\left(\begin{matrix}
1 & 0 & 0 \\
1 & 1 & 1 \\
1 & -1 & 1 \\
1 & -2 & 4 \\
0 & 0 & 1
\end{matrix}\right)
\left(\begin{matrix}m_0 \\ m_1 \\ m_2\end{matrix}\right).

이 행렬은 평가 과정에서 만들었던 행렬과 같은 방식으로 만들어진 것이다. 가우스 소거법을 통해 이 행렬의 역행렬을 구할수도 있지만, 이는 너무 느리다. 하지만 우리가 앞서 고른 지점이 0, 1, &minus1, 2, &minus2 등으로 단순하므로 복잡한 계산과정 없이 행렬을 풀어낼 수 있다.

\begin{align}
\left(\begin{matrix}r_0 \\ r_1 \\ r_2 \\ r_3 \\ r_4\end{matrix}\right) & {} =
\left(\begin{matrix}
1 & 0 & 0 & 0 & 0 \\
1 & 1 & 1 & 1 & 1 \\
1 & -1 & 1 & -1 & 1 \\
1 & -2 & 4 & -8 & 16 \\
0 & 0 & 0 & 0 & 1
\end{matrix}\right)^{-1}
\left(\begin{matrix}r(0) \\ r(1) \\ r(-1) \\ r(-2) \\ r(\infty)\end{matrix}\right) \\
& {} =
\left(\begin{matrix}
 1 & 0 & 0 & 0 & 0 \\
 1/2 & 1/3 & -1 & 1/6 & -2 \\
 -1 & 1/2 & 1/2 & 0 & -1 \\
-1/2 & 1/6 & 1/2 & -1/6 & 2 \\
 0 & 0 & 0 & 0 & 1
\end{matrix}\right)
\left(\begin{matrix}r(0) \\ r(1) \\ r(-1) \\ r(-2) \\ r(\infty)\end{matrix}\right).
\end{align}

이제 남은 과정들은 모두 행렬-벡터 간의 곱셈이다. 행렬에 분수가 들어있지만, 그 결과는 정수로 나온다. 그렇기에 이 과정은 정수 간의 덧셈/뺄셈과 작은 상수를 곱하고 나누는 연산만 가지고 수행할 수 있다. 하지만 이 과정을 효율적으로 짜는 것은 쉽지 않은 일이다. 여기에서는 톰-3 알고리즘의 효율적인 방법을 소개한다.

만약 두 정수의 크기가 다르거나, 평가 지점이 다르다면 이 행렬 계산식 역시 달라질 것이다. 하지만 이는 사전에 계산될 수 있는 부분이므로 미리 효율적으로 작성해 둘 수 있다.

### 합성
최종적으로 다항식 ''r''(''x'')에 ''B''를 대입하여 결과를 얻어낼 수 있다. 여기서 b = 10이다.

위 결과가 1234567890123456789012와 987654321987654321098의 곱이다.

## ''k''값에 따른 보간 행렬
''k''값에 따른 보간 행렬을 몇 가지 정리해두었다.

### 톰-1
톰-1 (''k''

### 톰-1.5
톰-1.5 (''k''

### 톰-2
톰-2 (''k''

### 톰-2.5
톰-2.5 (''k''