# 多项式 · 符号计算的主力

> 计算机代数系统里，绝大多数硬核操作最后都落到多项式上。这一章讲清多项式的展开、合并、次数与系数，专门的 Poly 对象，以及最关键的多项式除法——它是下一章 GCD 与因式分解的地基。

- 作者：David（道雾轩）
- 专栏：符号计算的艺术（https://daiw.org/manual/symbolic-computing.md）
- 最后更新：2026-07-14
- 原文：https://daiw.org/manual/symbolic-computing/polynomials
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 多项式 · 符号计算的主力

进入代数引擎。如果说[表达式树](https://daiw.org/manual/symbolic-computing/expression-tree)是符号计算的骨架，那**多项式**就是它的肌肉——**计算机代数里绝大多数硬核算法，最后都归结到多项式的操作**：因式分解、解方程、符号积分、Gröbner 基…… 无一例外。先把这块主力吃透。

## 展开与合并：多项式的两个方向

多项式最基本的两个操作是一对反义词：**展开**（把乘积乘开）和**合并 / 因式分解**（把它收拢）。

```python
from sympy import *
x, y = symbols('x y')

print(expand((x + 1)**3))            # x**3 + 3*x**2 + 3*x + 1
print(collect(x**2*y + x**2 + x*y, x))   # x**2*(y + 1) + x*y  —— 按 x 的幂合并
```

`expand` 把 $(x+1)^3$ 乘成标准的**升幂 / 降幂形式**；`collect` 则把一个多元表达式**按某个变量的幂次归拢**。这两个是你整理多项式最顺手的工具。

## 次数与系数：读取多项式的信息

一个多项式，最重要的元数据是**次数**和**系数**：

```python
print(degree(x**5 - 3*x + 1, x))          # 5    —— 最高次
print(Poly(3*x**2 + 2*x + 1, x).all_coeffs())   # [3, 2, 1]  —— 各次系数
```

`degree` 给最高次数，`all_coeffs` 从高次到低次列出所有系数。别小看这俩：很多算法（判断线性 / 二次、估计复杂度、选择解法）第一步就是看次数和系数。

## Poly 对象：高效的专用表示

你平时写的 `x**2 + 2*x + 1` 是一棵通用[表达式树](https://daiw.org/manual/symbolic-computing/expression-tree)，灵活但做多项式运算时不够快。SymPy 提供一个**专用的 `Poly` 对象**，把多项式存成更紧凑高效的形式：

```python
p = Poly(x**2 + 2*x + 1, x)
print(p)          # Poly(x**2 + 2*x + 1, x, domain='ZZ')
```

<Callout type="info">
  **注意那个 `domain='ZZ'`——它是多项式的「系数从哪个数集来」。** `ZZ` 是整数、`QQ` 是有理数、`RR` 是实数。**系数域（coefficient domain）是计算机代数一个核心概念**：同一个多项式，在不同的域上，能不能因式分解、GCD 是什么，**答案可能完全不同**（下一章 $x^2-2$ 在有理数域不可分、在含 $\sqrt2$ 的域可分，就是活例子）。`Poly` 显式带着域，算得又快又不含糊。

  底层实现上，多项式还有**稠密**（记下每一项，含系数为 0 的）和**稀疏**（只记非零项）两种表示——像 $x^{1000}+1$ 这种，稀疏表示能省掉中间 999 个零，天壤之别。这些 `Poly` 都替你管好了。
</Callout>

## 多项式除法：GCD 与因式分解的地基

整数能做带余除法（$17 = 5\times3 + 2$），多项式也能——而且这是后面一切的**地基**：

```python
quotient, remainder = div(x**3 - 1, x - 1)
print(quotient, '...', remainder)     # x**2 + x + 1 ... 0
```

$x^3-1$ 除以 $x-1$，商是 $x^2+x+1$，余数是 $0$——余数为零，说明 $x-1$ **整除** $x^3-1$，即 $x-1$ 是它的一个**因式**。这个「带余除法」是**多项式版的欧几里得算法**的核心：

> 就像求两个整数的最大公因数靠反复取余（辗转相除），求两个**多项式**的最大公因式，也靠反复做多项式除法取余。

下一章的 GCD 与因式分解，全都站在这个「多项式除法」上。**多项式除法之于符号代数，就像加减乘除之于算术——最不起眼，却支撑一切。**

## 小结与下一章

多项式是符号计算的主力：**展开** `expand` / **合并** `collect` 是一对基本方向；`degree`、`all_coeffs` 读取次数与系数；专用的 **`Poly` 对象**带着**系数域**（`ZZ`/`QQ`/…）高效运算，底层还有稠密 / 稀疏表示之分。最关键的是**多项式带余除法** `div`——它是欧几里得算法、GCD、因式分解的共同地基。

有了多项式除法，我们就能问两个多项式的「公因子」问题了。这把钥匙能打开两扇门：**因式分解**（把多项式拆成不可约的积）和**最大公因式**（约分、化简的基础）。下一章一起看。👉 [因式分解与最大公因式](https://daiw.org/manual/symbolic-computing/factor-gcd)。

## 参考文献

- [1] von zur Gathen & Gerhard.《Modern Computer Algebra》, ch. 2-4 —— 多项式表示与算术。
- [2] Knuth.《TAOCP, Vol. 2》, §4.6 —— 多项式运算。
- [3] SymPy 文档.「Polynomials Manipulation Module.」https://docs.sympy.org/latest/modules/polys/index.html
