SymPy-1-13-中文文档-二十七-

SymPy 1.13 中文文档(二十七)

原文:docs.sympy.org/latest/index.html

多项式级数操作

原文链接:docs.sympy.org/latest/modules/polys/ringseries.html

任何有限的泰勒级数在实际应用中实际上都是多项式。本模块利用高效的稀疏多项式表示和操作,实现了非常快速的多变量级数操作。与 SymPy 的 series 方法相比,典型的加速比在 20-100 之间,随着处理的级数越来越大,这一差距会进一步扩大。

所有函数都在用户指定的某个环上展开任何给定的级数。因此,计算出的级数的系数取决于使用的环。例如:

>>> from sympy.polys import ring, QQ, RR
>>> from sympy.polys.ring_series import rs_sin
>>> R, x, y = ring('x, y', QQ)
>>> rs_sin(x*y, x, 5)
-1/6*x**3*y**3 + x*y 

QQ 代表有理数域。在这里,所有系数都是有理数。建议在使用 ring series 时使用 QQ,因为它会自动选择最快的有理数类型。

同样地,如果使用实数域:

>>> R, x, y = ring('x, y', RR)
>>> rs_sin(x*y, x, 5)
-0.166666666666667*x**3*y**3 + x*y 

尽管多项式的定义限制了多项式模块仅用于泰勒级数,但我们将其扩展到允许 Laurent 甚至 Puiseux 级数(带有分数指数)。

>>> from sympy.polys.ring_series import rs_cos, rs_tan
>>> R, x, y = ring('x, y', QQ)

>>> rs_cos(x + x*y, x, 3)/x**3
-1/2*x**(-1)*y**2 - x**(-1)*y - 1/2*x**(-1) + x**(-3)

>>> rs_tan(x**QQ(2, 5)*y**QQ(1, 2), x, 2)
1/3*x**(6/5)*y**(3/2) + x**(2/5)*y**(1/2) 

默认情况下,PolyElement 不允许非自然数作为指数。它会将分数转换为整数,并在获取负指数时引发错误。ring series 模块的目标是快速级数展开,并不是使用 polys 模块。我们之所以选择它作为后端仅仅是因为它实现了稀疏表示和我们需要的大多数基本功能。然而,polys 的这种默认行为对于 ring series 是有限制的。

注意,在由 polys- dict 使用的数据结构中,不存在对有理指数的约束。稀疏多项式 (PolyElement) 使用 Python 字典逐项存储多项式,其中元组是指数,而系数是值。我们完全可以在 dict 中使用有理数值以支持有理指数。

因此,我们采取的方法是修改稀疏 polys 以允许非自然指数。而这个修改实际上非常简单。我们只需要在 PolyElement__pow__ 方法中删除指数转换为整数的部分。因此:

>>> x**QQ(3, 4)
x**(3/4) 

而不是之前的 1

尽管这种改变违反了多项式的定义,但目前尚未造成任何破坏。理想情况下,我们不应以任何方式修改 polys。但为了拥有我们想要的所有 series 功能,没有找到其他简单的解决方案。如果需要的话,我们可以将 polys 的修改部分与核心 polys 分开。如果能找到其他优雅的解决方案将是极好的。

本模块函数返回的所有级数都是 PolyElement 类的实例。要与其他 SymPy 类型一起使用它们,请将它们转换为 Expr

>>> from sympy.polys.ring_series import rs_exp
>>> from sympy.abc import a, b, c
>>> series = rs_exp(x, x, 5)
>>> a + series.as_expr()
a + x**4/24 + x**3/6 + x**2/2 + x + 1 

rs_series

直接使用基本环级数函数确实提供了更多控制,但同时也有限制。创建适当的环以进行所需的级数展开,并知道调用哪个环级数函数,这些可能不是每个人都熟悉的事情。

(rs_series) 是一个函数,它接受任意的 Expr 并通过调用适当的环级数函数返回其展开。返回的级数是在几乎可能的最简单环上的多项式。它在解析给定表达式时递归地构建环,并在需要时将生成器添加到环中。一些示例:

>>> from sympy.polys.ring_series import rs_series
>>> from sympy.functions.elementary.trigonometric import sin
>>> rs_series(sin(a + b), a, 5) 
1/24*sin(b)*a**4 - 1/2*sin(b)*a**2 + sin(b) - 1/6*cos(b)*a**3 + cos(b)*a

>>> rs_series(sin(exp(a*b) + cos(a + c)), a, 2) 
-sin(c)*cos(cos(c) + 1)*a + cos(cos(c) + 1)*a*b + sin(cos(c) + 1)

>>> rs_series(sin(a + b)*cos(a + c)*tan(a**2 + b), a, 2) 
cos(b)*cos(c)*tan(b)*a - sin(b)*sin(c)*tan(b)*a + sin(b)*cos(c)*tan(b) 

它可以快速展开涉及多个函数的复杂多变量表达式:

>>> %timeit ((sin(a) + cos(a))**10).series(a, 0, 5) 
1 loops, best of 3: 1.33 s per loop

>>> %timeit rs_series((sin(a) + cos(a))**10, a, 5) 
100 loops, best of 3: 4.13 ms per loop 

(rs_series) 的速度快了 300 多倍。给定一个要展开的表达式,解析它需要一些固定的开销。因此,对于更大的阶数,速度改进更为显著:

>>> %timeit rs_series((sin(a) + cos(a))**10, a, 100) 
10 loops, best of 3: 32.8 ms per loop 

要找出给定表达式的正确环,(rs_series) 使用 sring 函数,该函数又使用 polys 的其他函数。如上所述,不允许非自然指数。但限制在指数而不是生成器上。因此,polys 允许各种符号术语作为生成器,以确保指数是自然数:

>>> from sympy.polys.rings import sring
>>> R, expr = sring(1/a**3 + a**QQ(3, 7)); R
Polynomial ring in 1/a, a**(1/7) over ZZ with lex order 

在上面的例子中,(1/a) 和 (a(1/7)) 将被视为完全不同的原子。对于所有实际目的,我们可以让 (b = 1/a) 和 (c = a(1/7)),然后进行操作。实际上,涉及 (1/a) 和 (a**(1/7))(及其幂次)的表达式永远不会简化:

>>> expr*R(1/a)
(1/a)**4 + (1/a)*(a**(1/7))**3 

这导致与早期面对的操作 Laurent 和 Puiseux 级数类似的问题。幸运的是,这次我们有了一个优雅的解决方案,并能够将 seriespolys 的行为彼此隔离。我们在多项式的允许选项列表中引入了一个布尔标志 series(请参阅 sympy.polys.polyoptions.Options),以便在需要 sring 允许有理指数时提供 series=True 标志:

>>> rs_series(sin(a**QQ(1, 3)), a, 3)
-1/5040*a**(7/3) + 1/120*a**(5/3) - 1/6*a + a**(1/3) 

贡献

目前,(rs_series) 尚未完全实现。目前,它仅支持涉及 sincosexptan 的多变量泰勒展开。其余功能将逐步添加。如果您有兴趣帮助,请阅读 ring_series.py 中的注释。目前,它不支持普伊塞累级数(尽管基本函数支持)。预计很快将修复此问题。

您还可以将更多函数添加到 ring_series.py 中。目前仅支持基本函数。长远目标是用 rs_series 替换 SymPy 的当前 series 方法。

参考

此模块中的函数带有前缀 rs_,代表“环级数”。它们操作由 polys.ring.ring 提供的稀疏表示中的有限幂级数。

基本函数

sympy.polys.ring_series.rs_log(p, x, prec)

pO(x**prec)的对数。

注意

使用integral dx p**-1*d p/dx的截断。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_log
>>> R, x = ring('x', QQ)
>>> rs_log(1 + x, x, 8)
1/7*x**7 - 1/6*x**6 + 1/5*x**5 - 1/4*x**4 + 1/3*x**3 - 1/2*x**2 + x
>>> rs_log(x**QQ(3, 2) + 1, x, 5)
1/3*x**(9/2) - 1/2*x**3 + x**(3/2) 
sympy.polys.ring_series.rs_LambertW(p, x, prec)

计算 Lambert W 函数的主分支的级数展开。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_LambertW
>>> R, x, y = ring('x, y', QQ)
>>> rs_LambertW(x + x*y, x, 3)
-x**2*y**2 - 2*x**2*y - x**2 + x*y + x 

另请参阅

LambertW

sympy.polys.ring_series.rs_exp(p, x, prec)

一系列的指数化模O(x**prec)

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_exp
>>> R, x = ring('x', QQ)
>>> rs_exp(x**2, x, 7)
1/6*x**6 + 1/2*x**4 + x**2 + 1 
sympy.polys.ring_series.rs_atan(p, x, prec)

一系列的反正切

返回p的反正切的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_atan
>>> R, x, y = ring('x, y', QQ)
>>> rs_atan(x + x*y, x, 4)
-1/3*x**3*y**3 - x**3*y**2 - x**3*y - 1/3*x**3 + x*y + x 

另请参阅

atan

sympy.polys.ring_series.rs_asin(p, x, prec)

一系列的反正弦

返回p的反正弦的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_asin
>>> R, x, y = ring('x, y', QQ)
>>> rs_asin(x, x, 8)
5/112*x**7 + 3/40*x**5 + 1/6*x**3 + x 

另请参阅

asin

sympy.polys.ring_series.rs_tan(p, x, prec)

一系列的正切。

返回p的正切的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_tan
>>> R, x, y = ring('x, y', QQ)
>>> rs_tan(x + x*y, x, 4)
1/3*x**3*y**3 + x**3*y**2 + x**3*y + 1/3*x**3 + x*y + x 

另请参阅

_tan1, tan

sympy.polys.ring_series._tan1(p, x, prec)

rs_tan()的辅助函数。

使用牛顿法返回单变量级数的正切的级数展开。它利用了 atan 的级数展开比 tan 的级数展开更简单的事实。

考虑(f(x) = y - \arctan(x)),让 r 是用牛顿法找到的 f(x)的根。然后(f(r) = 0)或(y = \arctan(x))其中(x = \tan(y))如所需。

sympy.polys.ring_series.rs_cot(p, x, prec)

一系列的余切

返回p的余切的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_cot
>>> R, x, y = ring('x, y', QQ)
>>> rs_cot(x, x, 6)
-2/945*x**5 - 1/45*x**3 - 1/3*x + x**(-1) 

另请参阅

cot

sympy.polys.ring_series.rs_sin(p, x, prec)

一系列的正弦

返回p的正弦的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_sin
>>> R, x, y = ring('x, y', QQ)
>>> rs_sin(x + x*y, x, 4)
-1/6*x**3*y**3 - 1/2*x**3*y**2 - 1/2*x**3*y - 1/6*x**3 + x*y + x
>>> rs_sin(x**QQ(3, 2) + x*y**QQ(7, 5), x, 4)
-1/2*x**(7/2)*y**(14/5) - 1/6*x**3*y**(21/5) + x**(3/2) + x*y**(7/5) 

另请参阅

sin

sympy.polys.ring_series.rs_cos(p, x, prec)

一系列的余弦

返回p的余弦的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_cos
>>> R, x, y = ring('x, y', QQ)
>>> rs_cos(x + x*y, x, 4)
-1/2*x**2*y**2 - x**2*y - 1/2*x**2 + 1
>>> rs_cos(x + x*y, x, 4)/x**QQ(7, 5)
-1/2*x**(3/5)*y**2 - x**(3/5)*y - 1/2*x**(3/5) + x**(-7/5) 

另请参阅

cos

sympy.polys.ring_series.rs_cos_sin(p, x, prec)

返回元组(rs_cos(p, x, prec), rs_sin(p, x, prec))`。

比分别调用 rs_cos 和 rs_sin 更快

sympy.polys.ring_series.rs_atanh(p, x, prec)

一系列的双曲反正切

返回p的双曲反正切的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_atanh
>>> R, x, y = ring('x, y', QQ)
>>> rs_atanh(x + x*y, x, 4)
1/3*x**3*y**3 + x**3*y**2 + x**3*y + 1/3*x**3 + x*y + x 

另请参阅

atanh

sympy.polys.ring_series.rs_sinh(p, x, prec)

一系列的双曲正弦

返回p的双曲正弦的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_sinh
>>> R, x, y = ring('x, y', QQ)
>>> rs_sinh(x + x*y, x, 4)
1/6*x**3*y**3 + 1/2*x**3*y**2 + 1/2*x**3*y + 1/6*x**3 + x*y + x 

另请参阅

sinh

sympy.polys.ring_series.rs_cosh(p, x, prec)

一系列的双曲余弦

返回p的双曲余弦的级数展开,关于 0。

例子

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_cosh
>>> R, x, y = ring('x, y', QQ)
>>> rs_cosh(x + x*y, x, 4)
1/2*x**2*y**2 + x**2*y + 1/2*x**2 + 1 

另请参阅

双曲余弦

sympy.polys.ring_series.rs_tanh(p, x, prec)

一系列的双曲正切

返回p的 tanh 的系列展开,关于 0。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_tanh
>>> R, x, y = ring('x, y', QQ)
>>> rs_tanh(x + x*y, x, 4)
-1/3*x**3*y**3 - x**3*y**2 - x**3*y - 1/3*x**3 + x*y + x 

另请参见

双曲正切

sympy.polys.ring_series.rs_hadamard_exp(p1, inverse=False)

sum f_i*x**i返回sum f_i/i!*x**i,其中x是第一个变量。

如果invers=True,返回sum f_i*i!*x**i

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_hadamard_exp
>>> R, x = ring('x', QQ)
>>> p = 1 + x + x**2 + x**3
>>> rs_hadamard_exp(p)
1/6*x**3 + 1/2*x**2 + x + 1 

操作

sympy.polys.ring_series.rs_mul(p1, p2, x, prec)

返回给定两个系列的乘积,模O(x**prec)

x是系列变量或其在生成器中的位置。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_mul
>>> R, x = ring('x', QQ)
>>> p1 = x**2 + 2*x + 1
>>> p2 = x + 1
>>> rs_mul(p1, p2, x, 3)
3*x**2 + 3*x + 1 
sympy.polys.ring_series.rs_square(p1, x, prec)

平方系列模O(x**prec)

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_square
>>> R, x = ring('x', QQ)
>>> p = x**2 + 2*x + 1
>>> rs_square(p, x, 3)
6*x**2 + 4*x + 1 
sympy.polys.ring_series.rs_pow(p1, n, x, prec)

返回p1**nO(x**prec)

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_pow
>>> R, x = ring('x', QQ)
>>> p = x + 1
>>> rs_pow(p, 4, x, 3)
6*x**2 + 4*x + 1 
sympy.polys.ring_series.rs_series_inversion(p, x, prec)

多元级数反转1/pO(x**prec)

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_series_inversion
>>> R, x, y = ring('x, y', QQ)
>>> rs_series_inversion(1 + x*y**2, x, 4)
-x**3*y**6 + x**2*y**4 - x*y**2 + 1
>>> rs_series_inversion(1 + x*y**2, y, 4)
-x*y**2 + 1
>>> rs_series_inversion(x + x**2, x, 4)
x**3 - x**2 + x - 1 + x**(-1) 
sympy.polys.ring_series.rs_series_reversion(p, x, n, y)

一系列的反转。

p是形式为(p = ax + f(x))的系列,其中(a)是不为零的数。

(f(x) = \sum_{k=2}^{n-1} a_kx_k)

参数:

a_k:可以多项式地依赖其他变量,未指示。

x:名称为 x 的变量。y:名称为 y 的变量。

返回:

解决(p = y),即给定(ax + f(x) - y = 0)

找到解(x = r(y)),直到(O(y^n))。

算法

如果(r_i)是顺序(i)的解,则:(ar_i + f(r_i) - y = O\left(y^{i + 1}\right))

如果(r_{i + 1})是顺序(i + 1)的解,则:(ar_{i + 1} + f(r_{i + 1}) - y = O\left(y^{i + 2}\right))

我们有,(r_{i + 1} = r_i + e),使得,(ae + f(r_i) = O\left(y^{i + 2}\right))或(e = -f(r_i)/a)

因此,我们使用递归关系:(r_{i + 1} = r_i - f(r_i)/a)与边界条件:(r_1 = y)

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_series_reversion, rs_trunc
>>> R, x, y, a, b = ring('x, y, a, b', QQ)
>>> p = x - x**2 - 2*b*x**2 + 2*a*b*x**2
>>> p1 = rs_series_reversion(p, x, 3, y); p1
-2*y**2*a*b + 2*y**2*b + y**2 + y
>>> rs_trunc(p.compose(x, p1), y, 3)
y 
sympy.polys.ring_series.rs_nth_root(p, n, x, prec)

p的 n 次根的多元级数展开。

参数:

p:表达式

计算根的多项式。

n:整数

要计算的根的顺序。

xPolyElement

prec:整数

展开系列的顺序。

注释

此函数的结果取决于多项式定义的环。如果答案涉及常数的根,请确保多项式在实数域上。它目前无法处理符号的根。

示例

>>> from sympy.polys.domains import QQ, RR
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_nth_root
>>> R, x, y = ring('x, y', QQ)
>>> rs_nth_root(1 + x + x*y, -3, x, 3)
2/9*x**2*y**2 + 4/9*x**2*y + 2/9*x**2 - 1/3*x*y - 1/3*x + 1
>>> R, x, y = ring('x, y', RR)
>>> rs_nth_root(3 + x + x*y, 3, x, 2)
0.160249952256379*x*y + 0.160249952256379*x + 1.44224957030741 
sympy.polys.ring_series.rs_trunc(p1, x, prec)

截断x变量的系列,精度为prec,即模O(x**prec)

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_trunc
>>> R, x = ring('x', QQ)
>>> p = x**10 + x**5 + x + 1
>>> rs_trunc(p, x, 12)
x**10 + x**5 + x + 1
>>> rs_trunc(p, x, 10)
x**5 + x + 1 
sympy.polys.ring_series.rs_subs(p, rules, x, prec)

根据rules中的映射进行截断替换。

返回具有生成器x中精度prec的系列展开

请注意,不是依次进行替换

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_subs
>>> R, x, y = ring('x, y', QQ)
>>> p = x**2 + y**2
>>> rs_subs(p, {x: x+ y, y: x+ 2*y}, x, 3)
2*x**2 + 6*x*y + 5*y**2
>>> (x + y)**2 + (x + 2*y)**2
2*x**2 + 6*x*y + 5*y**2 

不同于

>>> rs_subs(rs_subs(p, {x: x+ y}, x, 3), {y: x+ 2*y}, x, 3)
5*x**2 + 12*x*y + 8*y**2 

参数:

pPolyElement 输入系列。

rules:具有替换映射的dict

xPolyElement 进行系列截断的变量。

prec整数 截断后系列的顺序。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_subs
>>> R, x, y = ring('x, y', QQ)
>>> rs_subs(x**2+y**2, {y: (x+y)**2}, x, 3)
 6*x**2*y**2 + x**2 + 4*x*y**3 + y**4 
sympy.polys.ring_series.rs_diff(p, x)

返回关于xp的偏导数。

参数:

xPolyElement 对其进行p的微分。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_diff
>>> R, x, y = ring('x, y', QQ)
>>> p = x + x**2*y**3
>>> rs_diff(p, x)
2*x*y**3 + 1 
sympy.polys.ring_series.rs_integrate(p, x)

p关于x积分。

参数:

xPolyElement 对其进行p的积分。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_integrate
>>> R, x, y = ring('x, y', QQ)
>>> p = x + x**2*y**3
>>> rs_integrate(p, x)
1/3*x**3*y**3 + 1/2*x**2 
sympy.polys.ring_series.rs_newton(p, x, prec)

计算多项式p的截断牛顿和。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_newton
>>> R, x = ring('x', QQ)
>>> p = x**2 - 2
>>> rs_newton(p, x, 5)
8*x**4 + 4*x**2 + 2 
sympy.polys.ring_series.rs_compose_add(p1, p2)

计算由p1的根beta组成的复合和prod(p2(x - beta) for beta root of p1)

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_compose_add
>>> R, x = ring('x', QQ)
>>> f = x**2 - 2
>>> g = x**2 - 3
>>> rs_compose_add(f, g)
x**4 - 10*x**2 + 1 

参考文献

[R823]

A. Bostan, P. Flajolet, B. Salvy and E. Schost “Fast Computation with Two Algebraic Numbers”, (2002) 研究报告 4579, Institut National de Recherche en Informatique et en Automatique

实用函数

sympy.polys.ring_series.rs_is_puiseux(p, x)

测试p是否为关于x的普维苏级数。

如果在x中有负幂,则引发异常。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_is_puiseux
>>> R, x = ring('x', QQ)
>>> p = x**QQ(2,5) + x**QQ(2,3) + x
>>> rs_is_puiseux(p, x)
True 
sympy.polys.ring_series.rs_puiseux(f, p, x, prec)

返回(f(p, x, prec))的普维苏级数。

仅当函数f用于常规级数时使用。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_puiseux, rs_exp
>>> R, x = ring('x', QQ)
>>> p = x**QQ(2,5) + x**QQ(2,3) + x
>>> rs_puiseux(rs_exp,p, x, 1)
1/2*x**(4/5) + x**(2/3) + x**(2/5) + 1 
sympy.polys.ring_series.rs_puiseux2(f, p, q, x, prec)

返回(f(p, q, x, prec))的普维苏级数。

仅当函数f用于常规级数时使用。

sympy.polys.ring_series.rs_series_from_list(p, c, x, prec, concur=1)

返回级数(sum c[n]*pn)模(O(xprec))。

通过同时求和减少乘法次数。

(ax = [1, p, p2, .., p(J - 1)]) (s = sum(c[i]ax[i]) for i in (range(r, (r + 1)J))p**((K - 1)J)) with (K >= (n + 1)/J)

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_series_from_list, rs_trunc
>>> R, x = ring('x', QQ)
>>> p = x**2 + x + 1
>>> c = [1, 2, 3]
>>> rs_series_from_list(p, c, x, 4)
6*x**3 + 11*x**2 + 8*x + 6
>>> rs_trunc(1 + 2*p + 3*p**2, x, 4)
6*x**3 + 11*x**2 + 8*x + 6
>>> pc = R.from_list(list(reversed(c)))
>>> rs_trunc(pc.compose(x, p), x, 4)
6*x**3 + 11*x**2 + 8*x + 6 
sympy.polys.ring_series.rs_fun(p, f, *args)

通过替换计算多变量级数的函数。

当函数名为 f 时,用于计算多变量级数(rs_tan)和(rs_nth_root)的情况:

(rs_fun(p, tan, iv, prec))

首先对虚拟变量 _x 计算正切级数,即(rs_tan(_x, iv, prec))。然后我们用p替换 _x 以获得所需的级数。

参数:

pPolyElement 要展开的多变量级数。

f:(ring_series)应用于p的函数。

args[-2]PolyElement 对其进行级数展开。

args[-1]:展开级数所需的阶数。

示例

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import rs_fun, _tan1
>>> R, x, y = ring('x, y', QQ)
>>> p = x + x*y + x**2*y + x**3*y**2
>>> rs_fun(p, _tan1, x, 4)
1/3*x**3*y**3 + 2*x**3*y**2 + x**3*y + 1/3*x**3 + x**2*y + x*y + x 
sympy.polys.ring_series.mul_xin(p, i, n)

返回(p*x_i**n)。

(x_i)是p中的第 i 个变量。

sympy.polys.ring_series.pow_xin(p, i, n)
>>> from sympy.polys.domains import QQ
>>> from sympy.polys.rings import ring
>>> from sympy.polys.ring_series import pow_xin
>>> R, x, y = ring('x, y', QQ)
>>> p = x**QQ(2,5) + x + x**QQ(2,3)
>>> index = p.ring.gens.index(x)
>>> pow_xin(p, index, 15)
x**15 + x**10 + x**6 

Literature

Original text:docs.sympy.org/latest/modules/polys/literature.html

下面是用作多项式操作模块实现理论基础的非全面列表。

[Kozen89]

D. Kozen, S. Landau, 多项式分解算法, Journal of Symbolic Computation 7 (1989), pp. 445-456

[Liao95]

Hsin-Chao Liao, R. Fateman, 启发式多项式最大公因式的评估, International Symposium on Symbolic and Algebraic Computation (ISSAC), ACM Press, 加拿大魁北克蒙特利尔, 1995, pp. 240–247

[Gathen99]

J. von zur Gathen, J. Gerhard, 现代计算代数, 第一版, Cambridge University Press, 1999

[Weisstein09]

Eric W. Weisstein, 循环多项式, From MathWorld - A Wolfram Web Resource, mathworld.wolfram.com/CyclotomicPolynomial.html

[Wang78]

P. S. Wang, 改进的多变量多项式因式分解算法, Math. of Computation 32, 1978, pp. 1215–1231

[Geddes92]

K. Geddes, S. R. Czapor, G. Labahn, 计算代数的算法, Springer, 1992

[Monagan93]

Michael Monagan, Z_n 上多项式的原地算术, Proceedings of DISCO ‘92, Springer-Verlag LNCS, 721, 1993, pp. 22–34

[Kaltofen98]

E. Kaltofen, V. Shoup, 有限域上多项式的次二次时间因式分解, Mathematics of Computation, Volume 67, Issue 223, 1998, pp. 1179–1197

[Shoup95]

V. Shoup, 新的多项式因式分解算法及其实现, Journal of Symbolic Computation, Volume 20, Issue 4, 1995, pp. 363–397

[Gathen92]

J. von zur Gathen, V. Shoup, 计算 Frobenius 映射和多项式因式分解, ACM Symposium on Theory of Computing, 1992, pp. 187–224

[Shoup91]

V. Shoup, 有限特征域上多项式的快速确定性因式分解算法, In Proceedings of International Symposium on Symbolic and Algebraic Computation, 1991, pp. 14–21

[Cox97]

D. Cox, J. Little, D. O’Shea, 理想、变量和算法, Springer, 第二版, 1997

[Ajwa95]

I.A. Ajwa, Z. Liu, P.S. Wang, Groebner 基础算法, citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=2bb46c0852bf74c9d74d1a12af6d11f69f7e8363, 1995

[Bose03]

N.K. Bose, B. Buchberger, J.P. Guiver, 多维系统理论与应用, Springer, 2003

[Giovini91]

A. Giovini, T. Mora, “一粒糖,请” 或 Buchberger 算法中的选择策略, ISSAC ‘91, ACM

[Bronstein93]

M. Bronstein, B. Salvy, 有理函数的全部部分分解, Proceedings ISSAC ‘93, ACM Press, 乌克兰基辅, 1993, pp. 157–160

[Buchberger01]

B. Buchberger, Groebner 基础: 系统理论家的简介, In: R. Moreno-Diaz, B. Buchberger, J. L. Freire, Proceedings of EUROCAST’01, 2001 年 2 月

[Davenport88]

J.H. Davenport, Y. Siret, E. Tournier, 计算代数系统和代数计算的算法,学术出版社,伦敦,1988 年,第 124–128 页

[Greuel2008]

G.-M. Greuel, Gerhard Pfister, 《交换代数的奇异导论》,Springer,2008

[Atiyah69]

M.F. Atiyah, I.G. MacDonald, 《交换代数导论》,Addison-Wesley,1969

[Collins67]

G.E. Collins, 子结果和减少的多项式余数序列。J. ACM 14 (1967) 128-142

[BrownTraub71]

W.S. Brown, J.F. Traub, 关于欧几里德算法和子结果理论。J. ACM 18 (1971) 505-514

[Brown78]

W.S. Brown, 子结果 PRS 算法。ACM 数学软件交易 4 (1978) 237-249

[Monagan00]

M. Monagan 和 A. Wittkopf, 关于整数和数域上 Brown 算法的设计和实现,ISSAC 2000 论文集,pp. 225-233,ACM,2000。

[Brown71]

W.S. Brown, 关于欧几里德算法和计算多项式最大公因数,J. ACM 18, 4, pp. 478-504,1971 年。

[Hoeij04]

M. van Hoeij 和 M. Monagan, 代数函数域上多项式 GCD 计算的算法,ISSAC 2004 论文集,pp. 297-304,ACM,2004。

[Wang81]

P.S. Wang, 一种用于单变量部分分数的 p-进制算法,SYMSAC 1981 论文集,pp. 212-217,ACM,1981。

[Hoeij02]

M. van Hoeij 和 M. Monagan, 用多个扩展展示的模块化数域 GCD 算法,ISSAC 2002 论文集,pp. 109-116,ACM,2002

[ManWright94]

Yiu-Kwong Man 和 Francis J. Wright, “快速多项式离散计算及其在无限和中的应用”, 国际符号和代数计算研讨会论文集,1994 年,第 175-180 页 dl.acm.org/doi/10.1145/190347.190413

[Koepf98]

Wolfram Koepf, “超几何求和:求和和特殊函数恒等式的算法方法”,数学高级讲座,Vieweg,1998

[Abramov71]

S. A. Abramov, “有理函数求和”,《苏联计算数学和数学物理学报》,第 11 卷,第 4 期,1971 年,第 324-330 页

[Man93]

Yiu-Kwong Man, “关于计算无限和的封闭形式”,《符号计算杂志》,第 16 卷,第 4 期,1993 年,第 355-376 页 www.sciencedirect.com/science/article/pii/S0747717183710539

[Kapur1994]

Deepak Kapur, Tushar Saxena, 和 Lu Yang. “使用 Dixon resultants 进行代数和几何推理”, 在国际符号和代数计算研讨会(ISSAC ‘94)论文集中,1994 年,第 99-107 页。www.researchgate.net/publication/2514261_Algebraic_and_Geometric_Reasoning_using_Dixon_Resultants

[Palancz08]

B Paláncz, P Zaletnyik, JL Awange, EW Grafarend. “地理多项式方程组的 Dixon 结果解法”, Journal of Geodesy, 2008, Springer, www.researchgate.net/publication/225607735_Dixon_resultant's_solution_of_systems_of_geodetic_polynomial_equations.

[Bruce97]

Bruce Randall Donald, Deepak Kapur, 和 Joseph L. Mundy (主编). “人工智能的符号和数值计算”, 第二章, Academic Press, Inc., Orlando, FL, USA, 1997, donaldlab.cs.duke.edu/Books/SymbolicNumericalComputation/045-087.pdf

[Stiller96]

P Stiller. “结果式理论导论”, Mathematics and Computer Science, T&M University, 1996, Citeseer, isc.tamu.edu/resources/preprints/1996/1996-02.pdf

[Cohen93]

Henri Cohen. “计算代数数论课程”, Springer, 1993.

[Trager76]

Barry M. Trager. “代数因式分解和有理函数积分”, SYMSAC 1976 年会议论文集, pp. 219-226, ACM, 1976. dl.acm.org/doi/abs/10.1145/800205.806338

[Yun76]

David Y.Y. Yun. “关于无平方因式分解算法”, SYMSAC 1976 年会议论文集, pp. 219-226, ACM, 1976. dl.acm.org/doi/10.1145/800205.806320

[Abbott13]

John Abbott. “Z[x]中因子的界限”. Journal of Symbolic Computation 50 (2013), pp. 532-563 doi.org/10.1016/j.jsc.2012.09.004

多项式求解器

原文链接:docs.sympy.org/latest/modules/polys/solvers.html

此模块提供用于解决 sympy 内部使用的线性方程组的函数。

低级线性系统求解器。

sympy.polys.solvers.solve_lin_sys(eqs, ring, _raw=True)

解决多项式环中的线性方程组

参数:

eqs: list[PolyElement]

要解的线性方程作为 PolynomialRing 的元素(假定为零)。

ring: PolynomialRing

从中提取 eqs 的多项式环。此环的生成器是要解的未知数,环的域是方程组的系数的域。

_raw: bool

如果 _raw 是 False,则返回的字典中的键和值将是 Expr 类型(并且从键中移除了字段的单位),否则将返回低级 polys 类型,例如 PolyElement: PythonRational。

返回:

如果系统无解,则返回 None

如果 _raw=False,则返回 dict[Symbol, Expr]

如果 _raw=True,则返回 dict[Symbol, DomainElement]。

说明

解决给定作为 PolynomialRing 的 PolyElement 实例的线性方程组。基本算术使用 DomainElement 的实例进行,这比对于最常见的输入使用 Expr 更高效。

虽然这是一个公共函数,但主要用于内部使用,因此其接口未必方便。建议用户使用 sympy.solvers.solveset.linsolve() 函数(该函数内部使用此函数)。

示例

>>> from sympy import symbols
>>> from sympy.polys.solvers import solve_lin_sys, sympy_eqs_to_ring
>>> x, y = symbols('x, y')
>>> eqs = [x - y, x + y - 2]
>>> eqs_ring, ring = sympy_eqs_to_ring(eqs, [x, y])
>>> solve_lin_sys(eqs_ring, ring)
{y: 1, x: 1} 

传递 _raw=False 返回相同的结果,除了键是 Expr 而不是低级多项式类型。

>>> solve_lin_sys(eqs_ring, ring, _raw=False)
{x: 1, y: 1} 

另请参阅

sympy_eqs_to_ring

准备输入以供 solve_lin_sys 使用。

linsolve

linsolve 在内部使用 solve_lin_sys

sympy.solvers.solvers.solve

solve 在内部使用 solve_lin_sys

sympy.polys.solvers.eqs_to_matrix(eqs_coeffs, eqs_rhs, gens, domain)

从线性方程组中的字典格式获取矩阵。

参数:

eqs_coeffs: list[dict[Symbol, DomainElement]]

方程的左侧作为从符号到系数映射的字典,其中系数是 DomainElement 的实例。

eqs_rhs: list[DomainElements]

方程的右侧作为 DomainElement 的实例。

gens: list[Symbol]

方程组中的未知数。

domain: Domain

系数的域,用于 lhs 和 rhs。

返回:

系统的扩展矩阵表示为 DomainMatrix。

说明

获取线性方程组的矩阵表示,表示为带有低级 DomainElement 系数的字典。这是一个内部函数,被 solve_lin_sys 使用。

示例

>>> from sympy import symbols, ZZ
>>> from sympy.polys.solvers import eqs_to_matrix
>>> x, y = symbols('x, y')
>>> eqs_coeff = [{x:ZZ(1), y:ZZ(1)}, {x:ZZ(1), y:ZZ(-1)}]
>>> eqs_rhs = [ZZ(0), ZZ(-1)]
>>> eqs_to_matrix(eqs_coeff, eqs_rhs, [x, y], ZZ)
DomainMatrix([[1, 1, 0], [1, -1, 1]], (2, 3), ZZ) 

另请参见

solve_lin_sys

在内部使用eqs_to_matrix()

sympy.polys.solvers.sympy_eqs_to_ring(eqs, symbols)

将从表达式转换为 PolyRing 的方程系统

参数:

eqs: Expr 列表

作为 Expr 实例的方程列表

symbols: 符号列表

系统方程中的未知符号列表。

返回:

Tuple[List[PolyElement], Ring]: 方程作为 PolyElement 实例

以及每个方程中表示的多项式环。

解释

高级函数如 solve 期望 Expr 作为输入,但可以在内部使用 solve_lin_sys。此函数将方程从 Expr 转换为 solve_lin_sys 函数使用的低级多项式类型。

示例

>>> from sympy import symbols
>>> from sympy.polys.solvers import sympy_eqs_to_ring
>>> a, x, y = symbols('a, x, y')
>>> eqs = [x-y, x+a*y]
>>> eqs_ring, ring = sympy_eqs_to_ring(eqs, [x, y])
>>> eqs_ring
[x - y, x + a*y]
>>> type(eqs_ring[0])
<class 'sympy.polys.rings.PolyElement'>
>>> ring
ZZ(a)[x,y] 

在这种形式的方程中,它们可以被传递给solve_lin_sys

>>> from sympy.polys.solvers import solve_lin_sys
>>> solve_lin_sys(eqs_ring, ring)
{y: 0, x: 0} 
sympy.polys.solvers._solve_lin_sys(eqs_coeffs, eqs_rhs, ring)

从多项式环系数的字典中解决线性系统

解释

这是一个内部函数,用于在方程被预处理后由solve_lin_sys()使用。此函数的作用是将系统拆分为连接组件,并将其传递给_solve_lin_sys_component()

示例

设定一个系统为 (x-y=0) 和 (x+y=2) 并解决:

>>> from sympy import symbols, sring
>>> from sympy.polys.solvers import _solve_lin_sys
>>> x, y = symbols('x, y')
>>> R, (xr, yr) = sring([x, y], [x, y])
>>> eqs = [{xr:R.one, yr:-R.one}, {xr:R.one, yr:R.one}]
>>> eqs_rhs = [R.zero, -2*R.one]
>>> _solve_lin_sys(eqs, eqs_rhs, R)
{y: 1, x: 1} 

另请参见

solve_lin_sys

此函数在solve_lin_sys()内部使用。

sympy.polys.solvers._solve_lin_sys_component(eqs_coeffs, eqs_rhs, ring)

从多项式环系数的字典中解决线性系统

解释

这是一个内部函数,用于在方程被预处理后由solve_lin_sys()使用。在_solve_lin_sys()将系统拆分为连接组件后,对每个组件调用此函数。方程组使用高斯-约当消元法进行解决,然后进行回代。

示例

设定一个系统为 (x-y=0) 和 (x+y=2) 并解决:

>>> from sympy import symbols, sring
>>> from sympy.polys.solvers import _solve_lin_sys_component
>>> x, y = symbols('x, y')
>>> R, (xr, yr) = sring([x, y], [x, y])
>>> eqs = [{xr:R.one, yr:-R.one}, {xr:R.one, yr:R.one}]
>>> eqs_rhs = [R.zero, -2*R.one]
>>> _solve_lin_sys_component(eqs, eqs_rhs, R)
{y: 1, x: 1} 

另请参见

solve_lin_sys

此函数在solve_lin_sys()内部使用。

介绍多项式模块的domainmatrix

原文链接:docs.sympy.org/latest/modules/polys/domainmatrix.html

此页面介绍了在 SymPy 的sympy.polys模块中使用的domainmatrix的概念。这是一个相对高级的主题,为了更好地理解,建议阅读关于DomainDDM以及sympy.matrices模块的内容。

什么是domainmatrix

这是将矩阵与Domain关联的方式。

DomainMatrix代表一个具有特定域内元素的矩阵。每个DomainMatrix内部包装一个DDM,用于底层操作。其思想在于,DomainMatrix类提供了方便的例程,用于在Expr和多项式域之间进行转换,以及统一具有不同域的矩阵。

通常,我们表示一个矩阵而不关心Domain如下:

>>> from sympy import Matrix
>>> from sympy.polys.matrices import DomainMatrix
>>> A = Matrix([
... [1, 2],
... [3, 4]])
>>> A
Matrix([
[1, 2],
[3, 4]]) 

DomainMatrix类的模块。

DomainMatrix代表一个具有特定域内元素的矩阵。每个DomainMatrix内部包装一个DDM,用于底层操作。其思想在于,DomainMatrix类提供了方便的例程,用于在Expr和多项式域之间进行转换,以及统一具有不同域的矩阵。

sympy.polys.matrices.domainmatrix.DM(rows, domain)

用于DomainMatrix.from_list的便捷别名。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> DM([[1, 2], [3, 4]], ZZ)
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ) 

参见

DomainMatrix.from_list

class sympy.polys.matrices.domainmatrix.DomainMatrix(rows, shape, domain, *, fmt=None)

将矩阵与Domain关联

解释

DomainMatrix使用Domain作为其内部表示,这使得它在许多常见操作上比 SymPy 矩阵类(目前)更快,但这一优势也使其与矩阵不完全兼容。DomainMatrix类似于带有“dtype”的 numpy 数组。在DomainMatrix中,每个元素都有诸如 ZZ 或 QQ的域。

示例

从现有的矩阵类创建DomainMatrix

>>> from sympy import Matrix
>>> from sympy.polys.matrices import DomainMatrix
>>> Matrix1 = Matrix([
...    [1, 2],
...    [3, 4]])
>>> A = DomainMatrix.from_Matrix(Matrix1)
>>> A
DomainMatrix({0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}}, (2, 2), ZZ) 

直接形成一个DomainMatrix

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> A
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ) 

参见

DDMSDMDomainPoly

add(B)

添加两个相同域的 DomainMatrix 矩阵

参数:

A, B: DomainMatrix

要添加的矩阵

返回:

DomainMatrix

添加后的 DomainMatrix

引发:

DMShapeError

如果两个 DomainMatrix 的维度不相等

ValueError

如果两个 DomainMatrix 的域不同

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([
...    [ZZ(4), ZZ(3)],
...    [ZZ(2), ZZ(1)]], (2, 2), ZZ) 
>>> A.add(B)
DomainMatrix([[5, 5], [5, 5]], (2, 2), ZZ) 

另见

sub, matmul

adj_det()

正方形 DomainMatrix 的伴随矩阵和行列式。

返回:

(伴随, 行列式) : (DomainMatrix, DomainScalar)

此矩阵的伴随矩阵和行列式。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> A = DM([
...     [ZZ(1), ZZ(2)],
...     [ZZ(3), ZZ(4)]], ZZ)
>>> adjA, detA = A.adj_det()
>>> adjA
DomainMatrix([[4, -2], [-3, 1]], (2, 2), ZZ)
>>> detA
-2 

另见

adjugate

仅返回伴随矩阵。

det

仅返回行列式。

inv_den

返回一个表示逆矩阵/分母对的矩阵,但可能与伴随和行列式由一个公共因子不同。

adj_poly_det(cp=None)

返回多项式 (p),使得 (p(A) = adj(A)),同时返回 (A) 的行列式。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DM
>>> A = DM([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], QQ)
>>> p, detA = A.adj_poly_det()
>>> p
[-1, 5]
>>> p_A = A.eval_poly(p)
>>> p_A
DomainMatrix([[4, -2], [-3, 1]], (2, 2), QQ)
>>> p[0]*A**1 + p[1]*A**0 == p_A
True
>>> p_A == A.adjugate()
True
>>> A * A.adjugate() == detA * A.eye(A.shape, A.domain).to_dense()
True 

另见

adjugate, eval_poly, adj_det

adjugate()

正方形 DomainMatrix 的伴随矩阵。

伴随矩阵是余因子矩阵的转置,与逆矩阵的关系为:

adj(A) = det(A) * A.inv() 

不同于逆矩阵,伴随矩阵可以在地面域中计算和表示,无需分割或分数。

返回:

DomainMatrix

具有相同域的此矩阵的伴随矩阵。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> A = DM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], ZZ)
>>> A.adjugate()
DomainMatrix([[4, -2], [-3, 1]], (2, 2), ZZ) 

另见

adj_det

cancel_denom(denom)

取消矩阵和分母之间的因子。

返回一个矩阵和最低术语上的分母。

在地面域中需要 gcd

方法如 solve_den(), inv_den()rref_den() 返回一个矩阵和分母,但不一定是最简形式。可以使用 cancel_denom() 将其化简为没有分数的最简形式。

示例

>>> from sympy.polys.matrices import DM
>>> from sympy import ZZ
>>> M = DM([[2, 2, 0],
...         [0, 2, 2],
...         [0, 0, 2]], ZZ)
>>> Minv, den = M.inv_den()
>>> Minv.to_Matrix()
Matrix([
[1, -1,  1],
[0,  1, -1],
[0,  0,  1]])
>>> den
2
>>> Minv_reduced, den_reduced = Minv.cancel_denom(den)
>>> Minv_reduced.to_Matrix()
Matrix([
[1, -1,  1],
[0,  1, -1],
[0,  0,  1]])
>>> den_reduced
2
>>> Minv_reduced.to_field() / den_reduced == Minv.to_field() / den
True 

分母相对于单位是规范化的(例如,负分母变为正数):

>>> M = DM([[2, 2, 0]], ZZ)
>>> den = ZZ(-4)
>>> M.cancel_denom(den)
(DomainMatrix([[-1, -1, 0]], (1, 3), ZZ), 2) 

任何在 _ 所有 _ 元素中都通用的因子都会被取消,但矩阵元素和分母之间可能仍然存在共同因子。要取消每个元素与分母之间的因子,请使用 cancel_denom_elementwise() 或者转换为域并使用除法:

>>> M = DM([[4, 6]], ZZ)
>>> den = ZZ(12)
>>> M.cancel_denom(den)
(DomainMatrix([[2, 3]], (1, 2), ZZ), 6)
>>> numers, denoms = M.cancel_denom_elementwise(den)
>>> numers
DomainMatrix([[1, 1]], (1, 2), ZZ)
>>> denoms
DomainMatrix([[3, 2]], (1, 2), ZZ)
>>> M.to_field() / den
DomainMatrix([[1/3, 1/2]], (1, 2), QQ) 

参见

solve_den, inv_den, rref_den, cancel_denom_elementwise

cancel_denom_elementwise(denom)

取消矩阵元素与分母之间的因子。

返回分子矩阵和分母矩阵。

需要在基本域中使用 gcd

示例

>>> from sympy.polys.matrices import DM
>>> from sympy import ZZ
>>> M = DM([[2, 3], [4, 12]], ZZ)
>>> denom = ZZ(6)
>>> numers, denoms = M.cancel_denom_elementwise(denom)
>>> numers.to_Matrix()
Matrix([
[1, 1],
[2, 2]])
>>> denoms.to_Matrix()
Matrix([
[3, 2],
[3, 1]])
>>> M_frac = (M.to_field() / denom).to_Matrix()
>>> M_frac
Matrix([
[1/3, 1/2],
[2/3,   2]])
>>> denoms_inverted = denoms.to_Matrix().applyfunc(lambda e: 1/e)
>>> numers.to_Matrix().multiply_elementwise(denoms_inverted) == M_frac
True 

使用 cancel_denom() 取消矩阵与分母之间的因子,同时保持标量分母的形式。

参见

cancel_denom

charpoly()

方阵的特征多项式。

使用不需要除法的算术完全展开特征多项式。如果需要特征多项式的因式分解,则调用 charpoly_factor_list() 比调用 charpoly() 然后对结果进行因式分解更有效。

返回:

列表:DomainElement 的列表

特征多项式的系数

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ) 
>>> A.charpoly()
[1, -5, -2] 

另请参见

charpoly_factor_list

计算特征多项式的因式分解。

charpoly_factor_blocks

特征多项式的部分因式分解,可以比完全因式分解或完全展开的多项式更有效地计算。

charpoly_base()

charpoly_factor_blocks()块分解后的基础情况。

该方法在charpoly_factor_blocks()内部被用作计算块的特征多项式的基础情况。与直接调用该方法相比,调用charpoly_factor_blocks()charpoly()charpoly_factor_list()更有效率。

这将根据矩阵的稀疏性使用密集或稀疏实现,并在调用charpoly_berk()计算特征多项式之前清除可能的分母。

另请参见

charpolycharpoly_factor_listcharpoly_factor_blockscharpoly_berk

charpoly_berk()

使用伯克维茨算法计算特征多项式。

此方法直接调用伯克维茨算法的底层实现(sympy.polys.matrices.dense.ddm_berk()sympy.polys.matrices.sdm.sdm_berk())。

此方法由charpoly()和其他方法用作计算特征多项式的基本情况。然而,这些方法会在调用此方法之前应用其他优化,如块分解、清除分母和在密集和稀疏表示之间转换。调用这些方法比调用此方法更有效,但此方法提供了直接访问伯克维茨算法的功能。

示例

>>> from sympy.polys.matrices import DM
>>> from sympy import QQ
>>> M = DM([[6, -1, 0, 0],
...         [9, 12, 0, 0],
...         [0,  0, 1, 2],
...         [0,  0, 5, 6]], QQ)
>>> M.charpoly_berk()
[1, -25, 203, -495, -324] 

另见

charpoly, charpoly_base, charpoly_factor_list, charpoly_factor_blocks, sympy.polys.matrices.dense.ddm_berk, sympy.polys.matrices.sdm.sdm_berk

charpoly_factor_blocks()

特征多项式的部分因式分解。

此因式分解源自矩阵的块结构(如果存在),因此因子不能保证是不可约的。charpoly_factor_blocks() 方法是获取特征多项式表示的最有效方式,但结果既不是完全展开也不是完全因式分解的。

返回:

列表:因子和重数的列表

特征多项式的部分因式分解。

示例

>>> from sympy.polys.matrices import DM
>>> from sympy import ZZ
>>> M = DM([[6, -1, 0, 0],
...         [9, 12, 0, 0],
...         [0,  0, 1, 2],
...         [0,  0, 5, 6]], ZZ) 

这将使用矩阵的块结构计算部分因式分解以揭示因子:

>>> M.charpoly_factor_blocks()
[([1, -18, 81], 1), ([1, -7, -4], 1)] 

这些因子对应于矩阵中的两个对角块:

>>> DM([[6, -1], [9, 12]], ZZ).charpoly()
[1, -18, 81]
>>> DM([[1, 2], [5, 6]], ZZ).charpoly()
[1, -7, -4] 

使用charpoly_factor_list()获取完整的不可约因式分解:

>>> M.charpoly_factor_list()
[([1, -9], 2), ([1, -7, -4], 1)] 

使用charpoly()获取展开的特征多项式:

>>> M.charpoly()
[1, -25, 203, -495, -324] 

另见

charpoly

计算特征多项式的完全展开。

charpoly_factor_list

计算特征多项式的完整因式分解。

charpoly_factor_list()

特征多项式的完整因式分解。

返回:

list: 因子和重数的列表

特征多项式的完整因式分解。

示例

>>> from sympy.polys.matrices import DM
>>> from sympy import ZZ
>>> M = DM([[6, -1, 0, 0],
...         [9, 12, 0, 0],
...         [0,  0, 1, 2],
...         [0,  0, 5, 6]], ZZ) 

计算特征多项式的因式分解:

>>> M.charpoly_factor_list()
[([1, -9], 2), ([1, -7, -4], 1)] 

使用charpoly()获取未因式分解的特征多项式:

>>> M.charpoly()
[1, -25, 203, -495, -324] 

Matrix进行相同的计算:

>>> M.to_Matrix().charpoly().as_expr()
lambda**4 - 25*lambda**3 + 203*lambda**2 - 495*lambda - 324
>>> M.to_Matrix().charpoly().as_expr().factor()
(lambda - 9)**2*(lambda**2 - 7*lambda - 4) 

另请参阅

charpoly

特征多项式的展开形式。

charpoly_factor_blocks

可以更有效地计算的特征多项式的部分因式分解。

choose_domain(**opts)

转换为通过construct_domain()找到的域。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> M = DM([[1, 2], [3, 4]], ZZ)
>>> M
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ)
>>> M.choose_domain(field=True)
DomainMatrix([[1, 2], [3, 4]], (2, 2), QQ) 
>>> from sympy.abc import x
>>> M = DM([[1, x], [x**2, x**3]], ZZ[x])
>>> M.choose_domain(field=True).domain
ZZ(x) 

关键字参数传递给construct_domain()

另请参阅

construct_domain, convert_to

clear_denoms(convert=False)

清除分母,但保持域不变。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DM
>>> A = DM([[(1,2), (1,3)], [(1,4), (1,5)]], QQ)
>>> den, Anum = A.clear_denoms()
>>> den.to_sympy()
60
>>> Anum.to_Matrix()
Matrix([
[30, 20],
[15, 12]])
>>> den * A == Anum
True 

分子矩阵将与原始矩阵相同的域,除非将convert设置为True

>>> A.clear_denoms()[1].domain
QQ
>>> A.clear_denoms(convert=True)[1].domain
ZZ 

分母总是在相关环中:

>>> A.clear_denoms()[0].domain
ZZ
>>> A.domain.get_ring()
ZZ 

另请参阅

sympy.polys.polytools.Poly.clear_denoms, clear_denoms_rowwise

clear_denoms_rowwise(convert=False)

清除矩阵每行的分母。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DM
>>> A = DM([[(1,2), (1,3), (1,4)], [(1,5), (1,6), (1,7)]], QQ)
>>> den, Anum = A.clear_denoms_rowwise()
>>> den.to_Matrix()
Matrix([
[12,   0],
[ 0, 210]])
>>> Anum.to_Matrix()
Matrix([
[ 6,  4,  3],
[42, 35, 30]]) 

分母矩阵是一个对角线矩阵,其对角线上的每行分母。不变量是:

>>> den * A == Anum
True
>>> A == den.to_field().inv() * Anum
True 

分子矩阵将与原始矩阵相同的域,除非将convert设置为True

>>> A.clear_denoms_rowwise()[1].domain
QQ
>>> A.clear_denoms_rowwise(convert=True)[1].domain
ZZ 

分母矩阵的域是相关环:

>>> A.clear_denoms_rowwise()[0].domain
ZZ 

另请参阅

sympy.polys.polytools.Poly.clear_denomsclear_denoms

columnspace()

返回域矩阵的列空间

返回:

域矩阵

此矩阵的列形成列空间的基础。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [QQ(1), QQ(-1)],
...    [QQ(2), QQ(-2)]], (2, 2), QQ)
>>> A.columnspace()
DomainMatrix([[1], [2]], (2, 1), QQ) 
content()

返回矩阵元素的最大公约数。

需要在基础域中的最大公约数。

示例

>>> from sympy.polys.matrices import DM
>>> from sympy import ZZ
>>> M = DM([[2, 4], [4, 12]], ZZ)
>>> M.content()
2 

另请参阅

primitivecancel_denom

convert_to(K)

将域矩阵的域更改为所需的域或字段

参数:

K:表示所需的域或字段。

或者,可以传递 None,在这种情况下,此方法只返回此域矩阵的副本。

返回:

域矩阵

带有所需域或字段的域矩阵

示例

>>> from sympy import ZZ, ZZ_I
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ) 
>>> A.convert_to(ZZ_I)
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ_I) 
det()

返回一个方阵 DomainMatrix 的行列式。

返回:

行列式:域元素

矩阵的行列式。

引发:

ValueError

如果域矩阵的域不是一个域

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ) 
>>> A.det()
-2 
classmethod diag(diagonal, domain, shape=None)

返回对角矩阵,其条目来自 diagonal

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import ZZ
>>> DomainMatrix.diag([ZZ(5), ZZ(6)], ZZ)
DomainMatrix({0: {0: 5}, 1: {1: 6}}, (2, 2), ZZ) 
diagonal()

获取矩阵的对角条目作为列表。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> M = DM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], ZZ)
>>> M.diagonal()
[1, 4] 

另请参阅

is_diagonaldiag

eval_poly(p)

评估矩阵的多项式函数 (p(A))。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DM
>>> A = DM([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], QQ)
>>> p = [QQ(1), QQ(2), QQ(3)]
>>> p_A = A.eval_poly(p)
>>> p_A
DomainMatrix([[12, 14], [21, 33]], (2, 2), QQ)
>>> p_A == p[0]*A**2 + p[1]*A + p[2]*A**0
True 

另请参阅

eval_poly_mul

eval_poly_mul(p, B)

评估多项式矩阵乘积 (p(A) \times B)。

使用霍纳方法计算多项式矩阵乘积 (p(A) \times B),而不显式创建矩阵 (p(A))。如果 (B) 是列矩阵,则此方法将仅使用矩阵-向量乘法,无需矩阵-矩阵乘法。

如果 (B) 是方阵或宽阵列,或者如果 (A) 可以在比 (B) 更简单的域中表示,则直接评估 (p(A)) 可能会更快 (参见 eval_poly()),然后与 (B) 相乘。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DM
>>> A = DM([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], QQ)
>>> b = DM([[QQ(5)], [QQ(6)]], QQ)
>>> p = [QQ(1), QQ(2), QQ(3)]
>>> p_A_b = A.eval_poly_mul(p, b)
>>> p_A_b
DomainMatrix([[144], [303]], (2, 1), QQ)
>>> p_A_b == p[0]*A**2*b + p[1]*A*b + p[2]*b
True
>>> A.eval_poly_mul(p, b) == A.eval_poly(p)*b
True 

另请参阅

eval_polysolve_den_charpoly

classmethod eye(shape, domain)

返回大小为 n 或形状为 (m, n) 的单位矩阵。

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> DomainMatrix.eye(3, QQ)
DomainMatrix({0: {0: 1}, 1: {1: 1}, 2: {2: 1}}, (3, 3), QQ) 
classmethod from_Matrix(M, fmt='sparse', **kwargs)

转换矩阵为域矩阵

参数:

M: 矩阵

返回:

返回具有与 M 相同元素的域矩阵

示例

>>> from sympy import Matrix
>>> from sympy.polys.matrices import DomainMatrix
>>> M = Matrix([
...    [1.0, 3.4],
...    [2.4, 1]])
>>> A = DomainMatrix.from_Matrix(M)
>>> A
DomainMatrix({0: {0: 1.0, 1: 3.4}, 1: {0: 2.4, 1: 1.0}}, (2, 2), RR) 

我们可以使用 fmt=’dense’ 保留内部表示为 ddm >>> from sympy import Matrix, QQ >>> from sympy.polys.matrices import DomainMatrix >>> A = DomainMatrix.from_Matrix(Matrix([[QQ(1, 2), QQ(3, 4)], [QQ(0, 1), QQ(0, 1)]]), fmt=’dense’) >>> A.rep [[1/2, 3/4], [0, 0]]

参见

Matrix

classmethod from_dict_sympy(nrows, ncols, elemsdict, **kwargs)

参数:

nrows: 行数

ncols: 列数

elemsdict: 包含域矩阵非零元素的字典

返回:

包含 elemsdict 元素的域矩阵

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.abc import x,y,z
>>> elemsdict = {0: {0:x}, 1:{1: y}, 2: {2: z}}
>>> A = DomainMatrix.from_dict_sympy(3, 3, elemsdict)
>>> A
DomainMatrix({0: {0: x}, 1: {1: y}, 2: {2: z}}, (3, 3), ZZ[x,y,z]) 

参见

from_list_sympy

classmethod from_dod(dod, shape, domain)

从字典格式的键(dod)创建稀疏 DomainMatrix

参见 to_dod() 以获取解释。

参见

to_dod, from_dod_like

from_dod_like(dod, domain=None)

从字典格式的键(dod)创建 DomainMatrix 类似 self

参见 to_dod() 以获取解释。

参见

to_dod, from_dod

classmethod from_dok(dok, shape, domain)

从键(dok)格式的字典创建 DomainMatrix

参见 to_dok() 以获取解释。

参见

to_dok

from_flat_nz(elements, data, domain)

在调用 to_flat_nz() 后重新构建 DomainMatrix

参见 to_flat_nz() 以获取解释。

参见

to_flat_nz

classmethod from_list(rows, domain)

将列表的列表转换为 DomainMatrix

参数:

rows: list of lists

每个内部列表的元素应该是要传递给域构造函数的单个参数或参数元组,以便按顺序形成域的元素。参见示例。

返回:

包含在 rows 中定义的元素的 DomainMatrix

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import FF, QQ, ZZ
>>> A = DomainMatrix.from_list([[1, 0, 1], [0, 0, 1]], ZZ)
>>> A
DomainMatrix([[1, 0, 1], [0, 0, 1]], (2, 3), ZZ)
>>> B = DomainMatrix.from_list([[1, 0, 1], [0, 0, 1]], FF(7))
>>> B
DomainMatrix([[1 mod 7, 0 mod 7, 1 mod 7], [0 mod 7, 0 mod 7, 1 mod 7]], (2, 3), GF(7))
>>> C = DomainMatrix.from_list([[(1, 2), (3, 1)], [(1, 4), (5, 1)]], QQ)
>>> C
DomainMatrix([[1/2, 3], [1/4, 5]], (2, 2), QQ) 

另请参阅

from_list_sympy

classmethod from_list_flat(elements, shape, domain)

从平面列表创建 DomainMatrix

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> element_list = [ZZ(1), ZZ(2), ZZ(3), ZZ(4)]
>>> A = DomainMatrix.from_list_flat(element_list, (2, 2), ZZ)
>>> A
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ)
>>> A == A.from_list_flat(A.to_list_flat(), A.shape, A.domain)
True 

另请参阅

to_list_flat

classmethod from_list_sympy(nrows, ncols, rows, **kwargs)

使用 construct_domain 将 Expr 的列表列表转换为 DomainMatrix

参数:

nrows: 行数

ncols: 列数

rows: list of lists

返回:

包含 rows 元素的 DomainMatrix

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.abc import x, y, z
>>> A = DomainMatrix.from_list_sympy(1, 3, [[x, y, z]])
>>> A
DomainMatrix([[x, y, z]], (1, 3), ZZ[x,y,z]) 

另请参阅

sympy.polys.constructor.construct_domain, from_dict_sympy

classmethod from_rep(rep)

从 DDM/SDM 高效创建新的 DomainMatrix。

参数:

rep: SDM 或 DDM

矩阵的内部稀疏或密集表示。

返回:

DomainMatrix

使用 rep 创建包装的 DomainMatrix

示例

创建带有密集内部表示的 DomainMatrix:

>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.polys.matrices.ddm import DDM
>>> drep = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> dM = DomainMatrix.from_rep(drep)
>>> dM
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ) 

创建带有稀疏内部表示的 DomainMatrix:

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import ZZ
>>> drep = SDM({0:{1:ZZ(1)},1:{0:ZZ(2)}}, (2, 2), ZZ)
>>> dM = DomainMatrix.from_rep(drep)
>>> dM
DomainMatrix({0: {1: 1}, 1: {0: 2}}, (2, 2), ZZ) 

注意

这将以 rep 作为其内部表示拥有。如果 rep 在其他地方发生变异,则应提供副本给 from_rep。对 rep 的验证或检查仅做最小限度的处理,因为这应该是一个高效的内部程序。

hstack(*B)

水平堆叠给定的矩阵。

参数:

B: DomainMatrix

要水平堆叠的矩阵。

返回:

DomainMatrix

通过水平堆叠创建的 DomainMatrix。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix 
>>> A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ)
>>> A.hstack(B)
DomainMatrix([[1, 2, 5, 6], [3, 4, 7, 8]], (2, 4), ZZ) 
>>> C = DomainMatrix([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ)
>>> A.hstack(B, C)
DomainMatrix([[1, 2, 5, 6, 9, 10], [3, 4, 7, 8, 11, 12]], (2, 6), ZZ) 

另请参阅

unify

inv()

如果存在,则查找 DomainMatrix 的逆。

返回:

DomainMatrix

反向后的 DomainMatrix

引发:

ValueError

如果 DomainMatrix 的域不是一个 Field

DMNonSquareMatrixError

如果 DomainMatrix 不是正方形 DomainMatrix

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...     [QQ(2), QQ(-1), QQ(0)],
...     [QQ(-1), QQ(2), QQ(-1)],
...     [QQ(0), QQ(0), QQ(2)]], (3, 3), QQ)
>>> A.inv()
DomainMatrix([[2/3, 1/3, 1/6], [1/3, 2/3, 1/3], [0, 0, 1/2]], (3, 3), QQ) 

另请参阅

neg

inv_den(method=None)

返回一个DomainMatrix作为分母的逆。

参数:

method : str, optional

用于计算逆的方法。可以是None'rref''charpoly'之一。如果None,则自动选择方法(详见solve_den())。

返回:

(inv, den):(DomainMatrix, DomainElement)

逆矩阵及其分母。

这基本上等同于adj_det(),只是inv

den 不能保证是伴随和逆。该

比率inv/den等同于adj/det,但某些因素

invden之间可能会被取消。在简单情况下,这种情况

可能只是一个负号,所以(inv, den) == (-adj, -det)

因素比-1更复杂的因素也可以被取消。

取消不能保证完全,所以invden

可能不是最低项。如果和分母den为零

仅当行列式为零时。

如果需要实际的伴随和行列式,请使用adj_det()

替代。如果意图是计算逆矩阵或解

方程组,然后inv_den()更有效。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...     [ZZ(2), ZZ(-1), ZZ(0)],
...     [ZZ(-1), ZZ(2), ZZ(-1)],
...     [ZZ(0), ZZ(0), ZZ(2)]], (3, 3), ZZ)
>>> Ainv, den = A.inv_den()
>>> den
6
>>> Ainv
DomainMatrix([[4, 2, 1], [2, 4, 2], [0, 0, 3]], (3, 3), ZZ)
>>> A * Ainv == den * A.eye(A.shape, A.domain).to_dense()
True 

另请参阅

inv, det, adj_det, solve_den

property is_diagonal

如果矩阵是对角线的,则为真。

如果矩阵不是对角矩阵,则返回 true。如果M[i,j] == 0,则矩阵是对角线的。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> M = DM([[ZZ(1), ZZ(0)], [ZZ(0), ZZ(1)]], ZZ)
>>> M.is_diagonal
True 

另请参阅

is_upper, is_lower, is_square, diagonal

property is_lower

指示此矩阵是否为下三角形。即使矩阵不是方阵,也可以返回 True。

property is_square

如果矩阵是方阵,则为真。

property is_upper

指示此矩阵是否为上三角形。即使矩阵不是方阵,也可以返回 True。

iter_items()

迭代矩阵非零元素的索引和值。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([[ZZ(1), ZZ(0)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> list(A.iter_items())
[((0, 0), 1), ((1, 0), 3), ((1, 1), 4)] 

查看也

iter_values, to_dok, sympy.matrices.matrixbase.MatrixBase.iter_items

iter_values()

迭代矩阵的非零元素。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([[ZZ(1), ZZ(0)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> list(A.iter_values())
[1, 3, 4] 

参见也

iter_items, to_list_flat, sympy.matrices.matrixbase.MatrixBase.iter_values

lll(delta=MPQ(3, 4))

执行 Lenstra–Lenstra–Lovász (LLL) 基础约简算法。参见[R772][R773]

参数:

delta : QQ,可选

Lovász 参数。必须在区间(0.25, 1)内,较大的值会产生更简化的基础。出于历史原因,默认值为 0.75。

返回:

作为 ZZ 上的 DomainMatrix 的简化基础。

抛出

如果 delta 不在范围 (0.25, 1) 内则会抛出 DMValueError;如果矩阵不是形状为 (m, n) 且 m <= n 的形状则会抛出 DMShapeError;如果矩阵域不是 ZZ 则会抛出 DMDomainError;如果矩阵包含线性相关行则会抛出 DMRankError。

示例

>>> from sympy.polys.domains import ZZ, QQ
>>> from sympy.polys.matrices import DM
>>> x = DM([[1, 0, 0, 0, -20160],
...         [0, 1, 0, 0, 33768],
...         [0, 0, 1, 0, 39578],
...         [0, 0, 0, 1, 47757]], ZZ)
>>> y = DM([[10, -3, -2, 8, -4],
...         [3, -9, 8, 1, -11],
...         [-3, 13, -9, -3, -9],
...         [-12, -7, -11, 9, -1]], ZZ)
>>> assert x.lll(delta=QQ(5, 6)) == y 

注意

实现源自于在[R774](pp.68-69)的 Figures 4.3 和 4.4 中给出的 Maple 代码。它使用了仅在需要时计算状态更新的高效方法。

参见也

lll_transform

参考文献

[R772] (1,2)

en.wikipedia.org/wiki/Lenstra%E2%80%93Lenstra%E2%80%93Lov%C3%A1sz_lattice_basis_reduction_algorithm

[R773] (1,2)

web.archive.org/web/20221029115428/https://web.cs.elte.hu/~lovasz/scans/lll.pdf

[R774] (1,2)

Murray R. Bremner, “Lattice Basis Reduction: An Introduction to the LLL Algorithm and Its Applications”

lll_transform(delta=MPQ(3, 4))

Performs the Lenstra–Lenstra–Lovász (LLL) basis reduction algorithm and returns the reduced basis and transformation matrix.

Explanation

Parameters, algorithm and basis are the same as for lll() except that the return value is a tuple ((B, T)) with (B) the reduced basis and (T) a transformation matrix. The original basis (A) is transformed to (B) with (T*A == B). If only (B) is needed then lll() should be used as it is a little faster.

Examples

>>> from sympy.polys.domains import ZZ, QQ
>>> from sympy.polys.matrices import DM
>>> X = DM([[1, 0, 0, 0, -20160],
...         [0, 1, 0, 0, 33768],
...         [0, 0, 1, 0, 39578],
...         [0, 0, 0, 1, 47757]], ZZ)
>>> B, T = X.lll_transform(delta=QQ(5, 6))
>>> T * X == B
True 

See also

lll

lu()

Returns Lower and Upper decomposition of the DomainMatrix

Returns:

(L, U, exchange)

L, U are Lower and Upper decomposition of the DomainMatrix, exchange is the list of indices of rows exchanged in the decomposition.

Raises:

ValueError

If the domain of DomainMatrix not a Field

Examples

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [QQ(1), QQ(-1)],
...    [QQ(2), QQ(-2)]], (2, 2), QQ)
>>> L, U, exchange = A.lu()
>>> L
DomainMatrix([[1, 0], [2, 1]], (2, 2), QQ)
>>> U
DomainMatrix([[1, -1], [0, 0]], (2, 2), QQ)
>>> exchange
[] 

See also

lu_solve

lu_solve(rhs)

Solver for DomainMatrix x in the A*x = B

Parameters:

rhs : DomainMatrix B

Returns:

DomainMatrix

x in A*x = B

Raises:

DMShapeError

If the DomainMatrix A and rhs have different number of rows

ValueError

If the domain of DomainMatrix A not a Field

Examples

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [QQ(1), QQ(2)],
...    [QQ(3), QQ(4)]], (2, 2), QQ)
>>> B = DomainMatrix([
...    [QQ(1), QQ(1)],
...    [QQ(0), QQ(1)]], (2, 2), QQ) 
>>> A.lu_solve(B)
DomainMatrix([[-2, -1], [3/2, 1]], (2, 2), QQ) 

See also

lu

matmul(B)

Performs matrix multiplication of two DomainMatrix matrices

Parameters:

A, B: DomainMatrix

to multiply

Returns:

DomainMatrix

DomainMatrix after multiplication

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([
...    [ZZ(1), ZZ(1)],
...    [ZZ(0), ZZ(1)]], (2, 2), ZZ) 
>>> A.matmul(B)
DomainMatrix([[1, 3], [3, 7]], (2, 2), ZZ) 

See also

mul, pow, add, sub

mul(b)

对第一个 DomainMatrix 进行逐项乘法,返回一个 DomainMatrix,其行是在逐项乘法后创建的 DomainMatrix 矩阵列表。

参数:

A, B:DomainMatrix

逐项乘法的矩阵

返回:

DomainMatrix

逐项乘法后的 DomainMatrix

例子

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> b = ZZ(2) 
>>> A.mul(b)
DomainMatrix([[2, 4], [6, 8]], (2, 2), ZZ) 

另请参阅

matmul

neg()

返回 DomainMatrix 的负值

参数:

A:表示一个 DomainMatrix

返回:

DomainMatrix

否定后的 DomainMatrix

例子

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ) 
>>> A.neg()
DomainMatrix([[-1, -2], [-3, -4]], (2, 2), ZZ) 
nnz()

矩阵中非零元素的数量。

例子

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> A = DM([[1, 0], [0, 4]], ZZ)
>>> A.nnz()
2 
nullspace(divide_last=False)

返回 DomainMatrix 的零空间

参数:

divide_last:bool,可选

如果为 False(默认值),则不对向量进行归一化,并使用rref_den()计算 RREF 并丢弃分母。如果为 True,则每行都除以其最后一个元素;在这种情况下,域必须是一个域。

返回:

DomainMatrix

此矩阵的行形成零空间的基础。

例子

>>> from sympy import QQ
>>> from sympy.polys.matrices import DM
>>> A = DM([
...    [QQ(2), QQ(-2)],
...    [QQ(4), QQ(-4)]], QQ)
>>> A.nullspace()
DomainMatrix([[1, 1]], (1, 2), QQ) 

返回的矩阵是零空间的一组基:

>>> A_null = A.nullspace().transpose()
>>> A * A_null
DomainMatrix([[0], [0]], (2, 1), QQ)
>>> rows, cols = A.shape
>>> nullity = rows - A.rank()
>>> A_null.shape == (cols, nullity)
True 

对于非域环也可以计算零空间。如果环不是域,则不使用除法。在这种情况下将divide_last设置为 True 会引发错误:

>>> from sympy import ZZ
>>> B = DM([[6, -3],
...         [4, -2]], ZZ)
>>> B.nullspace()
DomainMatrix([[3, 6]], (1, 2), ZZ)
>>> B.nullspace(divide_last=True)
Traceback (most recent call last):
...
DMNotAField: Cannot normalize vectors over a non-field 

在具有定义gcd的环上,零空间可能通过primitive()来减少:

>>> B.nullspace().primitive()
(3, DomainMatrix([[1, 2]], (1, 2), ZZ)) 

矩阵在环上通常可以通过转换为域来归一化,但这通常是一个不好的主意:

>>> from sympy.abc import a, b, c
>>> from sympy import Matrix
>>> M = Matrix([[        a*b,       b + c,        c],
...             [      a - b,         b*c,     c**2],
...             [a*b + a - b, b*c + b + c, c**2 + c]])
>>> M.to_DM().domain
ZZ[a,b,c]
>>> M.to_DM().nullspace().to_Matrix().transpose()
Matrix([
[                             c**3],
[            -a*b*c**2 + a*c - b*c],
[a*b**2*c - a*b - a*c + b**2 + b*c]]) 

这里的非标准形式比在整个矩阵中分布一个大分母的标准化形式更好:

>>> M.to_DM().to_field().nullspace(divide_last=True).to_Matrix().transpose()
Matrix([
[                   c**3/(a*b**2*c - a*b - a*c + b**2 + b*c)],
[(-a*b*c**2 + a*c - b*c)/(a*b**2*c - a*b - a*c + b**2 + b*c)],
[                                                          1]]) 

另请参阅

nullspace_from_rref, rref, rref_den, rowspace

nullspace_from_rref(pivots=None)

从 rref 和主元计算零空间。

矩阵的域可以是任何域。

矩阵必须已经处于简化行梯形形式中。否则结果将不正确。首先使用 rref()rref_den() 获取简化行梯形形式,或者使用 nullspace() 替代。

另请参见

nullspace, rref, rref_den, sympy.polys.matrices.sdm.SDM.nullspace_from_rref, sympy.polys.matrices.ddm.DDM.nullspace_from_rref

classmethod ones(shape, domain)

返回一个大小为 shape、属于指定域的 1 的 DomainMatrix

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> DomainMatrix.ones((2,3), QQ)
DomainMatrix([[1, 1, 1], [1, 1, 1]], (2, 3), QQ) 
pow(n)

计算 A**n

参数:

A : DomainMatrix

n : A 的指数

返回:

DomainMatrix

在计算 A**n 上的 DomainMatrix

引发:

NotImplementedError

如果 n 为负数。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(1)],
...    [ZZ(0), ZZ(1)]], (2, 2), ZZ) 
>>> A.pow(2)
DomainMatrix([[1, 2], [0, 1]], (2, 2), ZZ) 

另请参见

matmul

primitive()

将矩阵元素的 gcd 因子分离出来。

在基础域中需要 gcd

示例

>>> from sympy.polys.matrices import DM
>>> from sympy import ZZ
>>> M = DM([[2, 4], [4, 12]], ZZ)
>>> content, M_primitive = M.primitive()
>>> content
2
>>> M_primitive
DomainMatrix([[1, 2], [2, 6]], (2, 2), ZZ)
>>> content * M_primitive == M
True
>>> M_primitive.content() == ZZ(1)
True 

另请参见

content, cancel_denom

rowspace()

返回 DomainMatrix 的行空间

返回:

DomainMatrix

该矩阵的行形成行空间的基础。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [QQ(1), QQ(-1)],
...    [QQ(2), QQ(-2)]], (2, 2), QQ)
>>> A.rowspace()
DomainMatrix([[1, -1]], (1, 2), QQ) 
rref(*, method='auto')

返回简化的行梯形形式(RREF)和主元列表。

如果域不是一个域,则将其转换为一个域。参见 rref_den() 获取返回带分母的简化分数版本的例程。

域必须是一个域,或者具有相关的分数域(参见 to_field())。

参数:

method : str, optional (default: ‘auto’)

计算 RREF 的方法。默认值为 'auto',将尝试选择最快的方法。其他选项包括:

  • A.rref(method='GJ') 使用高斯-约当消元法进行计算。如果定义域不是一个域,则首先会通过 to_field() 转换为域,然后在每行中通过倒置主元素进行 RREF 计算。这对于非常稀疏的矩阵或其元素具有复杂分母的矩阵效率最高。
  • A.rref(method='FF') 使用无分数的高斯-约当消元法。消元过程中使用精确除法(exquo)来控制系数的增长。在此情况下,始终使用当前定义域进行消元,但如果定义域不是一个域,则最终会转换为域并除以分母。对于密集矩阵或具有简单分母的矩阵,效率最高。
  • A.rref(method='CD') 在使用无分数的高斯-约当消元法之前清除分母,适用于具有非常简单分母的密集矩阵。
  • A.rref(method='GJ_dense')A.rref(method='FF_dense')A.rref(method='CD_dense') 与上述方法相同,只是使用了算法的密集实现。默认情况下,A.rref(method='auto') 通常会选择稀疏实现的 RREF。

无论使用哪种算法,返回的矩阵始终具有与输入相同的格式(稀疏或密集),其定义域始终是输入定义域的分数域。

返回:

(DomainMatrix,列表)

DomainMatrix 的行阶梯形式和主元列表。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...     [QQ(2), QQ(-1), QQ(0)],
...     [QQ(-1), QQ(2), QQ(-1)],
...     [QQ(0), QQ(0), QQ(2)]], (3, 3), QQ) 
>>> rref_matrix, rref_pivots = A.rref()
>>> rref_matrix
DomainMatrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]], (3, 3), QQ)
>>> rref_pivots
(0, 1, 2) 

另请参阅

rref_den

带有分母的 RREF

sympy.polys.matrices.sdm.sdm_irref

method='GJ' 的稀疏实现。

sympy.polys.matrices.sdm.sdm_rref_den

method='FF'method='CD' 的稀疏实现。

sympy.polys.matrices.dense.ddm_irref

method='GJ' 的密集实现。

sympy.polys.matrices.dense.ddm_irref_den

method='FF'method='CD' 的密集实现。

clear_denoms

从矩阵中清除分母,被 method='CD' 和在原始定义域不是域时被 method='GJ' 使用。

rref_den(*, method='auto', keep_domain=True)

返回具有分母和主元列表的行阶梯形式。

需要在基域中进行精确除法(exquo)。

参数:

method:str,可选(默认为 'auto')

用于计算 RREF 的方法。默认值为'auto',将尝试选择最快的方法。其他选项包括:

  • A.rref(method='FF') 使用无分数高斯-约当消元。消除过程使用精确除法(exquo)控制系数的增长。在这种情况下,始终使用当前域进行消除,并始终将结果作为当前域上的矩阵返回。对于密集矩阵或具有简单分母的矩阵,这是最有效的。
  • A.rref(method='CD') 在关联环中使用无分数高斯-约当消元前先清除分母。结果将转换回原始域,除非传入keep_domain=False,在这种情况下结果将在消除环中。对于具有非常简单分母的密集矩阵,这是最有效的。
  • A.rref(method='GJ') 使用带有除法的高斯-约当消元。如果域不是一个域,那么首先将其转换为域,通过to_field()进行转换,然后通过倒转每行中的主元素来计算 RREF。结果将通过清除分母转换回原始域,除非传入keep_domain=False,在这种情况下结果将在用于消除的域中。对于非常稀疏的矩阵或其元素具有复杂分母的矩阵,这是最有效的。
  • A.rref(method='GJ_dense')A.rref(method='FF_dense')A.rref(method='CD_dense') 与上述方法相同,只是使用了算法的密集实现。默认情况下,A.rref(method='auto') 通常会选择稀疏实现的 RREF。

无论使用哪种算法,返回的矩阵格式(稀疏或密集)始终与输入相同,如果keep_domain=True,其域将始终与输入相同。

keep_domain : 布尔值,可选

如果为 True(默认值),返回矩阵的域和分母与输入矩阵的域相同。如果为 False,则返回矩阵的域可能会更改为相关的环或域,如果算法使用了不同的域,这对于效率是有益的,例如在A.rref(method='GJ')的情况下,避免了清除分母。

返回:

(域矩阵,标量,列表)

行简化阶梯形式,分母和主元素索引列表。

示例

>>> from sympy import ZZ, QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...     [ZZ(2), ZZ(-1), ZZ(0)],
...     [ZZ(-1), ZZ(2), ZZ(-1)],
...     [ZZ(0), ZZ(0), ZZ(2)]], (3, 3), ZZ) 
>>> A_rref, denom, pivots = A.rref_den()
>>> A_rref
DomainMatrix([[6, 0, 0], [0, 6, 0], [0, 0, 6]], (3, 3), ZZ)
>>> denom
6
>>> pivots
(0, 1, 2)
>>> A_rref.to_field() / denom
DomainMatrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]], (3, 3), QQ)
>>> A_rref.to_field() / denom == A.convert_to(QQ).rref()[0]
True 

另请参阅

rref

域矩阵域的 RREF 不带分母。

sympy.polys.matrices.sdm.sdm_irref

method='GJ' 的稀疏实现。

sympy.polys.matrices.sdm.sdm_rref_den

method='FF'method='CD' 的稀疏实现。

sympy.polys.matrices.dense.ddm_irref

method='GJ' 的密集实现。

sympy.polys.matrices.dense.ddm_irref_den

method='FF'method='CD' 的密集实现。

clear_denoms

清除矩阵的分母,由 method='CD' 使用。

scc()

计算域矩阵的强连通分量

返回:

整数列表的列表

每个列表表示一个强连通分量。

解释

可以将方阵视为有向图的邻接矩阵,其中行和列索引是顶点。在这个图中,如果从顶点 i 到顶点 j 有一条边,则 M[i, j] 不为零。此例程计算该图的强连通分量,这些分量是由矩阵某些非零元素连接的行和列的子集。强连通分量非常有用,因为许多操作如行列式可以通过处理与每个分量对应的子矩阵来计算。

示例

查找矩阵的强连通分量:

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> M = DomainMatrix([[ZZ(1), ZZ(0), ZZ(2)],
...                   [ZZ(0), ZZ(3), ZZ(0)],
...                   [ZZ(4), ZZ(6), ZZ(5)]], (3, 3), ZZ)
>>> M.scc()
[[1], [0, 2]] 

计算组件的行列式:

>>> MM = M.to_Matrix()
>>> MM
Matrix([
[1, 0, 2],
[0, 3, 0],
[4, 6, 5]])
>>> MM[[1], [1]]
Matrix([[3]])
>>> MM[[0, 2], [0, 2]]
Matrix([
[1, 2],
[4, 5]])
>>> MM.det()
-9
>>> MM[[1], [1]].det() * MM[[0, 2], [0, 2]].det()
-9 

组件以逆拓扑顺序给出,并表示行和列的排列,将矩阵转换为块下三角形式:

>>> MM[[1, 0, 2], [1, 0, 2]]
Matrix([
[3, 0, 0],
[0, 1, 2],
[6, 4, 5]]) 

另请参阅

sympy.matrices.matrixbase.MatrixBase.strongly_connected_componentssympy.utilities.iterables.strongly_connected_components

solve_den(b, method=None)

在基域中解决矩阵方程 (Ax = b),不涉及分数。

参数:

selfDomainMatrix

在方程 (Ax = b) 中的 m x n 矩阵 (A)。不支持欠定系统,因此 m >= n:(A) 应为方阵或行数多于列数。

bDomainMatrix

右手边的 n x m 矩阵 (b)。

cpDomainElement 的列表,可选

矩阵(A)的特征多项式。如果未给出,则将使用charpoly()计算。

method: str, optional

用于解决系统的方法。可以是None'charpoly''rref'之一。如果是None(默认值),则方法将自动选择。

charpoly方法使用solve_den_charpoly(),只能在矩阵为方阵时使用。此方法无需除法,可用于任何域。

rref方法是无分数的,但在基域(exquo)中需要精确的除法。这也适用于大多数域。此方法可用于过度确定系统(方程比未知数多)但不能用于不完全确定的系统,因为寻求唯一解。

返回:

(xnum, xden):(DomainMatrix, DomainElement)

方程(Ax = b)的解作为一个对,包括一个n x m矩阵的分子xnum和一个标量分母xden

解(x)由x = xnum / xden给出。无需除法

不变量是A * xnum == xden * b。如果(A)是方阵,则

分母xden将是行列式(det(A))的一个除数。

引发:

DMNonInvertibleMatrixError

如果系统(Ax = b)没有唯一解。

示例

在整数上解矩阵方程:

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> A = DM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], ZZ)
>>> b = DM([[ZZ(5)], [ZZ(6)]], ZZ)
>>> xnum, xden = A.solve_den(b)
>>> xden
-2
>>> xnum
DomainMatrix([[8], [-9]], (2, 1), ZZ)
>>> A * xnum == xden * b
True 

在多项式环上解矩阵方程:

>>> from sympy import ZZ
>>> from sympy.abc import x, y, z, a, b
>>> R = ZZ[x, y, z, a, b]
>>> M = DM([[x*y, x*z], [y*z, x*z]], R)
>>> b = DM([[a], [b]], R)
>>> M.to_Matrix()
Matrix([
[x*y, x*z],
[y*z, x*z]])
>>> b.to_Matrix()
Matrix([
[a],
[b]])
>>> xnum, xden = M.solve_den(b)
>>> xden
x**2*y*z - x*y*z**2
>>> xnum.to_Matrix()
Matrix([
[ a*x*z - b*x*z],
[-a*y*z + b*x*y]])
>>> M * xnum == xden * b
True 

解可以用分数域表示,这将取消分母与分子元素之间的最大公约数:

>>> xsol = xnum.to_field() / xden
>>> xsol.to_Matrix()
Matrix([
[           (a - b)/(x*y - y*z)],
[(-a*z + b*x)/(x**2*z - x*z**2)]])
>>> (M * xsol).to_Matrix() == b.to_Matrix()
True 

在解大型方程组时,此取消步骤可能比solve_den()本身慢得多。解也可以表示为Matrix,而无需尝试分子和分母之间的任何多项式取消,从而更快地给出一个不太简化的结果:

>>> xsol_uncancelled = xnum.to_Matrix() / xnum.domain.to_sympy(xden)
>>> xsol_uncancelled
Matrix([
[ (a*x*z - b*x*z)/(x**2*y*z - x*y*z**2)],
[(-a*y*z + b*x*y)/(x**2*y*z - x*y*z**2)]])
>>> from sympy import cancel
>>> cancel(xsol_uncancelled) == xsol.to_Matrix()
True 

参见

solve_den_charpolysolve_den_rrefinv_den

solve_den_charpoly(b, cp=None, check=True)

使用特征多项式解矩阵方程(Ax = b)。

这种方法通过特征多项式在基域中无需任何除法或分数来解决方阵方程(Ax = b)中的(x)。

参数:

self:DomainMatrix

在方程(Ax = b)中,(A)是一个n x n矩阵。必须是方阵且可逆。

b:DomainMatrix

为 rhs 的n x m矩阵(b)。

cp:列表,可选

矩阵 (A) 的特征多项式(如果已知)。如果未给出,则将使用 charpoly() 计算。

check:bool,可选

如果 True(默认)检查行列式是否不为零,并在其为零时引发错误。如果 False,则如果行列式为零,则返回值将等于 (A.adjugate()*b, 0)

返回:

(xnum, detA):(DomainMatrix,DomainElement)

方程 (Ax = b) 的解作为矩阵分子和标量分母的配对。分母等于 (A) 的行列式,分子是 adj(A)*b

解 (x) 由 x = xnum / detA 给出。分割免费

不变量是 A * xnum == detA * b

如果 b 是单位矩阵,则 xnum 是伴随矩阵

而且我们有 A * adj(A) == detA * I

例子

解整数上的矩阵方程:

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> A = DM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], ZZ)
>>> b = DM([[ZZ(5)], [ZZ(6)]], ZZ)
>>> xnum, detA = A.solve_den_charpoly(b)
>>> detA
-2
>>> xnum
DomainMatrix([[8], [-9]], (2, 1), ZZ)
>>> A * xnum == detA * b
True 

另请参见

solve_den

解决带有分母的矩阵方程的主前端。

solve_den_rref

使用无分数 RREF 解矩阵方程。

inv_den

使用特征多项式反转矩阵。

solve_den_rref(b)

使用无分数 RREF 解矩阵方程 (Ax = b)

解矩阵方程 (Ax = b) 的 (x) 并返回解作为分子/分母对。

例子

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> A = DM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], ZZ)
>>> b = DM([[ZZ(5)], [ZZ(6)]], ZZ)
>>> xnum, xden = A.solve_den_rref(b)
>>> xden
-2
>>> xnum
DomainMatrix([[8], [-9]], (2, 1), ZZ)
>>> A * xnum == xden * b
True 

另请参见

solve_den, solve_den_charpoly

sub(B)

减去相同域的两个 DomainMatrix 矩阵

参数:

A, B: DomainMatrix

矩阵相减

返回:

DomainMatrix

减法后的 DomainMatrix

Raises:

DMShapeError

如果两个 DomainMatrix 的尺寸不相等

ValueError

如果两个 DomainMatrix 的域不相同

例子

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([
...    [ZZ(4), ZZ(3)],
...    [ZZ(2), ZZ(1)]], (2, 2), ZZ) 
>>> A.sub(B)
DomainMatrix([[-3, -1], [1, 3]], (2, 2), ZZ) 

另请参见

add, matmul

to_Matrix()

将 DomainMatrix 转换为矩阵

返回:

矩阵

可变稠密矩阵用于 DomainMatrix

例子

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ) 
>>> A.to_Matrix()
Matrix([
 [1, 2],
 [3, 4]]) 

另请参见

from_Matrix

to_ddm()

返回 selfDDM 表示。

例子

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix({0: {0: 1}, 1: {1: 2}}, (2, 2), QQ)
>>> ddm = A.to_ddm()
>>> ddm
[[1, 0], [0, 2]]
>>> type(ddm)
<class 'sympy.polys.matrices.ddm.DDM'> 

另请参见

to_sdm, to_dense, sympy.polys.matrices.ddm.DDM.to_sdm

to_dense()

返回一个密集的自我域矩阵表示。

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix({0: {0: 1}, 1: {1: 2}}, (2, 2), QQ)
>>> A.rep
{0: {0: 1}, 1: {1: 2}}
>>> B = A.to_dense()
>>> B.rep
[[1, 0], [0, 2]] 
to_dfm()

返回一个DFM表示的自我

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix([[1, 0],[0, 2]], (2, 2), QQ)
>>> dfm = A.to_dfm()
>>> dfm
[[1, 0], [0, 2]]
>>> type(dfm)
<class 'sympy.polys.matrices._dfm.DFM'> 

另请参阅

to_ddm, to_dense, DFM

to_dfm_or_ddm()

返回一个DFMDDM表示的自我

解释

如果地面类型是flint且地面域受到python-flint支持,则可以使用DFM表示。如果可能,此方法将返回一个DFM表示,否则将返回一个DDM表示。

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix([[1, 0],[0, 2]], (2, 2), QQ)
>>> dfm = A.to_dfm_or_ddm()
>>> dfm
[[1, 0], [0, 2]]
>>> type(dfm)  # Depends on the ground domain and ground types
<class 'sympy.polys.matrices._dfm.DFM'> 

另请参阅

to_ddm

总是返回一个DDM表示。

to_dfm

返回一个DFM表示或引发错误。

to_dense

内部转换为DFMDDM

DFM

DFM密集的 FLINT 矩阵表示。

DDM

Python DDM密集域矩阵表示。

to_dod()

DomainMatrix转换为字典格式的字典(dod)。

解释

返回表示矩阵的字典格式的字典。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DM
>>> A = DM([[ZZ(1), ZZ(2), ZZ(0)], [ZZ(3), ZZ(0), ZZ(4)]], ZZ)
>>> A.to_dod()
{0: {0: 1, 1: 2}, 1: {0: 3, 2: 4}}
>>> A.to_sparse() == A.from_dod(A.to_dod(), A.shape, A.domain)
True
>>> A == A.from_dod_like(A.to_dod())
True 

另请参阅

from_dod, from_dod_like, to_dok, to_list, to_list_flat, to_flat_nz, sympy.matrices.matrixbase.MatrixBase.todod

to_dok()

DomainMatrix 转换为键列表(DOK)格式的字典。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(0)],
...    [ZZ(0), ZZ(4)]], (2, 2), ZZ)
>>> A.to_dok()
{(0, 0): 1, (1, 1): 4} 

虽然重构的矩阵始终处于稀疏格式,但可以通过调用 from_dok() 来重建矩阵:

>>> A.to_sparse() == A.from_dok(A.to_dok(), A.shape, A.domain)
True 

另请参见

from_dok, to_list, to_list_flat, to_flat_nz

to_field()

返回一个带有适当字段的 DomainMatrix

返回:

DomainMatrix

带有适当字段的 DomainMatrix

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ) 
>>> A.to_field()
DomainMatrix([[1, 2], [3, 4]], (2, 2), QQ) 
to_flat_nz()

DomainMatrix 转换为非零元素和数据的列表。

解释

返回一个元组 (elements, data),其中 elements 是矩阵元素的列表,可能不包括零。可以通过将这些元素传递给 from_flat_nz() 来重构矩阵。其思想是能够修改元素的平面列表,然后在相同位置创建具有修改元素的相同形状的新矩阵。

data的格式取决于底层表示是密集还是稀疏的,但无论如何它都以一种方式表示列表中元素的位置,from_flat_nz()可以使用这种方式重构矩阵。from_flat_nz()方法应在调用to_flat_nz()的同一个DomainMatrix上调用。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> elements, data = A.to_flat_nz()
>>> elements
[1, 2, 3, 4]
>>> A == A.from_flat_nz(elements, data, A.domain)
True 

创建一个元素翻倍的矩阵:

>>> elements_doubled = [2*x for x in elements]
>>> A2 = A.from_flat_nz(elements_doubled, data, A.domain)
>>> A2 == 2*A
True 

参见

from_flat_nz

to_list()

DomainMatrix转换为列表的列表。

参见

from_list, to_list_flat, to_flat_nz, to_dok

to_list_flat()

DomainMatrix转换为平坦列表。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> A.to_list_flat()
[1, 2, 3, 4] 

参见

from_list_flat, to_list, to_flat_nz, to_dok

to_sdm()

返回selfSDM表示。

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix([[1, 0],[0, 2]], (2, 2), QQ)
>>> sdm = A.to_sdm()
>>> sdm
{0: {0: 1}, 1: {1: 2}}
>>> type(sdm)
<class 'sympy.polys.matrices.sdm.SDM'> 

参见

to_ddm, to_sparse, sympy.polys.matrices.sdm.SDM.to_ddm

to_sparse()

返回self的稀疏 DomainMatrix 表示。

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix([[1, 0],[0, 2]], (2, 2), QQ)
>>> A.rep
[[1, 0], [0, 2]]
>>> B = A.to_sparse()
>>> B.rep
{0: {0: 1}, 1: {1: 2}} 
transpose()

self的矩阵转置

unify(*others, fmt=None)

统一自身和其他矩阵的域和格式。

参数:

others : 域矩阵

fmt: 字符串 ‘dense’, ‘sparse’ 或 None(默认)

如果自身和其他矩阵尚未处于相同格式,则优选转换的格式。如果 (None) 或未指定,则不执行转换。

返回:

Tuple[DomainMatrix]

具有统一域和格式的矩阵

示例

统一具有不同域的 DomainMatrix 的域:

>>> from sympy import ZZ, QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([[ZZ(1), ZZ(2)]], (1, 2), ZZ)
>>> B = DomainMatrix([[QQ(1, 2), QQ(2)]], (1, 2), QQ)
>>> Aq, Bq = A.unify(B)
>>> Aq
DomainMatrix([[1, 2]], (1, 2), QQ)
>>> Bq
DomainMatrix([[1/2, 2]], (1, 2), QQ) 

统一格式(密集或稀疏):

>>> A = DomainMatrix([[ZZ(1), ZZ(2)]], (1, 2), ZZ)
>>> B = DomainMatrix({0:{0: ZZ(1)}}, (2, 2), ZZ)
>>> B.rep
{0: {0: 1}} 
>>> A2, B2 = A.unify(B, fmt='dense')
>>> B2.rep
[[1, 0], [0, 0]] 

另请参阅

convert_to, to_dense, to_sparse

vstack(*B)

垂直堆叠给定的矩阵。

参数:

B: 域矩阵

垂直堆叠的矩阵。

返回:

域矩阵

通过垂直堆叠来进行域矩阵

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix 
>>> A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ)
>>> A.vstack(B)
DomainMatrix([[1, 2], [3, 4], [5, 6], [7, 8]], (4, 2), ZZ) 
>>> C = DomainMatrix([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ)
>>> A.vstack(B, C)
DomainMatrix([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]], (6, 2), ZZ) 

另请参阅

unify

classmethod zeros(shape, domain, *, fmt='sparse')

返回指定域的大小形状的零域矩阵

示例

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> DomainMatrix.zeros((2, 3), QQ)
DomainMatrix({}, (2, 3), QQ) 

DDM 类的模块。

DDM 类是 DomainMatrix 使用的内部表示。DDM 代表 Dense Domain Matrix。DDM 实例使用多项式域(例如 ZZ, QQ 等)中的元素以密集矩阵表示矩阵。

基本用法:

>>> from sympy import ZZ, QQ
>>> from sympy.polys.matrices.ddm import DDM
>>> A = DDM([[ZZ(0), ZZ(1)], [ZZ(-1), ZZ(0)]], (2, 2), ZZ)
>>> A.shape
(2, 2)
>>> A
[[0, 1], [-1, 0]]
>>> type(A)
<class 'sympy.polys.matrices.ddm.DDM'>
>>> A @ A
[[-1, 0], [0, -1]] 

ddm_* 函数设计用于 DDM 和普通列表列表上的操作:

>>> from sympy.polys.matrices.dense import ddm_idet
>>> ddm_idet(A, QQ)
1
>>> ddm_idet([[0, 1], [-1, 0]], QQ)
1
>>> A
[[-1, 0], [0, -1]] 

注意,ddm_idet 在原地修改输入矩阵。建议改用 DDM.det 方法作为友好接口,它会处理矩阵的复制:

>>> B = DDM([[ZZ(0), ZZ(1)], [ZZ(-1), ZZ(0)]], (2, 2), ZZ)
>>> B.det()
1 

通常情况下,不直接使用 DDM,它只是 DomainMatrix 的内部表示的一部分,后者增加了进一步的功能,包括统一域等。

DDM 使用的密集格式是一个元素列表的列表,例如 2x2 单位矩阵类似于 [[1, 0], [0, 1]]。DDM 类本身是 list 的子类,其列表项是普通列表。元素的访问方式如 ddm[i][j],其中 ddm[i] 给出第 i 行,ddm[i][j] 获取该行中第 j 列的元素。子类化 list 使得迭代和索引非常高效。我们不重写 getitem,因为这会失去这种好处。

核心例程由 dense.py 中定义的 ddm_* 函数实现。这些函数旨在能够在矩阵的原始列表列表表示上进行操作,大多数函数都是原地操作。DDM 类负责复制等操作,并且还存储与其元素关联的 Domain 对象。这使得可以实现诸如 A + B 之类的操作,具有域检查和形状检查,使列表列表表示更加友好。

class sympy.polys.matrices.ddm.DDM(rowslist, shape, domain)

基于多项式域元素的密集矩阵

这是一个列表的子类,是一个支持基本矩阵算术+, -, *, **的列表列表包装器。

add(b)

a + b

charpoly()

a 的特征多项式的系数

det()

a 的行列式

classmethod diag(values, domain)

返回一个带有对角线上数值的方形对角矩阵。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import DDM
>>> DDM.diag([ZZ(1), ZZ(2), ZZ(3)], ZZ)
[[1, 0, 0], [0, 2, 0], [0, 0, 3]] 

另请参阅

sympy.polys.matrices.domainmatrix.DomainMatrix.diag

diagonal()

返回矩阵对角线上元素的列表。

classmethod from_dod(dod, shape, domain)

从字典字典(dod)格式创建 DDM

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> dod = {0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}}
>>> A = DDM.from_dod(dod, (2, 2), QQ)
>>> A
[[1, 2], [3, 4]] 

另请参阅

to_dod, sympy.polys.matrices.sdm.SDM.from_dod, sympy.polys.matrices.domainmatrix.DomainMatrix.from_dod

classmethod from_dok(dok, shape, domain)

从字典键(dok)格式创建 DDM

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> dok = {(0, 0): 1, (0, 1): 2, (1, 0): 3, (1, 1): 4}
>>> A = DDM.from_dok(dok, (2, 2), QQ)
>>> A
[[1, 2], [3, 4]] 

另请参阅

to_dok, sympy.polys.matrices.sdm.SDM.from_dok, sympy.polys.matrices.domainmatrix.DomainMatrix.from_dok

classmethod from_flat_nz(elements, data, domain)

在调用 to_flat_nz() 后重构 DDM

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> elements, data = A.to_flat_nz()
>>> elements
[1, 2, 3, 4]
>>> A == DDM.from_flat_nz(elements, data, A.domain)
True 

另请参阅

to_flat_nz, sympy.polys.matrices.sdm.SDM.from_flat_nz, sympy.polys.matrices.domainmatrix.DomainMatrix.from_flat_nz

classmethod from_list(rowslist, shape, domain)

从列表列表创建 DDM

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.ddm import DDM
>>> A = DDM.from_list([[ZZ(0), ZZ(1)], [ZZ(-1), ZZ(0)]], (2, 2), ZZ)
>>> A
[[0, 1], [-1, 0]]
>>> A == DDM([[ZZ(0), ZZ(1)], [ZZ(-1), ZZ(0)]], (2, 2), ZZ)
True 

另请参阅

from_list_flat

classmethod from_list_flat(flat, shape, domain)

从一个扁平元素列表创建 DDM

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.ddm import DDM
>>> A = DDM.from_list_flat([1, 2, 3, 4], (2, 2), QQ)
>>> A
[[1, 2], [3, 4]]
>>> A == DDM.from_list_flat(A.to_list_flat(), A.shape, A.domain)
True 

另请参阅

to_list_flat, sympy.polys.matrices.domainmatrix.DomainMatrix.from_list_flat

hstack(*B)

水平堆叠 DDM 矩阵。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import DDM 
>>> A = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DDM([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ)
>>> A.hstack(B)
[[1, 2, 5, 6], [3, 4, 7, 8]] 
>>> C = DDM([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ)
>>> A.hstack(B, C)
[[1, 2, 5, 6, 9, 10], [3, 4, 7, 8, 11, 12]] 
inv()

a 的逆

is_diagonal()

说这个矩阵是否是对角线的。即使矩阵不是方的,也可以返回 True。

is_lower()

说这个矩阵是否是下三角形的。即使矩阵不是方的,也可以返回 True。

is_upper()

说这个矩阵是否是上三角形的。即使矩阵不是方的,也可以返回 True。

is_zero_matrix()

说这个矩阵是否有全零条目。

iter_items()

迭代矩阵非零元素的索引和值。

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[QQ(1), QQ(0)], [QQ(3), QQ(4)]], (2, 2), QQ)
>>> list(A.iter_items())
[((0, 0), 1), ((1, 0), 3), ((1, 1), 4)] 

参见

iter_valuesto_doksympy.polys.matrices.domainmatrix.DomainMatrix.iter_items

iter_values()

矩阵非零值的迭代器。

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[QQ(1), QQ(0)], [QQ(3), QQ(4)]], (2, 2), QQ)
>>> list(A.iter_values())
[1, 3, 4] 

参见

iter_itemsto_list_flatsympy.polys.matrices.domainmatrix.DomainMatrix.iter_values

lu()

L, U 分解 a

lu_solve(b)

x 其中 a*x = b

matmul(b)

a @ b(矩阵乘积)

neg()

-a

nnz()

DDM 矩阵中的非零条目数。

参见

sympy.polys.matrices.domainmatrix.DomainMatrix.nnz

nullspace()

返回矩阵 a 的零空间的基础。

矩阵的域必须是一个域。

参见

rrefsympy.polys.matrices.domainmatrix.DomainMatrix.nullspace

nullspace_from_rref(pivots=None)

计算矩阵从其 rref 的零空间。

矩阵的域可以是任何域。

返回一个元组(基础,非主元)。

参见

sympy.polys.matrices.domainmatrix.DomainMatrix.nullspace

该函数的更高级接口。

rref()

矩阵 a 的行简化阶梯形式和主元列表。

参见

sympy.polys.matrices.domainmatrix.DomainMatrix.rref

该函数的更高级接口。

sympy.polys.matrices.dense.ddm_irref

底层算法。

rref_den()

矩阵 a 的行简化阶梯形式,带分母和主元列表

参见

sympy.polys.matrices.domainmatrix.DomainMatrix.rref_den

此函数的高级接口。

sympy.polys.matrices.dense.ddm_irref_den

底层算法。

scc()

方阵 a 的强连通分量。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import DDM
>>> A = DDM([[ZZ(1), ZZ(0)], [ZZ(0), ZZ(1)]], (2, 2), ZZ)
>>> A.scc()
[[0], [1]] 

请参阅

sympy.polys.matrices.domainmatrix.DomainMatrix.scc

sub(b)

a - b

to_ddm()

转换为 DDM

仅返回 self,以与其他矩阵类型如 SDM 中对应方法保持一致。

请参阅

to_sdm, to_dfm, to_dfm_or_ddm, sympy.polys.matrices.sdm.SDM.to_ddm, sympy.polys.matrices.domainmatrix.DomainMatrix.to_ddm

to_dfm()

DDM 转换为 DFM

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> A.to_dfm()
[[1, 2], [3, 4]]
>>> type(A.to_dfm())
<class 'sympy.polys.matrices._dfm.DFM'> 

请参阅

DFM, sympy.polys.matrices._dfm.DFM.to_ddm

to_dfm_or_ddm()

如果可能,转换为 DFM,否则返回自身。

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> A.to_dfm_or_ddm()
[[1, 2], [3, 4]]
>>> type(A.to_dfm_or_ddm())
<class 'sympy.polys.matrices._dfm.DFM'> 

请参阅

to_dfm, to_ddm, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dfm_or_ddm

to_dod()

转换为字典的字典(dod)格式。

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> A.to_dod()
{0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}} 

请参阅

from_dod, sympy.polys.matrices.sdm.SDM.to_dod, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dod

to_dok()

DDM 转换为键值对(dok)格式。

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> A.to_dok()
{(0, 0): 1, (0, 1): 2, (1, 0): 3, (1, 1): 4} 

请参阅

from_dok, sympy.polys.matrices.sdm.SDM.to_dok, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dok

to_flat_nz()

转换为非零元素和数据的平坦列表。

解释

该方法用于操作矩阵元素列表,然后使用from_flat_nz()重构矩阵。列表中包括零元素,但将来可能会发生变化。

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> elements, data = A.to_flat_nz()
>>> elements
[1, 2, 3, 4]
>>> A == DDM.from_flat_nz(elements, data, A.domain)
True 

另请参见

from_flat_nz, sympy.polys.matrices.sdm.SDM.to_flat_nz, sympy.polys.matrices.domainmatrix.DomainMatrix.to_flat_nz

to_list()

转换为列表列表。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.ddm import DDM
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> A.to_list()
[[1, 2], [3, 4]] 

另请参见

to_list_flat, sympy.polys.matrices.domainmatrix.DomainMatrix.to_list

to_list_flat()

转换为元素的平坦列表。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.ddm import DDM
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> A.to_list_flat()
[1, 2, 3, 4]
>>> A == DDM.from_list_flat(A.to_list_flat(), A.shape, A.domain)
True 

另请参见

sympy.polys.matrices.domainmatrix.DomainMatrix.to_list_flat

to_sdm()

转换为SDM

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy import QQ
>>> A = DDM([[1, 2], [3, 4]], (2, 2), QQ)
>>> A.to_sdm()
{0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}}
>>> type(A.to_sdm())
<class 'sympy.polys.matrices.sdm.SDM'> 

另请参见

SDM, sympy.polys.matrices.sdm.SDM.to_ddm

vstack(*B)

垂直堆叠DDM矩阵。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import DDM 
>>> A = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DDM([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ)
>>> A.vstack(B)
[[1, 2], [3, 4], [5, 6], [7, 8]] 
>>> C = DDM([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ)
>>> A.vstack(B, C)
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]] 

用于在列表列表矩阵表示中操作矩阵的 ddm_*例程的模块。

这些例程在 DDM 类内部使用,该类还为它们提供了更友好的接口。这里的思路是以一种可以应用于任何简单列表表示的核心矩阵例程的方式实现,而无需使用特定的矩阵类。例如,我们可以计算类似以下矩阵的 RREF:

>>> from sympy.polys.matrices.dense import ddm_irref
>>> M = [[1, 2, 3], [4, 5, 6]]
>>> pivots = ddm_irref(M)
>>> M
[[1.0, 0.0, -1.0], [0, 1.0, 2.0]] 

这些是主要在原地工作的低级例程。这个级别的例程不应该知道元素的域是什么,但最好文档化它们将使用的操作和它们需要提供的函数。

DDM 类是使用这些例程的下一级,但它们包装了一个处理复制等操作的接口,并跟踪矩阵元素的域:

>>> from sympy.polys.domains import QQ
>>> from sympy.polys.matrices.ddm import DDM
>>> M = DDM([[QQ(1), QQ(2), QQ(3)], [QQ(4), QQ(5), QQ(6)]], (2, 3), QQ)
>>> M
[[1, 2, 3], [4, 5, 6]]
>>> Mrref, pivots = M.rref()
>>> Mrref
[[1, 0, -1], [0, 1, 2]] 
class sympy.polys.matrices.dense.R

矩阵元素的类型变量,属于一个环

TypeVar(‘R’, bound=RingElement) 的别名

class sympy.polys.matrices.dense.T

矩阵元素的类型变量

TypeVar(‘T’) 的别名

sympy.polys.matrices.dense.ddm_berk(M, K)

伯克维兹算法用于计算特征多项式。

说明

伯克维兹算法是一个无除法算法,用于计算系数环中任何可交换环上矩阵的特征多项式,只使用算术运算。

示例

>>> from sympy import Matrix
>>> from sympy.polys.matrices.dense import ddm_berk
>>> from sympy.polys.domains import ZZ
>>> M = [[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]]
>>> ddm_berk(M, ZZ)
[[1], [-5], [-2]]
>>> Matrix(M).charpoly()
PurePoly(lambda**2 - 5*lambda - 2, lambda, domain='ZZ') 

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.charpoly

该函数的高级接口。

参考文献

[R775]

en.wikipedia.org/wiki/Samuelson%E2%80%93Berkowitz_algorithm

sympy.polys.matrices.dense.ddm_iadd(a: list[list[R]], b: Sequence[Sequence[R]]) → None

a += b

sympy.polys.matrices.dense.ddm_idet(a, K)

a <– echelon(a); return det

说明

使用无分式的伯莱斯算法计算矩阵 (a) 的行列式。在原地修改矩阵 (a)。其对角线元素是前导主子式的行列式。返回矩阵 (a) 的行列式。

域 (K) 必须支持精确除法 (K.exquo)。这种方法适用于大多数精确环和域,如 ZZ,QQ 和 QQ,但不适用于不精确的域,如 RR 和 CC。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.ddm import ddm_idet
>>> a = [[ZZ(1), ZZ(2), ZZ(3)], [ZZ(4), ZZ(5), ZZ(6)], [ZZ(7), ZZ(8), ZZ(9)]]
>>> a
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> ddm_idet(a, ZZ)
0
>>> a
[[1, 2, 3], [4, -3, -6], [7, -6, 0]]
>>> [a[i][i] for i in range(len(a))]
[1, -3, 0] 

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.det

参考文献

[R776]

en.wikipedia.org/wiki/Bareiss_algorithm

[R777]

www.math.usm.edu/perry/Research/Thesis_DRL.pdf

sympy.polys.matrices.dense.ddm_iinv(ainv, a, K)

ainv <– inv(a)

使用高斯-约旦消元法计算域 (K) 上矩阵 (a) 的逆矩阵。结果存储在 (ainv) 中。

使用基域中的除法,这个域应该是一个精确的域。

示例

>>> from sympy.polys.matrices.ddm import ddm_iinv, ddm_imatmul
>>> from sympy import QQ
>>> a = [[QQ(1), QQ(2)], [QQ(3), QQ(4)]]
>>> ainv = [[None, None], [None, None]]
>>> ddm_iinv(ainv, a, QQ)
>>> ainv
[[-2, 1], [3/2, -1/2]]
>>> result = [[QQ(0), QQ(0)], [QQ(0), QQ(0)]]
>>> ddm_imatmul(result, a, ainv)
>>> result
[[1, 0], [0, 1]] 

另见

ddm_irref

底层程序。

sympy.polys.matrices.dense.ddm_ilu(a)

a <– LU(a)

在原地计算矩阵的 LU 分解。返回执行的行交换列表。

使用基域中的除法,这个域应该是一个精确的域。

这只适用于像 GF(p),QQ,QQ_I 和 QQ 这样的域。对于像 K(x) 这样的有理函数域,最好清除分母并使用无除法的算法。为避免精确零点,使用枢轴选取,但不适用于浮点精度,因此 RR 和 CC 不适合(请使用 ddm_irref() 替代)。

示例

>>> from sympy.polys.matrices.dense import ddm_ilu
>>> from sympy import QQ
>>> a = [[QQ(1, 2), QQ(1, 3)], [QQ(1, 4), QQ(1, 5)]]
>>> swaps = ddm_ilu(a)
>>> swaps
[]
>>> a
[[1/2, 1/3], [1/2, 1/30]] 

The same example using Matrix:

>>> from sympy import Matrix, S
>>> M = Matrix([[S(1)/2, S(1)/3], [S(1)/4, S(1)/5]])
>>> L, U, swaps = M.LUdecomposition()
>>> L
Matrix([
[  1, 0],
[1/2, 1]])
>>> U
Matrix([
[1/2,  1/3],
[  0, 1/30]])
>>> swaps
[] 

See also

ddm_irref, ddm_ilu_solve, sympy.matrices.matrixbase.MatrixBase.LUdecomposition

sympy.polys.matrices.dense.ddm_ilu_solve(x, L, U, swaps, b)

x <– solve(LUx = swaps(b))

Solve a linear system, (A*x = b), given an LU factorization of (A).

Uses division in the ground domain which must be a field.

Modifies (x) in place.

Examples

Compute the LU decomposition of (A) (in place):

>>> from sympy import QQ
>>> from sympy.polys.matrices.dense import ddm_ilu, ddm_ilu_solve
>>> A = [[QQ(1), QQ(2)], [QQ(3), QQ(4)]]
>>> swaps = ddm_ilu(A)
>>> A
[[1, 2], [3, -2]]
>>> L = U = A 

Solve the linear system:

>>> b = [[QQ(5)], [QQ(6)]]
>>> x = [[None], [None]]
>>> ddm_ilu_solve(x, L, U, swaps, b)
>>> x
[[-4], [9/2]] 

See also

ddm_ilu

Compute the LU decomposition of a matrix in place.

ddm_ilu_split

Compute the LU decomposition of a matrix and separate (L) and (U).

sympy.polys.matrices.domainmatrix.DomainMatrix.lu_solve

Higher level interface to this function.

sympy.polys.matrices.dense.ddm_ilu_split(L, U, K)

L, U <– LU(U)

Compute the LU decomposition of a matrix (L) in place and store the lower and upper triangular matrices in (L) and (U), respectively. Returns a list of row swaps that were performed.

Uses division in the ground domain which should be an exact field.

Examples

>>> from sympy.polys.matrices.ddm import ddm_ilu_split
>>> from sympy import QQ
>>> L = [[QQ(0), QQ(0)], [QQ(0), QQ(0)]]
>>> U = [[QQ(1), QQ(2)], [QQ(3), QQ(4)]]
>>> swaps = ddm_ilu_split(L, U, QQ)
>>> swaps
[]
>>> L
[[0, 0], [3, 0]]
>>> U
[[1, 2], [0, -2]] 

See also

ddm_ilu, ddm_ilu_solve

sympy.polys.matrices.dense.ddm_imatmul(a: list[list[R]], b: Sequence[Sequence[R]], c: Sequence[Sequence[R]]) → None

a += b @ c

sympy.polys.matrices.dense.ddm_imul(a: list[list[R]], b: R) → None

a <– a*b

sympy.polys.matrices.dense.ddm_ineg(a: list[list[R]]) → None

a <– -a

sympy.polys.matrices.dense.ddm_irmul(a: list[list[R]], b: R) → None

a <– b*a

sympy.polys.matrices.dense.ddm_irref(a, _partial_pivot=False)

In-place reduced row echelon form of a matrix.

Compute the reduced row echelon form of (a). Modifies (a) in place and returns a list of the pivot columns.

Uses naive Gauss-Jordan elimination in the ground domain which must be a field.

This routine is only really suitable for use with simple field domains like GF(p), QQ and QQ although even for QQ with larger matrices it is possibly more efficient to use fraction free approaches.

This method is not suitable for use with rational function fields (K(x)) because the elements will blowup leading to costly gcd operations. In this case clearing denominators and using fraction free approaches is likely to be more efficient.

For inexact numeric domains like RR and CC pass _partial_pivot=True to use partial pivoting to control rounding errors.

Examples

>>> from sympy.polys.matrices.dense import ddm_irref
>>> from sympy import QQ
>>> M = [[QQ(1), QQ(2), QQ(3)], [QQ(4), QQ(5), QQ(6)]]
>>> pivots = ddm_irref(M)
>>> M
[[1, 0, -1], [0, 1, 2]]
>>> pivots
[0, 1] 

See also

sympy.polys.matrices.domainmatrix.DomainMatrix.rref

Higher level interface to this routine.

ddm_irref_den

这一例程的无分数版本。

sdm_irref

这一例程的稀疏版本。

参考文献

[R778]

en.wikipedia.org/wiki/Row_echelon_form#Reduced_row_echelon_form

sympy.polys.matrices.dense.ddm_irref_den(a, K)

a <– rref(a); 返回 (den, pivots)

计算矩阵 (a) 的无分数化简行阶梯形式(RREF)。直接修改 (a) 并返回一个包含 RREF 分母和主元列列表的元组。

解释

所使用的算法是高斯-约当消元的无分数版本,简称为 FFGJ,见[R779]。这里修改过以处理零或丢失的主元,并避免冗余算术。

域 (K) 必须支持精确的除法(K.exquo),但不需要是一个域。此方法适用于大多数精确的环和域,如 ZZ, QQ 和 QQ。对于 QQ 或 K(x),清除分母并使用 ZZ 或 K[x] 可能更有效。

对于 RR 和 CC 等非精确域,请使用 ddm_irref

示例

>>> from sympy.polys.matrices.dense import ddm_irref_den
>>> from sympy import ZZ, Matrix
>>> M = [[ZZ(1), ZZ(2), ZZ(3)], [ZZ(4), ZZ(5), ZZ(6)]]
>>> den, pivots = ddm_irref_den(M, ZZ)
>>> M
[[-3, 0, 3], [0, -3, -6]]
>>> den
-3
>>> pivots
[0, 1]
>>> Matrix(M).rref()[0]
Matrix([
[1, 0, -1],
[0, 1,  2]]) 

另见

ddm_irref

一种使用场分割的这一例程的版本。

sdm_irref

ddm_irref()的稀疏版本。

sdm_rref_den

ddm_irref_den()的稀疏版本。

sympy.polys.matrices.domainmatrix.DomainMatrix.rref_den

更高级的接口。

参考文献

[R779] (1,2)

线性和多项式方程的无分数算法。George C. Nakos,Peter R. Turner,Robert M. Williams。dl.acm.org/doi/10.1145/271130.271133

sympy.polys.matrices.dense.ddm_isub(a: list[list[R]], b: Sequence[Sequence[R]]) → None

a -= b

sympy.polys.matrices.dense.ddm_transpose(matrix: Sequence[Sequence[T]]) → list[list[T]]

矩阵转置

class sympy.polys.matrices._typing.RingElement(*args, **kwargs)

一个环元素。

必须支持+, -, *, **-

用于 SDM 类的模块。

class sympy.polys.matrices.sdm.SDM(elemsdict, shape, domain)

基于多项式域元素的稀疏矩阵

这是一个字典子类,是一个包装器,支持基本矩阵算术 +, -, *, **

为了创建一个新的SDM,需要一个将非零元素映射到它们在矩阵中相应行和列的字典的字典。

我们还需要指定我们SDM对象的形状和Domain

如下所示,我们声明一个属于 QQ 域的 2x2 SDM 矩阵。示例中的 2x2 矩阵是

[\begin{split}A = \left[\begin{array}{ccc} 0 & \frac{1}{2} \ 0 & 0 \end{array} \right]\end{split}]

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1:QQ(1, 2)}}
>>> A = SDM(elemsdict, (2, 2), QQ)
>>> A
{0: {1: 1/2}} 

我们可以像操作矩阵类一样操作SDM

>>> from sympy import ZZ
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B  = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ)
>>> A + B
{0: {0: 3, 1: 2}, 1: {0: 1, 1: 4}} 

乘法

>>> A*B
{0: {1: 8}, 1: {0: 3}}
>>> A*ZZ(2)
{0: {1: 4}, 1: {0: 2}} 
add(B)

添加两个SDM矩阵

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ)
>>> A.add(B)
{0: {0: 3, 1: 2}, 1: {0: 1, 1: 4}} 
charpoly()

返回SDM矩阵的特征多项式的系数。这些元素将是域元素。元素的域与SDM的域相同。

示例

>>> from sympy import QQ, Symbol
>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy.polys import Poly
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.charpoly()
[1, -5, -2] 

我们可以使用系数创建多项式,使用Poly

>>> x = Symbol('x')
>>> p = Poly(A.charpoly(), x, domain=A.domain)
>>> p
Poly(x**2 - 5*x - 2, x, domain='QQ') 
convert_to(K)

SDM矩阵的Domain转换为 K

示例

>>> from sympy import ZZ, QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.convert_to(QQ)
{0: {1: 2}, 1: {0: 1}} 
copy()

返回SDM对象的副本

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1:QQ(2)}, 1:{}}
>>> A = SDM(elemsdict, (2, 2), QQ)
>>> B = A.copy()
>>> B
{0: {1: 2}, 1: {}} 
det()

返回 A 的行列式

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.det()
-2 
diagonal()

返回矩阵的对角线作为列表。

classmethod eye(shape, domain)

返回指定域大小 x 大小的单位SDM矩阵

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> I = SDM.eye((2, 2), QQ)
>>> I
{0: {0: 1}, 1: {1: 1}} 
classmethod from_ddm(ddm)

DDM创建SDM

示例

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> ddm = DDM( [[QQ(1, 2), 0], [0, QQ(3, 4)]], (2, 2), QQ)
>>> A = SDM.from_ddm(ddm)
>>> A
{0: {0: 1/2}, 1: {1: 3/4}}
>>> SDM.from_ddm(ddm).to_ddm() == ddm
True 

另请参见

to_ddm, from_list, from_list_flat, from_dok

classmethod from_dod(dod, shape, domain)

从字典(dod)格式的字典创建SDM

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> dod = {0: {1: QQ(2)}, 1: {0: QQ(3)}}
>>> A = SDM.from_dod(dod, (2, 2), QQ)
>>> A
{0: {1: 2}, 1: {0: 3}}
>>> A == SDM.from_dod(A.to_dod(), A.shape, A.domain)
True 

另请参见

to_dod, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dod

classmethod from_dok(dok, shape, domain)

从键(dok)格式的字典创建SDM

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> dok = {(0, 1): QQ(2), (1, 0): QQ(3)}
>>> A = SDM.from_dok(dok, (2, 2), QQ)
>>> A
{0: {1: 2}, 1: {0: 3}}
>>> A == SDM.from_dok(A.to_dok(), A.shape, A.domain)
True 

另请参见

to_dok, from_list, from_list_flat, from_ddm

classmethod from_flat_nz(elements, data, domain)

在调用 to_flat_nz() 后重建 SDM

参见 to_flat_nz() 的解释。

参见

to_flat_nz, from_list_flat, sympy.polys.matrices.ddm.DDM.from_flat_nz, sympy.polys.matrices.domainmatrix.DomainMatrix.from_flat_nz

classmethod from_list(ddm, shape, domain)

从列表的列表创建 SDM 对象。

参数:

ddm:

包含域元素的列表的列表

形状:

SDM 矩阵的维度

域:

表示 SDM 对象的 Domain

返回:

包含 ddm 元素的 SDM

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> ddm = [[QQ(1, 2), QQ(0)], [QQ(0), QQ(3, 4)]]
>>> A = SDM.from_list(ddm, (2, 2), QQ)
>>> A
{0: {0: 1/2}, 1: {1: 3/4}} 

参见

to_list, from_list_flat, from_dok, from_ddm

classmethod from_list_flat(elements, shape, domain)

从元素的扁平列表创建 SDM

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM.from_list_flat([QQ(0), QQ(2), QQ(0), QQ(0)], (2, 2), QQ)
>>> A
{0: {1: 2}}
>>> A == A.from_list_flat(A.to_list_flat(), A.shape, A.domain)
True 

参见

to_list_flat, from_list, from_dok, from_ddm

hstack(*B)

水平堆叠 SDM 矩阵。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM 
>>> A = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ)
>>> B = SDM({0: {0: ZZ(5), 1: ZZ(6)}, 1: {0: ZZ(7), 1: ZZ(8)}}, (2, 2), ZZ)
>>> A.hstack(B)
{0: {0: 1, 1: 2, 2: 5, 3: 6}, 1: {0: 3, 1: 4, 2: 7, 3: 8}} 
>>> C = SDM({0: {0: ZZ(9), 1: ZZ(10)}, 1: {0: ZZ(11), 1: ZZ(12)}}, (2, 2), ZZ)
>>> A.hstack(B, C)
{0: {0: 1, 1: 2, 2: 5, 3: 6, 4: 9, 5: 10}, 1: {0: 3, 1: 4, 2: 7, 3: 8, 4: 11, 5: 12}} 
inv()

返回矩阵 A 的逆。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.inv()
{0: {0: -2, 1: 1}, 1: {0: 3/2, 1: -1/2}} 
is_diagonal()

返回此矩阵是否为对角矩阵。即使矩阵不是方阵,也可以返回 True。

is_lower()

判断此矩阵是否为下三角形。即使矩阵不是方阵,也可以返回 True。

is_upper()

判断此矩阵是否为上三角形。即使矩阵不是方阵,也可以返回 True。

is_zero_matrix()

判断此矩阵是否全为零。

iter_items()

遍历非零元素的索引和值。

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> list(A.iter_items())
[((0, 1), 2), ((1, 0), 3)] 

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.iter_items

iter_values()

遍历SDM 矩阵的非零值。

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> list(A.iter_values())
[2, 3] 
lll(delta=MPQ(3, 4))

返回矩阵SDM 的 LLL-简化基础。

lll_transform(delta=MPQ(3, 4))

返回 LLL-简化基础和变换矩阵。

lu()

返回矩阵 A 的 LU 分解

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.lu()
({0: {0: 1}, 1: {0: 3, 1: 1}}, {0: {0: 1, 1: 2}, 1: {1: -2}}, []) 
lu_solve(b)

使用 LU 分解来解 Ax = b,

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> b = SDM({0:{0:QQ(1)}, 1:{0:QQ(2)}}, (2, 1), QQ)
>>> A.lu_solve(b)
{1: {0: 1/2}} 
matmul(B)

执行两个 SDM 矩阵的矩阵乘法

参数:

A, B: SDM 相乘

返回:

SDM

SDM 相乘后

抛出:

域错误

如果 A 的域与 B 的域不匹配

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B = SDM({0:{0:ZZ(2), 1:ZZ(3)}, 1:{0:ZZ(4)}}, (2, 2), ZZ)
>>> A.matmul(B)
{0: {0: 8}, 1: {0: 2, 1: 3}} 
mul(b)

将矩阵 A 的每个元素与标量 b 相乘

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.mul(ZZ(3))
{0: {1: 6}, 1: {0: 3}} 
neg()

返回SDM 矩阵的负数

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.neg()
{0: {1: -2}, 1: {0: -1}} 
classmethod new(sdm, shape, domain)

参数:

sdm: SDM 中非零元素的字典

shape: 表示 SDM 的维度的元组

domain: 表示 SDM 的 :py:class:~.Domain

返回:

一个SDM 对象

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1: QQ(2)}}
>>> A = SDM.new(elemsdict, (2, 2), QQ)
>>> A
{0: {1: 2}} 
nnz()

SDM 矩阵中非零元素的数量。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.nnz()
2 

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.nnz

nullspace()

矩阵SDM A 的零空间。

矩阵的定义必须是一个字段。

最好使用 nullspace() 方法,而不是这个已不再使用的方法。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0: QQ(2), 1: QQ(4)}}, (2, 2), QQ)
>>> A.nullspace()
({0: {0: -2, 1: 1}}, [1]) 

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.nullspace

获取矩阵零空间的首选方法。

nullspace_from_rref(pivots=None)

返回SDM 矩阵 A 的零空间。

矩阵的定义可以是任何定义。

矩阵必须已经处于行阶梯形式(RREF)。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0: QQ(2), 1: QQ(4)}}, (2, 2), QQ)
>>> A_rref, pivots = A.rref()
>>> A_null, nonpivots = A_rref.nullspace_from_rref(pivots)
>>> A_null
{0: {0: -2, 1: 1}}
>>> pivots
[0]
>>> nonpivots
[1] 

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.nullspace

通常应直接调用的高级函数。

sympy.polys.matrices.domainmatrix.DomainMatrix.nullspace_from_rref

这个函数的更高级直接等效。

sympy.polys.matrices.ddm.DDM.nullspace_from_rref

稠密 DDM 矩阵的等效函数。

rref()

返回带有分母和主元列表的 SDM

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(2), 1:QQ(4)}}, (2, 2), QQ)
>>> A.rref()
({0: {0: 1, 1: 2}}, [0]) 
rref_den()

返回行简化阶梯形式 (RREF),带有分母和主元。

示例

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(2), 1:QQ(4)}}, (2, 2), QQ)
>>> A.rref_den()
({0: {0: 1, 1: 2}}, 1, [0]) 
scc()

矩阵 A 的强连通分量。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0: ZZ(2)}, 1:{1:ZZ(1)}}, (2, 2), ZZ)
>>> A.scc()
[[0], [1]] 

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.scc

sub(B)

减去两个 SDM 矩阵

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B  = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ)
>>> A.sub(B)
{0: {0: -3, 1: 2}, 1: {0: 1, 1: -4}} 
to_ddm()

SDM 对象转换为 DDM 对象

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.to_ddm()
[[0, 2], [0, 0]] 
to_dfm()

SDM 对象转换为 DFM 对象

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.to_dfm()
[[0, 2], [0, 0]] 

另见

to_ddm, to_dfm_or_ddm, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dfm

to_dfm_or_ddm()

如果可能,转换为 DFM,否则为 DDM

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.to_dfm_or_ddm()
[[0, 2], [0, 0]]
>>> type(A.to_dfm_or_ddm())  # depends on the ground types
<class 'sympy.polys.matrices._dfm.DFM'> 

另见

to_ddm, to_dfm, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dfm_or_ddm

to_dod()

转换为字典的字典 (dod) 格式。

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> A.to_dod()
{0: {1: 2}, 1: {0: 3}} 

另见

from_dod, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dod

to_dok()

转换为键的字典 (dok) 格式。

示例

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> A.to_dok()
{(0, 1): 2, (1, 0): 3} 

另见

from_dok, to_list, to_list_flat, to_ddm

to_flat_nz()

SDM转换为非零元素和数据的平坦列表。

解释

用于操作矩阵元素列表,然后使用from_flat_nz()在相同位置重构修改后的矩阵。列表中省略了零元素。

例子

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{0: QQ(3)}}, (2, 2), QQ)
>>> elements, data = A.to_flat_nz()
>>> elements
[2, 3]
>>> A == A.from_flat_nz(elements, data, A.domain)
True 

参见

from_flat_nz, to_list_flat, sympy.polys.matrices.ddm.DDM.to_flat_nz, sympy.polys.matrices.domainmatrix.DomainMatrix.to_flat_nz

to_list()

将一个SDM对象转换为一个列表的列表。

例子

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1:QQ(2)}, 1:{}}
>>> A = SDM(elemsdict, (2, 2), QQ)
>>> A.to_list()
[[0, 2], [0, 0]] 
to_list_flat()

SDM转换为平坦列表。

例子

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{0: QQ(3)}}, (2, 2), QQ)
>>> A.to_list_flat()
[0, 2, 3, 0]
>>> A == A.from_list_flat(A.to_list_flat(), A.shape, A.domain)
True 

参见

from_list_flat, to_list, to_dok, to_ddm

to_sdm()

SDM格式转换为自身。

transpose()

返回一个SDM矩阵的转置。

例子

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.transpose()
{1: {0: 2}} 
vstack(*B)

垂直堆叠SDM矩阵。

例子

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM 
>>> A = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ)
>>> B = SDM({0: {0: ZZ(5), 1: ZZ(6)}, 1: {0: ZZ(7), 1: ZZ(8)}}, (2, 2), ZZ)
>>> A.vstack(B)
{0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}, 2: {0: 5, 1: 6}, 3: {0: 7, 1: 8}} 
>>> C = SDM({0: {0: ZZ(9), 1: ZZ(10)}, 1: {0: ZZ(11), 1: ZZ(12)}}, (2, 2), ZZ)
>>> A.vstack(B, C)
{0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}, 2: {0: 5, 1: 6}, 3: {0: 7, 1: 8}, 4: {0: 9, 1: 10}, 5: {0: 11, 1: 12}} 
classmethod zeros(shape, domain)

返回指定域的大小为形状的SDM

在下面的示例中,我们声明一个矩阵 A,其中,

[\begin{split}A := \left[\begin{array}{ccc} 0 & 0 & 0 \ 0 & 0 & 0 \end{array} \right]\end{split}]

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM.zeros((2, 3), QQ)
>>> A
{} 
sympy.polys.matrices.sdm.sdm_berk(M, n, K)

用于计算特征多项式的伯克维兹算法。

解释

伯克维兹算法是一种在任何可交换环上计算矩阵特征多项式的无除算法,仅使用系数环中的算术运算。该实现适用于以字典格式表示的稀疏矩阵(例如SDM)。

例子

>>> from sympy import Matrix
>>> from sympy.polys.matrices.sdm import sdm_berk
>>> from sympy.polys.domains import ZZ
>>> M = {0: {0: ZZ(1), 1:ZZ(2)}, 1: {0:ZZ(3), 1:ZZ(4)}}
>>> sdm_berk(M, 2, ZZ)
{0: 1, 1: -5, 2: -2}
>>> Matrix([[1, 2], [3, 4]]).charpoly()
PurePoly(lambda**2 - 5*lambda - 2, lambda, domain='ZZ') 

参见

sympy.polys.matrices.domainmatrix.DomainMatrix.charpoly

调用此函数的高级接口。

sympy.polys.matrices.dense.ddm_berk

此函数的密集版。

参考文献

[R780]

en.wikipedia.org/wiki/Samuelson%E2%80%93Berkowitz_algorithm

sympy.polys.matrices.sdm.sdm_irref(A)

矩阵A的 RREF 和主元。

计算矩阵A的行阶梯形式(RREF),并返回主元列的列表。此例程不在原地工作,保持原矩阵A不变。

矩阵的域必须是一个域。

示例

此例程适用于字典表示的稀疏矩阵:

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import sdm_irref
>>> A = {0: {0: QQ(1), 1: QQ(2)}, 1: {0: QQ(3), 1: QQ(4)}}
>>> Arref, pivots, _ = sdm_irref(A)
>>> Arref
{0: {0: 1}, 1: {1: 1}}
>>> pivots
[0, 1] 

MutableDenseMatrix类似的计算会是

>>> from sympy import Matrix
>>> M = Matrix([[1, 2], [3, 4]])
>>> Mrref, pivots = M.rref()
>>> Mrref
Matrix([
[1, 0],
[0, 1]])
>>> pivots
(0, 1) 

注释

此算法的成本完全由矩阵中非零元素决定。在该算法的任何步骤中,成本都不依赖于矩阵的行数或列数。甚至不依赖于非零行数,除了主要的循环。该实现比稀疏矩阵的 ddm_rref 快得多。事实上,甚至在输入为完全密集矩阵时,它也比密集实现稍微快一些,因此似乎在所有情况下都更快。

矩阵的元素应支持精确的除法,例如任何域(如QQ)的元素都应该没问题。不尝试处理不精确的算术。

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.rref

通常用来调用此例程的高级函数。

sympy.polys.matrices.dense.ddm_irref

这个例程的密集版。

sdm_rref_den

这个例程的无分数版本。

sympy.polys.matrices.sdm.sdm_nullspace_from_rref(A, one, ncols, pivots, nonzero_cols)

A中获取处于 RREF 中的零空间

sympy.polys.matrices.sdm.sdm_particular_from_rref(A, ncols, pivots)

A中获取处于 RREF 中的特定解

sympy.polys.matrices.sdm.sdm_rref_den(A, K)

返回矩阵A的行阶梯形式(RREF)和分母。

使用无分数的高斯-约旦消元计算 RREF。

解释

所用算法是高斯-约旦消元的无分数版本,被描述为 FFGJ,详见[R781]。这里对其进行了修改,以处理零或缺失的主元,并避免冗余运算。此实现还针对稀疏矩阵进行了优化。

域(K)必须支持精确除法(K.exquo),但不必是一个字段。对大多数精确环和类似 ZZ、QQ 和 QQ的域来说,此方法是合适的。在 QQ 或 K(x)的情况下,清除分母并使用 ZZ 或K[x]可能更有效。

对于 RR 和 CC 等不精确域,请改用ddm_irref

示例

>>> from sympy.polys.matrices.sdm import sdm_rref_den
>>> from sympy.polys.domains import ZZ
>>> A = {0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}
>>> A_rref, den, pivots = sdm_rref_den(A, ZZ)
>>> A_rref
{0: {0: -2}, 1: {1: -2}}
>>> den
-2
>>> pivots
[0, 1] 

另见

sympy.polys.matrices.matrices.domainmatrix.DomainMatrix.rref_den

sdm_rref_den的高级接口,通常用于直接调用此函数的情况下。

sympy.polys.matrices.sdm.sdm_rref_den

使用这个函数的SDM方法。

sdm_irref

使用字段除法计算 RREF。

ddm_irref_den

此算法的稠密版本。

参考

[R781] (1,2)

线性和多项式方程的无分数算法。George C. Nakos,Peter R. Turner,Robert M. Williams。dl.acm.org/doi/10.1145/271130.271133

class sympy.polys.matrices._dfm.DFM(rowslist, shape, domain)

稠密的 FLINT 矩阵。这个类是 Python-FLINT 中矩阵的包装器。

>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.matrices.dfm import DFM
>>> dfm = DFM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.rep
[1, 2]
[3, 4]
>>> type(dfm.rep)  
<class 'flint._flint.fmpz_mat'> 

通常情况下,DFM 类不会直接实例化,而是作为DomainMatrix的内部表示创建。当(SYMPY_GROUND_TYPES)设置为(flint)并安装了(python-flint)时,如果域受到 python-flint 支持,将自动使用DFM类作为DomainMatrix的稠密格式内部表示。

>>> from sympy.polys.matrices.domainmatrix import DM
>>> dM = DM([[1, 2], [3, 4]], ZZ)
>>> dM.rep
[[1, 2], [3, 4]] 

通过调用to_dfm()方法,DomainMatrix可以转换为DFM

>>> dM.to_dfm()
[[1, 2], [3, 4]] 
add(other)

添加两个 DFM 矩阵。

applyfunc(func, domain)

对 DFM 矩阵的每个条目应用函数。

charpoly()

使用 FLINT 计算矩阵的特征多项式。

示例

>>> from sympy import Matrix
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm()  # need ground types = 'flint'
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.charpoly()
[1, -5, -2] 

注意事项

调用底层 FLINT 矩阵的.charpoly()方法。

对于 ZZ 或 QQ,这将分别调用fmpz_mat_charpolyfmpq_mat_charpoly

在编写时,fmpq_mat_charpoly清除整个矩阵的分母,然后调用fmpz_mat_charpoly。特征多项式的系数然后乘以分母的幂。

fmpz_mat_charpoly方法使用带有 CRT 重建的模块化算法。模块化算法使用nmod_mat_charpoly,它对小矩阵和非素数模或者 Danilevsky 方法。

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.charpoly

更高级的接口来计算矩阵的特征多项式。

convert_to(domain)

转换到新的域。

copy()

返回 self 的副本。

det()

使用 FLINT 计算矩阵的行列式。

示例

>>> from sympy import Matrix
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm()
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.det()
-2 

注意

调用底层 FLINT 矩阵的.det()方法。

对于 ZZ 或 QQ,分别调用fmpz_mat_detfmpq_mat_det

在编写时,fmpz_mat_det的实现根据矩阵的大小和条目的比特大小使用多种算法。使用的算法有:

  • 对于非常小的矩阵(最多 4x4),伴随矩阵。

  • 小矩阵(最多 25x25)的 Bareiss 算法。

  • 对于较大的矩阵(最多 60x60)或具有大比特大小的较大矩阵的模块化算法。

  • 对于更大的矩阵(60x60 及以上),如果比特大小小于矩阵的尺寸,则采用模块化的“加速”方法。

fmpq_mat_det的实现从每行清除分母(而不是整个矩阵),然后调用fmpz_mat_det并除以分母的乘积。

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.det

更高级的接口来计算矩阵的行列式。

classmethod diag(elements, domain)

返回对角矩阵。

diagonal()

返回 DFM 矩阵的对角线。

extract(rowslist, colslist)

提取子矩阵。

extract_slice(rowslice, colslice)

切片一个 DFM。

classmethod eye(n, domain)

返回大小为 n 的单位矩阵。

classmethod from_ddm(ddm)

从 DDM 转换。

classmethod from_dod(dod, shape, domain)

to_dod()的逆运算。

classmethod from_dok(dok, shape, domain)

to_dod的逆运算。

classmethod from_flat_nz(elements, data, domain)

to_flat_nz()的逆运算。

classmethod from_list(rowslist, shape, domain)

从嵌套列表构造。

classmethod from_list_flat(elements, shape, domain)

to_list_flat()的逆运算。

getitem(i, j)

获取(i, j)位置的条目。

hstack(*others)

水平堆叠矩阵。

inv()

使用 FLINT 计算矩阵的逆。

示例

>>> from sympy import Matrix, QQ
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm().convert_to(QQ)
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.inv()
[[-2, 1], [3/2, -1/2]]
>>> dfm.matmul(dfm.inv())
[[1, 0], [0, 1]] 

注意

调用底层 FLINT 矩阵的.inv()方法。

目前,如果域是 ZZ,这将引发错误,但将使用 QQ 的 FLINT 方法。

对于 ZZ 和 QQ,FLINT 方法分别是 fmpz_mat_invfmpq_mat_invfmpz_mat_inv 方法计算带有分母的逆矩阵。这是通过调用 fmpz_mat_solve 实现的(有关算法的说明,请参见 lu_solve() 中的注释)。

fmpq_mat_inv 方法会从每行清除分母,然后将其乘到 rhs 单位矩阵中,最后调用 fmpz_mat_solve

另请参见

sympy.polys.matrices.domainmatrix.DomainMatrix.inv

计算矩阵的逆的更高级方法。

is_diagonal()

如果矩阵是对角的,则返回 True

is_lower()

如果矩阵是下三角形,则返回 True

is_upper()

如果矩阵是上三角形,则返回 True

is_zero_matrix()

如果矩阵是零矩阵,则返回 True

iter_items()

迭代矩阵非零元素的索引和值。

iter_values()

迭代矩阵的非零值。

lll(delta=0.75)

使用 FLINT 计算 LLL 简化基。

有关更多信息,请参阅 lll_transform()

示例

>>> from sympy import Matrix
>>> M = Matrix([[1, 2, 3], [4, 5, 6]])
>>> M.to_DM().to_dfm().lll()
[[2, 1, 0], [-1, 1, 3]] 

另请参见

sympy.polys.matrices.domainmatrix.DomainMatrix.lll

更高级的接口,用于计算 LLL 简化基。

lll_transform

计算 LLL 简化基和变换矩阵。

lll_transform(delta=0.75)

使用 FLINT 计算 LLL 简化基和变换。

示例

>>> from sympy import Matrix
>>> M = Matrix([[1, 2, 3], [4, 5, 6]]).to_DM().to_dfm()
>>> M_lll, T = M.lll_transform()
>>> M_lll
[[2, 1, 0], [-1, 1, 3]]
>>> T
[[-2, 1], [3, -1]]
>>> T.matmul(M) == M_lll
True 

另请参见

sympy.polys.matrices.domainmatrix.DomainMatrix.lll

更高级的接口,用于计算 LLL 简化基。

lll

计算 LLL 简化基,不包括变换矩阵。

lu()

返回矩阵的 LU 分解。

lu_solve(rhs)

使用 FLINT 解矩阵方程。

示例

>>> from sympy import Matrix, QQ
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm().convert_to(QQ)
>>> dfm
[[1, 2], [3, 4]]
>>> rhs = Matrix([1, 2]).to_DM().to_dfm().convert_to(QQ)
>>> dfm.lu_solve(rhs)
[[0], [1/2]] 

注释

调用底层 FLINT 矩阵的 .solve() 方法。

目前,如果域是 ZZ,则会引发错误,但会使用 QQ 的 FLINT 方法。

对于 ZZ 和 QQ,FLINT 方法分别是 fmpz_mat_solvefmpq_mat_solvefmpq_mat_solve 方法使用其中两种算法之一:

  • 对于小矩阵(<25 行),它会在矩阵和 rhs 之间清除分母,并使用 fmpz_mat_solve

  • 对于较大的矩阵,它使用 fmpq_mat_solve_dixon,这是一种在 QQ 上的模块化方法,带有 CRT 重构。

fmpz_mat_solve 方法使用其中四种算法之一:

  • 对于非常小(<= 3x3)的矩阵,它使用克莱姆法则。

  • 对于小型(<= 15x15)矩阵,它使用无分数 LU 解法。

  • 否则,它使用迪克森法或其他多模块方法。

另见

sympy.polys.matrices.domainmatrix.DomainMatrix.lu_solve

解决矩阵方程的高级接口。

matmul(other)

两个 DFM 矩阵相乘。

mul(other)

将 DFM 矩阵从右侧乘以一个标量。

mul_elementwise(other)

两个 DFM 矩阵的逐元素乘法。

neg()

反转一个 DFM 矩阵。

nnz()

返回矩阵中非零元素的数量。

nullspace()

返回矩阵的零空间的基。

nullspace_from_rref(pivots=None)

返回矩阵的零空间的基。

classmethod ones(shape, domain)

返回一个单位 DFM 矩阵。

particular()

返回系统的特定解。

rmul(other)

将 DFM 矩阵从左侧乘以一个标量。

scc()

返回矩阵的强连通分量。

setitem(i, j, value)

设置第(i, j)个条目。

sub(other)

减去两个 DFM 矩阵。

to_ddm()

转换为 DDM。

to_dfm()

返回自身。

to_dfm_or_ddm()

转换为DFM

DFM方法存在于DDMSDM方法的并行之中。对于DFM,它将始终返回自身。

另见

to_ddm, to_sdm, sympy.polys.matrices.domainmatrix.DomainMatrix.to_dfm_or_ddm

to_dod()

转换为 DOD。

to_dok()

转换为 DOK。

to_flat_nz()

转换为非零的扁平列表。

to_list()

转换为嵌套列表。

to_list_flat()

转换为扁平列表。

to_sdm()

转换为 SDM。

transpose()

转置一个 DFM 矩阵。

vstack(*others)

垂直堆叠矩阵。

classmethod zeros(shape, domain)

返回一个零的 DFM 矩阵。

sympy.polys.matrices.normalforms.smith_normal_form(m)

返回矩阵(m)在环(domain)上的 Smith 正规形式。仅当环是主理想域时才起作用。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.polys.matrices.normalforms import smith_normal_form
>>> m = DomainMatrix([[ZZ(12), ZZ(6), ZZ(4)],
...                   [ZZ(3), ZZ(9), ZZ(6)],
...                   [ZZ(2), ZZ(16), ZZ(14)]], (3, 3), ZZ)
>>> print(smith_normal_form(m).to_Matrix())
Matrix([[1, 0, 0], [0, 10, 0], [0, 0, -30]]) 
sympy.polys.matrices.normalforms.hermite_normal_form(A, *, D=None, check_rank=False)

计算DomainMatrix A 在 ZZ 上的 Hermite 正规形式。

参数:

A:(m \times n)在 ZZ 上的DomainMatrix

D:ZZ,可选

设(W)为A的 HNF。如果预先已知,可以提供任意多个(\det(W))的正整数D。在这种情况下,如果A也具有秩(m),那么我们可以使用一个工作于模D下的替代算法,以防止系数爆炸。

check_rank:布尔值,可选(默认为 False)

基本假设是,如果你为D传递了一个值,那么你已经相信A的秩为(m),因此我们不会浪费时间为你检查它。如果你确实希望进行检查(并且在检查失败时使用普通的、非模D算法),请将check_rank设置为True

返回:

DomainMatrix

矩阵 A 的 HNF。

引发:

DMDomainError

如果矩阵的域不是 ZZ,或者给定的 D 不在 ZZ 中。

DMShapeError

如果使用模 D 算法但矩阵的行数大于列数。

示例

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.polys.matrices.normalforms import hermite_normal_form
>>> m = DomainMatrix([[ZZ(12), ZZ(6), ZZ(4)],
...                   [ZZ(3), ZZ(9), ZZ(6)],
...                   [ZZ(2), ZZ(16), ZZ(14)]], (3, 3), ZZ)
>>> print(hermite_normal_form(m).to_Matrix())
Matrix([[10, 0, 2], [0, 15, 3], [0, 0, 2]]) 

参考文献

[R782]

Cohen, H. 计算代数数论课程. (参见算法 2.4.5 和 2.4.8.)

posted @ 2024-06-27 17:15  绝不原创的飞龙  阅读(2)  评论(0编辑  收藏  举报