SymPy-1-13-中文文档-二十六-
SymPy 1.13 中文文档(二十六)
多项式操作模块的内部结构
多项式模块的实现在内部结构上被划分为“级别”。有四个级别,分别为 L0、L1、L2 和 L3。三级和四级包含面向用户的功能,并在上一节中进行了描述。本节重点介绍零级和一级。
零级提供了核心的类 C 风格低级接口的多项式操作功能。一级将这些低级功能封装到面向对象的结构中。这些并非用户可见的类,而是整个 polys 模块内部使用的类。
实现中还有一个额外的复杂性。这源于所有多项式操作都是相对于基础域进行的。例如,在因式分解多项式 (x^{10} - 1) 时,必须决定系数应属于哪个环,或者更不显然地,哪些系数允许在因式分解中出现。这种系数的选择称为基础域。典型的选择包括整数 (\mathbb{Z}),有理数 (\mathbb{Q}) 或各种相关的环和域。但在这种情况下,可以合法地(尽管无趣地)在多项式环上如 (k[Y]) 进行因式分解,其中 (k) 是某个固定域。
因此,多项式操作算法(包括复杂的如因式分解和简单的如加法或乘法)必须依赖其他代码来操作系数。在多项式操作模块中,这样的代码封装在所谓的“域”中。域基本上是一个工厂对象:它接受各种数据表示,并将它们转换为具有统一接口的对象。域创建的每个对象都必须实现算术运算 (+)、(-) 和 (\times)。其他操作通过域访问,例如像 ZZ.quo(ZZ(4), ZZ(2))
。
注意,这里存在一定的循环性:多项式环域使用一级类,一级类使用零级函数,而零级函数则使用环域。原则上可以,但在当前实现中无法像 (k[X][Y]) 这样工作。这会创建更多层级。因此,首选在同构环 (k[X, Y]) 中工作。
零级
零级包含了多项式操作模块的大部分代码。
稠密、多变量多项式的操作
这些函数可用于操纵K[X_0, \ldots, X_u]
中的多项式。仅适用于单变量多项式(即( u = 0 ))的函数带有前缀dup_
。必须显式传递地域( K )。对于许多多变量多项式操作函数,还必须传递级别( u ),即生成器数量减一。(请注意,在许多情况下,dup_
版本的函数可用,可能会稍微更有效。)
基本操作:
sympy.polys.densebasic.dmp_LC(f, K)
返回f
的主导系数。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import poly_LC
>>> poly_LC([], ZZ)
0
>>> poly_LC([ZZ(1), ZZ(2), ZZ(3)], ZZ)
1
sympy.polys.densebasic.dmp_TC(f, K)
返回f
的尾随系数。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import poly_TC
>>> poly_TC([], ZZ)
0
>>> poly_TC([ZZ(1), ZZ(2), ZZ(3)], ZZ)
3
sympy.polys.densebasic.dmp_ground_LC(f, u, K)
返回地主导系数。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_ground_LC
>>> f = ZZ.map([[[1], [2, 3]]])
>>> dmp_ground_LC(f, 2, ZZ)
1
sympy.polys.densebasic.dmp_ground_TC(f, u, K)
返回地尾随系数。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_ground_TC
>>> f = ZZ.map([[[1], [2, 3]]])
>>> dmp_ground_TC(f, 2, ZZ)
3
sympy.polys.densebasic.dmp_true_LT(f, u, K)
返回主导项 c * x_1**n_1 ... x_k**n_k
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_true_LT
>>> f = ZZ.map([[4], [2, 0], [3, 0, 0]])
>>> dmp_true_LT(f, 1, ZZ)
((2, 0), 4)
sympy.polys.densebasic.dmp_degree(f, u)
返回f
在K[X]
中关于x_0
的主导度。
注意,0 的度是负无穷 (float('-inf')
)。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_degree
>>> dmp_degree([[[]]], 2)
-inf
>>> f = ZZ.map([[2], [1, 2, 3]])
>>> dmp_degree(f, 1)
1
sympy.polys.densebasic.dmp_degree_in(f, j, u)
返回f
在K[X]
中关于x_j
的主导度。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_degree_in
>>> f = ZZ.map([[2], [1, 2, 3]])
>>> dmp_degree_in(f, 0, 1)
1
>>> dmp_degree_in(f, 1, 1)
2
sympy.polys.densebasic.dmp_degree_list(f, u)
返回f
在K[X]
中的度列表。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_degree_list
>>> f = ZZ.map([[1], [1, 2, 3]])
>>> dmp_degree_list(f, 1)
(1, 2)
sympy.polys.densebasic.dmp_strip(f, u)
从K[X]
中的f
中移除前导零。
例子
>>> from sympy.polys.densebasic import dmp_strip
>>> dmp_strip([[], [0, 1, 2], [1]], 1)
[[0, 1, 2], [1]]
sympy.polys.densebasic.dmp_validate(f, K=None)
返回f
中的级别数,并递归地剥离它。
例子
>>> from sympy.polys.densebasic import dmp_validate
>>> dmp_validate([[], [0, 1, 2], [1]])
([[1, 2], [1]], 1)
>>> dmp_validate([[1], 1])
Traceback (most recent call last):
...
ValueError: invalid data structure for a multivariate polynomial
sympy.polys.densebasic.dup_reverse(f)
计算x**n * f(1/x)
,即在K[x]
中反转f
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dup_reverse
>>> f = ZZ.map([1, 2, 3, 0])
>>> dup_reverse(f)
[3, 2, 1]
sympy.polys.densebasic.dmp_copy(f, u)
在K[X]
中创建f
的新拷贝。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_copy
>>> f = ZZ.map([[1], [1, 2]])
>>> dmp_copy(f, 1)
[[1], [1, 2]]
sympy.polys.densebasic.dmp_to_tuple(f, u)
将f
转换为嵌套元组的元组。
这是为了哈希而需要的。这类似于dmp_copy()
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_to_tuple
>>> f = ZZ.map([[1], [1, 2]])
>>> dmp_to_tuple(f, 1)
((1,), (1, 2))
sympy.polys.densebasic.dmp_normal(f, u, K)
在给定域中规范化多变量多项式。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_normal
>>> dmp_normal([[], [0, 1, 2]], 1, ZZ)
[[1, 2]]
sympy.polys.densebasic.dmp_convert(f, u, K0, K1)
将f
的地域从K0
转换为K1
。
例子
>>> from sympy.polys.rings import ring
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_convert
>>> R, x = ring("x", ZZ)
>>> dmp_convert([[R(1)], [R(2)]], 1, R.to_domain(), ZZ)
[[1], [2]]
>>> dmp_convert([[ZZ(1)], [ZZ(2)]], 1, ZZ, R.to_domain())
[[1], [2]]
sympy.polys.densebasic.dmp_from_sympy(f, u, K)
将f
的地域从 SymPy 转换为K
。
例子
>>> from sympy import S
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_from_sympy
>>> dmp_from_sympy([[S(1)], [S(2)]], 1, ZZ) == [[ZZ(1)], [ZZ(2)]]
True
sympy.polys.densebasic.dmp_nth(f, n, u, K)
返回f
在K[x]
中的第n
个系数。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_nth
>>> f = ZZ.map([[1], [2], [3]])
>>> dmp_nth(f, 0, 1, ZZ)
[3]
>>> dmp_nth(f, 4, 1, ZZ)
[]
sympy.polys.densebasic.dmp_ground_nth(f, N, u, K)
返回f
在K[x]
中关于n
的地n
次系数。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_ground_nth
>>> f = ZZ.map([[1], [2, 3]])
>>> dmp_ground_nth(f, (0, 1), 1, ZZ)
2
sympy.polys.densebasic.dmp_zero_p(f, u)
如果f
在K[X]
中为零则返回True
。
例子
>>> from sympy.polys.densebasic import dmp_zero_p
>>> dmp_zero_p([[[[[]]]]], 4)
True
>>> dmp_zero_p([[[[[1]]]]], 4)
False
sympy.polys.densebasic.dmp_zero(u)
返回一个多变量零点。
例子
>>> from sympy.polys.densebasic import dmp_zero
>>> dmp_zero(4)
[[[[[]]]]]
sympy.polys.densebasic.dmp_one_p(f, u, K)
如果f
在K[X]
中是一则返回True
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_one_p
>>> dmp_one_p([[[ZZ(1)]]], 2, ZZ)
True
sympy.polys.densebasic.dmp_one(u, K)
返回在K
上的一个多变量一。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_one
>>> dmp_one(2, ZZ)
[[[1]]]
sympy.polys.densebasic.dmp_ground_p(f, c, u)
如果f
在K[X]
中是常量则返回True
。
例子
>>> from sympy.polys.densebasic import dmp_ground_p
>>> dmp_ground_p([[[3]]], 3, 2)
True
>>> dmp_ground_p([[[4]]], None, 2)
True
sympy.polys.densebasic.dmp_ground(c, u)
返回一个多变量常数。
例子
>>> from sympy.polys.densebasic import dmp_ground
>>> dmp_ground(3, 5)
[[[[[[3]]]]]]
>>> dmp_ground(1, -1)
1
sympy.polys.densebasic.dmp_zeros(n, u, K)
返回多变量零点列表。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_zeros
>>> dmp_zeros(3, 2, ZZ)
[[[[]]], [[[]]], [[[]]]]
>>> dmp_zeros(3, -1, ZZ)
[0, 0, 0]
sympy.polys.densebasic.dmp_grounds(c, n, u)
返回多变量常数列表。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_grounds
>>> dmp_grounds(ZZ(4), 3, 2)
[[[[4]]], [[[4]]], [[[4]]]]
>>> dmp_grounds(ZZ(4), 3, -1)
[4, 4, 4]
sympy.polys.densebasic.dmp_negative_p(f, u, K)
如果LC(f)
为负则返回True
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_negative_p
>>> dmp_negative_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ)
False
>>> dmp_negative_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ)
True
sympy.polys.densebasic.dmp_positive_p(f, u, K)
如果LC(f)
为正则返回True
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_positive_p
>>> dmp_positive_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ)
True
>>> dmp_positive_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ)
False
sympy.polys.densebasic.dmp_from_dict(f, u, K)
从dict
创建一个K[X]
多项式。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_from_dict
>>> dmp_from_dict({(0, 0): ZZ(3), (0, 1): ZZ(2), (2, 1): ZZ(1)}, 1, ZZ)
[[1, 0], [], [2, 3]]
>>> dmp_from_dict({}, 0, ZZ)
[]
sympy.polys.densebasic.dmp_to_dict(f, u, K=None, zero=False)
将K[X]
多项式转换为py dict``
。
例子
>>> from sympy.polys.densebasic import dmp_to_dict
>>> dmp_to_dict([[1, 0], [], [2, 3]], 1)
{(0, 0): 3, (0, 1): 2, (2, 1): 1}
>>> dmp_to_dict([], 0)
{}
sympy.polys.densebasic.dmp_swap(f, i, j, u, K)
将K[..x_i..x_j..]
转换为K[..x_j..x_i..]
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_swap
>>> f = ZZ.map([[[2], [1, 0]], []])
>>> dmp_swap(f, 0, 1, 2, ZZ)
[[[2], []], [[1, 0], []]]
>>> dmp_swap(f, 1, 2, 2, ZZ)
[[[1], [2, 0]], [[]]]
>>> dmp_swap(f, 0, 2, 2, ZZ)
[[[1, 0]], [[2, 0], []]]
sympy.polys.densebasic.dmp_permute(f, P, u, K)
返回一个多项式在K[x_{P(1)},..,x_{P(n)}]
中。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_permute
>>> f = ZZ.map([[[2], [1, 0]], []])
>>> dmp_permute(f, [1, 0, 2], 2, ZZ)
[[[2], []], [[1, 0], []]]
>>> dmp_permute(f, [1, 2, 0], 2, ZZ)
[[[1], []], [[2, 0], []]]
sympy.polys.densebasic.dmp_nest(f, l, K)
返回嵌套l
级别的多变量值。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_nest
>>> dmp_nest([[ZZ(1)]], 2, ZZ)
[[[[1]]]]
sympy.polys.densebasic.dmp_raise(f, l, u, K)
返回提升l
级别的多变量多项式。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_raise
>>> f = ZZ.map([[], [1, 2]])
>>> dmp_raise(f, 2, 1, ZZ)
[[[[]]], [[[1]], [[2]]]]
sympy.polys.densebasic.dmp_deflate(f, u, K)
在K[X]
多项式中将x_i**m_i
映射到y_i
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_deflate
>>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]])
>>> dmp_deflate(f, 1, ZZ)
((2, 3), [[1, 2], [3, 4]])
sympy.polys.densebasic.dmp_multi_deflate(polys, u, K)
在K[X]
多项式集合中将x_i**m_i
映射到y_i
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_multi_deflate
>>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]])
>>> g = ZZ.map([[1, 0, 2], [], [3, 0, 4]])
>>> dmp_multi_deflate((f, g), 1, ZZ)
((2, 1), ([[1, 0, 0, 2], [3, 0, 0, 4]], [[1, 0, 2], [3, 0, 4]]))
sympy.polys.densebasic.dmp_inflate(f, M, u, K)
在K[X]
中的多项式中将y_i
映射到x_i**k_i
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_inflate
>>> f = ZZ.map([[1, 2], [3, 4]])
>>> dmp_inflate(f, (2, 3), 1, ZZ)
[[1, 0, 0, 2], [], [3, 0, 0, 4]]
sympy.polys.densebasic.dmp_exclude(f, u, K)
从f
中排除无用的级别。
返回排除的级别,新排除的f
和新的u
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_exclude
>>> f = ZZ.map([[[1]], [[1], [2]]])
>>> dmp_exclude(f, 2, ZZ)
([2], [[1], [1, 2]], 1)
sympy.polys.densebasic.dmp_include(f, J, u, K)
在f
中包括无用的级别。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_include
>>> f = ZZ.map([[1], [1, 2]])
>>> dmp_include(f, [2], 1, ZZ)
[[[1]], [[1], [2]]]
sympy.polys.densebasic.dmp_inject(f, u, K, front=False)
将f
从K[X][Y]
转换为K[X,Y]
。
例子
>>> from sympy.polys.rings import ring
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_inject
>>> R, x,y = ring("x,y", ZZ)
>>> dmp_inject([R(1), x + 2], 0, R.to_domain())
([[[1]], [[1], [2]]], 2)
>>> dmp_inject([R(1), x + 2], 0, R.to_domain(), front=True)
([[[1]], [[1, 2]]], 2)
sympy.polys.densebasic.dmp_eject(f, u, K, front=False)
将f
从K[X,Y]
转换为K[X][Y]
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_eject
>>> dmp_eject([[[1]], [[1], [2]]], 2, ZZ['x', 'y'])
[1, x + 2]
sympy.polys.densebasic.dmp_terms_gcd(f, u, K)
从K[X]
中去除f
的项的最大公约数。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_terms_gcd
>>> f = ZZ.map([[1, 0], [1, 0, 0], [], []])
>>> dmp_terms_gcd(f, 1, ZZ)
((2, 1), [[1], [1, 0]])
sympy.polys.densebasic.dmp_list_terms(f, u, K, order=None)
按给定顺序order
列出f
中的所有非零项。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_list_terms
>>> f = ZZ.map([[1, 1], [2, 3]])
>>> dmp_list_terms(f, 1, ZZ)
[((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)]
>>> dmp_list_terms(f, 1, ZZ, order='grevlex')
[((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)]
sympy.polys.densebasic.dmp_apply_pairs(f, g, h, args, u, K)
对f
和g
的系数对应应用h
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dmp_apply_pairs
>>> h = lambda x, y, z: 2*x + y - z
>>> dmp_apply_pairs([[1], [2, 3]], [[3], [2, 1]], h, (1,), 1, ZZ)
[[4], [5, 6]]
sympy.polys.densebasic.dmp_slice(f, m, n, u, K)
在K[X]
中取f
的连续子序列。
sympy.polys.densebasic.dup_random(n, a, b, K)
返回n
阶多项式,其系数在[a, b]
中。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.densebasic import dup_random
>>> dup_random(3, -10, 10, ZZ)
[-2, -8, 9, -4]
算术运算:
sympy.polys.densearith.dmp_add_term(f, c, i, u, K)
在K[X]
中将c(x_2..x_u)*x_0**i
添加到f
中。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_add_term(x*y + 1, 2, 2)
2*x**2 + x*y + 1
sympy.polys.densearith.dmp_sub_term(f, c, i, u, K)
从K[X]
中的f
中减去c(x_2..x_u)*x_0**i
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_sub_term(2*x**2 + x*y + 1, 2, 2)
x*y + 1
sympy.polys.densearith.dmp_mul_term(f, c, i, u, K)
在K[X]
中将f
乘以c(x_2..x_u)*x_0**i
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_mul_term(x**2*y + x, 3*y, 2)
3*x**4*y**2 + 3*x**3*y
sympy.polys.densearith.dmp_add_ground(f, c, u, K)
向f
中添加地域域的元素。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_add_ground(x**3 + 2*x**2 + 3*x + 4, ZZ(4))
x**3 + 2*x**2 + 3*x + 8
sympy.polys.densearith.dmp_sub_ground(f, c, u, K)
从f
中减去地域域的元素。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_sub_ground(x**3 + 2*x**2 + 3*x + 4, ZZ(4))
x**3 + 2*x**2 + 3*x
sympy.polys.densearith.dmp_mul_ground(f, c, u, K)
在K[X]
中将f
乘以一个常数值。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_mul_ground(2*x + 2*y, ZZ(3))
6*x + 6*y
sympy.polys.densearith.dmp_quo_ground(f, c, u, K)
在K[X]
中对常数进行除法。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_quo_ground(2*x**2*y + 3*x, ZZ(2))
x**2*y + x
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_quo_ground(2*x**2*y + 3*x, QQ(2))
x**2*y + 3/2*x
sympy.polys.densearith.dmp_exquo_ground(f, c, u, K)
在K[X]
中对常数进行精确除法。
示例
>>> from sympy.polys import ring, QQ
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_exquo_ground(x**2*y + 2*x, QQ(2))
1/2*x**2*y + x
sympy.polys.densearith.dup_lshift(f, n, K)
在K[x]
中高效地将f
乘以x**n
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_lshift(x**2 + 1, 2)
x**4 + x**2
sympy.polys.densearith.dup_rshift(f, n, K)
在K[x]
中高效地将f
除以x**n
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_rshift(x**4 + x**2, 2)
x**2 + 1
>>> R.dup_rshift(x**4 + x**2 + 2, 2)
x**2 + 1
sympy.polys.densearith.dmp_abs(f, u, K)
使K[X]
中所有系数为正。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_abs(x**2*y - x)
x**2*y + x
sympy.polys.densearith.dmp_neg(f, u, K)
在K[X]
中对f
进行否定。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_neg(x**2*y - x)
-x**2*y + x
sympy.polys.densearith.dmp_add(f, g, u, K)
在K[X]
中添加密集多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_add(x**2 + y, x**2*y + x)
x**2*y + x**2 + x + y
sympy.polys.densearith.dmp_sub(f, g, u, K)
在K[X]
中减去密集多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_sub(x**2 + y, x**2*y + x)
-x**2*y + x**2 - x + y
sympy.polys.densearith.dmp_add_mul(f, g, h, u, K)
返回f + g*h
,其中f, g, h
在K[X]
中。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_add_mul(x**2 + y, x, x + 2)
2*x**2 + 2*x + y
sympy.polys.densearith.dmp_sub_mul(f, g, h, u, K)
返回f - g*h
,其中f, g, h
在K[X]
中。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_sub_mul(x**2 + y, x, x + 2)
-2*x + y
sympy.polys.densearith.dmp_mul(f, g, u, K)
在K[X]
中乘以密集多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_mul(x*y + 1, x)
x**2*y + x
sympy.polys.densearith.dmp_sqr(f, u, K)
在K[X]
中平方密集多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_sqr(x**2 + x*y + y**2)
x**4 + 2*x**3*y + 3*x**2*y**2 + 2*x*y**3 + y**4
sympy.polys.densearith.dmp_pow(f, n, u, K)
将f
提升到n
次幂在K[X]
中。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_pow(x*y + 1, 3)
x**3*y**3 + 3*x**2*y**2 + 3*x*y + 1
sympy.polys.densearith.dmp_pdiv(f, g, u, K)
在K[X]
中进行多项式伪除法。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_pdiv(x**2 + x*y, 2*x + 2)
(2*x + 2*y - 2, -4*y + 4)
sympy.polys.densearith.dmp_prem(f, g, u, K)
在K[X]
中进行多项式伪除法。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_prem(x**2 + x*y, 2*x + 2)
-4*y + 4
sympy.polys.densearith.dmp_pquo(f, g, u, K)
在K[X]
中进行精确的多项式伪除法。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x**2 + x*y
>>> g = 2*x + 2*y
>>> h = 2*x + 2
>>> R.dmp_pquo(f, g)
2*x
>>> R.dmp_pquo(f, h)
2*x + 2*y - 2
sympy.polys.densearith.dmp_pexquo(f, g, u, K)
在K[X]
中进行多项式伪除法。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x**2 + x*y
>>> g = 2*x + 2*y
>>> h = 2*x + 2
>>> R.dmp_pexquo(f, g)
2*x
>>> R.dmp_pexquo(f, h)
Traceback (most recent call last):
...
ExactQuotientFailed: [[2], [2]] does not divide [[1], [1, 0], []]
sympy.polys.densearith.dmp_rr_div(f, g, u, K)
在环上进行多变量除法并得到余数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_rr_div(x**2 + x*y, 2*x + 2)
(0, x**2 + x*y)
sympy.polys.densearith.dmp_ff_div(f, g, u, K)
在一个域上进行多项式除法并得到余数。
示例
>>> from sympy.polys import ring, QQ
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_ff_div(x**2 + x*y, 2*x + 2)
(1/2*x + 1/2*y - 1/2, -y + 1)
sympy.polys.densearith.dmp_div(f, g, u, K)
在K[X]
中进行多项式除法并得到余数。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_div(x**2 + x*y, 2*x + 2)
(0, x**2 + x*y)
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_div(x**2 + x*y, 2*x + 2)
(1/2*x + 1/2*y - 1/2, -y + 1)
sympy.polys.densearith.dmp_rem(f, g, u, K)
返回K[X]
中的多项式余数。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_rem(x**2 + x*y, 2*x + 2)
x**2 + x*y
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_rem(x**2 + x*y, 2*x + 2)
-y + 1
sympy.polys.densearith.dmp_quo(f, g, u, K)
返回K[X]
中的精确多项式商。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_quo(x**2 + x*y, 2*x + 2)
0
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_quo(x**2 + x*y, 2*x + 2)
1/2*x + 1/2*y - 1/2
sympy.polys.densearith.dmp_exquo(f, g, u, K)
返回K[X]
中的多项式商。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x**2 + x*y
>>> g = x + y
>>> h = 2*x + 2
>>> R.dmp_exquo(f, g)
x
>>> R.dmp_exquo(f, h)
Traceback (most recent call last):
...
ExactQuotientFailed: [[2], [2]] does not divide [[1], [1, 0], []]
sympy.polys.densearith.dmp_max_norm(f, u, K)
返回K[X]
中多项式的最大范数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_max_norm(2*x*y - x - 3)
3
sympy.polys.densearith.dmp_l1_norm(f, u, K)
返回K[X]
中多项式的 l1 范数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_l1_norm(2*x*y - x - 3)
6
sympy.polys.densearith.dmp_expand(polys, u, K)
在K[X]
中将多个多项式相乘。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_expand([x**2 + y**2, x + 1])
x**3 + x**2 + x*y**2 + y**2
进一步的工具:
sympy.polys.densetools.dmp_integrate(f, m, u, K)
在K[X]
中计算x_0
的f
的不定积分。
示例
>>> from sympy.polys import ring, QQ
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_integrate(x + 2*y, 1)
1/2*x**2 + 2*x*y
>>> R.dmp_integrate(x + 2*y, 2)
1/6*x**3 + x**2*y
sympy.polys.densetools.dmp_integrate_in(f, m, j, u, K)
在K[X]
中计算x_j
的f
的不定积分。
示例
>>> from sympy.polys import ring, QQ
>>> R, x,y = ring("x,y", QQ)
>>> R.dmp_integrate_in(x + 2*y, 1, 0)
1/2*x**2 + 2*x*y
>>> R.dmp_integrate_in(x + 2*y, 1, 1)
x*y + y**2
sympy.polys.densetools.dmp_diff(f, m, u, K)
在K[X]
中x_0
的m
阶导数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x*y**2 + 2*x*y + 3*x + 2*y**2 + 3*y + 1
>>> R.dmp_diff(f, 1)
y**2 + 2*y + 3
>>> R.dmp_diff(f, 2)
0
sympy.polys.densetools.dmp_diff_in(f, m, j, u, K)
在K[X]
中x_j
的m
阶导数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x*y**2 + 2*x*y + 3*x + 2*y**2 + 3*y + 1
>>> R.dmp_diff_in(f, 1, 0)
y**2 + 2*y + 3
>>> R.dmp_diff_in(f, 1, 1)
2*x*y + 2*x + 4*y + 3
sympy.polys.densetools.dmp_eval(f, a, u, K)
使用 Horner 方案在K[X]
中评估多项式在x_0 = a
处的值。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_eval(2*x*y + 3*x + y + 2, 2)
5*y + 8
sympy.polys.densetools.dmp_eval_in(f, a, j, u, K)
使用 Horner 方案在K[X]
中评估多项式在x_j = a
处的值。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 2*x*y + 3*x + y + 2
>>> R.dmp_eval_in(f, 2, 0)
5*y + 8
>>> R.dmp_eval_in(f, 2, 1)
7*x + 4
sympy.polys.densetools.dmp_eval_tail(f, A, u, K)
在K[X]
中评估多项式在x_j = a_j, ...
处。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 2*x*y + 3*x + y + 2
>>> R.dmp_eval_tail(f, [2])
7*x + 4
>>> R.dmp_eval_tail(f, [2, 2])
18
sympy.polys.densetools.dmp_diff_eval_in(f, m, a, j, u, K)
在K[X]
中以x_j
处于a
时区分和评估多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x*y**2 + 2*x*y + 3*x + 2*y**2 + 3*y + 1
>>> R.dmp_diff_eval_in(f, 1, 2, 0)
y**2 + 2*y + 3
>>> R.dmp_diff_eval_in(f, 1, 2, 1)
6*x + 11
sympy.polys.densetools.dmp_trunc(f, p, u, K)
在K[Y]
中用多项式p
对K[X]
中的多项式进行取模。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 3*x**2*y + 8*x**2 + 5*x*y + 6*x + 2*y + 3
>>> g = (y - 1).drop(x)
>>> R.dmp_trunc(f, g)
11*x**2 + 11*x + 5
sympy.polys.densetools.dmp_ground_trunc(f, p, u, K)
在K
中用常数p
对K[X]
多项式进行取模。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 3*x**2*y + 8*x**2 + 5*x*y + 6*x + 2*y + 3
>>> R.dmp_ground_trunc(f, ZZ(3))
-x**2 - x*y - y
sympy.polys.densetools.dup_monic(f, K)
在K[x]
中将所有系数除以LC(f)
。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x = ring("x", ZZ)
>>> R.dup_monic(3*x**2 + 6*x + 9)
x**2 + 2*x + 3
>>> R, x = ring("x", QQ)
>>> R.dup_monic(3*x**2 + 4*x + 2)
x**2 + 4/3*x + 2/3
sympy.polys.densetools.dmp_ground_monic(f, u, K)
在K[X]
中将所有系数除以LC(f)
。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 3*x**2*y + 6*x**2 + 3*x*y + 9*y + 3
>>> R.dmp_ground_monic(f)
x**2*y + 2*x**2 + x*y + 3*y + 1
>>> R, x,y = ring("x,y", QQ)
>>> f = 3*x**2*y + 8*x**2 + 5*x*y + 6*x + 2*y + 3
>>> R.dmp_ground_monic(f)
x**2*y + 8/3*x**2 + 5/3*x*y + 2*x + 2/3*y + 1
sympy.polys.densetools.dup_content(f, K)
计算K[x]
中f
的系数的最大公约数。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x = ring("x", ZZ)
>>> f = 6*x**2 + 8*x + 12
>>> R.dup_content(f)
2
>>> R, x = ring("x", QQ)
>>> f = 6*x**2 + 8*x + 12
>>> R.dup_content(f)
2
sympy.polys.densetools.dmp_ground_content(f, u, K)
计算K[X]
中f
的系数的最大公约数。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 2*x*y + 6*x + 4*y + 12
>>> R.dmp_ground_content(f)
2
>>> R, x,y = ring("x,y", QQ)
>>> f = 2*x*y + 6*x + 4*y + 12
>>> R.dmp_ground_content(f)
2
sympy.polys.densetools.dup_primitive(f, K)
计算 f
在 K[x]
中的内容和原始形式。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x = ring("x", ZZ)
>>> f = 6*x**2 + 8*x + 12
>>> R.dup_primitive(f)
(2, 3*x**2 + 4*x + 6)
>>> R, x = ring("x", QQ)
>>> f = 6*x**2 + 8*x + 12
>>> R.dup_primitive(f)
(2, 3*x**2 + 4*x + 6)
sympy.polys.densetools.dmp_ground_primitive(f, u, K)
计算 f
在 K[X]
中的内容和原始形式。
示例
>>> from sympy.polys import ring, ZZ, QQ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 2*x*y + 6*x + 4*y + 12
>>> R.dmp_ground_primitive(f)
(2, x*y + 3*x + 2*y + 6)
>>> R, x,y = ring("x,y", QQ)
>>> f = 2*x*y + 6*x + 4*y + 12
>>> R.dmp_ground_primitive(f)
(2, x*y + 3*x + 2*y + 6)
sympy.polys.densetools.dup_extract(f, g, K)
从一对 K[x]
中的多项式中提取共同内容。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_extract(6*x**2 + 12*x + 18, 4*x**2 + 8*x + 12)
(2, 3*x**2 + 6*x + 9, 2*x**2 + 4*x + 6)
sympy.polys.densetools.dmp_ground_extract(f, g, u, K)
从一对 K[X]
中的多项式中提取共同内容。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_ground_extract(6*x*y + 12*x + 18, 4*x*y + 8*x + 12)
(2, 3*x*y + 6*x + 9, 2*x*y + 4*x + 6)
sympy.polys.densetools.dup_real_imag(f, K)
找到 f1
和 f2
,使得 f(x+I*y) = f1(x,y) + f2(x,y)*I
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dup_real_imag(x**3 + x**2 + x + 1)
(x**3 + x**2 - 3*x*y**2 + x - y**2 + 1, 3*x**2*y + 2*x*y - y**3 + y)
>>> from sympy.abc import x, y, z
>>> from sympy import I
>>> (z**3 + z**2 + z + 1).subs(z, x+I*y).expand().collect(I)
x**3 + x**2 - 3*x*y**2 + x - y**2 + I*(3*x**2*y + 2*x*y - y**3 + y) + 1
sympy.polys.densetools.dup_mirror(f, K)
高效评估 K[x]
中的组合 f(-x)
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_mirror(x**3 + 2*x**2 - 4*x + 2)
-x**3 + 2*x**2 + 4*x + 2
sympy.polys.densetools.dup_scale(f, a, K)
高效评估 K[x]
中的组合 f(a*x)
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_scale(x**2 - 2*x + 1, ZZ(2))
4*x**2 - 4*x + 1
sympy.polys.densetools.dup_shift(f, a, K)
高效评估 K[x]
中的泰勒变换 f(x + a)
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_shift(x**2 - 2*x + 1, ZZ(2))
x**2 + 2*x + 1
sympy.polys.densetools.dup_transform(f, p, q, K)
在 K[x]
中评估函数变换 q**n * f(p/q)
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_transform(x**2 - 2*x + 1, x**2 + 1, x - 1)
x**4 - 2*x**3 + 5*x**2 - 4*x + 4
sympy.polys.densetools.dmp_compose(f, g, u, K)
在 K[X]
中评估函数组合 f(g)
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_compose(x*y + 2*x + y, y)
y**2 + 3*y
sympy.polys.densetools.dup_decompose(f, K)
计算 f
在 K[x]
中的函数分解。
给定系数为零特征场中的一元多项式 f
,返回列表 [f_1, f_2, ..., f_n]
,其中:
f = f_1 o f_2 o ... f_n = f_1(f_2(... f_n))
而 f_2, ..., f_n
是至少二次的单项且齐次多项式。
与因式分解不同,多项式的完整函数分解并非唯一,考虑示例:
-
f o g = f(x + b) o (g - b)
-
x**n o x**m = x**m o x**n
-
T_n o T_m = T_m o T_n
其中 T_n
和 T_m
是切比雪夫多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_decompose(x**4 - 2*x**3 + x**2)
[x**2, x**2 - x]
参考文献
[R784]
sympy.polys.densetools.dmp_lift(f, u, K)
将代数系数转换为 K[X]
中的整数。
示例
>>> from sympy.polys import ring, QQ
>>> from sympy import I
>>> K = QQ.algebraic_field(I)
>>> R, x = ring("x", K)
>>> f = x**2 + K([QQ(1), QQ(0)])*x + K([QQ(2), QQ(0)])
>>> R.dmp_lift(f)
x**8 + 2*x**6 + 9*x**4 - 8*x**2 + 16
sympy.polys.densetools.dup_sign_variations(f, K)
计算 f
在 K[x]
中的符号变化数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_sign_variations(x**4 - x**2 - x + 1)
2
sympy.polys.densetools.dmp_clear_denoms(f, u, K0, K1=None, convert=False)
清除分母,即将 K_0
转换为 K_1
。
示例
>>> from sympy.polys import ring, QQ
>>> R, x,y = ring("x,y", QQ)
>>> f = QQ(1,2)*x + QQ(1,3)*y + 1
>>> R.dmp_clear_denoms(f, convert=False)
(6, 3*x + 2*y + 6)
>>> R.dmp_clear_denoms(f, convert=True)
(6, 3*x + 2*y + 6)
sympy.polys.densetools.dmp_revert(f, g, u, K)
使用牛顿迭代计算 f**(-1)
mod x**n
。
示例
>>> from sympy.polys import ring, QQ
>>> R, x,y = ring("x,y", QQ)
处理具有有限域系数的密集单变量多项式
本模块中的函数具有前缀 gf_
,指的是有限域的经典名称“伽罗瓦场”。需要指出,许多多项式因式分解算法通过将问题归约到有限域情况来实现,因此对这种情况进行特殊实现既有性能上的正当性,也有某些方法在一般域上甚至是没有意义的必要性。
sympy.polys.galoistools.gf_crt(U, M, K=None)
中国剩余定理。
给定整数余数集合 u_0,...,u_n
和互质整数模数集合 m_0,...,m_n
,返回一个整数 u
,使得 u = u_i mod m_i
for pyi = ``0,...,n
。
示例
考虑一个余数集合 U = [49, 76, 65]
和一个模数集合 M = [99, 97, 95]
。然后我们有:
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_crt
>>> gf_crt([49, 76, 65], [99, 97, 95], ZZ)
639985
这是正确的结果,因为:
>>> [639985 % m for m in [99, 97, 95]]
[49, 76, 65]
注意:这是一个低级别的例程,没有错误检查。
参见
sympy.ntheory.modular.crt
一个更高级的 crt 例程
sympy.ntheory.modular.solve_congruence
sympy.polys.galoistools.gf_crt1(M, K)
中国剩余定理的第一部分。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_crt, gf_crt1, gf_crt2
>>> U = [49, 76, 65]
>>> M = [99, 97, 95]
下面两个代码有相同的结果。
>>> gf_crt(U, M, ZZ)
639985
>>> p, E, S = gf_crt1(M, ZZ)
>>> gf_crt2(U, M, p, E, S, ZZ)
639985
然而,当我们想要固定 M
并为多个 U
计算时,速度更快,即以下情况:
>>> p, E, S = gf_crt1(M, ZZ)
>>> Us = [[49, 76, 65], [23, 42, 67]]
>>> for U in Us:
... print(gf_crt2(U, M, p, E, S, ZZ))
639985
236237
参见
sympy.ntheory.modular.crt1
一个更高级的 crt 例程
sympy.polys.galoistools.gf_crt
,sympy.polys.galoistools.gf_crt2
sympy.polys.galoistools.gf_crt2(U, M, p, E, S, K)
中国剩余定理的第二部分。
查看gf_crt1
的使用方法。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_crt2
>>> U = [49, 76, 65]
>>> M = [99, 97, 95]
>>> p = 912285
>>> E = [9215, 9405, 9603]
>>> S = [62, 24, 12]
>>> gf_crt2(U, M, p, E, S, ZZ)
639985
另请参阅
sympy.ntheory.modular.crt2
一个更高级别的 CRT 例程
sympy.polys.galoistools.gf_crt
,sympy.polys.galoistools.gf_crt1
sympy.polys.galoistools.gf_int(a, p)
将a mod p
强制转换为范围为[-p/2, p/2]
的整数。
示例
>>> from sympy.polys.galoistools import gf_int
>>> gf_int(2, 7)
2
>>> gf_int(5, 7)
-2
sympy.polys.galoistools.gf_degree(f)
返回f
的最高次数。
示例
>>> from sympy.polys.galoistools import gf_degree
>>> gf_degree([1, 1, 2, 0])
3
>>> gf_degree([])
-1
sympy.polys.galoistools.gf_LC(f, K)
返回f
的最高系数。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_LC
>>> gf_LC([3, 0, 1], ZZ)
3
sympy.polys.galoistools.gf_TC(f, K)
返回f
的尾系数。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_TC
>>> gf_TC([3, 0, 1], ZZ)
1
sympy.polys.galoistools.gf_strip(f)
从f
中去除前导零。
示例
>>> from sympy.polys.galoistools import gf_strip
>>> gf_strip([0, 0, 0, 3, 0, 1])
[3, 0, 1]
sympy.polys.galoistools.gf_trunc(f, p)
将所有系数模p
减小。
示例
>>> from sympy.polys.galoistools import gf_trunc
>>> gf_trunc([7, -2, 3], 5)
[2, 3, 3]
sympy.polys.galoistools.gf_normal(f, p, K)
将K
中的所有系数标准化。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_normal
>>> gf_normal([5, 10, 21, -3], 5, ZZ)
[1, 2]
sympy.polys.galoistools.gf_from_dict(f, p, K)
从字典创建GF(p)[x]
多项式。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_from_dict
>>> gf_from_dict({10: ZZ(4), 4: ZZ(33), 0: ZZ(-1)}, 5, ZZ)
[4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4]
sympy.polys.galoistools.gf_to_dict(f, p, symmetric=True)
将GF(p)[x]
多项式转换为字典。
示例
>>> from sympy.polys.galoistools import gf_to_dict
>>> gf_to_dict([4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4], 5)
{0: -1, 4: -2, 10: -1}
>>> gf_to_dict([4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4], 5, symmetric=False)
{0: 4, 4: 3, 10: 4}
sympy.polys.galoistools.gf_from_int_poly(f, p)
创建一个从Z[x]
到GF(p)[x]
的多项式。
示例
>>> from sympy.polys.galoistools import gf_from_int_poly
>>> gf_from_int_poly([7, -2, 3], 5)
[2, 3, 3]
sympy.polys.galoistools.gf_to_int_poly(f, p, symmetric=True)
将GF(p)[x]
多项式转换为Z[x]
。
示例
>>> from sympy.polys.galoistools import gf_to_int_poly
>>> gf_to_int_poly([2, 3, 3], 5)
[2, -2, -2]
>>> gf_to_int_poly([2, 3, 3], 5, symmetric=False)
[2, 3, 3]
sympy.polys.galoistools.gf_neg(f, p, K)
在GF(p)[x]
中取负多项式。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_neg
>>> gf_neg([3, 2, 1, 0], 5, ZZ)
[2, 3, 4, 0]
sympy.polys.galoistools.gf_add_ground(f, a, p, K)
计算f + a
,其中f
在GF(p)[x]
,a
在GF(p)
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_add_ground
>>> gf_add_ground([3, 2, 4], 2, 5, ZZ)
[3, 2, 1]
sympy.polys.galoistools.gf_sub_ground(f, a, p, K)
计算f - a
,其中f
在GF(p)[x]
,a
在GF(p)
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_sub_ground
>>> gf_sub_ground([3, 2, 4], 2, 5, ZZ)
[3, 2, 2]
sympy.polys.galoistools.gf_mul_ground(f, a, p, K)
计算f * a
,其中f
在GF(p)[x]
,a
在GF(p)
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_mul_ground
>>> gf_mul_ground([3, 2, 4], 2, 5, ZZ)
[1, 4, 3]
sympy.polys.galoistools.gf_quo_ground(f, a, p, K)
计算f/a
,其中f
在GF(p)[x]
,a
在GF(p)
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_quo_ground
>>> gf_quo_ground(ZZ.map([3, 2, 4]), ZZ(2), 5, ZZ)
[4, 1, 2]
sympy.polys.galoistools.gf_add(f, g, p, K)
在GF(p)[x]
中添加多项式。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_add
>>> gf_add([3, 2, 4], [2, 2, 2], 5, ZZ)
[4, 1]
sympy.polys.galoistools.gf_sub(f, g, p, K)
在GF(p)[x]
中减去多项式。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_sub
>>> gf_sub([3, 2, 4], [2, 2, 2], 5, ZZ)
[1, 0, 2]
sympy.polys.galoistools.gf_mul(f, g, p, K)
在GF(p)[x]
中乘法多项式。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_mul
>>> gf_mul([3, 2, 4], [2, 2, 2], 5, ZZ)
[1, 0, 3, 2, 3]
sympy.polys.galoistools.gf_sqr(f, p, K)
在GF(p)[x]
中平方多项式。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_sqr
>>> gf_sqr([3, 2, 4], 5, ZZ)
[4, 2, 3, 1, 1]
sympy.polys.galoistools.gf_add_mul(f, g, h, p, K)
返回f + g*h
,其中f
,g
,h
在GF(p)[x]
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_add_mul
>>> gf_add_mul([3, 2, 4], [2, 2, 2], [1, 4], 5, ZZ)
[2, 3, 2, 2]
sympy.polys.galoistools.gf_sub_mul(f, g, h, p, K)
计算f - g*h
,其中f
,g
,h
在GF(p)[x]
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_sub_mul
>>> gf_sub_mul([3, 2, 4], [2, 2, 2], [1, 4], 5, ZZ)
[3, 3, 2, 1]
sympy.polys.galoistools.gf_expand(F, p, K)
扩展factor()
在GF(p)[x]
中的结果。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_expand
>>> gf_expand([([3, 2, 4], 1), ([2, 2], 2), ([3, 1], 3)], 5, ZZ)
[4, 3, 0, 3, 0, 1, 4, 1]
sympy.polys.galoistools.gf_div(f, g, p, K)
在GF(p)[x]
中进行除法与余数。
给定系数在有限元素p
的域中的一元多项式f
和g
,返回多项式q
和r
(商和余数),使得f = q*g + r
。
考虑 GF(2)中的多项式x**3 + x + 1
和x**2 + x
:
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_div, gf_add_mul
>>> gf_div(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
([1, 1], [1])
结果是商x + 1
和余数1
,因此:
>>> gf_add_mul(ZZ.map([1]), ZZ.map([1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
[1, 0, 1, 1]
参考文献
[R785]
[R786]
sympy.polys.galoistools.gf_rem(f, g, p, K)
在GF(p)[x]
中计算多项式余数。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_rem
>>> gf_rem(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
[1]
sympy.polys.galoistools.gf_quo(f, g, p, K)
在GF(p)[x]
中计算精确的商。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_quo
>>> gf_quo(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
[1, 1]
>>> gf_quo(ZZ.map([1, 0, 3, 2, 3]), ZZ.map([2, 2, 2]), 5, ZZ)
[3, 2, 4]
sympy.polys.galoistools.gf_exquo(f, g, p, K)
在GF(p)[x]
中计算多项式商。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_exquo
>>> gf_exquo(ZZ.map([1, 0, 3, 2, 3]), ZZ.map([2, 2, 2]), 5, ZZ)
[3, 2, 4]
>>> gf_exquo(ZZ.map([1, 0, 1, 1]), ZZ.map([1, 1, 0]), 2, ZZ)
Traceback (most recent call last):
...
ExactQuotientFailed: [1, 1, 0] does not divide [1, 0, 1, 1]
sympy.polys.galoistools.gf_lshift(f, n, K)
高效地将f
乘以x**n
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_lshift
>>> gf_lshift([3, 2, 4], 4, ZZ)
[3, 2, 4, 0, 0, 0, 0]
sympy.polys.galoistools.gf_rshift(f, n, K)
高效地将f
除以x**n
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_rshift
>>> gf_rshift([1, 2, 3, 4, 0], 3, ZZ)
([1, 2], [3, 4, 0])
sympy.polys.galoistools.gf_pow(f, n, p, K)
使用重复平方算法在GF(p)[x]
中计算f**n
。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_pow
>>> gf_pow([3, 2, 4], 3, 5, ZZ)
[2, 4, 4, 2, 2, 1, 4]
sympy.polys.galoistools.gf_pow_mod(f, n, g, p, K)
使用重复平方算法在GF(p)[x]/(g)
中计算f**n
。
对于给定的多项式f
和g
在GF(p)[x]
以及非负整数n
,高效地计算f**n (mod g)
,即通过重复平方算法得到f**n
除以g
的余数。
示例
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_pow_mod
>>> gf_pow_mod(ZZ.map([3, 2, 4]), 3, ZZ.map([1, 1]), 5, ZZ)
[]
参考文献
[R787]
sympy.polys.galoistools.gf_gcd(f, g, p, K)
GF(p)[x]
中的欧几里得算法。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_gcd
>>> gf_gcd(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 3]), 5, ZZ)
[1, 3]
sympy.polys.galoistools.gf_lcm(f, g, p, K)
在GF(p)[x]
中计算多项式 LCM。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_lcm
>>> gf_lcm(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 3]), 5, ZZ)
[1, 2, 0, 4]
sympy.polys.galoistools.gf_cofactors(f, g, p, K)
计算GF(p)[x]
中的多项式 GCD 和余因子。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_cofactors
>>> gf_cofactors(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 3]), 5, ZZ)
([1, 3], [3, 3], [2, 1])
sympy.polys.galoistools.gf_gcdex(f, g, p, K)
GF(p)[x]
中的扩展欧几里得算法。
给定GF(p)[x]
中的多项式f
和g
,计算多项式s
,t
和h
,使得h = gcd(f, g)
和s*f + t*g = h
。扩展欧几里得算法的典型应用是解多项式丢番图方程。
考虑GF(11)[x]
中的多项式f = (x + 7) (x + 1)
,g = (x + 7) (x**2 + 1)
。应用扩展欧几里得算法得到:
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_gcdex, gf_mul, gf_add
>>> s, t, g = gf_gcdex(ZZ.map([1, 8, 7]), ZZ.map([1, 7, 1, 7]), 11, ZZ)
>>> s, t, g
([5, 6], [6], [1, 7])
作为结果,我们得到多项式s = 5*x + 6
和t = 6
,而且另外gcd(f, g) = x + 7
。这是正确的,因为:
>>> S = gf_mul(s, ZZ.map([1, 8, 7]), 11, ZZ)
>>> T = gf_mul(t, ZZ.map([1, 7, 1, 7]), 11, ZZ)
>>> gf_add(S, T, 11, ZZ) == [1, 7]
True
参考文献
[R788]
sympy.polys.galoistools.gf_monic(f, p, K)
计算GF(p)[x]
中的 LC 和首一多项式。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_monic
>>> gf_monic(ZZ.map([3, 2, 4]), 5, ZZ)
(3, [1, 4, 3])
sympy.polys.galoistools.gf_diff(f, p, K)
在GF(p)[x]
中不同地化多项式。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_diff
>>> gf_diff([3, 2, 4], 5, ZZ)
[1, 2]
sympy.polys.galoistools.gf_eval(f, a, p, K)
使用 Horner 方案在GF(p)
中评估f(a)
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_eval
>>> gf_eval([3, 2, 4], 2, 5, ZZ)
0
sympy.polys.galoistools.gf_multi_eval(f, A, p, K)
对于GF(p)
中的f(a)
进行评估,其中a
在[a_1, ..., a_n]
中。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_multi_eval
>>> gf_multi_eval([3, 2, 4], [0, 1, 2, 3, 4], 5, ZZ)
[4, 4, 0, 2, 0]
sympy.polys.galoistools.gf_compose(f, g, p, K)
计算GF(p)[x]
中的多项式组合f(g)
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_compose
>>> gf_compose([3, 2, 4], [2, 2, 2], 5, ZZ)
[2, 4, 0, 3, 0]
sympy.polys.galoistools.gf_compose_mod(g, h, f, p, K)
在GF(p)[x]/(f)
中计算多项式组合g(h)
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_compose_mod
>>> gf_compose_mod(ZZ.map([3, 2, 4]), ZZ.map([2, 2, 2]), ZZ.map([4, 3]), 5, ZZ)
[4]
sympy.polys.galoistools.gf_trace_map(a, b, c, n, f, p, K)
在GF(p)[x]/(f)
中计算多项式迹映射。
给定GF(p)[x]
中的多项式f
,商环GF(p)[x]/(f)
中的多项式a
,b
,c
,使得对于某个正幂t
,b = c**t (mod f)
和正整数n
,返回映射:
a -> a**t**n, a + a**t + a**t**2 + ... + a**t**n (mod f)
在因式分解上下文中,b = x**p mod f
和c = x mod f
。通过这种方式,我们可以在等阶因式分解程序中有效地计算迹多项式,比如对于大阶数,比其他方法(如迭代 Frobenius 算法)要快得多。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_trace_map
>>> gf_trace_map([1, 2], [4, 4], [1, 1], 4, [3, 2, 4], 5, ZZ)
([1, 3], [1, 3])
参考文献
[R789]
sympy.polys.galoistools.gf_random(n, p, K)
在GF(p)[x]
中生成随机多项式n
次。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_random
>>> gf_random(10, 5, ZZ)
[1, 2, 3, 2, 1, 1, 1, 2, 0, 4, 2]
sympy.polys.galoistools.gf_irreducible(n, p, K)
在GF(p)[x]
中生成随机不可约多项式n
次。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_irreducible
>>> gf_irreducible(10, 5, ZZ)
[1, 4, 2, 2, 3, 2, 4, 1, 4, 0, 4]
sympy.polys.galoistools.gf_irreducible_p(f, p, K)
测试多项式GF(p)[x]
的不可约性。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_irreducible_p
>>> gf_irreducible_p(ZZ.map([1, 4, 2, 2, 3, 2, 4, 1, 4, 0, 4]), 5, ZZ)
True
>>> gf_irreducible_p(ZZ.map([3, 2, 4]), 5, ZZ)
False
sympy.polys.galoistools.gf_sqf_p(f, p, K)
如果GF(p)[x]
中的f
是平方自由的,则返回True
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_sqf_p
>>> gf_sqf_p(ZZ.map([3, 2, 4]), 5, ZZ)
True
>>> gf_sqf_p(ZZ.map([2, 4, 4, 2, 2, 1, 4]), 5, ZZ)
False
sympy.polys.galoistools.gf_sqf_part(f, p, K)
返回GF(p)[x]
多项式的平方自由部分。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_sqf_part
>>> gf_sqf_part(ZZ.map([1, 1, 3, 0, 1, 0, 2, 2, 1]), 5, ZZ)
[1, 4, 3]
sympy.polys.galoistools.gf_sqf_list(f, p, K, all=False)
返回GF(p)[x]
多项式的平方自由分解。
给定GF(p)[x]
中的多项式f
,返回f
的首项系数和平方自由分解f_1**e_1 f_2**e_2 ... f_k**e_k
,其中所有f_i
都是首一多项式且(f_i, f_j)
对于i != j
互质,e_1 ... e_k
按递增顺序给出。所有平凡项(即f_i = 1
)都不包括在输出中。
考虑GF(11)[x]
中的多项式f = x**11 + 1
:
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import (
... gf_from_dict, gf_diff, gf_sqf_list, gf_pow,
... )
...
>>> f = gf_from_dict({11: ZZ(1), 0: ZZ(1)}, 11, ZZ)
注意f'(x) = 0
:
>>> gf_diff(f, 11, ZZ)
[]
在零特征中不会发生这种现象。但是我们仍然可以使用gf_sqf()
计算f
的平方自由分解:
>>> gf_sqf_list(f, 11, ZZ)
(1, [([1, 1], 11)])
我们得到因式分解f = (x + 1)**11
。这是正确的,因为:
>>> gf_pow([1, 1], 11, 11, ZZ) == f
True
参考文献
[R790]
sympy.polys.galoistools.gf_Qmatrix(f, p, K)
计算 Berlekamp 的Q
矩阵。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_Qmatrix
>>> gf_Qmatrix([3, 2, 4], 5, ZZ)
[[1, 0],
[3, 4]]
>>> gf_Qmatrix([1, 0, 0, 0, 1], 5, ZZ)
[[1, 0, 0, 0],
[0, 4, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 4]]
sympy.polys.galoistools.gf_Qbasis(Q, p, K)
计算Q
的核的基础。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_Qmatrix, gf_Qbasis
>>> gf_Qbasis(gf_Qmatrix([1, 0, 0, 0, 1], 5, ZZ), 5, ZZ)
[[1, 0, 0, 0], [0, 0, 1, 0]]
>>> gf_Qbasis(gf_Qmatrix([3, 2, 4], 5, ZZ), 5, ZZ)
[[1, 0]]
sympy.polys.galoistools.gf_berlekamp(f, p, K)
对小p
中的平方自由f
进行因式分解。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_berlekamp
>>> gf_berlekamp([1, 0, 0, 0, 1], 5, ZZ)
[[1, 0, 2], [1, 0, 3]]
sympy.polys.galoistools.gf_zassenhaus(f, p, K)
对中等p
中的平方自由f
进行因式分解。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_zassenhaus
>>> gf_zassenhaus(ZZ.map([1, 4, 3]), 5, ZZ)
[[1, 1], [1, 3]]
sympy.polys.galoistools.gf_shoup(f, p, K)
在大的 p
下,对 GF(p)[x]
中的无平方 f
进行因式分解。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_shoup
>>> gf_shoup(ZZ.map([1, 4, 3]), 5, ZZ)
[[1, 1], [1, 3]]
sympy.polys.galoistools.gf_factor_sqf(f, p, K, method=None)
在 GF(p)[x]
中因式分解无平方多项式 f
。
例子
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_factor_sqf
>>> gf_factor_sqf(ZZ.map([3, 2, 4]), 5, ZZ)
(3, [[1, 1], [1, 3]])
sympy.polys.galoistools.gf_factor(f, p, K)
在 GF(p)[x]
中因式分解(非无平方)多项式。
给定在 GF(p)[x]
中可能非无平方的多项式 f
,返回其完整的不可约因式分解:
f_1(x)**e_1 f_2(x)**e_2 ... f_d(x)**e_d
这里每个 f_i
是单阶多项式,且对于 i != j
,有 gcd(f_i, f_j) == 1
。结果以领导系数的元组形式给出,以及具有它们乘数的 f
因子列表。
算法首先通过计算 f
的无平方因子分解,然后迭代地对每个无平方因子进行因式分解。
考虑在 GF(11)[x]
中的非无平方多项式 f = (7*x + 1) (x + 2)**2
。我们得到其不可约因式分解如下:
>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.galoistools import gf_factor
>>> gf_factor(ZZ.map([5, 2, 7, 2]), 11, ZZ)
(5, [([1, 2], 1), ([1, 8], 2)])
我们得到了因式分解 f = 5 (x + 2) (x + 8)**2
。我们没有恢复输入多项式的确切形式,因为我们要求单独获取 f
的单阶因子及其领导系数。
f
的无平方因子可以使用三种非常不同的方法在 GF(p)
上进行不可约因式分解:
Berlekamp
对于非常小的 p
值(通常 p < 25
)效率高。
Cantor-Zassenhaus
对于平均输入和“典型” p
,效率很高。
Shoup-Kaltofen-Gathen
对于非常大的输入和模数,效率高。
如果您想使用特定的因式分解方法而不是默认方法,请设置 GF_FACTOR_METHOD
为 berlekamp
、zassenhaus
或 shoup
中的一个值。
参考
[R791]
sympy.polys.galoistools.gf_value(f, a)
在域 R 中多项式 'f' 在 'a' 处的值。
例子
>>> from sympy.polys.galoistools import gf_value
>>> gf_value([1, 7, 2, 4], 11)
2204
sympy.polys.galoistools.gf_csolve(f, n)
解决 f(x) 同余于 0 mod(n)。
将 n 分解为规范因子,并为每个因子解决 f(x) cong 0 mod(p**e)。将中国剩余定理应用于结果返回最终答案。
例子
解 [1, 1, 7] 同余于 0 mod(189):
>>> from sympy.polys.galoistools import gf_csolve
>>> gf_csolve([1, 1, 7], 189)
[13, 49, 76, 112, 139, 175]
另见
sympy.ntheory.residue_ntheory.polynomial_congruence
一个更高层次的解决程序
参考
[R792]
‘An introduction to the Theory of Numbers’ 5th Edition by Ivan Niven, Zuckerman and Montgomery.
稀疏分布多项式和向量的操作
如果变量数量增加,密集表示会迅速需要不可行的存储量和计算时间。因此,有代码来在稀疏表示中操作多项式。环对象和元素由类PolyRing
和PolyElement
实现。
在交换代数中,人们经常研究不仅是多项式,还有多项式环上的 模块。多项式操作模块提供了有限生成自由模块的基本低级支持。这主要用于格罗布纳基础计算(见那里),因此仅提供所需的操作函数。它们带有前缀 sdm_
。请注意,在示例中,自由模块的生成器称为 (f_1, f_2, \ldots)。
sympy.polys.distributedmodules.sdm_monomial_mul(M, X)
将表示 K[X]
单项式的元组 X
乘到表示 F
单项式的元组 M
中。
示例
将 (xy³) 乘到 (x f_1) 中得到 (x² y³ f_1):
>>> from sympy.polys.distributedmodules import sdm_monomial_mul
>>> sdm_monomial_mul((1, 1, 0), (1, 3))
(1, 2, 3)
sympy.polys.distributedmodules.sdm_monomial_deg(M)
返回 M
的总次数。
示例
例如,(x² y f_5) 的总次数为 3:
>>> from sympy.polys.distributedmodules import sdm_monomial_deg
>>> sdm_monomial_deg((5, 2, 1))
3
sympy.polys.distributedmodules.sdm_monomial_divides(A, B)
是否存在(多项式)单项式 X,使得 XA = B?
示例
正例:
在下面的示例中,单项式以 x、y 和生成器(f_1, f_2 等)的形式给出。该单项式的元组形式用于调用 sdm_monomial_divides
。注意:生成器在表达式中最后出现,但在元组中首先出现,其他因子按它们在单项式表达式中出现的顺序出现。
(A = f_1) 整除 (B = f_1)
>>> from sympy.polys.distributedmodules import sdm_monomial_divides
>>> sdm_monomial_divides((1, 0, 0), (1, 0, 0))
True
(A = f_1) 整除 (B = x² y f_1)
>>> sdm_monomial_divides((1, 0, 0), (1, 2, 1))
True
(A = xy f_5) 整除 (B = x² y f_5)
>>> sdm_monomial_divides((5, 1, 1), (5, 2, 1))
True
负例:
(A = f_1) 不整除 (B = f_2)
>>> sdm_monomial_divides((1, 0, 0), (2, 0, 0))
False
(A = x f_1) 不整除 (B = f_1)
>>> sdm_monomial_divides((1, 1, 0), (1, 0, 0))
False
(A = xy² f_5) 不能整除 (B = y f_5)
>>> sdm_monomial_divides((5, 1, 2), (5, 0, 1))
False
sympy.polys.distributedmodules.sdm_LC(f, K)
返回 f
的主系数。
sympy.polys.distributedmodules.sdm_to_dict(f)
从分布多项式创建字典。
sympy.polys.distributedmodules.sdm_from_dict(d, O)
从字典创建一个 sdm。
这里 O
是要使用的单项式顺序。
示例
>>> from sympy.polys.distributedmodules import sdm_from_dict
>>> from sympy.polys import QQ, lex
>>> dic = {(1, 1, 0): QQ(1), (1, 0, 0): QQ(2), (0, 1, 0): QQ(0)}
>>> sdm_from_dict(dic, lex)
[((1, 1, 0), 1), ((1, 0, 0), 2)]
sympy.polys.distributedmodules.sdm_add(f, g, O, K)
添加两个模元素 f
, g
。
加法是在底域 K
上进行的,单项式按 O
排序。
示例
所有示例使用词典序。
((xy f_1) + (f_2) = f_2 + xy f_1)
>>> from sympy.polys.distributedmodules import sdm_add
>>> from sympy.polys import lex, QQ
>>> sdm_add([((1, 1, 1), QQ(1))], [((2, 0, 0), QQ(1))], lex, QQ)
[((2, 0, 0), 1), ((1, 1, 1), 1)]
((xy f_1) + (-xy f_1)) = 0`
>>> sdm_add([((1, 1, 1), QQ(1))], [((1, 1, 1), QQ(-1))], lex, QQ)
[]
((f_1) + (2f_1) = 3f_1)
>>> sdm_add([((1, 0, 0), QQ(1))], [((1, 0, 0), QQ(2))], lex, QQ)
[((1, 0, 0), 3)]
((yf_1) + (xf_1) = xf_1 + yf_1)
>>> sdm_add([((1, 0, 1), QQ(1))], [((1, 1, 0), QQ(1))], lex, QQ)
[((1, 1, 0), 1), ((1, 0, 1), 1)]
sympy.polys.distributedmodules.sdm_LM(f)
返回 f
的主单项式。
仅在 f \ne 0
时有效。
示例
>>> from sympy.polys.distributedmodules import sdm_LM, sdm_from_dict
>>> from sympy.polys import QQ, lex
>>> dic = {(1, 2, 3): QQ(1), (4, 0, 0): QQ(1), (4, 0, 1): QQ(1)}
>>> sdm_LM(sdm_from_dict(dic, lex))
(4, 0, 1)
sympy.polys.distributedmodules.sdm_LT(f)
返回 f
的主项。
仅在 f \ne 0
时有效。
示例
>>> from sympy.polys.distributedmodules import sdm_LT, sdm_from_dict
>>> from sympy.polys import QQ, lex
>>> dic = {(1, 2, 3): QQ(1), (4, 0, 0): QQ(2), (4, 0, 1): QQ(3)}
>>> sdm_LT(sdm_from_dict(dic, lex))
((4, 0, 1), 3)
sympy.polys.distributedmodules.sdm_mul_term(f, term, O, K)
将分布模元素 f
乘以(多项式)项 term
。
系数的乘法是在底域 K
上进行的,并且单项式按 O
排序。
示例
(0 f_1 = 0)
>>> from sympy.polys.distributedmodules import sdm_mul_term
>>> from sympy.polys import lex, QQ
>>> sdm_mul_term([((1, 0, 0), QQ(1))], ((0, 0), QQ(0)), lex, QQ)
[]
(x 0 = 0)
>>> sdm_mul_term([], ((1, 0), QQ(1)), lex, QQ)
[]
((x) (f_1) = xf_1)
>>> sdm_mul_term([((1, 0, 0), QQ(1))], ((1, 0), QQ(1)), lex, QQ)
[((1, 1, 0), 1)]
((2xy) (3x f_1 + 4y f_2) = 8xy² f_2 + 6x²y f_1)
>>> f = [((2, 0, 1), QQ(4)), ((1, 1, 0), QQ(3))]
>>> sdm_mul_term(f, ((1, 1), QQ(2)), lex, QQ)
[((2, 1, 2), 8), ((1, 2, 1), 6)]
sympy.polys.distributedmodules.sdm_zero()
返回零模元素。
sympy.polys.distributedmodules.sdm_deg(f)
f
的次数。
这是其所有单项式的次数的最大值。如果 f
是零,则无效。
示例
>>> from sympy.polys.distributedmodules import sdm_deg
>>> sdm_deg([((1, 2, 3), 1), ((10, 0, 1), 1), ((2, 3, 4), 4)])
7
sympy.polys.distributedmodules.sdm_from_vector(vec, O, K, **opts)
从表达式的可迭代对象创建一个 sdm。
系数在底域 K
中创建,项根据单项式顺序 O
排序。命名参数传递给 polys 转换代码,并可用于指定例如生成器。
示例
>>> from sympy.polys.distributedmodules import sdm_from_vector
>>> from sympy.abc import x, y, z
>>> from sympy.polys import QQ, lex
>>> sdm_from_vector([x**2+y**2, 2*z], lex, QQ)
[((1, 0, 0, 1), 2), ((0, 2, 0, 0), 1), ((0, 0, 2, 0), 1)]
sympy.polys.distributedmodules.sdm_to_vector(f, gens, K, n=None)
将 sdm f
转换为多项式表达式列表。
多项式环的生成器通过 gens
指定。模块的秩是猜测的,或者通过 n
传递。假定底域是 K
。
示例
>>> from sympy.polys.distributedmodules import sdm_to_vector
>>> from sympy.abc import x, y, z
>>> from sympy.polys import QQ
>>> f = [((1, 0, 0, 1), QQ(2)), ((0, 2, 0, 0), QQ(1)), ((0, 0, 2, 0), QQ(1))]
>>> sdm_to_vector(f, [x, y, z], QQ)
[x**2 + y**2, 2*z]
多项式因式分解算法
Euclid's algorithm 的许多变种:
经典余序列
设 (K) 是一个域,并考虑单变元 (X) 的多项式的环 (K[X]),其系数在 (K) 中。给定 (K[X]) 中的两个元素 (f) 和 (g),其中 (g \neq 0),存在唯一的多项式 (q) 和 (r) 使得 (f = qg + r) 且 (\deg(r) < \deg(g)) 或 (r = 0)。它们由 (\mathrm{quo}(f,g))(商)和 (\mathrm{rem}(f,g))(余)表示,因此我们有除法恒等式
[f = \mathrm{quo}(f,g)g + \mathrm{rem}(f,g).]
由此可知,(K[X]) 的每一个理想 (I) 都是主理想,由任意非零最小次元的元素生成(假设 (I) 非零)。事实上,如果 (g) 是这样的多项式,(f) 是 (I) 中的任意元素,则 (\mathrm{rem}(f,g)) 作为 (f) 和 (g) 的线性组合属于 (I),因此必须为零;因此 (f) 是 (g) 的倍数。
利用此结果可以在 (K[X]) 中找到任何多项式 (f,g,\ldots) 的最大公约数。如果 (I) 是由给定多项式的所有线性组合形成的理想,(d) 是其生成元,那么多项式的每一个公因子也会除 (d)。另一方面,给定的多项式是生成元 (d) 的倍数;因此 (d) 是多项式的最大公约数,表示为 (\mathrm{gcd}(f,g,\ldots))。
现在可以获得 (K[X]) 中两个多项式 (f) 和 (g) 的最大公约数算法如下。根据除法恒等式,(r = \mathrm{rem}(f,g)) 在由 (f) 和 (g) 生成的理想中,同时 (f) 在由 (g) 和 (r) 生成的理想中。因此,由对 ((f,g)) 和 ((g,r)) 生成的理想是相同的。设 (f_0 = f),(f_1 = g),并递归定义 (f_i = \mathrm{rem}(f_{i-2},f_{i-1})) 对 (i \ge 2)。递归在有限步后结束,因为多项式的次数严格递减。根据上述评论,所有对 ((f_{i-1},f_i)) 生成相同的理想。特别地,由 (f) 和 (g) 生成的理想仅由 (f_k) 生成,因为 (f_{k+1} = 0)。因此 (d = f_k) 是 (f) 和 (g) 的最大公约数。
多项式序列 (f_0), (f_1,\ldots, f_k) 称为由 ((f,g)) 确定的欧几里得多项式余序列,因为类似于自然数的欧几里得算法。
可以通过使用完整的除法恒等式将每个 (f_i) 递归地写成 (f) 和 (g) 的线性组合来扩展算法,从而获得 (d) 的表达式。这导致一个方程
[d = uf + vg\qquad (u,v \in K[X])]
在整数情况下类似于贝祖等式。
sympy.polys.euclidtools.dmp_half_gcdex(f, g, u, K)
在 (F[X]) 中的半扩展欧几里得算法。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
sympy.polys.euclidtools.dmp_gcdex(f, g, u, K)
(F[X]) 中的扩展欧几里得算法。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
sympy.polys.euclidtools.dmp_invert(f, g, u, K)
在 (F[X]) 中计算 (f) 模 (g) 的乘法逆元。
示例
>>> from sympy.polys import ring, QQ
>>> R, x = ring("x", QQ)
sympy.polys.euclidtools.dmp_euclidean_prs(f, g, u, K)
(K[X]) 中的欧几里得多项式余数序列(PRS)。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
简化的余数序列
假设按照通常情况,系数域 (K) 是整环 (A) 的分式域。在这种情况下,欧几里得余数序列中多项式的系数(分子和分母)往往会快速增长。
如果 (A) 是唯一因子分解域,则可以通过取消分子和分母的公因子来减少系数。进一步的简化可能性在于注意到 (K[X]) 中的多项式的 gcd 不唯一:它可以乘以任何(非零)常数因子。
任何 (K[X]) 中的多项式 (f) 都可以通过提取其系数的分母和公因子来简化。这导致了表示 (f = cF),其中 (c\in K) 是 (f) 的内容,(F) 是一个原始多项式,即 (A[X]) 中具有互质系数的多项式。
可以通过用给定多项式 (f) 和 (g) 的原始部分替换来启动算法。这只会通过一个常数因子修改 (\mathrm{rem}(f,g))。用其原始部分替换后,继续递归地获得欧几里得余数序列中所有多项式的原始部分,包括原始 (\mathrm{gcd}(f,g))。
这个序列是原始多项式余数序列。它是一般多项式余数序列的一个例子,其中计算得到的余数通过常数乘法器(或除法器)进行修改,以简化结果。
sympy.polys.euclidtools.dmp_primitive_prs(f, g, u, K)
(K[X]) 中的原始多项式余数序列(PRS)。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
子结果序列
原始多项式序列的系数并不会过分增长,但计算原始部分需要额外的处理工作。此外,该方法仅适用于唯一因子分解域的分式域,例如一般数域则不包括在内。
Collins [Collins67] 意识到一对多项式的所谓子结果多项式也形成了广义的余数序列。这些多项式的系数可以表示为给定多项式系数的行列式。因此,它们(的对数)的大小仅线性增长。此外,如果给定多项式的系数在子域 (A) 中,那么子结果多项式的系数也在子域中。这意味着子结果序列与不依赖于 (A) 中唯一因子分解的原始余数序列是可比较的。
要了解子结果与余数序列的关联,回想一下序列中的所有多项式 (h) 都是给定多项式 (f) 和 (g) 的线性组合。
[h = uf+vg]
其中(u)和(v)是(K[X])中的多项式。此外,正如从扩展欧几里德算法中可以看到的那样,(u)和(v)的次数相对较低,并且从步骤到步骤的增长是有限的。
设(n = \deg(f)),(m = \deg(g)),并假设(n \ge m)。如果(\deg(h) = j < m),则在乘积(uf)和(vg)中,幂(X^k) ((k > j))的系数会互相抵消。特别地,这些乘积必须有相同的次数,称为(l)。然后(\deg(u) = l - n)和(\deg(v) = l - m),需要确定的系数总数为(2l - n - m + 2)。
另一方面,等式(h = uf + vg)意味着系数的(l - j)线性组合为零,这些系数与幂(X^i) ((j < i \leq l))相关联,并且其中一个具有给定的非零值,即(h)的首项系数。
要满足这些(l - j + 1)个线性方程,要确定的系数总数一般不能低于(l - j + 1)。这导致不等式(l \ge n + m - j - 1)。取(l = n + m - j - 1),我们得到(\deg(u) = m - j - 1)和(\deg(v) = n - j - 1)。
当(j = 0)时,导致线性方程组的矩阵是与(f)和(g)相关的Sylvester 矩阵(S(f,g)),一个((n+m)\times (n+m))的矩阵,其系数是(f)和(g)的系数。它的行列式是对偶(f)和(g)的结果式(\mathrm{res}(f,g))。当且仅当(f)和(g)互素时,它是非零的。
对于任意的(j),其取值范围在(0)到(m)之间,线性系统的矩阵是 Sylvester 矩阵的一个((n+m-2j)\times (n+m-2j))子矩阵。它的行列式(s_j(f,g))被称为(f)和(g)的第(j)个标量子结果式。
如果(s_j(f,g))不为零,则相关的方程(h = uf + vg)有一个唯一的解,其中(\deg(h) = j)且(h)的首项系数具有任意给定的值;其中具有首项系数(s_j(f,g))的是第(j)个子结果式多项式或简称为子结果式((f,g)),记作(S_j(f,g))。这个选择确保其余系数也是 Sylvester 矩阵的某些子行列式。特别地,如果(f)和(g)在(A[X])中,则(S_j(f,g))也在其中。这种子结果式的构造适用于(0)到(m)之间的任何(j),无论(s_j(f,g))的值如何;如果它为零,则(\deg(S_j(f,g)) < j)。
子结果式的性质如下。设(n_0 = \deg(f)),(n_1 = \deg(g)),(n_2, \ldots, n_k)是余序列中多项式次数的递减序列。设(0 \le j \le n_1);则
-
(s_j(f,g)\ne 0) if and only if (j = n_i) for some (i).
-
(S_j(f,g)\ne 0) if and only if (j = n_i) or (j = n_i - 1) for some (i).
通常情况下,对于(1 < i \le k),(n_{i-1} - n_i = 1)。如果某些(i)(异常情况)中(n_{i-1} - n_i > 1),那么(S_{n_{i-1}-1}(f,g))和(S_{n_i}(f,g))是彼此的常数倍数。因此,多项式余序列中可以包含任意一个。前者由更小的行列式给出,因此预计其系数较小。
Collins 通过设定子结果余算法定义了
[f_i = S_{n_{i-1}-1}(f,g) \qquad (2\le i \le k).]
在正常情况下,这些与(S_{n_i}(f,g))相同。他还推导出了余式公式中常数(\gamma_i)的表达式。
[\gamma_i f_i = \mathrm{rem}(f_{i-2},f_{i-1})]
关于在域(K)中的(f_1,\ldots,f_{i-1})的首项系数工作。
Brown 和 Traub [BrownTraub71]随后开发了一个递归过程来计算系数(\gamma_i)。他们的算法专门处理域(A)的元素(假设(f,g\in A[X]))。然而,在异常情况下存在一个问题,即在(A)中的除法可能只能猜测是精确的。
这后来被 Brown [Brown78]证明,他表明除法的结果实际上是标量子结果。更具体地说,在计算(f_i)中出现的常数是(s_{n_{i-2}}(f,g))(定理 3)。这一发现的含义是,在算法的副产品中计算出了除(f_{k+1}=0)之外的所有非零标量子结果。完成最后一步我们得到了所有非零的标量子结果,包括最后一个如果它不为零的话就是结果。
sympy.polys.euclidtools.dmp_inner_subresultants(f, g, u, K)
在(K[X])中的子结果多项式剩余序列算法。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 3*x**2*y - y**3 - 4
>>> g = x**2 + x*y**3 - 9
>>> a = 3*x*y**4 + y**3 - 27*y + 4
>>> b = -3*y**10 - 12*y**7 + y**6 - 54*y**4 + 8*y**3 + 729*y**2 - 216*y + 16
>>> prs = [f, g, a, b]
>>> sres = [[1], [1], [3, 0, 0, 0, 0], [-3, 0, 0, -12, 1, 0, -54, 8, 729, -216, 16]]
>>> R.dmp_inner_subresultants(f, g) == (prs, sres)
True
sympy.polys.euclidtools.dmp_subresultants(f, g, u, K)
计算(K[X])中两个多项式的子结果多项式剩余序列。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 3*x**2*y - y**3 - 4
>>> g = x**2 + x*y**3 - 9
>>> a = 3*x*y**4 + y**3 - 27*y + 4
>>> b = -3*y**10 - 12*y**7 + y**6 - 54*y**4 + 8*y**3 + 729*y**2 - 216*y + 16
>>> R.dmp_subresultants(f, g) == [f, g, a, b]
True
sympy.polys.euclidtools.dmp_prs_resultant(f, g, u, K)
在(K[X])中使用子结果多项式剩余序列算法得到的结果算法。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 3*x**2*y - y**3 - 4
>>> g = x**2 + x*y**3 - 9
>>> a = 3*x*y**4 + y**3 - 27*y + 4
>>> b = -3*y**10 - 12*y**7 + y**6 - 54*y**4 + 8*y**3 + 729*y**2 - 216*y + 16
>>> res, prs = R.dmp_prs_resultant(f, g)
>>> res == b # resultant has n-1 variables
False
>>> res == b.drop(x)
True
>>> prs == [f, g, a, b]
True
sympy.polys.euclidtools.dmp_zz_modular_resultant(f, g, p, u, K)
计算(f)和(g)模素数(p)的结果。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x + y + 2
>>> g = 2*x*y + x + 3
>>> R.dmp_zz_modular_resultant(f, g, 5)
-2*y**2 + 1
sympy.polys.euclidtools.dmp_zz_collins_resultant(f, g, u, K)
在(Z[X])中的 Collins 模余结果算法。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x + y + 2
>>> g = 2*x*y + x + 3
>>> R.dmp_zz_collins_resultant(f, g)
-2*y**2 - 5*y + 1
sympy.polys.euclidtools.dmp_qq_collins_resultant(f, g, u, K0)
在(Q[X])中的 Collins 模余结果算法。
例子
>>> from sympy.polys import ring, QQ
>>> R, x,y = ring("x,y", QQ)
>>> f = QQ(1,2)*x + y + QQ(2,3)
>>> g = 2*x*y + x + 3
>>> R.dmp_qq_collins_resultant(f, g)
-2*y**2 - 7/3*y + 5/6
sympy.polys.euclidtools.dmp_resultant(f, g, u, K, includePRS=False)
计算(K[X])中两个多项式的结果。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = 3*x**2*y - y**3 - 4
>>> g = x**2 + x*y**3 - 9
>>> R.dmp_resultant(f, g)
-3*y**10 - 12*y**7 + y**6 - 54*y**4 + 8*y**3 + 729*y**2 - 216*y + 16
sympy.polys.euclidtools.dmp_discriminant(f, u, K)
计算(K[X])中多项式的判别式。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y,z,t = ring("x,y,z,t", ZZ)
>>> R.dmp_discriminant(x**2*y + x*z + t)
-4*y*t + z**2
sympy.polys.euclidtools.dmp_rr_prs_gcd(f, g, u, K)
使用环上的子结果多项式剩余序列计算多项式最大公因数。
返回(h, cff, cfg)
,使得a = gcd(f, g)
,cff = quo(f, h)
,以及cfg = quo(g, h)
。
例子
>>> from sympy.polys import ring, ZZ
>>> R, x,y, = ring("x,y", ZZ)
>>> f = x**2 + 2*x*y + y**2
>>> g = x**2 + x*y
>>> R.dmp_rr_prs_gcd(f, g)
(x + y, x + y, x)
sympy.polys.euclidtools.dmp_ff_prs_gcd(f, g, u, K)
使用域上的子结果多项式剩余序列计算多项式最大公因数。
返回(h, cff, cfg)
,使得a = gcd(f, g)
,cff = quo(f, h)
,以及cfg = quo(g, h)
。
例子
>>> from sympy.polys import ring, QQ
>>> R, x,y, = ring("x,y", QQ)
>>> f = QQ(1,2)*x**2 + x*y + QQ(1,2)*y**2
>>> g = x**2 + x*y
>>> R.dmp_ff_prs_gcd(f, g)
(x + y, 1/2*x + 1/2*y, x)
sympy.polys.euclidtools.dmp_zz_heu_gcd(f, g, u, K)
在(Z[X])中的启发式多项式最大公因数。
给定整系数一元多项式(f)和(g),返回它们的最大公因数及其余因子,即多项式h
,cff
和cfg
,使得:
h = gcd(f, g), cff = quo(f, h) and cfg = quo(g, h)
该算法是纯启发式的,这意味着它可能无法计算最大公因数。这将通过引发异常来表示。在这种情况下,您需要切换到另一种最大公因数的方法。
该算法通过在特定点评估多项式 (f) 和 (g) 并计算这些评估的(快速)整数最大公约数来计算多项式的最大公约数。通过插值从整数图像中恢复多项式最大公约数。评估过程逐步将 (f) 和 (g) 逐变量减少为一个大整数。最后一步是验证插值多项式是否是正确的最大公约数。这会作为副作用给出输入多项式的余式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y, = ring("x,y", ZZ)
>>> f = x**2 + 2*x*y + y**2
>>> g = x**2 + x*y
>>> R.dmp_zz_heu_gcd(f, g)
(x + y, x + y, x)
参考文献
[R793]
sympy.polys.euclidtools.dmp_qq_heu_gcd(f, g, u, K0)
在 (Q[X]) 中的启发式多项式最大公约数。
返回 (h, cff, cfg)
,使得 a = gcd(f, g)
,cff = quo(f, h)
,且 cfg = quo(g, h)
。
示例
>>> from sympy.polys import ring, QQ
>>> R, x,y, = ring("x,y", QQ)
>>> f = QQ(1,4)*x**2 + x*y + y**2
>>> g = QQ(1,2)*x**2 + x*y
>>> R.dmp_qq_heu_gcd(f, g)
(x + 2*y, 1/4*x + 1/2*y, 1/2*x)
sympy.polys.euclidtools.dmp_inner_gcd(f, g, u, K)
计算 (K[X]) 中多项式 (f) 和 (g) 的最大公约数及其余式。
返回 (h, cff, cfg)
,使得 a = gcd(f, g)
,cff = quo(f, h)
,且 cfg = quo(g, h)
。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y, = ring("x,y", ZZ)
>>> f = x**2 + 2*x*y + y**2
>>> g = x**2 + x*y
>>> R.dmp_inner_gcd(f, g)
(x + y, x + y, x)
sympy.polys.euclidtools.dmp_gcd(f, g, u, K)
在 (K[X]) 中计算多项式 (f) 和 (g) 的最大公约数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y, = ring("x,y", ZZ)
>>> f = x**2 + 2*x*y + y**2
>>> g = x**2 + x*y
>>> R.dmp_gcd(f, g)
x + y
sympy.polys.euclidtools.dmp_lcm(f, g, u, K)
计算 (K[X]) 中多项式 (f) 和 (g) 的最小公倍数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y, = ring("x,y", ZZ)
>>> f = x**2 + 2*x*y + y**2
>>> g = x**2 + x*y
>>> R.dmp_lcm(f, g)
x**3 + 2*x**2*y + x*y**2
sympy.polys.euclidtools.dmp_content(f, u, K)
返回多变量系数的最大公约数。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y, = ring("x,y", ZZ)
>>> R.dmp_content(2*x*y + 6*x + 4*y + 12)
2*y + 6
sympy.polys.euclidtools.dmp_primitive(f, u, K)
返回多变量内容和原始多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y, = ring("x,y", ZZ)
>>> R.dmp_primitive(2*x*y + 6*x + 4*y + 12)
(2*y + 6, x + 2)
sympy.polys.euclidtools.dmp_cancel(f, g, u, K, include=True)
取消有理函数 (f/g) 中的公因子。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_cancel(2*x**2 - 2, x**2 - 2*x + 1)
(2*x + 2, x - 1)
零特征下的多项式因子化:
sympy.polys.factortools.dup_trial_division(f, factors, K)
使用试除法确定单变量多项式的因子重数。
如果任何因子不除 f
,将引发错误。
sympy.polys.factortools.dmp_trial_division(f, factors, u, K)
使用试除法确定多变量多项式的因子重数。
如果任何因子不除 f
,将引发错误。
sympy.polys.factortools.dup_zz_mignotte_bound(f, K)
在 K[x]
中,Knuth-Cohen 变体的单变量多项式的 Mignotte 界。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> f = x**3 + 14*x**2 + 56*x + 64
>>> R.dup_zz_mignotte_bound(f)
152
通过检查 factor(f)
,我们可以看到最大系数为 8。
也考虑 f
是不可约的情况,例如 f = 2*x**2 + 3*x + 4
。为了避免这些情况下的错误,我们返回界限以及 f
的最大系数。
>>> f = 2*x**2 + 3*x + 4
>>> R.dup_zz_mignotte_bound(f)
6
最后,为了查看新旧 Mignotte 界的区别,请考虑不可约多项式:
>>> f = 87*x**7 + 4*x**6 + 80*x**5 + 17*x**4 + 9*x**3 + 12*x**2 + 49*x + 26
>>> R.dup_zz_mignotte_bound(f)
744
新的 Mignotte 界为 744,而旧的(SymPy 1.5.1)为 1937664。
参考文献
..[1] [Abbott13]
sympy.polys.factortools.dmp_zz_mignotte_bound(f, u, K)
在 (K[X]) 中多变量多项式的 Mignotte 界。
sympy.polys.factortools.dup_zz_hensel_step(m, f, g, h, s, t, K)
在 (Z[x]) 中的 Hensel 提升的一个步骤。
给定正整数 (m) 和 (Z[x]) 多项式 (f), (g), (h), (s) 和 (t),使得:
f = g*h (mod m)
s*g + t*h = 1 (mod m)
lc(f) is not a zero divisor (mod m)
lc(h) = 1
deg(f) = deg(g) + deg(h)
deg(s) < deg(h)
deg(t) < deg(g)
返回多项式 (G), (H), (S) 和 (T),使得:
f = G*H (mod m**2)
S*G + T*H = 1 (mod m**2)
参考文献
[R794]
sympy.polys.factortools.dup_zz_hensel_lift(p, f, f_list, l, K)
在 (Z[x]) 中进行多项式的 Hensel 提升。
给定素数 (p),在 (Z[x]) 上的多项式 (f),使得 (lc(f)) 在模 (p) 时是单位,且在 (Z[x]) 上满足互质的单项式:
f = lc(f) f_1 ... f_r (mod p)
和正整数 (l),返回满足条件的单变量多项式 (F_1,\ F_2,\ \dots,\ F_r) 的单项式多项式列表:
f = lc(f) F_1 ... F_r (mod p**l)
F_i = f_i (mod p), i = 1..r
参考文献
[R795]
sympy.polys.factortools.dup_zz_zassenhaus(f, K)
在 (Z[x]) 中因子化原始的平方自由多项式。
sympy.polys.factortools.dup_zz_irreducible_p(f, K)
使用 Eisenstein 准则测试不可约性。
sympy.polys.factortools.dup_cyclotomic_p(f, K, irreducible=False)
高效地测试 f
是否为旋转多项式。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> f = x**16 + x**14 - x**10 + x**8 - x**6 + x**2 + 1
>>> R.dup_cyclotomic_p(f)
False
>>> g = x**16 + x**14 - x**10 - x**8 - x**6 + x**2 + 1
>>> R.dup_cyclotomic_p(g)
True
参考文献
Bradford, Russell J., and James H. Davenport. “Effective tests for cyclotomic polynomials.” In International Symposium on Symbolic and Algebraic Computation, pp. 244-251. Springer, Berlin, Heidelberg, 1988.
sympy.polys.factortools.dup_zz_cyclotomic_poly(n, K)
高效生成第 n 个旋多项式。
sympy.polys.factortools.dup_zz_cyclotomic_factor(f, K)
高效地在(Z[x])中因式分解多项式(xn - 1)和(xn + 1)。
给定(Z[x])中的单变量多项式(f),如果(f)为(xn - 1)或(xn + 1)(其中(n >= 1)),则返回(f)的因子列表。否则返回 None。
使用(f)的循环分解来执行因式分解,这使得此方法比任何其他直接因式分解方法(例如 Zassenhaus 的方法)快得多。
参考文献
[R796]
sympy.polys.factortools.dup_zz_factor_sqf(f, K)
在(Z[x])中因式分解无平方因子(非原始)多项式。
sympy.polys.factortools.dup_zz_factor(f, K)
在(Z[x])中因式分解(非平方自由)多项式。
给定(Z[x])中的单变量多项式(f),计算其在整数上的完全因式分解(f_1, ..., f_n)成为不可约多项式:
f = content(f) f_1**k_1 ... f_n**k_n
因式分解通过将输入多项式简化为原始无平方多项式,并使用 Zassenhaus 算法进行因式分解。试除法用于恢复因子的重数。
结果以元组形式返回:
(content(f), [(f_1, k_1), ..., (f_n, k_n))
示例
考虑多项式(f = 2*x**4 - 2):
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_zz_factor(2*x**4 - 2)
(2, [(x - 1, 1), (x + 1, 1), (x**2 + 1, 1)])
结果如下进行了因式分解:
f = 2 (x - 1) (x + 1) (x**2 + 1)
请注意,这是对整数的完全因式分解,然而在高斯整数上,我们可以因式分解最后一项。
默认情况下,多项式(xn - 1)和(xn + 1)使用循环分解进行因式分解以加快计算速度。要禁用此行为,请设置 cyclotomic=False。
参考文献
[R797]
sympy.polys.factortools.dmp_zz_wang_non_divisors(E, cs, ct, K)
Wang/EEZ: 计算一组有效的除数。
sympy.polys.factortools.dmp_zz_wang_test_points(f, T, ct, A, u, K)
Wang/EEZ: 评估点的测试适用性。
sympy.polys.factortools.dmp_zz_wang_lead_coeffs(f, T, cs, E, H, A, u, K)
Wang/EEZ: 计算正确的主导系数。
sympy.polys.factortools.dup_zz_diophantine(F, m, p, K)
Wang/EEZ: 解决单变量丢番图方程。
sympy.polys.factortools.dmp_zz_diophantine(F, c, A, d, p, u, K)
Wang/EEZ: 解决多变量丢番图方程。
sympy.polys.factortools.dmp_zz_wang_hensel_lifting(f, H, LC, A, p, u, K)
Wang/EEZ: 并行 Hensel 提升算法。
sympy.polys.factortools.dmp_zz_wang(f, u, K, mod=None, seed=None)
在(Z[X])中因式分解原始的无平方因子多项式。
给定(Z[x_1,...,x_n])中的多变量多项式(f),该多项式在(x_1)中是原始的且无平方因子,计算(f)在整数上的不可约因式分解。
该过程基于 Wang 的增强扩展 Zassenhaus 算法。该算法通过将(f)视为(Z[x_2,...,x_n][x_1])中的单变量多项式来运行。
x_2 -> a_2, ..., x_n -> a_n
其中(a_i), 对于(i = 2, \dots, n), 是精心选择的整数。这种映射用于将(f)转化为(Z[x_1])中的单变量多项式,可以通过 Zassenhaus 算法高效地进行因式分解。最后一步是提升单变量因子以获得真正的多变量因子。为此,使用了并行的 Hensel 提升过程。
参数seed
被传递给 _randint,可用于种子 randint(当为整数时),或(用于测试目的)可以是一个数字序列。
参考文献
[R798]
[R799]
sympy.polys.factortools.dmp_zz_factor(f, u, K)
在(Z[X])中因式分解(非无平方因子的多项式)。
给定一个多变量多项式(f)在(Z[x])中,计算其在整数上的完全因式分解(f_1, \dots, f_n):
f = content(f) f_1**k_1 ... f_n**k_n
通过将输入多项式化简为原始无平方因子多项式,并使用增强的扩展 Zassenhaus(EEZ)算法进行因式分解。试除法用于恢复因子的重数。
结果作为一个元组返回:
(content(f), [(f_1, k_1), ..., (f_n, k_n))
考虑多项式(f = 2*(x2 - y2)):
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_zz_factor(2*x**2 - 2*y**2)
(2, [(x - y, 1), (x + y, 1)])
结果如下所示的因式分解:
f = 2 (x - y) (x + y)
参考
[R800]
sympy.polys.factortools.dup_qq_i_factor(f, K0)
在(QQ_I[x])中将一元多项式分解为不可约因式。
sympy.polys.factortools.dup_zz_i_factor(f, K0)
在(ZZ_I[x])中将一元多项式分解为不可约因式。
sympy.polys.factortools.dmp_qq_i_factor(f, u, K0)
在(QQ_I[X])中将多变量多项式分解为不可约因式。
sympy.polys.factortools.dmp_zz_i_factor(f, u, K0)
在(ZZ_I[X])中将多变量多项式分解为不可约因式。
sympy.polys.factortools.dup_ext_factor(f, K)
在代数数域上将一元多项式分解为不可约因式。
域(K)必须是代数数域(k(a))(参见 QQ)。
例子
首先定义代数数域(K = \mathbb{Q}(\sqrt{2})):
>>> from sympy import QQ, sqrt
>>> from sympy.polys.factortools import dup_ext_factor
>>> K = QQ.algebraic_field(sqrt(2))
现在我们可以在(K)上对多项式(x² - 2)进行因式分解:
>>> p = [K(1), K(0), K(-2)] # x² - 2
>>> p1 = [K(1), -K.unit] # x - sqrt(2)
>>> p2 = [K(1), +K.unit] # x + sqrt(2)
>>> dup_ext_factor(p, K) == (K.one, [(p1, 1), (p2, 1)])
True
通常这将在更高的层次上完成:
>>> from sympy import factor
>>> from sympy.abc import x
>>> factor(x**2 - 2, extension=sqrt(2))
(x - sqrt(2))*(x + sqrt(2))
解释
使用了特拉格尔的算法。特别是这个函数是来自[Trager76]的算法alg_factor
。
如果(f)是(k(a)[x])中的多项式,则其范数(g(x))是(k[x])中的多项式。如果(g(x))是无平方因子且具有不可约因子(g_1(x))、(g_2(x))、(\cdots),则(f)在(k(a)[x])中的不可约因子由(f_i(x) = \gcd(f(x), g_i(x)))给出,其中 GCD 在(k(a)[x])中计算。
特拉格尔算法的第一步是找到整数偏移(s),使得(f(x-sa))具有无平方因子的范数。然后在(k[x])中对范数进行因式分解,并且与每个因子的(偏移后的)(f)的 GCD 给出(f)在(k(a)[x])中的偏移后因子。最后取消偏移以恢复(f)在(k(a)[x])中的未偏移因子。
该算法将(k(a)[x])中的因式分解问题化简为在(k[x])中的因式分解,主要额外步骤包括计算范数(在(k[x,y])中的结果计算)和在(k(a)[x])中的一些多项式 GCD。
在 SymPy 的实践中,基础域(k)通常是有理数域 QQ,而此函数用于将系数在类似于(\mathbb{Q}(\sqrt{2}))的代数数域中的多项式进行因式分解。
另见
dmp_ext_factor
多变量多项式在k(a)
上的类似函数。
dup_sqf_norm
来自[Trager76]的子程序sqfr_norm
。
sympy.polys.polytools.factor
最终使用此函数所需的高层函数。
sympy.polys.factortools.dmp_ext_factor(f, u, K)
在代数数域上将多变元多项式因式分解为不可约多项式。
域 (K) 必须是代数数域 (k(a))(见 QQ)。
示例:
首先定义代数数域 (K = \mathbb{Q}(\sqrt{2})):
>>> from sympy import QQ, sqrt
>>> from sympy.polys.factortools import dmp_ext_factor
>>> K = QQ.algebraic_field(sqrt(2))
现在我们可以在 (K) 上因式分解多元多项式 (x² y² - 2):
>>> p = [[K(1),K(0),K(0)], [], [K(-2)]] # x**2*y**2 - 2
>>> p1 = [[K(1),K(0)], [-K.unit]] # x*y - sqrt(2)
>>> p2 = [[K(1),K(0)], [+K.unit]] # x*y + sqrt(2)
>>> dmp_ext_factor(p, 1, K) == (K.one, [(p1, 1), (p2, 1)])
True
通常这在更高层次上完成:
>>> from sympy import factor
>>> from sympy.abc import x, y
>>> factor(x**2*y**2 - 2, extension=sqrt(2))
(x*y - sqrt(2))*(x*y + sqrt(2))
解释:
这是特拉格尔(Trager)的多变元多项式算法。特别地,此函数是来自[Trager76]的算法 alg_factor
。
详见 dup_ext_factor()
进行解释。
另请参见:
dup_ext_factor
对于一元多项式在 k(a)
上的类似函数。
dmp_sqf_norm
从[Trager76]也是多变元多项式的 sqfr_norm
子程序的多变元版本。
sympy.polys.polytools.factor
最终使用此函数所需的高层函数。
sympy.polys.factortools.dup_gf_factor(f, K)
在有限域上分解一元多项式。
sympy.polys.factortools.dmp_gf_factor(f, u, K)
在有限域上将多变元多项式因式分解。
sympy.polys.factortools.dup_factor_list(f, K0)
在 (K[x]) 中将一元多项式因式分解为不可约的多项式。
sympy.polys.factortools.dup_factor_list_include(f, K)
在 (K[x]) 中将一元多项式因式分解为不可约的多项式。
sympy.polys.factortools.dmp_factor_list(f, u, K0)
在 (K[X]) 中将多变元多项式因式分解为不可约多项式。
sympy.polys.factortools.dmp_factor_list_include(f, u, K)
在 (K[X]) 中将多变元多项式因式分解为不可约多项式。
sympy.polys.factortools.dup_irreducible_p(f, K)
如果一元多项式 f
在其域上没有因子,则返回 True
。
sympy.polys.factortools.dmp_irreducible_p(f, u, K)
如果多变元多项式 f
在其域上没有因子,则返回 True
。
平方因子分解:
sympy.polys.sqfreetools.dup_sqf_p(f, K)
如果 f
是在 K[x]
中的平方自由多项式,则返回 True
。
示例:
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_sqf_p(x**2 - 2*x + 1)
False
>>> R.dup_sqf_p(x**2 - 1)
True
sympy.polys.sqfreetools.dmp_sqf_p(f, u, K)
如果 f
是在 K[X]
中的平方自由多项式,则返回 True
。
示例:
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_sqf_p(x**2 + 2*x*y + y**2)
False
>>> R.dmp_sqf_p(x**2 + y**2)
True
sympy.polys.sqfreetools.dup_sqf_norm(f, K)
在 (K[x]) 中找到一个使得 (f) 的移位具有平方自由规范。
域 (K) 必须是代数数域 (k(a))(见 QQ)。
返回 ((s,g,r)),使得 (g(x)=f(x-sa)),(r(x)=\text{Norm}(g(x))) 并且 (r) 是在 (k) 上的平方自由多项式。
示例:
首先我们创建代数数域 (K=k(a)=\mathbb{Q}(\sqrt{3})) 和环 (K[x]) 以及 (k[x]):
>>> from sympy.polys import ring, QQ
>>> from sympy import sqrt
>>> K = QQ.algebraic_field(sqrt(3))
>>> R, x = ring("x", K)
>>> _, X = ring("x", QQ)
现在我们可以找到 (f) 的一个平方自由规范的移位:
>>> f = x**2 - 1
>>> s, g, r = R.dup_sqf_norm(f)
移位 (s) 的选择是任意的,并且返回的 (g) 和 (r) 的具体值由 (s) 决定。
>>> s == 1
True
>>> g == x**2 - 2*sqrt(3)*x + 2
True
>>> r == X**4 - 8*X**2 + 4
True
不变量是:
>>> g == f.shift(-s*K.unit)
True
>>> g.norm() == r
True
>>> r.is_squarefree
True
解释:
这是特拉格尔(Trager)的多变元多项式因式分解算法的一部分。特别地,此函数是来自[Trager76]的算法 sqfr_norm
。
另请参见:
dmp_sqf_norm
对于多变元多项式在 k(a)
上的类似函数。
dmp_norm
直接计算(f)的范数,不需要任何偏移。
dup_ext_factor
实现了使用 Trager 算法的函数。
sympy.polys.polytools.sqf_norm
使用此函数的高级接口。
sympy.polys.sqfreetools.dmp_sqf_norm(f, u, K)
在(K[X])中找到f
的偏移,使其具有无平方项范数。
域(K)必须是代数数域(k(a))(见 QQ)。
返回((s,g,r)),使得(g(x_1,x_2,\cdots)=f(x_1-s_1 a, x_2 - s_2 a, \cdots)),(r(x)=\text{Norm}(g(x)))且(r)是(k)上的无平方项多项式。
示例
首先我们创建代数数域(K=k(a)=\mathbb{Q}(i))和环(K[x,y])以及(k[x,y]):
>>> from sympy.polys import ring, QQ
>>> from sympy import I
>>> K = QQ.algebraic_field(I)
>>> R, x, y = ring("x,y", K)
>>> _, X, Y = ring("x,y", QQ)
现在我们可以找到(f)的偏移的无平方项范数:
>>> f = x*y + y**2
>>> s, g, r = R.dmp_sqf_norm(f)
选择的偏移s
是任意的,而返回的具体值g
和r
由s
确定。
>>> s
[0, 1]
>>> g == x*y - I*x + y**2 - 2*I*y - 1
True
>>> r == X**2*Y**2 + X**2 + 2*X*Y**3 + 2*X*Y + Y**4 + 2*Y**2 + 1
True
所需的不变量是:
>>> g == f.shift_list([-si*K.unit for si in s])
True
>>> g.norm() == r
True
>>> r.is_squarefree
True
解释
这是 Trager 多项式在代数数域上因式分解的一部分。特别地,这个函数是算法sqfr_norm
从[Trager76]的多变量泛化。
参见
dup_sqf_norm
单变量多项式在k(a)
上的类似函数。
dmp_norm
直接计算(f)的范数,不需要任何偏移。
dmp_ext_factor
实现了使用 Trager 算法的函数。
sympy.polys.polytools.sqf_norm
使用此函数的高级接口。
sympy.polys.sqfreetools.dmp_norm(f, u, K)
(K[X])中f
的范数,通常不是无平方项的。
域(K)必须是代数数域(k(a))(见 QQ)。
示例
我们首先定义代数数域(K = k(a) = \mathbb{Q}(\sqrt{2})):
>>> from sympy import QQ, sqrt
>>> from sympy.polys.sqfreetools import dmp_norm
>>> k = QQ
>>> K = k.algebraic_field(sqrt(2))
现在我们可以计算多项式(p)在(K[x,y])中的范数:
>>> p = [[K(1)], [K(1),K.unit]] # x + y + sqrt(2)
>>> N = [[k(1)], [k(2),k(0)], [k(1),k(0),k(-2)]] # x**2 + 2*x*y + y**2 - 2
>>> dmp_norm(p, 1, K) == N
True
在更高级的函数中是:
>>> from sympy import expand, roots, minpoly
>>> from sympy.abc import x, y
>>> from math import prod
>>> a = sqrt(2)
>>> e = (x + y + a)
>>> e.as_poly([x, y], extension=a).norm()
Poly(x**2 + 2*x*y + y**2 - 2, x, y, domain='QQ')
这等于表达式的乘积(x + y + a_i),其中(a_i)是(a)的共轭:
>>> pa = minpoly(a)
>>> pa
_x**2 - 2
>>> rs = roots(pa, multiple=True)
>>> rs
[sqrt(2), -sqrt(2)]
>>> n = prod(e.subs(a, r) for r in rs)
>>> n
(x + y - sqrt(2))*(x + y + sqrt(2))
>>> expand(n)
x**2 + 2*x*y + y**2 - 2
解释
给定代数数域(K = k(a)),任何(K)中的元素(b)可以表示为多项式函数(b=g(a)),其中(g)在(k[x])中。如果(a)在(k)上的极小多项式是(p_a),那么(p_a(x))的根(a_1)、(a_2)、(\cdots)是(a)的共轭。(b)的范数是乘积(g(a1) \times g(a2) \times \cdots),是(k)中的一个元素。
如 [Trager76],我们将此范数扩展到 (K) 上的多变量多项式。如果 (b(x)) 是 (k(a)[X]) 中的多项式,则我们可以将 (b) 视为函数 (g_X(a)),其中 (g_X) 是 (k[X][y]) 的元素,即具有 (k[X]) 元素作为系数的多项式函数。然后 (b) 的范数是 (g_X(a1) \times g_X(a2) \times \cdots),并且将是 (k[X]) 的元素。
参见
dmp_sqf_norm
计算 (f) 的移位,使得 (\text{Norm}(f)) 是无平方因子的。
sympy.polys.polytools.Poly.norm
调用此函数的高级函数。
sympy.polys.sqfreetools.dup_gf_sqf_part(f, K)
计算 GF(p)[x]
中 f
的无平方部分。
sympy.polys.sqfreetools.dmp_gf_sqf_part(f, u, K)
计算 GF(p)[X]
中 f
的无平方部分。
sympy.polys.sqfreetools.dup_sqf_part(f, K)
返回 K[x]
中多项式的无平方部分。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_sqf_part(x**3 - 3*x - 2)
x**2 - x - 2
参见
sympy.polys.polytools.Poly.sqf_part
sympy.polys.sqfreetools.dmp_sqf_part(f, u, K)
返回 K[X]
中多项式的无平方部分。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> R.dmp_sqf_part(x**3 + 2*x**2*y + x*y**2)
x**2 + x*y
sympy.polys.sqfreetools.dup_gf_sqf_list(f, K, all=False)
计算 GF(p)[x]
中 f
的无平方分解。
sympy.polys.sqfreetools.dmp_gf_sqf_list(f, u, K, all=False)
计算 GF(p)[X]
中 f
的无平方分解。
sympy.polys.sqfreetools.dup_sqf_list(f, K, all=False)
返回 K[x]
中多项式的无平方分解。
使用来自 [Yun76] 的 Yun 算法。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> f = 2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16
>>> R.dup_sqf_list(f)
(2, [(x + 1, 2), (x + 2, 3)])
>>> R.dup_sqf_list(f, all=True)
(2, [(1, 1), (x + 1, 2), (x + 2, 3)])
参见
dmp_sqf_list
多变量多项式的相应函数。
sympy.polys.polytools.sqf_list
表达式的无平方因子分解的高级函数。
sympy.polys.polytools.Poly.sqf_list
Poly
上的类似方法。
参考文献
sympy.polys.sqfreetools.dup_sqf_list_include(f, K, all=False)
返回 K[x]
中多项式的无平方分解。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> f = 2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16
>>> R.dup_sqf_list_include(f)
[(2, 1), (x + 1, 2), (x + 2, 3)]
>>> R.dup_sqf_list_include(f, all=True)
[(2, 1), (x + 1, 2), (x + 2, 3)]
sympy.polys.sqfreetools.dmp_sqf_list(f, u, K, all=False)
返回 (K[X]) 中多项式的无平方分解。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x**5 + 2*x**4*y + x**3*y**2
>>> R.dmp_sqf_list(f)
(1, [(x + y, 2), (x, 3)])
>>> R.dmp_sqf_list(f, all=True)
(1, [(1, 1), (x + y, 2), (x, 3)])
解释
使用来自 [Yun76] 的单变量多项式的 Yun 算法进行递归处理。将多变量多项式视为其主变量的单变量多项式。然后 Yun 算法递归计算原始多项式的无平方因子分解和内容的因式分解。
最好使用专用于多变量多项式的算法。
参见
dup_sqf_list
单变量多项式的相应函数。
sympy.polys.polytools.sqf_list
表达式的无平方因子分解的高级函数。
sympy.polys.polytools.Poly.sqf_list
Poly
上的类似方法。
sympy.polys.sqfreetools.dmp_sqf_list_include(f, u, K, all=False)
返回 K[x]
中多项式的平方自由分解。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
>>> f = x**5 + 2*x**4*y + x**3*y**2
>>> R.dmp_sqf_list_include(f)
[(1, 1), (x + y, 2), (x, 3)]
>>> R.dmp_sqf_list_include(f, all=True)
[(1, 1), (x + y, 2), (x, 3)]
sympy.polys.sqfreetools.dup_gff_list(f, K)
计算 K[x]
中 f
的最大阶乘分解。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> R.dup_gff_list(x**5 + 2*x**4 - x**3 - 2*x**2)
[(x, 1), (x + 2, 4)]
sympy.polys.sqfreetools.dmp_gff_list(f, u, K)
计算 K[X]
中 f
的最大阶乘分解。
示例
>>> from sympy.polys import ring, ZZ
>>> R, x,y = ring("x,y", ZZ)
Groebner 基算法
Groebner 基础可以用来解决计算交换代数中的许多问题。它们的计算相当复杂,并且非常依赖性能。我们在这里介绍了各种 Groebner 基础计算算法的低级实现;请参阅手册的前一部分以获取使用说明。
sympy.polys.groebnertools.groebner(seq, ring, method=None)
计算在 ( K[X] ) 中一组多项式的 Groebner 基。
环绕(默认)改进的 Buchberger 算法和其他计算 Groebner 基础的算法。可以通过 method
参数或 sympy.polys.polyconfig.setup()
来更改算法的选择,其中 method
可以是 buchberger
或 f5b
。
sympy.polys.groebnertools.spoly(p1, p2, ring)
计算 LCM(LM(p1), LM(p2))/LM(p1)p1 - LCM(LM(p1), LM(p2))/LM(p2)p2 这是在 p1 和 p2 是单项式的情况下提供的 S-多项式
sympy.polys.groebnertools.red_groebner(G, ring)
计算从 BeckerWeispfenning93,p. 216 中的简化 Groebner 基
选择已经生成理想的子生成器,并计算它们的简化 Groebner 基。
sympy.polys.groebnertools.is_groebner(G, ring)
检查 G 是否是 Groebner 基。
sympy.polys.groebnertools.is_minimal(G, ring)
检查 G 是否为最小 Groebner 基。
sympy.polys.groebnertools.is_reduced(G, ring)
检查 G 是否为简化 Groebner 基。
sympy.polys.fglmtools.matrix_fglm(F, ring, O_to)
将零维理想的简化 Groebner 基 F
按 O_from
转换为简化 Groebner 基按 O_to
。
参考文献
[R801]
J.C. Faugere, P. Gianni, D. Lazard, T. Mora (1994). Efficient Computation of Zero-dimensional Groebner Bases by Change of Ordering
也提供了模块的 Groebner 基础算法:
sympy.polys.distributedmodules.sdm_spoly(f, g, O, K, phantom=None)
计算 f
和 g
的广义 s-多项式。
假设地面场是 K
,并按 O
排序单项式。
如果 f
或 g
中任何一个为零,则此操作无效。
如果 ( f ) 和 ( g ) 的领导项涉及 ( F ) 的不同基元素,则它们的 s-多项式被定义为零。否则,它是 ( f ) 和 ( g ) 的领导项在某种线性组合中,其中领导项相消。详见 [SCA,defn 2.3.6]。
如果 phantom
不是 None
,则它应该是一个模元素对,用于执行与 f
和 g
相同的操作。在这种情况下,返回两个结果。
示例
>>> from sympy.polys.distributedmodules import sdm_spoly
>>> from sympy.polys import QQ, lex
>>> f = [((2, 1, 1), QQ(1)), ((1, 0, 1), QQ(1))]
>>> g = [((2, 3, 0), QQ(1))]
>>> h = [((1, 2, 3), QQ(1))]
>>> sdm_spoly(f, h, lex, QQ)
[]
>>> sdm_spoly(f, g, lex, QQ)
[((1, 2, 1), 1)]
sympy.polys.distributedmodules.sdm_ecart(f)
计算 f
的差异。
这被定义为 ( f ) 的总次数与 ( f ) 的领导单项式的总次数之差 [SCA,defn 2.3.7]。
如果 f 为零,则无效。
示例
>>> from sympy.polys.distributedmodules import sdm_ecart
>>> sdm_ecart([((1, 2, 3), 1), ((1, 0, 1), 1)])
0
>>> sdm_ecart([((2, 2, 1), 1), ((1, 5, 1), 1)])
3
sympy.polys.distributedmodules.sdm_nf_mora(f, G, O, K, phantom=None)
计算 f
关于 G
和排序 O
的弱正规形式。
假设地面场是 K
,并按 O
排序单项式。
弱正规形式定义在[SCA, defn 2.3.3]中。它们不是唯一的。此函数根据 (G) 的顺序确定性地计算弱正规形式。
弱正规形式的最重要性质如下:如果 (R) 是与单项式顺序相关联的环(如果顺序是全局的,则我们只需 (R = K[x_1, \ldots, x_n]),否则它是这个环的某种局部化),(I) 是 (R) 的任何理想,(G) 是 (I) 的一个标准基,则对于任何 (f \in R),我们有 (f \in I) 当且仅当 (NF(f | G) = 0)。
这是计算关于任意单项式顺序的弱正规形式的广义 Mora 算法[SCA, algorithm 2.3.9]。
如果phantom
不是None
,则它应该是“幻影”参数的一对,用于对f
,G
执行相同的计算,然后返回两个结果。
sympy.polys.distributedmodules.sdm_groebner(G, NF, O, K, extended=False)
使用关于顺序 O
的算法计算 G
的最小标准基。
该算法使用正规形式 NF
,例如 sdm_nf_mora
。假设基础域为 K
,并根据 O
对单项式进行排序。
让 (N) 表示由 (G) 的元素生成的子模。(N) 的标准基是 (N) 的一个子集 (S),使得 (in(S) = in(N)),其中对于 (F) 的任何子集 (X),(in(X)) 表示元素 (X) 的初等形式生成的子模。[SCA, defn 2.3.2]
如果没有子集是标准基,则称标准基为最小标准基。
可以证明标准基始终是生成集。
最小标准基不唯一。此算法根据 (G) 的特定顺序计算确定性结果。
如果extended=True
,还要计算从初始生成器到格雷布纳基的过渡矩阵。也就是说,返回一个系数向量的列表,用 G
的元素表示格雷布纳基的元素。
此函数实现“糖”策略,请参阅
Giovini 等人:“一块糖方块,谢谢”或 Buchberger 算法中的选择策略。
选项
Poly
和公共 API 函数的选项管理器。
class sympy.polys.polyoptions.Options(gens, args, flags=None, strict=False)
多项式操作模块的选项管理器。
示例
>>> from sympy.polys.polyoptions import Options
>>> from sympy.polys.polyoptions import build_options
>>> from sympy.abc import x, y, z
>>> Options((x, y, z), {'domain': 'ZZ'})
{'auto': False, 'domain': ZZ, 'gens': (x, y, z)}
>>> build_options((x, y, z), {'domain': 'ZZ'})
{'auto': False, 'domain': ZZ, 'gens': (x, y, z)}
选项
-
扩展 — 布尔选项
-
生成器 — 选项
-
Wrt — 选项
-
排序 — 选项
-
顺序 — 选项
-
域 — 布尔选项
-
贪婪 — 布尔选项
-
域 — 选项
-
分割 — 布尔选项
-
高斯 — 布尔选项
-
扩展 — 选项
-
模数 — 选项
-
对称 — 布尔选项
-
严格 — 布尔选项
标志
-
自动 — 布尔标志
-
分数 — 布尔标志
-
形式 — 布尔标志
-
多项式 — 布尔标志
-
包括 — 布尔标志
-
全部 — 布尔标志
-
生成器 — 标志
-
系列 — 布尔标志
clone(updates={})
克隆 self
并更新指定的选项。
sympy.polys.polyoptions.build_options(gens, args=None)
从关键字参数或...选项构建选项。## 配置
多项式操作算法的配置实用程序。
sympy.polys.polyconfig.setup(key, value=None)
为配置项分配值(或重置)。
异常
这些是多项式模块定义的异常。
TODO 排序和解释
class sympy.polys.polyerrors.BasePolynomialError
多项式相关异常的基类。
class sympy.polys.polyerrors.ExactQuotientFailed(f, g, dom=None)
class sympy.polys.polyerrors.OperationNotSupported(poly, func)
class sympy.polys.polyerrors.HeuristicGCDFailed
class sympy.polys.polyerrors.HomomorphismFailed
class sympy.polys.polyerrors.IsomorphismFailed
class sympy.polys.polyerrors.ExtraneousFactors
class sympy.polys.polyerrors.EvaluationFailed
class sympy.polys.polyerrors.RefinementFailed
class sympy.polys.polyerrors.CoercionFailed
class sympy.polys.polyerrors.NotInvertible
class sympy.polys.polyerrors.NotReversible
class sympy.polys.polyerrors.NotAlgebraic
class sympy.polys.polyerrors.DomainError
class sympy.polys.polyerrors.PolynomialError
class sympy.polys.polyerrors.UnificationFailed
class sympy.polys.polyerrors.GeneratorsNeeded
class sympy.polys.polyerrors.ComputationFailed(func, nargs, exc)
class sympy.polys.polyerrors.GeneratorsError
class sympy.polys.polyerrors.UnivariatePolynomialError
class sympy.polys.polyerrors.MultivariatePolynomialError
class sympy.polys.polyerrors.PolificationFailed(opt, origs, exprs, seq=False)
class sympy.polys.polyerrors.OptionError
class sympy.polys.polyerrors.FlagError
参考
模 GCD
sympy.polys.modulargcd.modgcd_univariate(f, g)
使用模算法计算在 (\mathbb{Z}[x]) 中两个多项式的最大公约数。
该算法通过在适当的质数 (p) 下计算一元整数多项式 (f) 和 (g) 的 (\mathbb{Z}_p[x]) 中的最大公约数,然后利用中国剩余定理重构系数来计算其在 (\mathbb{Z}[x]) 中的最大公约数。只对那些极有可能是所需 GCD 的候选者进行试除。
参数:
f:PolyElement
一元整数多项式
g:PolyElement
一元整数多项式
返回:
h:PolyElement
多项式 (f) 和 (g) 的最大公约数
cff:PolyElement
(f) 的余子式,即 (\frac{f}{h})
cfg:PolyElement
(g) 的余子式,即 (\frac{g}{h})
示例
>>> from sympy.polys.modulargcd import modgcd_univariate
>>> from sympy.polys import ring, ZZ
>>> R, x = ring("x", ZZ)
>>> f = x**5 - 1
>>> g = x - 1
>>> h, cff, cfg = modgcd_univariate(f, g)
>>> h, cff, cfg
(x - 1, x**4 + x**3 + x**2 + x + 1, 1)
>>> cff * h == f
True
>>> cfg * h == g
True
>>> f = 6*x**2 - 6
>>> g = 2*x**2 + 4*x + 2
>>> h, cff, cfg = modgcd_univariate(f, g)
>>> h, cff, cfg
(2*x + 2, 3*x - 3, x + 1)
>>> cff * h == f
True
>>> cfg * h == g
True
参考
sympy.polys.modulargcd.modgcd_bivariate(f, g)
使用模算法计算在 (\mathbb{Z}[x, y]) 中两个多项式的最大公约数。
该算法通过在适当的质数 (p) 下计算二元整数多项式 (f) 和 (g) 的 (\mathbb{Z}_p[x, y]) 中的最大公约数,然后利用中国剩余定理重构系数来计算其在 (\mathbb{Z}[x, y]) 中的最大公约数。为了计算 (\mathbb{Z}_p) 上的二元 GCD,评估多项式 (f ; \mathrm{mod} , p) 和 (g ; \mathrm{mod} , p) 在某些 (a \in \mathbb{Z}_p) 下的值,然后计算它们在 (\mathbb{Z}_p[x]) 中的一元 GCD。通过插值得到 (\mathbb{Z}_p[x, y]) 中的二元 GCD。为了验证在 (\mathbb{Z}[x, y]) 中的结果,进行试除,但仅针对那些极有可能是所需 GCD 的候选者。
参数:
f:PolyElement
二元整数多项式
g:PolyElement
二元整数多项式
返回:
h:PolyElement
多项式 (f) 和 (g) 的最大公约数
cff:PolyElement
(f) 的余子式,即 (\frac{f}{h})
cfg:PolyElement
(g) 的余子式,即 (\frac{g}{h})
示例
>>> from sympy.polys.modulargcd import modgcd_bivariate
>>> from sympy.polys import ring, ZZ
>>> R, x, y = ring("x, y", ZZ)
>>> f = x**2 - y**2
>>> g = x**2 + 2*x*y + y**2
>>> h, cff, cfg = modgcd_bivariate(f, g)
>>> h, cff, cfg
(x + y, x - y, x + y)
>>> cff * h == f
True
>>> cfg * h == g
True
>>> f = x**2*y - x**2 - 4*y + 4
>>> g = x + 2
>>> h, cff, cfg = modgcd_bivariate(f, g)
>>> h, cff, cfg
(x + 2, x*y - x - 2*y + 2, 1)
>>> cff * h == f
True
>>> cfg * h == g
True
参考
sympy.polys.modulargcd.modgcd_multivariate(f, g)
使用模算法计算在 (\mathbb{Z}[x_0, \ldots, x_{k-1}]) 中两个多项式的最大公约数。
该算法通过在适当的质数 (p) 下计算多变量整数多项式 (f) 和 (g) 的 (\mathbb{Z}p[x_0, \ldots, x]) 中的最大公约数,然后利用中国剩余定理重构系数来计算其在 (\mathbb{Z}[x_0, \ldots, x_{k-1}]) 中的最大公约数。为了计算 (\mathbb{Z}p) 上的多变量 GCD,使用递归子例程 _modgcd_multivariate_p()
。为了验证在 (\mathbb{Z}[x_0, \ldots, x]) 中的结果,进行试除,但仅针对那些极有可能是所需 GCD 的候选者。
参数:
f:PolyElement
多变量整数多项式
g:PolyElement
多变量整数多项式
返回:
h:PolyElement
多项式 (f) 和 (g) 的最大公约数
cff:PolyElement
(f) 的余子式,即 (\frac{f}{h})
cfg:PolyElement
(g)的余因子,即(\frac{g}{h})
示例
>>> from sympy.polys.modulargcd import modgcd_multivariate
>>> from sympy.polys import ring, ZZ
>>> R, x, y = ring("x, y", ZZ)
>>> f = x**2 - y**2
>>> g = x**2 + 2*x*y + y**2
>>> h, cff, cfg = modgcd_multivariate(f, g)
>>> h, cff, cfg
(x + y, x - y, x + y)
>>> cff * h == f
True
>>> cfg * h == g
True
>>> R, x, y, z = ring("x, y, z", ZZ)
>>> f = x*z**2 - y*z**2
>>> g = x**2*z + z
>>> h, cff, cfg = modgcd_multivariate(f, g)
>>> h, cff, cfg
(z, x*z - y*z, x**2 + 1)
>>> cff * h == f
True
>>> cfg * h == g
True
另见
_modgcd_multivariate_p
参考文献
sympy.polys.modulargcd._modgcd_multivariate_p(f, g, p, degbound, contbound)
在(\mathbb{Z}p[x_0, \ldots, x])中计算两个多项式(f)和(g)的 GCD。
算法通过在适当的(a \in \mathbb{Z}_p)处评估多项式(f)和(g),逐步减少问题,并递归调用自身以在(\mathbb{Z}p[x_0, \ldots, x])中计算 GCD。如果这些递归调用在足够多的评估点上成功,那么在(k)个变量中的 GCD 将被插值,否则算法返回None
。每当计算 GCD 或内容时,它们的度数与界限进行比较。如果遇到大于界限的度数,则当前调用返回None
,并且必须选择新的评估点。如果某个时刻的度数较小,则更新相应的界限,并且算法失败。
参数:
f:PolyElement
在(\mathbb{Z}_p)中系数的多变量整数多项式
g:PolyElement
在(\mathbb{Z}_p)中系数的多变量整数多项式
p:整数
素数,(f)和(g)的模数
degbound:Integer 对象的列表
degbound[i]
是变量(x_i)中(f)和(g)的 GCD 的度数的上界
contbound:Integer 对象的列表
contbound[i]
是在(\mathbb{Z}p[x_i][x_0, \ldots, x])中 GCD 的内容的度数的上界,contbound[0]
不使用,因此可以任意选择。
返回:
h:PolyElement
(f)和(g)的多项式的 GCD 或
None
参考文献
sympy.polys.modulargcd.func_field_modgcd(f, g)
使用模算法在(\mathbb Q(\alpha)[x_0, \ldots, x_{n-1}])中计算两个多项式(f)和(g)的 GCD。
该算法首先计算在 (\mathbb{Z}[z]) 中最小多项式 (m_{\alpha}) 的原始关联物 (\check{m}{\alpha}(z)),以及在 ((\check{m})[x_0]) 中的 (f) 和 (g) 的原始关联物。然后在 (\mathbb{Q}(x_1, \ldots, x_{n-1})[z]/(m_{\alpha}(z))[x_0]) 中计算最大公因式。这是通过在适当的素数 (p) 上计算 (\mathbb{Z}p(x_1, \ldots, x)[z]/(\check{m}{\alpha}(z))[x_0]) 中的最大公因式,然后利用中国剩余定理和有理重构重建系数来完成的。在 (\mathbb{Z}p(z)/(\check{m}(z))[x_0]) 中使用欧几里得算法。这些递归调用的结果然后进行插值,并使用有理函数重构来获取正确的系数。在 (\mathbb{Q}(x_1, \ldots, x)[z]/(m_{\alpha}(z))[x_0]) 和 (\mathbb{Z}p(x_1, \ldots, x)[z]/(\check{m}_{\alpha}(z))[x_0]) 中的结果通过一个无分数试除法来验证。
除了上述的最大公因式计算外,还需计算 (\mathbb{Q}(\alpha)[x_1, \ldots, x_{n-1}]) 中的一些最大公因式,因为将多项式视为一元的可能导致最大公因式的虚假内容。为此,递归调用 func_field_modgcd
。
参数:
f, g :PolyElement
(\mathbb{Q}(\alpha)[x_0, \ldots, x_{n-1}]) 中的多项式
返回:
h :PolyElement
多项式 (f) 和 (g) 的首一最大公因式
cff :PolyElement
(f) 的余子式,即 (\frac{f}{h})
cfg :PolyElement
(g) 的余子式,即 (\frac{g}{h})
示例
>>> from sympy.polys.modulargcd import func_field_modgcd
>>> from sympy.polys import AlgebraicField, QQ, ring
>>> from sympy import sqrt
>>> A = AlgebraicField(QQ, sqrt(2))
>>> R, x = ring('x', A)
>>> f = x**2 - 2
>>> g = x + sqrt(2)
>>> h, cff, cfg = func_field_modgcd(f, g)
>>> h == x + sqrt(2)
True
>>> cff * h == f
True
>>> cfg * h == g
True
>>> R, x, y = ring('x, y', A)
>>> f = x**2 + 2*sqrt(2)*x*y + 2*y**2
>>> g = x + sqrt(2)*y
>>> h, cff, cfg = func_field_modgcd(f, g)
>>> h == x + sqrt(2)*y
True
>>> cff * h == f
True
>>> cfg * h == g
True
>>> f = x + sqrt(2)*y
>>> g = x + y
>>> h, cff, cfg = func_field_modgcd(f, g)
>>> h == R.one
True
>>> cff * h == f
True
>>> cfg * h == g
True
参考文献
未记录
polys 模块的许多部分仍然未记录,并且即使有文档,也非常少。请贡献!