AGCA - 代数几何与交换代数模块

介绍

代数几何是两种地中海文化思想的混合体。它是阿拉伯科学中快速计算方程解的方法与希腊艺术中位置和形状的叠加。这幅织锦最初在欧洲土地上编织,并在国际潮流的影响下不断完善。代数几何研究几何上可能与代数上可能之间的微妙平衡。每当这个数学跷跷板的一边压倒另一边时,人们立即失去兴趣,跑去寻找更刺激的娱乐。

—乔治·R·肯普夫(1944 – 2002)

代数几何指的是通过代数方法(有时反之亦然)研究几何问题。虽然这是一个相当古老的主题,但今天所理解的代数几何很大程度上是20世纪的发展。基于例如黎曼和戴德金的思想,人们认识到多项式方程组(称为代数簇)的解集的性质与该簇上多项式函数集(称为坐标环)的行为之间存在着密切的联系。

如同许多几何学科一样,我们可以区分局部问题和全局问题(以及方法)。代数几何中的局部研究本质上等同于研究某些环、它们的理想和模。后一主题也被称为交换代数。它是代数几何学家的基本局部工具集,就像微分分析是微分几何学家的局部工具集一样。

关于交换代数的一个很好的概念性介绍是 [Atiyah69]。一个更偏向于计算的介绍,以及本模块中大多数算法所基于的工作,是 [Greuel2008]

该模块旨在最终允许表达和解决局部和全局几何问题,无论是在域上的经典情况还是在更现代的算术情况中。然而,到目前为止,该模块完全没有几何功能。目前,该模块仅提供域上计算交换代数的工具。

所有代码示例均假设:

>>> from sympy import *
>>> x, y, z = symbols('x,y,z')
>>> init_printing(use_unicode=True)

参考

在本节中,我们记录了AGCA模块的使用方法。为了方便读者,插入了一些定义和示例/解释。

基环

交换代数中的几乎所有计算都是相对于一个“基环”进行的。(例如,当询问关于理想的问题时,基环是理想是其子集的环。)原则上,所有多项式“域”都可以用作基环。然而,只有对于域上的多项式环以及其各种局部化和商,才有实现有用的功能。

如下面的示例所示,创建你感兴趣的对象的最便捷方法是基于基础域逐步构建,然后使用各种方法从旧对象创建新对象。例如,为了在`mathbb{Q}`上创建节点三次曲线`y^2 = x^3`在原点的局部环,你可以这样做:

>>> lr = QQ.old_poly_ring(x, y, order="ilex") / [y**2 - x**3]
>>> lr
ℚ[x, y, order=ilex]
───────────────────
    ╱   3    2╲
    ╲- x  + y ╱

注意如何可以使用Python列表表示法作为表达理想的快捷方式。你可以使用 convert 方法将普通的sympy对象转换为AGCA模块理解的对象(尽管在许多情况下这会自动完成——例如,列表自动转换为理想,并且在此过程中符号 \(x\)\(y\) 自动转换为其他表示形式)。例如:

>>> X, Y = lr.convert(x), lr.convert(y) ; X
    ╱   3    2╲
x + ╲- x  + y ╱

>>> x**3 == y**2
False

>>> X**3 == Y**2
True

当不需要本地化时,可以使用更数学化的符号。例如,让我们创建三维仿射空间 \(\mathbb{A}^3\) 的坐标环:

>>> ar = QQ.old_poly_ring(x, y, z); ar
ℚ[x, y, z]

更多详情,请参阅以下类文档。请注意,作为域的基环是AGCA模块与polys模块之间主要的重叠点。所有域在polys参考中都有详细记录,因此我们在这里仅展示一个简要版本,列出与AGCA模块最相关的方法。

class sympy.polys.domains.ring.Ring[源代码][源代码]

表示一个环域。

方法

free_module(rank)

在自身上生成一个秩为 rank 的自由模。

ideal(*gens)

生成一个理想的 自我

quotient_ring(e)

形成 self 的商环。

free_module(rank)[源代码][源代码]

在自身上生成一个秩为 rank 的自由模。

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).free_module(2)
QQ[x]**2
ideal(*gens)[源代码][源代码]

生成一个理想的 自我

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).ideal(x**2)
<x**2>
quotient_ring(e)[源代码][源代码]

形成 self 的商环。

这里 e 可以是一个理想或一个可迭代对象。

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).quotient_ring(QQ.old_poly_ring(x).ideal(x**2))
QQ[x]/<x**2>
>>> QQ.old_poly_ring(x).quotient_ring([x**2])
QQ[x]/<x**2>

除法运算符已为此重载:

>>> QQ.old_poly_ring(x)/[x**2]
QQ[x]/<x**2>
sympy.polys.domains.polynomialring.PolynomialRing(
domain_or_ring,
symbols=None,
order=None,
)[源代码][源代码]

用于表示多元多项式环的类。

class sympy.polys.domains.quotientring.QuotientRing(ring, ideal)[源代码][源代码]

表示(交换)商环的类。

通常你不应该手动实例化这个对象,而是应该在构造过程中使用基环中的构造函数。

>>> from sympy.abc import x
>>> from sympy import QQ
>>> I = QQ.old_poly_ring(x).ideal(x**3 + 1)
>>> QQ.old_poly_ring(x).quotient_ring(I)
QQ[x]/<x**3 + 1>

可以有更短的版本:

>>> QQ.old_poly_ring(x)/I
QQ[x]/<x**3 + 1>
>>> QQ.old_poly_ring(x)/[x**3 + 1]
QQ[x]/<x**3 + 1>

属性:

  • ring - 基础环

  • base_ideal - 用于形成商的理想

属性:
别名
rep
tp

别名 dtype

方法

__call__(*args)

args 构造 self 域的一个元素。

abs(a)

a 的绝对值,意味着 __abs__

add(a, b)

ab 的和,意味着 __add__

alg_field_from_poly(poly[, alias, root_index])

通过根索引选择多项式的根来构造代数扩展的便捷方法。

algebraic_field(*extension[, alias])

返回一个代数数域,即 \(K(\alpha, \ldots)\)

almosteq(a, b[, tolerance])

检查 ab 是否几乎相等。

characteristic()

返回此域的特征。

cofactors(a, b)

返回 ab 的最大公约数和余因子。

convert(element[, base])

element 转换为 self.dtype

convert_from(element, base)

在给定的基本域中将 element 转换为 self.dtype

cyclotomic_field(n[, ss, alias, gen, root_index])

构造分圆域的便捷方法。

denom(a)

返回 \(a\) 的分母。

div(a, b)

ab 的除法,意味着 __divmod__

drop(*symbols)

从此域中移除生成器。

dtype

QuotientRingElement 的别名

evalf(a[, prec])

返回 a 的数值近似值。

exquo(a, b)

ab 的精确商,意味着 __floordiv__

exsqrt(a)

a 是平方数的域内的主平方根。

frac_field(*gens)

返回一个分数域,即 K(X)

free_module(rank)

self 上生成一个秩为 rank 的自由模。

from_AlgebraicField(a, K0)

将一个代数数转换为 dtype

from_ComplexField(a, K0)

将复杂元素转换为 dtype

from_ExpressionDomain(a, K0)

EX 对象转换为 dtype

from_ExpressionRawDomain(a, K0)

EX 对象转换为 dtype

from_FF(a, K0)

ModularInteger(int) 转换为 dtype

from_FF_gmpy(a, K0)

ModularInteger(mpz) 转换为 dtype

from_FF_python(a, K0)

ModularInteger(int) 转换为 dtype

from_FractionField(a, K0)

将 Python int 对象转换为 dtype

from_GlobalPolynomialRing(a, K0)

将 Python int 对象转换为 dtype

from_MonogenicFiniteExtension(a, K0)

ExtensionElement 转换为 dtype

from_PolynomialRing(a, K0)

将多项式转换为 dtype

from_QQ_gmpy(a, K0)

将 Python int 对象转换为 dtype

from_QQ_python(a, K0)

将 Python int 对象转换为 dtype

from_RealField(a, K0)

将 Python int 对象转换为 dtype

from_ZZ(a, K0)

将 Python int 对象转换为 dtype

from_ZZ_gmpy(a, K0)

将 Python int 对象转换为 dtype

from_ZZ_python(a, K0)

将 Python int 对象转换为 dtype

from_sympy(a)

gcd(a, b)

返回 ab 的最大公约数。

gcdex(a, b)

ab 的扩展最大公约数。

get_exact()

返回与 self 关联的精确域。

get_field()

返回与 self 关联的字段。

get_ring()

返回与 self 相关联的环。

half_gcdex(a, b)

ab 的半扩展最大公约数。

ideal(*gens)

生成一个理想的 自我

inject(*symbols)

将生成器注入此域。

invert(a, b)

返回 a mod b 的逆。

is_negative(a)

如果 a 为负数,则返回 True。

is_nonnegative(a)

如果 a 是非负的,则返回 True。

is_nonpositive(a)

如果 a 是非正数,则返回 True。

is_one(a)

如果 a 是 1,则返回 True。

is_positive(a)

如果 a 为正数,则返回 True。

is_square(a)

返回 a 是否是该域中的一个平方数。

is_zero(a)

lcm(a, b)

返回 ab 的最小公倍数。

log(a, b)

返回 a 的 b 进制对数。

map(seq)

递归地将 self 应用于 seq 的所有元素。

mul(a, b)

ab 的乘积,意味着 __mul__

n(a[, prec])

返回 a 的数值近似值。

neg(a)

返回 a 的否定值,意味着 __neg__

new(a)

a 构建 self 域的一个元素。

numer(a)

返回 a 的分子。

of_type(element)

检查 a 是否为 dtype 类型。

old_frac_field(*symbols, **kwargs)

返回一个分数域,即 \(K(X)\)

old_poly_ring(*symbols, **kwargs)

返回一个多项式环,即 \(K[X]\)

poly_ring(*gens)

返回一个多项式环,即 K[X]

pos(a)

返回 a 为正,意味着 __pos__

pow(a, b)

a 提升到 b 的幂,意味着 __pow__

quo(a, b)

ab 的商,意味着 __floordiv__

quotient_ring(e)

形成 self 的商环。

rem(a, b)

ab 的余数,意味着 __mod__

revert(a)

计算 a**(-1),如果可能的话。

sqrt(a)

返回 a 的(可能不精确的)平方根。

sub(a, b)

ab 的差异,意味着 __sub__

to_sympy(a)

unify(K1[, symbols])

构建一个包含 K0K1 元素的最小域。

unify_composite(K1)

统一两个领域,其中至少一个是复合的。

canonical_unit

from_GeneralizedPolynomialRing

from_QuotientRing

imag

is_unit

正常

真实

总和

unify_with_symbols

模块、理想及其基本性质

\(A\) 为一个环。一个 \(A\)-模是一个集合 \(M\),连同两个二元运算 \(+: M \times M \to M\)\(\times: R \times M \to M\),分别称为加法和标量乘法。这些运算需要满足某些公理,这些公理可以在例如 [Atiyah69] 中找到。通过这种方式,模是向量空间(\(A\) 为域)和阿贝尔群(\(A = \mathbb{Z}\))的直接推广。\(A\)-模 \(M\) 的*子模*是 \(M\) 的子集 \(N \subset M\),使得二元运算限制在 \(N\) 上,并且 \(N\) 在这些运算下成为一个 \(A\)-模。

\(A\) 本身具有自然的 \(A\)-模结构,其中模中的加法和乘法与环中的加法和乘法一致。这个 \(A\)-模也写作 \(A\)\(A\)\(A\)-子模称为 \(A\)理想。理想在代数几何中自然出现。更一般的模可以看作是在仅讨论理想之外提供技术便利的“活动空间”。

如果 \(M\), \(N\)\(A\)-模,那么在 \(M \times N\) 上存在一个自然的(逐分量)`A`-模结构。类似地,在更多分量的笛卡尔积上也存在 \(A\)-模结构。(对于有分类倾向的读者:有限多个 \(A\)-模的笛卡尔积,带有这种 \(A\)-模结构,是所有 \(A\)-模范畴中的有限双积。对于无限多个分量,它是直积(但无限直和需要以不同的方式构造)。)通常,\(A\)-模 \(M\) 的重复积记作 \(M, M^2, M^3 \ldots\),或者对于任意索引集 \(I\) 记作 \(M^I\)

一个 \(A\)-模 \(M\) 被称为*自由*的,如果它与某个(不一定是有限的)指标集 \(I\)\(A\)-模 \(A^I\) 同构(同构的定义请参见下一节)。\(I\) 的基数称为 \(M\) 的*秩*;可以证明这是良定义的。一般来说,AGCA 模块仅处理有限秩的自由模,以及与之密切相关的其他模。创建模的最简单方法是使用它们所构成的对象的成员方法。例如,让我们创建一个秩为 4 的自由模,该模在上面创建的 \(\mathbb{A}^2\) 的坐标环上,以及一个子模:

>>> F = ar.free_module(4) ; F
          4
ℚ[x, y, z]

>>> S = F.submodule([1, x, x**2, x**3], [0, 1, 0, y]) ; S
╱⎡       2   3⎤              ╲
╲⎣1, x, x , x ⎦, [0, 1, 0, y]╱

注意python列表如何可以用作模块元素(向量)的快捷表示法。像往常一样,可以使用 convert 方法将sympy/python对象转换为内部AGCA表示(参见下面的详细参考)。

以下是模块、自由模块和子模块的类的详细文档:

class sympy.polys.agca.modules.Module(ring)[源代码][源代码]

模块的抽象基类。

不要实例化 - 请使用环的显式构造函数代替:

>>> from sympy import QQ
>>> from sympy.abc import x
>>> QQ.old_poly_ring(x).free_module(2)
QQ[x]**2

属性:

  • dtype - 元素的类型

  • ring - 包含环

未实现的方法:

  • 子模块

  • 商模

  • is_zero

  • is_submodule

  • multiply_ideal

方法 convert 可能需要在子类中进行更改。

方法

contains(elem)

如果 elem 是此模块的元素,则返回 True。

convert(elem[, M])

elem 转换为此模块的内部表示形式。

identity_hom()

返回 self 上的恒等同态。

is_submodule(other)

如果 otherself 的子模块,则返回 True。

is_zero()

如果 self 是一个零模块,则返回 True。

multiply_ideal(other)

self 乘以理想值 other

quotient_module(other)

生成一个商模。

submodule(*gens)

生成一个子模块。

subset(other)

如果 otherself 的子集,则返回 True。

contains(elem)[源代码][源代码]

如果 elem 是此模块的元素,则返回 True。

convert(elem, M=None)[源代码][源代码]

elem 转换为此模块的内部表示形式。

如果 M 不是 None,它应该是一个包含它的模块。

identity_hom()[源代码][源代码]

返回 self 上的恒等同态。

is_submodule(other)[源代码][源代码]

如果 otherself 的子模块,则返回 True。

is_zero()[源代码][源代码]

如果 self 是一个零模块,则返回 True。

multiply_ideal(other)[源代码][源代码]

self 乘以理想值 other

quotient_module(other)[源代码][源代码]

生成一个商模。

submodule(*gens)[源代码][源代码]

生成一个子模块。

subset(other)[源代码][源代码]

如果 otherself 的子集,则返回 True。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> F.subset([(1, x), (x, 2)])
True
>>> F.subset([(1/x, x), (x, 2)])
False
class sympy.polys.agca.modules.FreeModule(ring, rank)[源代码][源代码]

自由模的抽象基类。

附加属性:

  • rank - 自由模的秩

未实现的方法:

  • 子模块

方法

basis()

返回一组基元素。

contains(elem)

如果 elem 是此模块的元素,则返回 True。

convert(elem[, M])

elem 转换为内部表示形式。

dtype

FreeModuleElement 的别名

identity_hom()

返回 self 上的恒等同态。

is_submodule(other)

如果 otherself 的子模块,则返回 True。

is_zero()

如果 self 是一个零模块,则返回 True。

multiply_ideal(other)

self 乘以理想值 other

quotient_module(submodule)

返回一个商模。

submodule(*gens)

生成一个子模块。

subset(other)

如果 otherself 的子集,则返回 True。

basis()[源代码][源代码]

返回一组基元素。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).free_module(3).basis()
([1, 0, 0], [0, 1, 0], [0, 0, 1])
convert(elem, M=None)[源代码][源代码]

elem 转换为内部表示形式。

每当计算涉及内部表示中不存在的元素时,此方法会被隐式调用。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> F.convert([1, 0])
[1, 0]
dtype[源代码]

FreeModuleElement 的别名

identity_hom()[源代码][源代码]

返回 self 上的恒等同态。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).free_module(2).identity_hom()
Matrix([
[1, 0], : QQ[x]**2 -> QQ[x]**2
[0, 1]])
is_submodule(other)[源代码][源代码]

如果 otherself 的子模块,则返回 True。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> M = F.submodule([2, x])
>>> F.is_submodule(F)
True
>>> F.is_submodule(M)
True
>>> M.is_submodule(F)
False
is_zero()[源代码][源代码]

如果 self 是一个零模块,则返回 True。

(如果,如本实现所假设的,系数环不是零环,那么这等价于秩为零。)

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).free_module(0).is_zero()
True
>>> QQ.old_poly_ring(x).free_module(1).is_zero()
False
multiply_ideal(other)[源代码][源代码]

self 乘以理想值 other

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> I = QQ.old_poly_ring(x).ideal(x)
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> F.multiply_ideal(I)
<[x, 0], [0, x]>
quotient_module(submodule)[源代码][源代码]

返回一个商模。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> M = QQ.old_poly_ring(x).free_module(2)
>>> M.quotient_module(M.submodule([1, x], [x, 2]))
QQ[x]**2/<[1, x], [x, 2]>

或者更简洁地,使用重载的除法运算符:

>>> QQ.old_poly_ring(x).free_module(2) / [[1, x], [x, 2]]
QQ[x]**2/<[1, x], [x, 2]>
class sympy.polys.agca.modules.FreeModuleElement(module, data)[源代码][源代码]

自由模的元素。数据存储为元组。

方法

add(d1, d2)

div(d, p)

eq(d1, d2)

如果 d1 和 d2 表示相同的元素,则返回 true。

mul(d, p)

class sympy.polys.agca.modules.SubModule(gens, container)[源代码][源代码]

子模块的基类。

属性:

  • container - 包含模块

  • gens - 生成器(包含模块的子集)

  • rank - 包含模块的等级

未实现的方法:

  • _包含

  • _syzygies

  • _in_terms_of_generators

  • _intersect

  • _module_quotient

在子类中可能需要更改的方法:

  • reduce_element

方法

contains(elem)

如果 elem 是此模块的元素,则返回 True。

convert(elem[, M])

elem 转换为内部表示形式。

identity_hom()

返回 self 上的恒等同态。

in_terms_of_generators(e)

用生成元表示 self 中的元素 e

inclusion_hom()

返回一个表示 self 包含映射的同态。

intersect(other, **options)

返回 self 与子模块 other 的交集。

is_full_module()

如果 self 是整个自由模组,则返回 True。

is_submodule(other)

如果 otherself 的子模块,则返回 True。

is_zero()

如果 self 是一个零模块,则返回 True。

module_quotient(other, **options)

返回 self 对子模块 other 的模商。

multiply_ideal(I)

self 乘以理想 I

quotient_module(other, **opts)

返回一个商模。

reduce_element(x)

将我们环中的元素 x 对理想 self 取模。

submodule(*gens)

生成一个子模块。

subset(other)

如果 otherself 的子集,则返回 True。

syzygy_module(**opts)

计算 self 生成元的 syzygy 模。

union(other)

返回由 selfother 的并集生成的模块。

convert(elem, M=None)[源代码][源代码]

elem 转换为内部表示形式。

大多数情况下被隐式调用。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> M = QQ.old_poly_ring(x).free_module(2).submodule([1, x])
>>> M.convert([2, 2*x])
[2, 2*x]
identity_hom()[源代码][源代码]

返回 self 上的恒等同态。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).free_module(2).submodule([x, x]).identity_hom()
Matrix([
[1, 0], : <[x, x]> -> <[x, x]>
[0, 1]])
in_terms_of_generators(e)[源代码][源代码]

用生成元表示 self 中的元素 e

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> M = F.submodule([1, 0], [1, 1])
>>> M.in_terms_of_generators([x, x**2])  
[DMP_Python([-1, 1, 0], QQ), DMP_Python([1, 0, 0], QQ)]
inclusion_hom()[源代码][源代码]

返回一个表示 self 包含映射的同态。

也就是说,从 selfself.container 的自然映射。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).free_module(2).submodule([x, x]).inclusion_hom()
Matrix([
[1, 0], : <[x, x]> -> QQ[x]**2
[0, 1]])
intersect(other, **options)[源代码][源代码]

返回 self 与子模块 other 的交集。

示例

>>> from sympy.abc import x, y
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x, y).free_module(2)
>>> F.submodule([x, x]).intersect(F.submodule([y, y]))
<[x*y, x*y]>

一些实现允许传递更多选项。目前,唯一实现的选项是 relations=True,在这种情况下,函数将返回一个三元组 (res, rela, relb),其中 res 是交集模块,而 relarelb 是系数向量列表,表示 res 的生成元在 self``(``rela)和 other``(``relb)的生成元中的表达。

>>> F.submodule([x, x]).intersect(F.submodule([y, y]), relations=True)
(<[x*y, x*y]>, [(DMP_Python([[1, 0]], QQ),)], [(DMP_Python([[1], []], QQ),)])

上述结果表明:交集模块由单个元素 \((-xy, -xy) = -y (x, x) = -x (y, y)\) 生成,其中 \((x, x)\)\((y, y)\) 分别是被交集的两个模块的唯一生成元。

is_full_module()[源代码][源代码]

如果 self 是整个自由模组,则返回 True。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> F.submodule([x, 1]).is_full_module()
False
>>> F.submodule([1, 1], [1, 2]).is_full_module()
True
is_submodule(other)[源代码][源代码]

如果 otherself 的子模块,则返回 True。

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> M = F.submodule([2, x])
>>> N = M.submodule([2*x, x**2])
>>> M.is_submodule(M)
True
>>> M.is_submodule(N)
True
>>> N.is_submodule(M)
False
is_zero()[源代码][源代码]

如果 self 是一个零模块,则返回 True。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> F.submodule([x, 1]).is_zero()
False
>>> F.submodule([0, 0]).is_zero()
True
module_quotient(other, **options)[源代码][源代码]

返回 self 对子模块 other 的模商。

也就是说,如果 self 是模块 \(M\),而 other\(N\),则返回理想 \(\{f \in R | fN \subset M\}\)

示例

>>> from sympy import QQ
>>> from sympy.abc import x, y
>>> F = QQ.old_poly_ring(x, y).free_module(2)
>>> S = F.submodule([x*y, x*y])
>>> T = F.submodule([x, x])
>>> S.module_quotient(T)
<y>

一些实现允许传递更多选项。目前,唯一实现的选项是 relations=True,只有在 other 是主理想时才能传递。在这种情况下,函数将返回一对 (res, rel),其中 res 是理想,而 rel 是系数向量的列表,表示理想的生成元与 other 的生成元在 self 的生成元中的乘积。

>>> S.module_quotient(T, relations=True)
(<y>, [[DMP_Python([[1]], QQ)]])

这意味着商理想由单个元素 \(y\) 生成,并且 \(y (x, x) = 1 (xy, xy)\),其中 \((x, x)\)\((xy, xy)\) 分别是 \(T\)\(S\) 的生成元。

multiply_ideal(I)[源代码][源代码]

self 乘以理想 I

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> I = QQ.old_poly_ring(x).ideal(x**2)
>>> M = QQ.old_poly_ring(x).free_module(2).submodule([1, 1])
>>> I*M
<[x**2, x**2]>
quotient_module(other, **opts)[源代码][源代码]

返回一个商模。

这与取包含模块的商的子模块相同。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> S1 = F.submodule([x, 1])
>>> S2 = F.submodule([x**2, x])
>>> S1.quotient_module(S2)
<[x, 1] + <[x**2, x]>>

或者更简洁地,使用重载的除法运算符:

>>> F.submodule([x, 1]) / [(x**2, x)]
<[x, 1] + <[x**2, x]>>
reduce_element(x)[源代码][源代码]

将我们环中的元素 x 对理想 self 取模。

这里,“reduce”没有特定的含义,它可能返回一个唯一的范式,稍微简化表达式,或者什么都不做。

submodule(*gens)[源代码][源代码]

生成一个子模块。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> M = QQ.old_poly_ring(x).free_module(2).submodule([x, 1])
>>> M.submodule([x**2, x])
<[x**2, x]>
syzygy_module(**opts)[源代码][源代码]

计算 self 生成元的 syzygy 模。

假设 \(M\) 是由环 \(R\) 上的 \(f_1, \ldots, f_n\) 生成的。考虑同态 \(\phi: R^n \to M\),它将 \((r_1, \ldots, r_n)\) 映射到 \(r_1 f_1 + \cdots + r_n f_n\)。合冲模被定义为 \(\phi\) 的核。

示例

syzygy 模块为零当且仅当生成元自由生成一个自由子模块:

>>> from sympy.abc import x, y
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).free_module(2).submodule([1, 0], [1, 1]).syzygy_module().is_zero()
True

一个稍微更有趣的例子:

>>> M = QQ.old_poly_ring(x, y).free_module(2).submodule([x, 2*x], [y, 2*y])
>>> S = QQ.old_poly_ring(x, y).free_module(2).submodule([y, -x])
>>> M.syzygy_module() == S
True
union(other)[源代码][源代码]

返回由 selfother 的并集生成的模块。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(1)
>>> M = F.submodule([x**2 + x]) # <x(x+1)>
>>> N = F.submodule([x**2 - 1]) # <(x-1)(x+1)>
>>> M.union(N) == F.submodule([x+1])
True

理想与模块的创建方式非常相似。例如,让我们验证节点三次曲线在原点确实是奇异的:

>>> I = lr.ideal(x, y)
>>> I == lr.ideal(x)
False

>>> I == lr.ideal(y)
False

我们在这里利用了曲线在某点非奇异当且仅当局部环的最大理想是主理想的事实,并且在这种情况下,\(x\)\(y\) 中至少有一个必须是生成元。

这是类 ideal 的详细文档。请注意,关于理想性质(如素性等)的大多数方法尚未实现。

class sympy.polys.agca.ideals.Ideal(ring)[源代码][源代码]

理想抽象基类。

不要实例化 - 请在环类中使用显式构造函数:

>>> from sympy import QQ
>>> from sympy.abc import x
>>> QQ.old_poly_ring(x).ideal(x+1)
<x + 1>

属性

  • ring - 这个理想所属的环

未实现的方法:

  • _contains_elem

  • _包含_理想

  • _quotient

  • _intersect

  • _union

  • _product

  • is_whole_ring

  • is_zero

  • is_prime, is_maximal, is_primary, is_radical

  • is_principal

  • 高度, 深度

  • 激进

在子类中可能需要重写的方法:

  • reduce_element

方法

contains(elem)

如果 elem 是这个理想的元素,则返回 True。

depth()

计算 self 的深度。

height()

计算 self 的高度。

intersect(J)

计算自身与理想 J 的交集。

is_maximal()

如果 self 是一个极大理想,则返回 True。

is_primary()

如果 self 是主理想,则返回 True。

is_prime()

如果 self 是一个素理想,则返回 True。

is_principal()

如果 self 是一个主理想,则返回 True。

is_radical()

如果 self 是一个根基理想,则返回 True。

is_whole_ring()

如果 self 是整个环,则返回 True。

is_zero()

如果 self 是零理想,则返回 True。

product(J)

计算 selfJ 的理想乘积。

quotient(J, **opts)

计算 self 除以 J 的理想商。

radical()

计算 self 的根。

reduce_element(x)

将我们环中的元素 x 对理想 self 取模。

saturate(J)

通过 J 计算 self 的理想饱和度。

subset(other)

如果 otherself 的子集,则返回 True。

union(J)

计算由 selfJ 的并集生成的理想。

contains(elem)[源代码][源代码]

如果 elem 是这个理想的元素,则返回 True。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).ideal(x+1, x-1).contains(3)
True
>>> QQ.old_poly_ring(x).ideal(x**2, x**3).contains(x)
False
depth()[源代码][源代码]

计算 self 的深度。

height()[源代码][源代码]

计算 self 的高度。

intersect(J)[源代码][源代码]

计算自身与理想 J 的交集。

示例

>>> from sympy.abc import x, y
>>> from sympy import QQ
>>> R = QQ.old_poly_ring(x, y)
>>> R.ideal(x).intersect(R.ideal(y))
<x*y>
is_maximal()[源代码][源代码]

如果 self 是一个极大理想,则返回 True。

is_primary()[源代码][源代码]

如果 self 是主理想,则返回 True。

is_prime()[源代码][源代码]

如果 self 是一个素理想,则返回 True。

is_principal()[源代码][源代码]

如果 self 是一个主理想,则返回 True。

is_radical()[源代码][源代码]

如果 self 是一个根基理想,则返回 True。

is_whole_ring()[源代码][源代码]

如果 self 是整个环,则返回 True。

is_zero()[源代码][源代码]

如果 self 是零理想,则返回 True。

product(J)[源代码][源代码]

计算 selfJ 的理想乘积。

也就是说,计算由 \(x\) 属于 self\(y \in J\) 的元素 \(xy\) 生成的理想。

示例

>>> from sympy.abc import x, y
>>> from sympy import QQ
>>> QQ.old_poly_ring(x, y).ideal(x).product(QQ.old_poly_ring(x, y).ideal(y))
<x*y>
quotient(J, **opts)[源代码][源代码]

计算 self 除以 J 的理想商。

也就是说,如果 self 是理想 \(I\),计算集合 \(I : J = \{x \in R | xJ \subset I \}\)

示例

>>> from sympy.abc import x, y
>>> from sympy import QQ
>>> R = QQ.old_poly_ring(x, y)
>>> R.ideal(x*y).quotient(R.ideal(x))
<y>
radical()[源代码][源代码]

计算 self 的根。

reduce_element(x)[源代码][源代码]

将我们环中的元素 x 对理想 self 取模。

这里“reduce”没有特定的含义:它可能返回一个唯一的范式,稍微简化表达式,或者什么都不做。

saturate(J)[源代码][源代码]

通过 J 计算 self 的理想饱和度。

也就是说,如果 self 是理想 \(I\),计算集合 \(I : J^\infty = \{x \in R | xJ^n \subset I \text{ 对于某些 } n\}\)

subset(other)[源代码][源代码]

如果 otherself 的子集,则返回 True。

这里 other 可能是一个理想。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> I = QQ.old_poly_ring(x).ideal(x+1)
>>> I.subset([x**2 - 1, x**2 + 2*x + 1])
True
>>> I.subset([x**2 + 1, x + 1])
False
>>> I.subset(QQ.old_poly_ring(x).ideal(x**2 - 1))
True
union(J)[源代码][源代码]

计算由 selfJ 的并集生成的理想。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> QQ.old_poly_ring(x).ideal(x**2 - 1).union(QQ.old_poly_ring(x).ideal((x+1)**2)) == QQ.old_poly_ring(x).ideal(x+1)
True

如果 \(M\)\(A\)-模,且 \(N\)\(A\)-子模,我们可以定义 \(M\) 中的两个元素 \(x\)\(y\) 等价,如果 \(x - y \in N\)。等价类集合记作 \(M/N\),并且具有自然的 \(A\)-模结构。这称为 \(M\)\(N\) 的商模。如果 \(K\) 是包含 \(N\)\(M\) 的子模,那么 \(K/N\) 以自然的方式是 \(M/N\) 的子模。这样的模称为子商模。以下是商模和子商模的文档:

class sympy.polys.agca.modules.QuotientModule(ring, base, submodule)[源代码][源代码]

商模类的类。

不要直接实例化这个。对于子商模,请参见 SubQuotientModule 类。

属性:

  • base - 我们作为商的基础模块

  • killed_module - 用于形成商的子模块

  • 基的秩

方法

contains(elem)

如果 elem 是此模块的元素,则返回 True。

convert(elem[, M])

elem 转换为内部表示形式。

dtype

QuotientModuleElement 的别名

identity_hom()

返回 self 上的恒等同态。

is_submodule(other)

如果 otherself 的子模块,则返回 True。

is_zero()

如果 self 是一个零模块,则返回 True。

multiply_ideal(other)

self 乘以理想值 other

quotient_hom()

返回商同态到 self

quotient_module(other)

生成一个商模。

submodule(*gens, **opts)

生成一个子模块。

subset(other)

如果 otherself 的子集,则返回 True。

convert(elem, M=None)[源代码][源代码]

elem 转换为内部表示形式。

每当计算涉及内部表示中不存在的元素时,此方法会被隐式调用。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)]
>>> F.convert([1, 0])
[1, 0] + <[1, 2], [1, x]>
dtype[源代码]

QuotientModuleElement 的别名

identity_hom()[源代码][源代码]

返回 self 上的恒等同态。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> M = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)]
>>> M.identity_hom()
Matrix([
[1, 0], : QQ[x]**2/<[1, 2], [1, x]> -> QQ[x]**2/<[1, 2], [1, x]>
[0, 1]])
is_submodule(other)[源代码][源代码]

如果 otherself 的子模块,则返回 True。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> Q = QQ.old_poly_ring(x).free_module(2) / [(x, x)]
>>> S = Q.submodule([1, 0])
>>> Q.is_submodule(S)
True
>>> S.is_submodule(Q)
False
is_zero()[源代码][源代码]

如果 self 是一个零模块,则返回 True。

这种情况当且仅当基础模块与被终止的子模块相同时发生。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> (F/[(1, 0)]).is_zero()
False
>>> (F/[(1, 0), (0, 1)]).is_zero()
True
quotient_hom()[源代码][源代码]

返回商同态到 self

也就是说,返回一个同态,表示从 self.baseself 的自然映射。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> M = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)]
>>> M.quotient_hom()
Matrix([
[1, 0], : QQ[x]**2 -> QQ[x]**2/<[1, 2], [1, x]>
[0, 1]])
submodule(*gens, **opts)[源代码][源代码]

生成一个子模块。

这与取基模的一个子模的商是相同的。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> Q = QQ.old_poly_ring(x).free_module(2) / [(x, x)]
>>> Q.submodule([x, 0])
<[x, 0] + <[x, x]>>
class sympy.polys.agca.modules.QuotientModuleElement(module, data)[源代码][源代码]

商模的元素。

方法

add(d1, d2)

添加数据 d1d2

div(m, d)

将模块数据 m 除以系数 d。

eq(d1, d2)

相等比较。

mul(m, d)

将模块数据 m 乘以系数 d。

eq(d1, d2)[源代码][源代码]

相等比较。

class sympy.polys.agca.modules.SubQuotientModule(gens, container, **opts)[源代码][源代码]

商模的子模。

等价地,子模的商模。

不要实例化这个,而是使用子模块或商模块构造方法:

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> S = F.submodule([1, 0], [1, x])
>>> Q = F/[(1, 0)]
>>> S/[(1, 0)] == Q.submodule([5, x])
True

属性:

  • base - 我们作为商的基模块

  • killed_module - 用于形成商的子模块

方法

contains(elem)

如果 elem 是此模块的元素,则返回 True。

convert(elem[, M])

elem 转换为内部表示形式。

identity_hom()

返回 self 上的恒等同态。

in_terms_of_generators(e)

用生成元表示 self 中的元素 e

inclusion_hom()

返回一个表示 self 包含映射的同态。

intersect(other, **options)

返回 self 与子模块 other 的交集。

is_full_module()

如果 self 是整个自由模组,则返回 True。

is_submodule(other)

如果 otherself 的子模块,则返回 True。

is_zero()

如果 self 是一个零模块,则返回 True。

module_quotient(other, **options)

返回 self 对子模块 other 的模商。

multiply_ideal(I)

self 乘以理想 I

quotient_hom()

返回商同态到自身。

quotient_module(other, **opts)

返回一个商模。

reduce_element(x)

将我们环中的元素 x 对理想 self 取模。

submodule(*gens)

生成一个子模块。

subset(other)

如果 otherself 的子集,则返回 True。

syzygy_module(**opts)

计算 self 生成元的 syzygy 模。

union(other)

返回由 selfother 的并集生成的模块。

is_full_module()[源代码][源代码]

如果 self 是整个自由模组,则返回 True。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> F.submodule([x, 1]).is_full_module()
False
>>> F.submodule([1, 1], [1, 2]).is_full_module()
True
quotient_hom()[源代码][源代码]

返回商同态到自身。

也就是说,返回从 self.baseself 的自然映射。

示例

>>> from sympy.abc import x
>>> from sympy import QQ
>>> M = (QQ.old_poly_ring(x).free_module(2) / [(1, x)]).submodule([1, 0])
>>> M.quotient_hom()
Matrix([
[1, 0], : <[1, 0], [1, x]> -> <[1, 0] + <[1, x]>, [1, x] + <[1, x]>>
[0, 1]])

模同态与合冲

\(M\)\(N\)\(A\)-模。满足各种明显性质的映射 \(f: M o N`(参见 [Atiyah69]_)称为 `A\)-模同态。在这种情况下,\(M\) 称为 定义域\(N\) 称为 陪域。集合 \(\{x \in M | f(x) = 0\}\) 称为 \(ker(f)\),而集合 \(\{f(x) | x \in M\}\) 称为 \(im(f)\)。核是 \(M\) 的子模,像是 \(N\) 的子模。同态 \(f\) 是单射当且仅当 \(ker(f) = 0\),是满射当且仅当 \(im(f) = N\)。双射同态称为 同构。等价地,\(ker(f) = 0\)\(im(f) = N\)。(一个相关的概念,目前在 AGCA 模块中没有特别的名称,是 余核\(coker(f) = N/im(f)\)。)

假设现在 \(M\) 是一个 \(A\)-模。\(M\) 被称为 有限生成 如果存在一个满同态 \(A^n o M\) 对于某个 \(n\)。如果选择了这样一个态射 \(f\)\(A^n\) 的标准基的像被称为 \(M\)生成元。模 \(ker(f)\) 被称为关于生成元的 合冲模。一个模被称为 有限表示 如果它是一个有限生成的模且其合冲模也是有限生成的。有限表示模的类是我们能够有意义地计算的最大类。

对于我们正在考虑的所有环,有限生成模的所有子模都是有限生成的,因此有限生成和有限表示的模是相同的,这是一个重要的定理。

syzygies 的概念,虽然一开始可能显得相当抽象,但实际上非常具有计算性。这是因为存在(相当简单的)算法来计算它们,而更一般的问题(核、交集等)通常被简化为 syzygy 计算。

让我们简单谈谈AGCA模块中同态的定义。首先假设 \(f : M o N\)\(A\)-模的任意态射。那么如果 \(K\)\(M\) 的子模,\(f\) 自然地定义了一个新的同态 \(g: K o N`(通过 `g(x) = f(x)\)),称为 \(f\)\(K\) 的*限制*。如果现在 \(K\) 包含在 \(f\) 的核中,那么 \(f\) 还自然地定义了一个同态 \(g: M/K o N`(公式与上面相同!),我们说 `f\) 下降*到 `M/K`。类似地,如果 `L` 是 `N` 的子模,存在一个自然同态 `g: M o N/L`,我们说 `g` *通过 `f` 分解。最后,如果现在 \(L\) 包含 \(f\) 的像,那么存在一个自然同态 \(g: M o L`(同样由相同的公式定义),我们说 `g\) 是通过限制 \(f\) 的陪域得到的。还要注意,这四种操作中的每一种都是可逆的,也就是说,给定 \(g\),总能(非唯一地)找到 \(f\),使得 \(g\) 以如上方式从 \(f\) 得到。

请注意,AGCA 中实现的所有模块都是通过连续取子模块和商模块从自由模块中获得的。因此,为了解释如何定义任意模块之间的同态,鉴于上述情况,我们只需要解释如何定义自由模块的同态。但是,根据自由模块的定义,从自由模块 \(A^n\) 到任何模块 \(M\) 的同态与给出 \(M\) 中的 \(n\) 个元素(标准基的像)完全相同,而给出自由模块 \(A^m\) 的一个元素与给出 \(A\) 中的 \(m\) 个元素完全相同。因此,自由模块 \(A^n\)\(A^m\) 的同态可以通过矩阵来指定,这与向量空间的情况完全类似。

Homomorphism 的函数 restrict_domain 等可以用于执行上述操作,原则上可以通过手动实例化自由模的同态。由于这些操作非常常见,因此有一个便捷函数 homomorphism 可以通过上述方法定义任意模块之间的同态。这基本上是用户创建同态的唯一方式。

sympy.polys.agca.homomorphisms.homomorphism(domain, codomain, matrix)[源代码][源代码]

创建一个同态对象。

此函数尝试通过矩阵 matrixdomain 构建到 codomain 的同态。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> R = QQ.old_poly_ring(x)
>>> T = R.free_module(2)

如果 domain 是由 \(e_1, \ldots, e_n\) 生成的自由模,那么 matrix 应该是一个包含 \(n\) 个元素的可迭代对象 \((b_1, \ldots, b_n)\),其中 \(b_i\)codomain 中的元素。构造的同态是唯一将 \(e_i\) 映射到 \(b_i\) 的同态。

>>> F = R.free_module(2)
>>> h = homomorphism(F, T, [[1, x], [x**2, 0]])
>>> h
Matrix([
[1, x**2], : QQ[x]**2 -> QQ[x]**2
[x,    0]])
>>> h([1, 0])
[1, x]
>>> h([0, 1])
[x**2, 0]
>>> h([1, 1])
[x**2 + 1, x]

如果 domain 是一个自由模的子模块,那么 matrix 确定了一个从包含自由模到 codomain 的同态,并且返回的同态是通过 domain 的限制得到的。

>>> S = F.submodule([1, 0], [0, x])
>>> homomorphism(S, T, [[1, x], [x**2, 0]])
Matrix([
[1, x**2], : <[1, 0], [0, x]> -> QQ[x]**2
[x,    0]])

如果 domain 是一个 (子)商 \(N/K\),那么 matrix 确定了一个从 \(N\)codomain 的同态。如果核包含 \(K\),这个同态下降到 domain 并返回;否则会引发异常。

>>> homomorphism(S/[(1, 0)], T, [0, [x**2, 0]])
Matrix([
[0, x**2], : <[1, 0] + <[1, 0]>, [0, x] + <[1, 0]>, [1, 0] + <[1, 0]>> -> QQ[x]**2
[0,    0]])
>>> homomorphism(S/[(0, x)], T, [0, [x**2, 0]])
Traceback (most recent call last):
...
ValueError: kernel <[1, 0], [0, 0]> must contain sm, got <[0,x]>

最后,这里是实际同态类别的详细参考:

class sympy.polys.agca.homomorphisms.ModuleHomomorphism(domain, codomain)[源代码][源代码]

模块同态的抽象基类。不要实例化。

相反,使用 homomorphism 函数:

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> homomorphism(F, F, [[1, 0], [0, 1]])
Matrix([
[1, 0], : QQ[x]**2 -> QQ[x]**2
[0, 1]])

属性:

  • 环 - 我们正在考虑模的环

  • domain - 领域模块

  • codomain - codomain 模块

  • _ker - 缓存的内核

  • _img - 缓存图像

未实现的方法:

  • _kernel

  • _image

  • _restrict_domain

  • _restrict_codomain

  • _quotient_domain

  • _quotient_codomain

  • _apply

  • _mul_scalar

  • _compose

  • _添加

方法

__call__(elem)

image()

计算 self 的图像。

is_injective()

如果 self 是单射的,则返回 True。

is_isomorphism()

如果 self 是一个同构,则返回 True。

is_surjective()

如果 self 是满射的,则返回 True。

is_zero()

如果 self 是一个零态射,则返回 True。

kernel()

计算 self 的核。

quotient_codomain(sm)

返回 self ,其陪域替换为 codomain/sm

quotient_domain(sm)

返回 self 并将域替换为 domain/sm

restrict_codomain(sm)

返回 self,其上域限制为 sm

restrict_domain(sm)

返回 self ,其域限制为 sm

image()[源代码][源代码]

计算 self 的图像。

也就是说,如果 self 是同态 \(\phi: M \to N\),那么计算 \(im(\phi) = \{\phi(x) | x \in M \}\)。 这是 \(N\) 的一个子模。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> homomorphism(F, F, [[1, 0], [x, 0]]).image() == F.submodule([1, 0])
True
is_injective()[源代码][源代码]

如果 self 是单射的,则返回 True。

也就是说,检查域中的元素是否映射到相同的陪域元素。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h.is_injective()
False
>>> h.quotient_domain(h.kernel()).is_injective()
True
is_isomorphism()[源代码][源代码]

如果 self 是一个同构,则返回 True。

也就是说,检查值域中的每个元素是否恰好有一个原像。等价地,self 既是单射的也是满射的。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h = h.restrict_codomain(h.image())
>>> h.is_isomorphism()
False
>>> h.quotient_domain(h.kernel()).is_isomorphism()
True
is_surjective()[源代码][源代码]

如果 self 是满射的,则返回 True。

也就是说,检查值域中的每个元素是否至少有一个原像。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h.is_surjective()
False
>>> h.restrict_codomain(h.image()).is_surjective()
True
is_zero()[源代码][源代码]

如果 self 是一个零态射,则返回 True。

也就是说,检查域中的每个元素是否在 self 下映射为零。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h.is_zero()
False
>>> h.restrict_domain(F.submodule()).is_zero()
True
>>> h.quotient_codomain(h.image()).is_zero()
True
kernel()[源代码][源代码]

计算 self 的核。

也就是说,如果 self 是同态 \(\phi: M \to N\),那么计算 \(ker(\phi) = \{x \in M | \phi(x) = 0\}\)。 这是 \(M\) 的一个子模。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> homomorphism(F, F, [[1, 0], [x, 0]]).kernel()
<[x, -1]>
quotient_codomain(sm)[源代码][源代码]

返回 self ,其陪域替换为 codomain/sm

这里 sm 必须是 self.codomain 的子模块。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h
Matrix([
[1, x], : QQ[x]**2 -> QQ[x]**2
[0, 0]])
>>> h.quotient_codomain(F.submodule([1, 1]))
Matrix([
[1, x], : QQ[x]**2 -> QQ[x]**2/<[1, 1]>
[0, 0]])

这与用左边的商映射进行组合是相同的:

>>> (F/[(1, 1)]).quotient_hom() * h
Matrix([
[1, x], : QQ[x]**2 -> QQ[x]**2/<[1, 1]>
[0, 0]])
quotient_domain(sm)[源代码][源代码]

返回 self 并将域替换为 domain/sm

这里 sm 必须是 self.kernel() 的子模块。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h
Matrix([
[1, x], : QQ[x]**2 -> QQ[x]**2
[0, 0]])
>>> h.quotient_domain(F.submodule([-x, 1]))
Matrix([
[1, x], : QQ[x]**2/<[-x, 1]> -> QQ[x]**2
[0, 0]])
restrict_codomain(sm)[源代码][源代码]

返回 self,其上域限制为 sm

这里 sm 必须是 self.codomain 的子模块,包含图像。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h
Matrix([
[1, x], : QQ[x]**2 -> QQ[x]**2
[0, 0]])
>>> h.restrict_codomain(F.submodule([1, 0]))
Matrix([
[1, x], : QQ[x]**2 -> <[1, 0]>
[0, 0]])
restrict_domain(sm)[源代码][源代码]

返回 self ,其域限制为 sm

这里 sm 必须是 self.domain 的子模块。

示例

>>> from sympy import QQ
>>> from sympy.abc import x
>>> from sympy.polys.agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> h = homomorphism(F, F, [[1, 0], [x, 0]])
>>> h
Matrix([
[1, x], : QQ[x]**2 -> QQ[x]**2
[0, 0]])
>>> h.restrict_domain(F.submodule([1, 0]))
Matrix([
[1, x], : <[1, 0]> -> QQ[x]**2
[0, 0]])

这与在右侧通过子模块包含进行组合是相同的:

>>> h * F.submodule([1, 0]).inclusion_hom()
Matrix([
[1, x], : <[1, 0]> -> QQ[x]**2
[0, 0]])

有限扩展

\(A\) 是一个(交换)环,\(B\)\(A\) 的扩展环。\(B\) 中的一个元素 \(t\)\(B\) 的生成元(在 \(A\) 上),如果 \(B\) 中的所有元素都可以表示为 \(t\) 的多项式,且系数在 \(A\) 中。当且仅当 \(t\) 满足无平凡多项式关系时,表示是唯一的,在这种情况下,\(B\) 可以被识别为 \(A\) 上的(单变量)多项式环。

\(t\) 为根的多项式通常形成一个非零理想。实践中最重要的情形是由一个首一多项式生成的理想。如果 \(t\) 满足这样一个多项式关系,那么它的最高次幂 \(t^n\) 可以表示为较低次幂的线性组合。由此,归纳地,所有更高次幂的 \(t\) 也具有这样的表示。因此,较低次幂 \(t^i\) (\(i = 0, \dots, n-1\)) 构成 \(B\) 的一组基,此时 \(B\) 被称为 \(A\) 的有限扩张,更准确地说,是一个单生成元有限扩张,因为它由单个元素 \(t\) 生成。

class sympy.polys.agca.extensions.MonogenicFiniteExtension(mod)[源代码][源代码]

由整元素生成的有限扩张。

生成器由从参数 mod 派生的单变量多项式定义。

一个更短的别名是 FiniteExtension

属性:
别名
has_CharacteristicZero
rep
tp

别名 dtype

方法

__call__(*args)

args 构造 self 域的一个元素。

abs(a)

a 的绝对值,意味着 __abs__

add(a, b)

ab 的和,意味着 __add__

alg_field_from_poly(poly[, alias, root_index])

通过根索引选择多项式的根来构造代数扩展的便捷方法。

algebraic_field(*extension[, alias])

返回一个代数数域,即 \(K(\alpha, \ldots)\)

almosteq(a, b[, tolerance])

检查 ab 是否几乎相等。

characteristic()

cofactors(a, b)

返回 ab 的最大公约数和余因子。

convert(f[, base])

convert_from(f, base)

cyclotomic_field(n[, ss, alias, gen, root_index])

构造分圆域的便捷方法。

denom(a)

返回 a 的分母。

div(a, b)

计算 ab 的商和余数。

drop(*symbols)

dtype

ExtensionElement 的别名

evalf(a[, prec])

返回 a 的数值近似值。

exquo(f, g)

exsqrt(a)

a 是平方数的域内的主平方根。

frac_field(*symbols[, order])

返回一个分数域,即 \(K(X)\)

from_AlgebraicField(a, K0)

将一个代数数转换为 dtype

from_ComplexField(a, K0)

将复杂元素转换为 dtype

from_ExpressionDomain(a, K0)

EX 对象转换为 dtype

from_ExpressionRawDomain(a, K0)

EX 对象转换为 dtype

from_FF(a, K0)

ModularInteger(int) 转换为 dtype

from_FF_gmpy(a, K0)

ModularInteger(mpz) 转换为 dtype

from_FF_python(a, K0)

ModularInteger(int) 转换为 dtype

from_FractionField(a, K0)

将一个有理函数转换为 dtype

from_GlobalPolynomialRing(a, K0)

将多项式转换为 dtype

from_MonogenicFiniteExtension(a, K0)

ExtensionElement 转换为 dtype

from_PolynomialRing(a, K0)

将多项式转换为 dtype

from_QQ_gmpy(a, K0)

将 GMPY 的 mpq 对象转换为 dtype

from_QQ_python(a, K0)

将 Python Fraction 对象转换为 dtype

from_RealField(a, K0)

将一个真实的元素对象转换为 dtype

from_ZZ_gmpy(a, K0)

将 GMPY 的 mpz 对象转换为 dtype

from_ZZ_python(a, K0)

将 Python int 对象转换为 dtype

from_sympy(f)

gcd(a, b)

返回 ab 的最大公约数。

gcdex(a, b)

ab 的扩展最大公约数。

get_exact()

返回与 self 关联的精确域。

get_field()

返回与 self 关联的字段。

get_ring()

返回与 self 相关联的环。

half_gcdex(a, b)

ab 的半扩展最大公约数。

inject(*symbols)

将生成器注入此域。

invert(a, b)

返回 a mod b 的逆,意味着某事。

is_negative(a)

is_nonnegative(a)

如果 a 是非负的,则返回 True。

is_nonpositive(a)

如果 a 是非正数,则返回 True。

is_one(a)

如果 a 是 1,则返回 True。

is_positive(a)

如果 a 为正数,则返回 True。

is_square(a)

返回 a 是否是该域中的一个平方数。

is_zero(a)

如果 a 为零,则返回 True。

lcm(a, b)

返回 ab 的最小公倍数。

log(a, b)

返回 a 的 b 进制对数。

map(seq)

递归地将 self 应用于 seq 的所有元素。

mul(a, b)

ab 的乘积,意味着 __mul__

n(a[, prec])

返回 a 的数值近似值。

neg(a)

返回 a 的否定值,意味着 __neg__

numer(a)

返回 a 的分子。

of_type(element)

检查 a 是否为 dtype 类型。

old_frac_field(*symbols, **kwargs)

返回一个分数域,即 \(K(X)\)

old_poly_ring(*symbols, **kwargs)

返回一个多项式环,即 \(K[X]\)

poly_ring(*symbols[, order])

返回一个多项式环,即 \(K[X]\)

pos(a)

返回 a 为正,意味着 __pos__

pow(a, b)

a 提升到 b 的幂,意味着 __pow__

quo(f, g)

rem(a, b)

ab 进行取模运算。

revert(a)

如果可能,返回 a**(-1)

sqrt(a)

返回 a 的(可能不精确的)平方根。

sub(a, b)

ab 的差异,意味着 __sub__

to_sympy(f)

unify(K1[, symbols])

构建一个包含 K0K1 元素的最小域。

unify_composite(K1)

统一两个领域,其中至少一个是复合的。

canonical_unit

from_GeneralizedPolynomialRing

imag

is_unit

正常

真实

设置域

总和

unify_with_symbols

示例

二次整数环 \(\mathbb{Z}[\sqrt2]\):

>>> from sympy import Symbol, Poly
>>> from sympy.polys.agca.extensions import FiniteExtension
>>> x = Symbol('x')
>>> R = FiniteExtension(Poly(x**2 - 2)); R
ZZ[x]/(x**2 - 2)
>>> R.rank
2
>>> R(1 + x)*(3 - 2*x)
x - 1

有限域 \(GF(5^3)\) 由本原多项式 \(x^3 + x^2 + 2\) 定义(在 \(\mathbb{Z}_5\) 上)。

>>> F = FiniteExtension(Poly(x**3 + x**2 + 2, modulus=5)); F
GF(5)[x]/(x**3 + x**2 + 2)
>>> F.basis
(1, x, x**2)
>>> F(x + 3)/(x**2 + 2)
-2*x**2 + x + 2

椭圆曲线的函数域:

>>> t = Symbol('t')
>>> FiniteExtension(Poly(t**2 - x**3 - x + 1, t, field=True))
ZZ(x)[t]/(t**2 - x**3 - x + 1)
dtype[源代码]

ExtensionElement 的别名

class sympy.polys.agca.extensions.ExtensionElement(rep, ext)[源代码][源代码]

有限扩张的元素。

一类在扩展 ext模数 下的单变量多项式。它由最低次数的唯一多项式 rep 表示。rep模数 的表示 mod 都是 DMP 类的。

属性:
扩展
is_ground
rep

方法

inverse()

乘法逆元。

parent()

as_expr

to_ground

inverse()[源代码][源代码]

乘法逆元。

Raises:
NotInvertible

如果该元素是一个零因子。