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

128 阅读38分钟

SymPy 1.13 中文文档(十七)

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

求解器

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

本模块文档详细介绍了 sympy.solvers 模块的函数。

内容

  • 丢番图方程

  • 不等式求解器

  • 常微分方程

  • 偏微分方程

  • 求解器

  • 解集

丢番图

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

注意

对于初学者的指南,重点在解决丢番图方程上,请参阅 代数解丢番图方程。

丢番图方程

“丢番图”一词源自于数学家丢番奴,他大约生活在公元 250 年左右的亚历山大大城市。他在其著作《算术》中提出了 150 个问题,标志着数论的早期发展,即关于整数及其性质的研究领域。丢番图方程在数论中起着核心和重要的作用。

我们称“丢番图方程”为形如 (f(x_1, x_2, \ldots x_n) = 0) 的方程,其中 (n \geq 2) 且 (x_1, x_2, \ldots x_n) 是整数变量。如果我们能找到 (n) 个整数 (a_1, a_2, \ldots a_n) 使得 (x_1 = a_1, x_2 = a_2, \ldots x_n = a_n) 满足上述方程,则称该方程可解。您可以在 [1][2] 中了解更多关于丢番图方程的信息。

目前,diophantine() 及其它丢番图模块的辅助函数可以解决以下五种类型的丢番图方程。

  • 线性丢番图方程:(a_1x_1 + a_2x_2 + \ldots + a_nx_n = b).

  • 一般二元二次方程:(ax² + bxy + cy² + dx + ey + f = 0)

  • 齐次三元二次方程:(ax² + by² + cz² + dxy + eyz + fzx = 0)

  • 扩展勾股定理方程:(a_{1}x_{1}² + a_{2}x_{2}² + \ldots + a_{n}x_{n}² = a_{n+1}x_{n+1}²)

  • 一般平方和:(x_{1}² + x_{2}² + \ldots + x_{n}² = k)

模块结构

这个模块包含 diophantine() 函数及其它辅助函数,用于解决特定的丢番图方程。其结构如下所示。

  • diophantine()

    • diop_solve()

      • classify_diop()

      • diop_linear()

      • diop_quadratic()

      • diop_ternary_quadratic()

      • diop_ternary_quadratic_normal()

      • diop_general_pythagorean()

      • diop_general_sum_of_squares()

      • diop_general_sum_of_even_powers()

    • merge_solution()

当方程被传递给diophantine()时,它会因式分解该方程(如果可能),并通过分别调用diop_solve()解决每个因子给出的方程。然后,所有结果都使用merge_solution()组合起来。

diop_solve()在内部使用classify_diop()来找到给定给它的方程的类型(以及其他一些细节),然后根据返回的类型调用适当的求解器函数。例如,如果classify_diop()返回方程的类型为“线性”,那么diop_solve()会调用diop_linear()来解决该方程。

每个函数,diop_linear(), diop_quadratic(), diop_ternary_quadratic(), diop_general_pythagorean()diop_general_sum_of_squares() 都解决特定类型的方程,根据名称可以轻易猜出类型。

除了这些函数外,“Diophantine Module”中还有大量其他函数,所有这些函数都列在用户函数和内部函数下。

教程

首先,让我们导入丢番图模块的最高级 API。

>>> from sympy.solvers.diophantine import diophantine 

在我们开始解决方程之前,我们需要定义变量。

>>> from sympy import symbols
>>> x, y, z = symbols("x, y, z", integer=True) 

让我们从解决最简单类型的丢番图方程开始,即线性丢番图方程。让我们解决 (2x + 3y = 5)。请注意,尽管我们以上述形式编写方程,但当我们将方程输入到丢番图模块中的任何函数时,它需要是 (eq = 0) 的形式。

>>> diophantine(2*x + 3*y - 5)
{(3*t_0 - 5, 5 - 2*t_0)} 

请注意,再往下一级,我们可以通过调用 diop_solve() 解决完全相同的方程。

>>> from sympy.solvers.diophantine.diophantine import diop_solve
>>> diop_solve(2*x + 3*y - 5)
(3*t_0 - 5, 5 - 2*t_0) 

请注意,它返回的是元组而不是集合。diophantine() 总是返回一组元组。但是,diop_solve() 可能根据给定方程的类型返回单个元组或一组元组。

我们还可以通过调用 diop_linear() 来解决这个方程,这是 diop_solve() 内部调用的函数。

>>> from sympy.solvers.diophantine.diophantine import diop_linear
>>> diop_linear(2*x + 3*y - 5)
(3*t_0 - 5, 5 - 2*t_0) 

如果给定方程没有解,则输出如下所示。

>>> diophantine(2*x + 4*y - 3)
set()
>>> diop_solve(2*x + 4*y - 3)
(None, None)
>>> diop_linear(2*x + 4*y - 3)
(None, None) 

请注意,除了最高级 API 外,如果没有解决方案,则返回一个 None 元组。元组的大小与变量数相同。此外,可以通过传递定制参数来设置解决方案中要使用的参数。考虑以下示例:

>>> m = symbols("m", integer=True)
>>> diop_solve(2*x + 3*y - 5, m)
(3*m_0 - 5, 5 - 2*m_0) 

对于线性丢番图方程,解决方案中每个自由变量的前缀都是定制参数。考虑以下示例:

>>> diop_solve(2*x + 3*y - 5*z + 7, m)
(m_0, m_0 + 5*m_1 - 14, m_0 + 3*m_1 - 7) 

在上述解中,(m_0) 和 (m_1) 是独立的自由变量。

请注意,目前用户只能为线性丢番图方程和二元二次方程设置参数。

让我们尝试解决一个二元二次方程,这是一个具有两个变量且二次度的方程。在尝试解决这些方程之前,了解与方程相关的各种情况会很有帮助。请参考[3][4]以获取关于不同情况和解的详细分析。让我们定义 (\Delta = b² - 4ac) 关于二元二次方程 (ax² + bxy + cy² + dx + ey + f = 0)。

当 (\Delta < 0) 时,要么没有解,要么只有有限个解。

>>> diophantine(x**2 - 4*x*y + 8*y**2 - 3*x + 7*y - 5)
{(2, 1), (5, 1)} 

在上述方程中 (\Delta = (-4)² - 418 = -16),因此只有有限个解存在。

当 (\Delta = 0) 时,我们可能没有解,或者有参数化的解。

>>> diophantine(3*x**2 - 6*x*y + 3*y**2 - 3*x + 7*y - 5)
set()
>>> diophantine(x**2 - 4*x*y + 4*y**2 - 3*x + 7*y - 5)
{(-2*t**2 - 7*t + 10, -t**2 - 3*t + 5)}
>>> diophantine(x**2 + 2*x*y + y**2 - 3*x - 3*y)
{(t_0, -t_0), (t_0, 3 - t_0)} 

最有趣的情况是当 (\Delta > 0) 且不是完全平方时。在这种情况下,方程要么没有解,要么有无限多个解。考虑下面 (\Delta = 8) 的情况。

>>> diophantine(x**2 - 4*x*y + 2*y**2 - 3*x + 7*y - 5)
set()
>>> from sympy import sqrt
>>> n = symbols("n", integer=True)
>>> s = diophantine(x**2 -  2*y**2 - 2*x - 4*y, n)
>>> x_1, y_1 = s.pop()
>>> x_2, y_2 = s.pop()
>>> x_n = -(-2*sqrt(2) + 3)**n/2 + sqrt(2)*(-2*sqrt(2) + 3)**n/2 - sqrt(2)*(2*sqrt(2) + 3)**n/2 - (2*sqrt(2) + 3)**n/2 + 1
>>> x_1 == x_n or x_2 == x_n
True
>>> y_n = -sqrt(2)*(-2*sqrt(2) + 3)**n/4 + (-2*sqrt(2) + 3)**n/2 + sqrt(2)*(2*sqrt(2) + 3)**n/4 + (2*sqrt(2) + 3)**n/2 - 1
>>> y_1 == y_n or y_2 == y_n
True 

这里 (n) 是整数。虽然 (x_n) 和 (y_n) 看起来可能不像整数,但是通过设置特定的 (n) 值(并简化)可以证明它们是整数。例如,考虑下面的例子,我们将 (n) 设为 9。

>>> from sympy import simplify
>>> simplify(x_n.subs({n: 9}))
-9369318 

任何形如 (ax² + bxy + cy² + dx + ey + f = 0) 的二元二次方程都可以转换成等价形式 (X² - DY² = N)。

>>> from sympy.solvers.diophantine.diophantine import find_DN, diop_DN, transformation_to_DN
>>> find_DN(x**2 - 3*x*y + y**2 - 7*x + 5*y - 3)
(5, 920) 

因此,上述方程在线性变换后等价于方程 (X² - 5Y² = 920)。如果我们想找到线性变换,我们可以使用 transformation_to_DN()

>>> A, B = transformation_to_DN(x**2 - 3*x*y + y**2 - 7*x + 5*y - 3) 

这里的 (A) 是一个 2 X 2 矩阵,(B) 是一个 2 X 1 矩阵,这样变换

[\begin{split}\begin{bmatrix} X\Y \end{bmatrix} = A \begin{bmatrix} x\y \end{bmatrix} + B\end{split}]

给出方程 (X² -5Y² = 920)。(A) 和 (B) 的值如下。

>>> A
Matrix([
[1/10, 3/10],
[   0,  1/5]])
>>> B
Matrix([
[  1/5],
[-11/5]]) 

我们可以通过将 (D) 和 (N) 传递给 diop_DN() 来解决形如 (X² - DY² = N) 的方程。

>>> diop_DN(5, 920)
[] 

不幸的是,我们的方程没有解。

现在让我们转向齐次三元二次方程。这些方程的形式为 (ax² + by² + cz² + dxy + eyz + fzx = 0)。这类方程要么有无限多个解,要么没有解(除了显然的解(0, 0, 0))。

>>> diophantine(3*x**2 + 4*y**2 - 5*z**2 + 4*x*y + 6*y*z + 7*z*x)
{(0, 0, 0)}
>>> diophantine(3*x**2 + 4*y**2 - 5*z**2 + 4*x*y - 7*y*z + 7*z*x)
{(-16*p**2 + 28*p*q + 20*q**2, 3*p**2 + 38*p*q - 25*q**2, 4*p**2 - 24*p*q + 68*q**2)} 

如果您只对基本解感兴趣,而不是参数化的一般解(更准确地说是一般解之一),您可以使用 diop_ternary_quadratic()

>>> from sympy.solvers.diophantine.diophantine import diop_ternary_quadratic
>>> diop_ternary_quadratic(3*x**2 + 4*y**2 - 5*z**2 + 4*x*y - 7*y*z + 7*z*x)
(-4, 5, 1) 

diop_ternary_quadratic() first converts the given equation to an equivalent equation of the form (w² = AX² + BY²) and then it uses descent() to solve the latter equation. You can refer to the docs of transformation_to_normal() to find more on this. The equation (w² = AX² + BY²) can be solved more easily by using the Aforementioned descent().

>>> from sympy.solvers.diophantine.diophantine import descent
>>> descent(3, 1) # solves the equation w**2 = 3*Y**2 + Z**2
(1, 0, 1) 

Here the solution tuple is in the order (w, Y, Z)

The extended Pythagorean equation, (a_{1}x_{1}² + a_{2}x_{2}² + \ldots + a_{n}x_{n}² = a_{n+1}x_{n+1}²) and the general sum of squares equation, (x_{1}² + x_{2}² + \ldots + x_{n}² = k) can also be solved using the Diophantine module.

>>> from sympy.abc import a, b, c, d, e, f
>>> diophantine(9*a**2 + 16*b**2 + c**2 + 49*d**2 + 4*e**2 - 25*f**2)
{(70*t1**2 + 70*t2**2 + 70*t3**2 + 70*t4**2 - 70*t5**2, 105*t1*t5, 420*t2*t5, 60*t3*t5, 210*t4*t5, 42*t1**2 + 42*t2**2 + 42*t3**2 + 42*t4**2 + 42*t5**2)} 

function diop_general_pythagorean() can also be called directly to solve the same equation. Either you can call diop_general_pythagorean() or use the high level API. For the general sum of squares, this is also true, but one advantage of calling diop_general_sum_of_squares() is that you can control how many solutions are returned.

>>> from sympy.solvers.diophantine.diophantine import diop_general_sum_of_squares
>>> eq = a**2 + b**2 + c**2 + d**2 - 18
>>> diophantine(eq)
{(0, 0, 3, 3), (0, 1, 1, 4), (1, 2, 2, 3)}
>>> diop_general_sum_of_squares(eq, 2)
{(0, 0, 3, 3), (1, 2, 2, 3)} 

The sum_of_squares() routine will providean iterator that returns solutions and one may control whether the solutions contain zeros or not (and the solutions not containing zeros are returned first):

>>> from sympy.solvers.diophantine.diophantine import sum_of_squares
>>> sos = sum_of_squares(18, 4, zeros=True)
>>> next(sos)
(1, 2, 2, 3)
>>> next(sos)
(0, 0, 3, 3) 

Simple Eqyptian fractions can be found with the Diophantine module, too. For example, here are the ways that one might represent 1/2 as a sum of two unit fractions:

>>> from sympy import Eq, S
>>> diophantine(Eq(1/x + 1/y, S(1)/2))
{(-2, 1), (1, -2), (3, 6), (4, 4), (6, 3)} 

To get a more thorough understanding of the Diophantine module, please refer to the following blog.

thilinaatsympy.wordpress.com/

References

User Functions

This functions is imported into the global namespace with from sympy import *:

sympy.solvers.diophantine.diophantine.diophantine(eq, param=t, syms=None, permute=False)

Simplify the solution procedure of diophantine equation eq by converting it into a product of terms which should equal zero.

Explanation

例如,当解决 (x² - y² = 0) 时,这被视为 ((x + y)(x - y) = 0),分别解决 (x + y = 0) 和 (x - y = 0),然后合并。每个术语通过调用 diop_solve() 来解决。(虽然可以直接调用 diop_solve(),但必须小心传递正确形式的方程并正确解释输出;diophantine() 是一般情况下使用的公共函数。)

diophantine() 的输出是一组元组。元组的元素是方程中每个变量的解决方案,并按照变量的字母顺序排列。例如,对于两个变量 (a) 和 (b) 的方程,元组的第一个元素是 (a) 的解,第二个是 (b) 的解。

用法

diophantine(eq, t, syms): 解决丢番图方程 eqt 是可选的 diop_solve() 使用的参数。syms 是一个可选的符号列表,确定返回元组中元素的顺序。

默认情况下,只返回基本解决方案。如果设置 permute 为 True,则在适用时将返回基本解决方案的排列组合和/或值符号的排列组合。

细节

eq 应为假设为零的表达式。t 是解决方案中使用的参数。

示例

>>> from sympy import diophantine
>>> from sympy.abc import a, b
>>> eq = a**4 + b**4 - (2**4 + 3**4)
>>> diophantine(eq)
{(2, 3)}
>>> diophantine(eq, permute=True)
{(-3, -2), (-3, 2), (-2, -3), (-2, 3), (2, -3), (2, 3), (3, -2), (3, 2)} 
>>> from sympy.abc import x, y, z
>>> diophantine(x**2 - y**2)
{(t_0, -t_0), (t_0, t_0)} 
>>> diophantine(x*(2*x + 3*y - z))
{(0, n1, n2), (t_0, t_1, 2*t_0 + 3*t_1)}
>>> diophantine(x**2 + 3*x*y + 4*x)
{(0, n1), (-3*t_0 - 4, t_0)} 

另请参阅

解丢番图方程, 排列符号, 符号排列

并且此函数通过 from sympy.solvers.diophantine import * 导入:

sympy.solvers.diophantine.diophantine.classify_diop(eq, _dict=True)

内部函数

这些函数旨在用于丢番图模块的内部使用。

sympy.solvers.diophantine.diophantine.diop_solve(eq, param=t)

解决丢番图方程 eq

解释

diophantine() 不同,不尝试对 eq 进行因式分解。使用 classify_diop() 确定方程的类型并调用适当的解算函数。

推荐使用 diophantine() 而不是其他辅助函数。diop_solve() 可以根据方程的性质返回集合或元组。

用法

diop_solve(eq, t): 使用 t 作为参数解决丢番图方程 eq

细节

eq 应为假设为零的表达式。t 是解决方案中使用的参数。

示例

>>> from sympy.solvers.diophantine import diop_solve
>>> from sympy.abc import x, y, z, w
>>> diop_solve(2*x + 3*y - 5)
(3*t_0 - 5, 5 - 2*t_0)
>>> diop_solve(4*x + 3*y - 4*z + 5)
(t_0, 8*t_0 + 4*t_1 + 5, 7*t_0 + 3*t_1 + 5)
>>> diop_solve(x + 3*y - 4*z + w - 6)
(t_0, t_0 + t_1, 6*t_0 + 5*t_1 + 4*t_2 - 6, 5*t_0 + 4*t_1 + 3*t_2 - 6)
>>> diop_solve(x**2 + y**2 - 5)
{(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)} 

另请参阅

丢番图方程

sympy.solvers.diophantine.diophantine.diop_linear(eq, param=t)

解决线性丢番图方程。

线性丢番图方程是形如 (a_{1}x_{1} + a_{2}x_{2} + .. + a_{n}x_{n} = 0) 的方程,其中 (a_{1}, a_{2}, ..a_{n}) 是整数常数,(x_{1}, x_{2}, ..x_{n}) 是整数变量。

用法

diop_linear(eq): 返回一个包含丢番图方程 eq 的解的元组。元组中的值按排序后的变量顺序排列。

详情

eq 是假设为零的线性丢番图方程。param 是解中要使用的参数。

示例

>>> from sympy.solvers.diophantine.diophantine import diop_linear
>>> from sympy.abc import x, y, z
>>> diop_linear(2*x - 3*y - 5) # solves equation 2*x - 3*y - 5 == 0
(3*t_0 - 5, 2*t_0 - 5) 

这里 x = -3t_0 - 5,y = -2t_0 - 5

>>> diop_linear(2*x - 3*y - 4*z -3)
(t_0, 2*t_0 + 4*t_1 + 3, -t_0 - 3*t_1 - 3) 

另请参见

diop_quadratic, diop_ternary_quadratic, diop_general_pythagorean, diop_general_sum_of_squares

sympy.solvers.diophantine.diophantine.base_solution_linear(c, a, b, t=None)

返回线性方程 (ax + by = c) 的基础解。

解释

diop_linear() 使用以找到线性丢番图方程的基础解。如果给定 t,则返回参数化解。

用法

base_solution_linear(c, a, b, t): a, b, c 是 (ax + by = c) 中的系数,t 是解中要使用的参数。

示例

>>> from sympy.solvers.diophantine.diophantine import base_solution_linear
>>> from sympy.abc import t
>>> base_solution_linear(5, 2, 3) # equation 2*x + 3*y = 5
(-5, 5)
>>> base_solution_linear(0, 5, 7) # equation 5*x + 7*y = 0
(0, 0)
>>> base_solution_linear(5, 2, 3, t) # equation 2*x + 3*y = 5
(3*t - 5, 5 - 2*t)
>>> base_solution_linear(0, 5, 7, t) # equation 5*x + 7*y = 0
(7*t, -5*t) 
sympy.solvers.diophantine.diophantine.diop_quadratic(eq, param=t)

解决二次丢番图方程。

即形式为 (Ax² + Bxy + Cy² + Dx + Ey + F = 0) 的方程。返回包含元组 ((x, y)) 的集合,包含解。如果没有解,则返回 ((None, None))。

用法

diop_quadratic(eq, param): eq 是二次二元丢番图方程。param 用于指示解中要使用的参数。

详情

eq 应为假设为零的表达式。param 是解中要使用的参数。

示例

>>> from sympy.abc import x, y, t
>>> from sympy.solvers.diophantine.diophantine import diop_quadratic
>>> diop_quadratic(x**2 + y**2 + 2*x + 2*y + 2, t)
{(-1, -1)} 

另请参见

diop_linear, diop_ternary_quadratic, diop_general_sum_of_squares, diop_general_pythagorean

参考

[R858]

解决方程 Ax² + Bxy + Cy² + Dx + Ey + F = 0 的方法,[在线],可访问:www.alpertron.com.ar/METHODS.HTM

[R859]

解决方程 ax²+ bxy + cy² + dx + ey + f= 0,[在线],可访问:web.archive.org/web/20160323033111/http://www.jpr2718.org/ax2p.pdf

sympy.solvers.diophantine.diophantine.diop_DN(D, N, t=t)

解决方程 (x² - Dy² = N)。

解释

主要关注(D > 0)且(D)不是完全平方数的情况,这与广义 Pell 方程相同。LMM 算法[R860]用于解决此方程。

对每个解类返回一个解元组((x, y))。可以根据 D 和 N 的值构造该类的其他解。

用法

diop_DN(D, N, t): D 和 N 是方程(x² - Dy² = N)中的整数,t是解的参数。

详情

DN对应于方程中的 D 和 N。t是解的参数。

示例

>>> from sympy.solvers.diophantine.diophantine import diop_DN
>>> diop_DN(13, -4) # Solves equation x**2 - 13*y**2 = -4
[(3, 1), (393, 109), (36, 10)] 

输出可以解释如下:方程(x² - 13y² = -4)有三个基本解,分别为(3, 1),(393, 109)和(36, 10)。每个元组都是形如(x, y)的形式,即解(3, 1)意味着(x = 3)且(y = 1)。

>>> diop_DN(986, 1) # Solves equation x**2 - 986*y**2 = 1
[(49299, 1570)] 

参见

find_DN, diop_bf_DN

参考

[R860] (1,2)

解决广义 Pell 方程(x² - D*y² = N),John P. Robertson,2004 年 7 月 31 日,第 16 - 17 页。[在线],可用:web.archive.org/web/20160323033128/http://www.jpr2718.org/pell.pdf

sympy.solvers.diophantine.diophantine.cornacchia(a: int, b: int, m: int) → set[tuple[int, int]]

解决方程(ax² + by² = m),其中(\gcd(a, b) = 1 = gcd(a, m)),且(a, b > 0)。

说明

使用 Cornacchia 算法。该方法仅找到原始解,即满足(\gcd(x, y) = 1)的解。因此,该方法不能用于寻找方程(x² + y² = 20)的解,因为前者的唯一解为((x, y) = (4, 2)),且不是原始解。当(a = b)时,仅找到满足(x \leq y)的解。更多详细信息,请参见参考资料。

示例

>>> from sympy.solvers.diophantine.diophantine import cornacchia
>>> cornacchia(2, 3, 35) # equation 2x**2 + 3y**2 = 35
{(2, 3), (4, 1)}
>>> cornacchia(1, 1, 25) # equation x**2 + y**2 = 25
{(4, 3)} 

参见

sympy.utilities.iterables.signed_permutations

参考

[R861]

  1. Nitaj,“L’algorithme de Cornacchia”

[R862]

通过 Cornacchia 方法解决二次丢番图方程 ax2 + by2 = m,[在线],可用:www.numbertheory.org/php/cornacchia.html

sympy.solvers.diophantine.diophantine.diop_bf_DN(D, N, t=t)

用暴力方法解决方程(x² - Dy² = N)。

说明

主要关注广义 Pell 方程,即当(D > 0)且(D)不是完全平方数的情况。有关此情况的更多信息,请参考[R863]。设((t, u))是方程(x² - Dy² = 1)的最小正解。然后,此方法要求(\sqrt{\frac{\mid N \mid (t \pm 1)}{2D}})要很小。

用法

diop_bf_DN(D, N, t): DN是方程(x² - Dy² = N)中的系数,t是解的参数。

详情

DN对应于方程中的 D 和 N。t是解的参数。

示例

>>> from sympy.solvers.diophantine.diophantine import diop_bf_DN
>>> diop_bf_DN(13, -4)
[(3, 1), (-3, 1), (36, 10)]
>>> diop_bf_DN(986, 1)
[(49299, 1570)] 

参见

diop_DN

参考文献

[R863] (1,2)

解决广义 Pell 方程 (x² - D*y² = N),John P. Robertson,2004 年 7 月 31 日,第 15 页。web.archive.org/web/20160323033128/http://www.jpr2718.org/pell.pdf

sympy.solvers.diophantine.diophantine.transformation_to_DN(eq)

此函数将一般二次方程 (ax² + bxy + cy² + dx + ey + f = 0) 转换为更易处理的形式 (X² - DY² = N)。

解释

这用于通过转换将一般二次方程解决为后一种形式。更详细的转换信息请参考[R864]。此函数返回一个元组 (A, B),其中 A 是一个 2 X 2 矩阵,B 是一个 2 X 1 矩阵,使得,

Transpose([x y]) = A * Transpose([X Y]) + B

用法

transformation_to_DN(eq): 其中 eq 是要转换的二次方程。

示例

>>> from sympy.abc import x, y
>>> from sympy.solvers.diophantine.diophantine import transformation_to_DN
>>> A, B = transformation_to_DN(x**2 - 3*x*y - y**2 - 2*y + 1)
>>> A
Matrix([
[1/26, 3/26],
[   0, 1/13]])
>>> B
Matrix([
[-6/13],
[-4/13]]) 

返回的 A, B 满足 Transpose((x y)) = A * Transpose((X Y)) + B。将这些值代入 (x) 和 (y) 并进行简化,得到形如 (x² - Dy² = N) 的方程。

>>> from sympy.abc import X, Y
>>> from sympy import Matrix, simplify
>>> u = (A*Matrix([X, Y]) + B)[0] # Transformation for x
>>> u
X/26 + 3*Y/26 - 6/13
>>> v = (A*Matrix([X, Y]) + B)[1] # Transformation for y
>>> v
Y/13 - 4/13 

接下来,我们将这些公式代入 (x) 和 (y) 并执行 simplify()

>>> eq = simplify((x**2 - 3*x*y - y**2 - 2*y + 1).subs(zip((x, y), (u, v))))
>>> eq
X**2/676 - Y**2/52 + 17/13 

通过适当地乘以分母,我们可以得到标准形式的 Pell 方程。

>>> eq * 676
X**2 - 13*Y**2 + 884 

如果只需要最终方程,则可以使用 find_DN()

另请参阅

find_DN

参考文献

[R864] (1,2)

解方程 (ax² + bxy + cy² + dx + ey + f = 0),John P.Robertson,2003 年 5 月 8 日,第 7 - 11 页。web.archive.org/web/20160323033111/http://www.jpr2718.org/ax2p.pdf

sympy.solvers.diophantine.diophantine.transformation_to_normal(eq)

返回转换矩阵,将一般三元二次方程 eq ((ax² + by² + cz² + dxy + eyz + fxz)) 转换为没有交叉项的形式:(ax² + by² + cz² = 0)。这不用于解决三元二次方程,仅仅是为了完整性而实现的。

sympy.solvers.diophantine.diophantine.find_DN(eq)

此函数返回简化形式的元组 ((D, N)),即 (x² - Dy² = N),对应于一般二次方程 (ax² + bxy + cy² + dx + ey + f = 0)。

解决一般二次方程等效于解决方程 (X² - DY² = N) 并通过使用 transformation_to_DN() 返回的转换矩阵转换解。

用法

find_DN(eq): 其中 eq 是要转换的二次方程。

示例

>>> from sympy.abc import x, y
>>> from sympy.solvers.diophantine.diophantine import find_DN
>>> find_DN(x**2 - 3*x*y - y**2 - 2*y + 1)
(13, -884) 

输出的解释是,我们通过使用 transformation_to_DN() 返回的转换来转换 (x² - 3xy - y² - 2y + 1) ,得到 (X² -13Y² = -884)。

另请参阅

transformation_to_DN

参考文献

[R865]

解决方程 (ax² + bxy + cy² + dx + ey + f = 0),John P.Robertson,2003 年 5 月 8 日,第 7 - 11 页。web.archive.org/web/20160323033111/http://www.jpr2718.org/ax2p.pdf

sympy.solvers.diophantine.diophantine.diop_ternary_quadratic(eq, parameterize=False)

解决一般的二次三元形式,(ax² + by² + cz² + fxy + gyz + hxz = 0)。

返回一个元组 ((x, y, z)),它是上述方程的一个基本解。如果没有解,则返回 ((None, None, None))。

用法

diop_ternary_quadratic(eq): 返回一个包含 eq 的基本解的元组。

详情

eq 应该是三个变量中二次齐次表达式,假定其为零。

示例

>>> from sympy.abc import x, y, z
>>> from sympy.solvers.diophantine.diophantine import diop_ternary_quadratic
>>> diop_ternary_quadratic(x**2 + 3*y**2 - z**2)
(1, 0, 1)
>>> diop_ternary_quadratic(4*x**2 + 5*y**2 - z**2)
(1, 0, 2)
>>> diop_ternary_quadratic(45*x**2 - 7*y**2 - 8*x*y - z**2)
(28, 45, 105)
>>> diop_ternary_quadratic(x**2 - 49*y**2 - z**2 + 13*z*y -8*x*y)
(9, 1, 5) 
sympy.solvers.diophantine.diophantine.square_factor(a)

返回整数 (c),使得 (a = c²k, \ c,k \in Z)。这里 (k) 是无平方因子。(a) 可以作为整数或因子字典给出。

示例

>>> from sympy.solvers.diophantine.diophantine import square_factor
>>> square_factor(24)
2
>>> square_factor(-36*3)
6
>>> square_factor(1)
1
>>> square_factor({3: 2, 2: 1, -1: 1})  # -18
3 

另见

sympy.ntheory.factor_.core

sympy.solvers.diophantine.diophantine.descent(A, B)

使用拉格朗日下降法和格点约简,返回一个非平凡解((x, y, z)),使得 (x² = Ay² + Bz²)。这里假定 (A) 和 (B) 是使这样的解存在的有效值。

该算法比普通的拉格朗日下降算法更快,因为使用了高斯约简。

示例

>>> from sympy.solvers.diophantine.diophantine import descent
>>> descent(3, 1) # x**2 = 3*y**2 + z**2
(1, 0, 1) 

((x, y, z) = (1, 0, 1)) 是上述方程的一个解。

>>> descent(41, -113)
(-16, -3, 1) 

参考文献

[R866]

Cremona, J. E., Rusin, D. (2003). Rational Conics 的有效解法。《计算数学》,72(243),1417-1441。doi.org/10.1090/S0025-5718-02-01480-1

sympy.solvers.diophantine.diophantine.diop_general_pythagorean(eq, param=m)

解决一般的勾股方程,(a_{1}²x_{1}² + a_{2}²x_{2}² + . . . + a_{n}²x_{n}² - a_{n + 1}²x_{n + 1}² = 0)。

返回一个包含按输入变量相同顺序排序的参数化解的元组。

用法

diop_general_pythagorean(eq, param):这里 eq 是一个被假定为零的一般勾股方程,param 是用于构造其他参数的基础参数。

示例

>>> from sympy.solvers.diophantine.diophantine import diop_general_pythagorean
>>> from sympy.abc import a, b, c, d, e
>>> diop_general_pythagorean(a**2 + b**2 + c**2 - d**2)
(m1**2 + m2**2 - m3**2, 2*m1*m3, 2*m2*m3, m1**2 + m2**2 + m3**2)
>>> diop_general_pythagorean(9*a**2 - 4*b**2 + 16*c**2 + 25*d**2 + e**2)
(10*m1**2  + 10*m2**2  + 10*m3**2 - 10*m4**2, 15*m1**2  + 15*m2**2  + 15*m3**2  + 15*m4**2, 15*m1*m4, 12*m2*m4, 60*m3*m4) 
sympy.solvers.diophantine.diophantine.diop_general_sum_of_squares(eq, limit=1)

解决方程 (x_{1}² + x_{2}² + . . . + x_{n}² - k = 0)。

返回最多limit个解。

用法

general_sum_of_squares(eq, limit):这里eq是一个被假定为零的表达式。同时,eq应该是这种形式,(x_{1}² + x_{2}² + . . . + x_{n}² - k = 0)。

详情

当 (n = 3) 时,如果 (k = 4^a(8m + 7)) 对某些 (a, m \in Z) 成立,则没有解。详见[R867]了解更多细节。

示例

>>> from sympy.solvers.diophantine.diophantine import diop_general_sum_of_squares
>>> from sympy.abc import a, b, c, d, e
>>> diop_general_sum_of_squares(a**2 + b**2 + c**2 + d**2 + e**2 - 2345)
{(15, 22, 22, 24, 24)} 

参考文献

[R867]

代表一个整数作为三个平方和的和,[在线],可参考:www.proofwiki.org/wiki/Integer_as_Sum_of_Three_Squares

sympy.solvers.diophantine.diophantine.diop_general_sum_of_even_powers(eq, limit=1)

解决形如 (x_{1}^e + x_{2}^e + . . . + x_{n}^e - k = 0) 的方程,其中 (e) 是偶数整数幂。

返回最多limit个解。

用法

general_sum_of_even_powers(eq, limit):这里 eq 是一个假设为零的表达式。此外,eq 应该是形如 (x_{1}^e + x_{2}^e + . . . + x_{n}^e - k = 0) 的形式。

示例

>>> from sympy.solvers.diophantine.diophantine import diop_general_sum_of_even_powers
>>> from sympy.abc import a, b
>>> diop_general_sum_of_even_powers(a**4 + b**4 - (2**4 + 3**4))
{(2, 3)} 

另请参阅

power_representation

sympy.solvers.diophantine.diophantine.power_representation(n, p, k, zeros=False)

返回一个生成器,用于找到整数 k 元组 ((n_{1}, n_{2}, . . . n_{k})),使得 (n = n_{1}^p + n_{2}^p + . . . n_{k}^p)。

用法

power_representation(n, p, k, zeros):将非负数 n 表示为 kp 次幂的和。如果 zeros 为 true,则允许解包含零。

示例

>>> from sympy.solvers.diophantine.diophantine import power_representation 

将 1729 表示为两个立方体的和:

>>> f = power_representation(1729, 3, 2)
>>> next(f)
(9, 10)
>>> next(f)
(1, 12) 

如果标志 zeros 为 True,则解可能包含具有零的元组;在不含零的解之后生成这些解:

>>> list(power_representation(125, 2, 3, zeros=True))
[(5, 6, 8), (3, 4, 10), (0, 5, 10), (0, 2, 11)] 

对于偶数 (p),可以使用 (permute_sign) 函数来获取所有带符号的值:

>>> from sympy.utilities.iterables import permute_signs
>>> list(permute_signs((1, 12)))
[(1, 12), (-1, 12), (1, -12), (-1, -12)] 

还可以获取所有可能的带符号排列:

>>> from sympy.utilities.iterables import signed_permutations
>>> list(signed_permutations((1, 12)))
[(1, 12), (-1, 12), (1, -12), (-1, -12), (12, 1), (-12, 1), (12, -1), (-12, -1)] 
sympy.solvers.diophantine.diophantine.partition(n, k=None, zeros=False)

返回一个生成器,用于生成整数 (n) 的分区。

解释

(n) 的一个分区是一组加起来等于 (n) 的正整数。例如,3 的分区有 3,1 + 2,1 + 1 + 1。分区以元组的形式返回。如果 k 等于 None,则返回所有可能的分区,而不考虑其大小;否则只返回大小为 k 的分区。如果将 zero 参数设置为 True,则在每个小于 k 大小的分区末尾添加适当数量的零。

zero 参数仅在 k 不为 None 时考虑。当分区结束时,最后的 (next()) 调用将引发 StopIteration 异常,因此应始终在 try-except 块中使用此函数。

细节

partition(n, k):这里 n 是一个正整数,k 是分区的大小,也是正整数。

示例

>>> from sympy.solvers.diophantine.diophantine import partition
>>> f = partition(5)
>>> next(f)
(1, 1, 1, 1, 1)
>>> next(f)
(1, 1, 1, 2)
>>> g = partition(5, 3)
>>> next(g)
(1, 1, 3)
>>> next(g)
(1, 2, 2)
>>> g = partition(5, 3, zeros=True)
>>> next(g)
(0, 0, 5) 
sympy.solvers.diophantine.diophantine.sum_of_three_squares(n)

返回一个 3-元组 ((a, b, c)),使得 (a² + b² + c² = n) 并且 (a, b, c \geq 0)。

如果 (n = 4^a(8m + 7)) 对于某些 (a, m \in \mathbb{Z}),则返回 None。详细信息请参见 [R868]

参数:

n :整数

非负整数

返回:

(int, int, int) | None :满足 a**2 + b**2 + c**2 = n 的三元组非负整数 (a, b, c)

a、b、c 按升序排列。如果没有这样的 (a,b,c),则返回 None

抛出:

数值错误

如果 n 是负整数

示例

>>> from sympy.solvers.diophantine.diophantine import sum_of_three_squares
>>> sum_of_three_squares(44542)
(18, 37, 207) 

另请参阅

power_representation

sum_of_three_squares(n)power_representation(n, 2, 3, zeros=True) 输出的解之一。

参考

[R868] (1,2)

将一个数表示为三个平方的和,[在线],可用:schorn.ch/lagrange.html

sympy.solvers.diophantine.diophantine.sum_of_four_squares(n)

返回一个 4-元组 ((a, b, c, d)),使得 (a² + b² + c² + d² = n)。这里 (a, b, c, d \geq 0)。

参数:

n :整数

非负整数

返回:

(int, int, int, int):满足 a**2 + b**2 + c**2 + d**2 = n 的 4-元组非负整数 (a, b, c, d)

a、b、c、d 按升序排列。

引发:

数值错误

如果 n 是负整数

示例

>>> from sympy.solvers.diophantine.diophantine import sum_of_four_squares
>>> sum_of_four_squares(3456)
(8, 8, 32, 48)
>>> sum_of_four_squares(1294585930293)
(0, 1234, 2161, 1137796) 

参见

power_representation

sum_of_four_squares(n) 是由 power_representation(n, 2, 4, zeros=True) 输出的解之一

参考文献

[R869]

表示一个数作为四个平方的和,[在线],可访问:schorn.ch/lagrange.html

sympy.solvers.diophantine.diophantine.sum_of_powers(n, p, k, zeros=False)

返回一个生成器,用于查找 k-元组整数 ((n_{1}, n_{2}, . . . n_{k})),使得 (n = n_{1}^p + n_{2}^p + . . . n_{k}^p)。

用法

power_representation(n, p, k, zeros): 将非负数 n 表示为 kp 次幂的和。如果 zeros 为真,则允许解包含零。

示例

>>> from sympy.solvers.diophantine.diophantine import power_representation 

将 1729 表示为两个立方体的和:

>>> f = power_representation(1729, 3, 2)
>>> next(f)
(9, 10)
>>> next(f)
(1, 12) 

如果标志 (zeros) 为 True,则解决方案可能包含带有零的元组;任何此类解决方案将在不带零的解决方案之后生成:

>>> list(power_representation(125, 2, 3, zeros=True))
[(5, 6, 8), (3, 4, 10), (0, 5, 10), (0, 2, 11)] 

对于偶数 ( p ),可以使用 ( permute_sign ) 函数来获取所有符号化的值:

>>> from sympy.utilities.iterables import permute_signs
>>> list(permute_signs((1, 12)))
[(1, 12), (-1, 12), (1, -12), (-1, -12)] 

也可以获得所有可能的符号化排列:

>>> from sympy.utilities.iterables import signed_permutations
>>> list(signed_permutations((1, 12)))
[(1, 12), (-1, 12), (1, -12), (-1, -12), (12, 1), (-12, 1), (12, -1), (-12, -1)] 
sympy.solvers.diophantine.diophantine.sum_of_squares(n, k, zeros=False)

返回生成器,产生非负值的 k-元组,其平方和为 n。如果 zeros 为 False(默认值),则解决方案不包含零。元组的非负元素已排序。

  • 如果 k == 1 并且 n 是平方数,则返回 (n,)。

  • 如果 k == 2,则仅当 n 在其因数分解中的每个形式为 4k + 3 的素数具有偶重数时,n 才能被写成两个平方的和。如果 n 是素数,则仅当它为 4k + 1 形式时,才能将其写成两个平方的和。

  • 如果 k == 3,则只要 n 不具有 4**m*(8*k + 7) 的形式,n 就可以被写成平方的和。

  • 所有整数都可以写成 4 个平方的和。

  • 如果 k > 4,则 n 可以被分区,并且每个分区可以被写成 4 个平方的和;如果 n 不是 4 的倍数,则仅当可以将附加分区写成平方的和时,n 才能被写成平方的和。例如,如果 k = 6,则 n 被分成两部分,第一部分被写成 4 个平方的和,第二部分被写成 2 个平方的和——只有当满足 k = 2 的条件时才能做到这一点,因此这将自动拒绝某些 n 的分区。

示例

>>> from sympy.solvers.diophantine.diophantine import sum_of_squares
>>> list(sum_of_squares(25, 2))
[(3, 4)]
>>> list(sum_of_squares(25, 2, True))
[(3, 4), (0, 5)]
>>> list(sum_of_squares(25, 4))
[(1, 2, 2, 4)] 

参见

sympy.utilities.iterables.signed_permutations

sympy.solvers.diophantine.diophantine.merge_solution(var, var_t, solution)

这用于从子方程的解构建完整的解决方案。

解释

例如,当解方程 ((x - y)(x² + y² - z²) = 0) 时,可以分别独立找到方程 (x - y = 0) 和 (x² + y² - z²) 的解。 (x - y = 0) 的解为 ((x, y) = (t, t))。但是在输出原始方程的解时,应为 (x - y = 0) 的解引入一个值为 z 的参数。此函数将 ((t, t)) 转换为 ((t, t, n_{1})),其中 (n_{1}) 是整数参数。

sympy.solvers.diophantine.diophantine.divisible(a, b)

如果 a 能被 b 整除则返回 (True),否则返回 (False)。

sympy.solvers.diophantine.diophantine.PQa(P_0, Q_0, D)

返回解决 Pell 方程所需的有用信息。

Explanation

与 (\frac{P + \sqrt{D}}{Q}) 的连分数表示相关的六个整数序列被定义,即 {(P_{i})}, {(Q_{i})}, {(a_{i})},{(A_{i})}, {(B_{i})}, {(G_{i})}。PQa() 以与上述顺序相同的 6 元组返回这些值。更详细的信息请参见 [R870]

使用

PQa(P_0, Q_0, D): P_0, Q_0D 是整数,分别对应于连分数 (\frac{P_{0} + \sqrt{D}}{Q_{0}}) 中的 (P_{0}), (Q_{0}) 和 (D)。同时假设 (P_{0}² == D mod(|Q_{0}|)),且 (D) 是无平方因子。

Examples

>>> from sympy.solvers.diophantine.diophantine import PQa
>>> pqa = PQa(13, 4, 5) # (13 + sqrt(5))/4
>>> next(pqa) # (P_0, Q_0, a_0, A_0, B_0, G_0)
(13, 4, 3, 3, 1, -1)
>>> next(pqa) # (P_1, Q_1, a_1, A_1, B_1, G_1)
(-1, 1, 1, 4, 1, 3) 

References

[R870] (1,2)

解决广义 Pell 方程 (x² - Dy² = N),John P. Robertson, 2004 年 7 月 31 日,第 4 - 8 页。web.archive.org/web/20160323033128/http://www.jpr2718.org/pell.pdf

sympy.solvers.diophantine.diophantine.equivalent(u, v, r, s, D, N)

如果两个解 ((u, v)) 和 ((r, s)) 满足 (x² - Dy² = N) 并属于同一等价类,则返回 True,否则返回 False。

Explanation

对于上述方程的两个解 ((u, v)) 和 ((r, s)),它们属于相同等价类当且仅当 ((ur - Dvs)) 和 ((us - vr)) 都能被 (N) 整除。参见引用 [R871]。不会对是否 ((u, v)) 和 ((r, s)) 实际上是方程的解进行测试。用户应当注意这一点。

Usage

equivalent(u, v, r, s, D, N): ((u, v)) 和 ((r, s)) 是方程 (x² - Dy² = N) 的两个解,涉及的所有参数都是整数。

Examples

>>> from sympy.solvers.diophantine.diophantine import equivalent
>>> equivalent(18, 5, -18, -5, 13, -1)
True
>>> equivalent(3, 1, -18, 393, 109, -4)
False 

References

[R871] (1,2)

解决广义 Pell 方程 (x² - D*y² = N),John P. Robertson, 2004 年 7 月 31 日,第 12 页。web.archive.org/web/20160323033128/http://www.jpr2718.org/pell.pdf

sympy.solvers.diophantine.diophantine.parametrize_ternary_quadratic(eq)

返回三元二次方程 eq 的参数化一般解,其形式为 (ax² + by² + cz² + fxy + gyz + hxz = 0)。

Examples

>>> from sympy import Tuple, ordered
>>> from sympy.abc import x, y, z
>>> from sympy.solvers.diophantine.diophantine import parametrize_ternary_quadratic 

可能会返回参数化解与三个参数:

>>> parametrize_ternary_quadratic(2*x**2 + y**2 - 2*z**2)
(p**2 - 2*q**2, -2*p**2 + 4*p*q - 4*p*r - 4*q**2, p**2 - 4*p*q + 2*q**2 - 4*q*r) 

也可能只有两个参数:

>>> parametrize_ternary_quadratic(4*x**2 + 2*y**2 - 3*z**2)
(2*p**2 - 3*q**2, -4*p**2 + 12*p*q - 6*q**2, 4*p**2 - 8*p*q + 6*q**2) 

Notes

考虑前两个参数解中的 pq,观察到给定一对参数可以表示多个解。如果 pq 不是互质的,这是显而易见的,因为共同因子也将是解值的公因子。但是即使 pq 是互质的,这也可能是真的:

>>> sol = Tuple(*_)
>>> p, q = ordered(sol.free_symbols)
>>> sol.subs([(p, 3), (q, 2)])
(6, 12, 12)
>>> sol.subs([(q, 1), (p, 1)])
(-1, 2, 2)
>>> sol.subs([(q, 0), (p, 1)])
(2, -4, 4)
>>> sol.subs([(q, 1), (p, 0)])
(-3, -6, 6) 

除了符号和一个公共因子外,这些等同于解(1, 2, 2)。

参考文献

[R872]

Diophantine 方程的算法解决,Nigel P. Smart,伦敦数学学会学生文集 41,剑桥大学出版社,剑桥,1998 年。

sympy.solvers.diophantine.diophantine.diop_ternary_quadratic_normal(eq, parameterize=False)

解二次三元丢番图方程 (ax² + by² + cz² = 0)。

解释

这里的系数 (a)、(b) 和 (c) 应为非零。否则方程将成为二次二进制或单变量方程。如果可解,返回满足给定方程的元组 ((x, y, z))。如果方程没有整数解,则返回 ((None, None, None))。

使用方法

diop_ternary_quadratic_normal(eq): 其中eq是形如 (ax² + by² + cz² = 0) 的方程。

示例

>>> from sympy.abc import x, y, z
>>> from sympy.solvers.diophantine.diophantine import diop_ternary_quadratic_normal
>>> diop_ternary_quadratic_normal(x**2 + 3*y**2 - z**2)
(1, 0, 1)
>>> diop_ternary_quadratic_normal(4*x**2 + 5*y**2 - z**2)
(1, 0, 2)
>>> diop_ternary_quadratic_normal(34*x**2 - 3*y**2 - 301*z**2)
(4, 9, 1) 
sympy.solvers.diophantine.diophantine.ldescent(A, B)

使用拉格朗日方法返回 (w² = Ax² + By²) 的非平凡解;如果没有这样的解,则返回 None。

参数:

A : 整数

B : 整数

非零整数

返回:

(int, int, int) | None : 一个元组 ((w_0, x_0, y_0)),它是上述方程的解。

示例

>>> from sympy.solvers.diophantine.diophantine import ldescent
>>> ldescent(1, 1) # w² = x² + y²
(1, 1, 0)
>>> ldescent(4, -7) # w² = 4x² - 7y²
(2, -1, 0) 

这意味着 (x = -1, y = 0) 和 (w = 2) 是方程 (w² = 4x² - 7y²) 的解。

>>> ldescent(5, -1) # w² = 5x² - y²
(2, 1, -1) 

参考资料

[R873]

Diophantine 方程的算法解决,Nigel P. Smart,伦敦数学学会学生文集 41,剑桥大学出版社,剑桥,1998 年。

[R874]

Cremona, J. E., Rusin, D. (2003). Rational Conics 的高效解法。计算数学,72(243),1417-1441。doi.org/10.1090/S0025-5718-02-01480-1

sympy.solvers.diophantine.diophantine.gaussian_reduce(w: int, a: int, b: int) → tuple[int, int]

返回对应模 (b) 的同余方程 (X² - aZ² \equiv 0 \pmod{b}) 的简化解 ((x, z)),使得 (x² + |a|z²) 尽可能小。这里 w 是满足同余方程 (x² \equiv a \pmod{b}) 的解。

此函数仅用于 descent()

参数:

w : 整数

w 满足 (w² \equiv a \pmod{b})

a : 整数

无平方因子的非零整数

b : 整数

无平方因子的非零整数

解释

高斯约简可以找到任何范数的最短向量。因此,我们对向量 (u = (u_1, u_2)) 和 (v = (v_1, v_2)) 定义特殊的范数如下。

[u \cdot v := (wu_1 + bu_2)(wv_1 + bv_2) + |a|u_1v_1]

注意,给定映射 (f: (u_1, u_2) \to (wu_1 + bu_2, u_1)),(f((u_1,u_2))) 是方程 (X² - aZ² \equiv 0 \pmod{b}) 的解。换句话说,找到这个范数中的最短向量将给出一个 (X² + |a|Z²) 较小的解。该算法从基础向量 ((0, 1)) 和 ((1, 0)) 开始(分别对应解 ((b, 0)) 和 ((w, 1))),并找到最短向量。最短向量不一定对应最小的解,但由于 descent() 只需最小可能的解,这已经足够。

示例

>>> from sympy.solvers.diophantine.diophantine import gaussian_reduce
>>> from sympy.ntheory.residue_ntheory import sqrt_mod
>>> a, b = 19, 101
>>> gaussian_reduce(sqrt_mod(a, b), a, b) # 1**2 - 19*(-4)**2 = -303
(1, -4)
>>> a, b = 11, 14
>>> x, z = gaussian_reduce(sqrt_mod(a, b), a, b)
>>> (x**2 - a*z**2) % b == 0
True 

它并不总是返回最小的解。

>>> a, b = 6, 95
>>> min_x, min_z = 1, 4
>>> x, z = gaussian_reduce(sqrt_mod(a, b), a, b)
>>> (x**2 - a*z**2) % b == 0 and (min_x**2 - a*min_z**2) % b == 0
True
>>> min_x**2 + abs(a)*min_z**2 < x**2 + abs(a)*z**2
True 

参考

[R875]

高斯格点缩减 [在线]. 可访问: web.archive.org/web/20201021115213/http://home.ie.cuhk.edu.hk/~wkshum/wordpress/?p=404

[R876]

Cremona, J. E., Rusin, D. (2003). 有效解决有理圆锥曲线问题. 计算数学, 72(243), 1417-1441. doi.org/10.1090/S0025-5718-02-01480-1

sympy.solvers.diophantine.diophantine.holzer(x, y, z, a, b, c)

简化方程 (ax² + by² = cz²) 的解 ((x, y, z)),其中 (a, b, c > 0) 且 (z² \geq \mid ab \mid),至一个新的减少解 ((x', y', z')),使得 (z'² \leq \mid ab \mid)。

该算法是 Mordell 的缩减的一种解释,如 Cremona 和 Rusin 论文第 8 页所述 [R877],以及 Mordell 在参考文献 [R878] 中的工作。

参考文献

[R877] (1,2)

Cremona, J. E., Rusin, D. (2003). 有效解决有理圆锥曲线问题. 计算数学, 72(243), 1417-1441. doi.org/10.1090/S0025-5718-02-01480-1

[R878] (1,2)

丢番图方程, L. J. Mordell, 第 48 页.

sympy.solvers.diophantine.diophantine.prime_as_sum_of_two_squares(p)

将素数 (p) 表示为两个平方数之和;仅当素数满足 (p \equiv 1 \pmod{4}) 时可行。

参数:

p : 整数

一个满足 (p \equiv 1 \pmod{4}) 的素数

返回:

(int, int) | None : 正整数对 (x, y) 满足 x**2 + y**2 = p

p 不满足 (p \equiv 1 \pmod{4}),则返回 None。

抛出:

ValueError

p 不是素数

示例

>>> from sympy.solvers.diophantine.diophantine import prime_as_sum_of_two_squares
>>> prime_as_sum_of_two_squares(7)  # can't be done
>>> prime_as_sum_of_two_squares(5)
(1, 2) 

参考

[R879]

将一个数表示为四个平方数之和 [在线]. 可访问: schorn.ch/lagrange.html

参见

sum_of_squares

sympy.solvers.diophantine.diophantine.sqf_normal(a, b, c, steps=False)

返回 (a', b', c'),即 (ax² + by² + cz² = 0) 的平方自由正则形式的系数,其中 (a', b', c') 是两两素数。如果 steps 为真,则还返回三个元组:(sq),(sqf) 和 ((a', b', c')),在去除 (gcd(a, b, c)) 后包含 (a),(b) 和 (c) 的平方因子。

对于 (ax² + by² + cz² = 0) 的解可以从 (a'x² + b'y² + c'z² = 0) 的解恢复。

示例

>>> from sympy.solvers.diophantine.diophantine import sqf_normal
>>> sqf_normal(2 * 3**2 * 5, 2 * 5 * 11, 2 * 7**2 * 11)
(11, 1, 5)
>>> sqf_normal(2 * 3**2 * 5, 2 * 5 * 11, 2 * 7**2 * 11, True)
((3, 1, 7), (5, 55, 11), (11, 1, 5)) 

参见

reconstruct

参考

[R880]

Legendre 定理,Lagrange 下降,public.csusm.edu/aitken_html/notes/legendre.pdf

sympy.solvers.diophantine.diophantine.reconstruct(A, B, z)

从等式的平方自由正常形式 (a'*x² + b'*y² + c'*z²) 的解的 (z) 值重建等价解的 (z) 值,其中 (a'), (b') 和 (c') 是平方自由的,且 (gcd(a', b', c') == 1)。

内部类

这些类旨在供丢番图模块内部使用。

class sympy.solvers.diophantine.diophantine.DiophantineSolutionSet(symbols_seq, parameters)

一特定丢番图方程的解集的容器。

基本表示是一组元组,代表每个解的解决方案。

参数:

symbols : 列表

原方程中的自由符号列表。

parameters: list

用于解决方案的参数列表。

示例

添加解决方案:

>>> from sympy.solvers.diophantine.diophantine import DiophantineSolutionSet
>>> from sympy.abc import x, y, t, u
>>> s1 = DiophantineSolutionSet([x, y], [t, u])
>>> s1
set()
>>> s1.add((2, 3))
>>> s1.add((-1, u))
>>> s1
{(-1, u), (2, 3)}
>>> s2 = DiophantineSolutionSet([x, y], [t, u])
>>> s2.add((3, 4))
>>> s1.update(*s2)
>>> s1
{(-1, u), (2, 3), (3, 4)} 

将解转换为字典:

>>> list(s1.dict_iterator())
[{x: -1, y: u}, {x: 2, y: 3}, {x: 3, y: 4}] 

替换数值:

>>> s3 = DiophantineSolutionSet([x, y], [t, u])
>>> s3.add((t**2, t + u))
>>> s3
{(t**2, t + u)}
>>> s3.subs({t: 2, u: 3})
{(4, 5)}
>>> s3.subs(t, -1)
{(1, u - 1)}
>>> s3.subs(t, 3)
{(9, u + 3)} 

特定值的评估。位置参数与参数顺序相同:

>>> s3(-2, 3)
{(4, 1)}
>>> s3(5)
{(25, u + 5)}
>>> s3(None, 2)
{(t**2, t + 2)} 
class sympy.solvers.diophantine.diophantine.DiophantineEquationType(equation, free_symbols=None)

特定丢番图方程类型的内部表示。

参数:

equation :

正在解决的丢番图方程。

free_symbols : 列表 (可选)

正在解决的符号。

属性

total_degree :方程中所有项的最大度数
homogeneous :方程是否包含度为 0 的项
homogeneous_order :方程中是否包含任何符号的系数
dimension :正在解决的符号数量
matches()

确定给定方程是否可以与特定方程类型匹配。

class sympy.solvers.diophantine.diophantine.Univariate(equation, free_symbols=None)

一元二次丢番图方程的表示。

一元二次丢番图方程是一个形如 (a_{0} + a_{1}x + a_{2}x² + .. + a_{n}x^n = 0) 的方程,其中 (a_{1}, a_{2}, ..a_{n}) 是整数常数,(x) 是整数变量。

示例

>>> from sympy.solvers.diophantine.diophantine import Univariate
>>> from sympy.abc import x
>>> Univariate((x - 2)*(x - 3)**2).solve() # solves equation (x - 2)*(x - 3)**2 == 0
{(2,), (3,)} 
class sympy.solvers.diophantine.diophantine.Linear(equation, free_symbols=None)

一元二次丢番图方程的表示。

线性丢番图方程是一个形如 (a_{1}x_{1} + a_{2}x_{2} + .. + a_{n}x_{n} = 0) 的方程,其中 (a_{1}, a_{2}, ..a_{n}) 是整数常数,(x_{1}, x_{2}, ..x_{n}) 是整数变量。

示例

>>> from sympy.solvers.diophantine.diophantine import Linear
>>> from sympy.abc import x, y, z
>>> l1 = Linear(2*x - 3*y - 5)
>>> l1.matches() # is this equation linear
True
>>> l1.solve() # solves equation 2*x - 3*y - 5 == 0
{(3*t_0 - 5, 2*t_0 - 5)} 

这里 x = -3t_0 - 5 和 y = -2t_0 - 5

>>> Linear(2*x - 3*y - 4*z -3).solve()
{(t_0, 2*t_0 + 4*t_1 + 3, -t_0 - 3*t_1 - 3)} 
class sympy.solvers.diophantine.diophantine.BinaryQuadratic(equation, free_symbols=None)

二元二次丢番图方程的表示。

二元二次丢番图方程是一个形如 (Ax² + Bxy + Cy² + Dx + Ey + F = 0) 的方程,其中 (A, B, C, D, E, F) 是整数常数,(x) 和 (y) 是整数变量。

示例

>>> from sympy.abc import x, y
>>> from sympy.solvers.diophantine.diophantine import BinaryQuadratic
>>> b1 = BinaryQuadratic(x**3 + y**2 + 1)
>>> b1.matches()
False
>>> b2 = BinaryQuadratic(x**2 + y**2 + 2*x + 2*y + 2)
>>> b2.matches()
True
>>> b2.solve()
{(-1, -1)} 

参考

[R881]

解决 Ax² + Bxy + Cy² + Dx + Ey + F = 0 的方法,[在线],可用:www.alpertron.com.ar/METHODS.HTM

[R882]

解方程(ax²+ bxy + cy² + dx + ey + f= 0),[在线],可参见:web.archive.org/web/20160323033111/http://www.jpr2718.org/ax2p.pdf

class sympy.solvers.diophantine.diophantine.InhomogeneousTernaryQuadratic(equation, free_symbols=None)

表示非均匀三元二次方程。

目前还没有为这种方程类型实现求解器。

class sympy.solvers.diophantine.diophantine.HomogeneousTernaryQuadraticNormal(equation, free_symbols=None)

表示均匀三元二次正规丢番图方程。

示例

>>> from sympy.abc import x, y, z
>>> from sympy.solvers.diophantine.diophantine import HomogeneousTernaryQuadraticNormal
>>> HomogeneousTernaryQuadraticNormal(4*x**2 - 5*y**2 + z**2).solve()
{(1, 2, 4)} 
class sympy.solvers.diophantine.diophantine.HomogeneousTernaryQuadratic(equation, free_symbols=None)

表示均匀三元二次丢番图方程。

示例

>>> from sympy.abc import x, y, z
>>> from sympy.solvers.diophantine.diophantine import HomogeneousTernaryQuadratic
>>> HomogeneousTernaryQuadratic(x**2 + y**2 - 3*z**2 + x*y).solve()
{(-1, 2, 1)}
>>> HomogeneousTernaryQuadratic(3*x**2 + y**2 - 3*z**2 + 5*x*y + y*z).solve()
{(3, 12, 13)} 
class sympy.solvers.diophantine.diophantine.InhomogeneousGeneralQuadratic(equation, free_symbols=None)

表示非均匀一般二次方程。

目前还没有为这种方程类型实现求解器。

class sympy.solvers.diophantine.diophantine.HomogeneousGeneralQuadratic(equation, free_symbols=None)

表示均匀一般二次方程。

目前还没有为这种方程类型实现求解器。

class sympy.solvers.diophantine.diophantine.GeneralSumOfSquares(equation, free_symbols=None)

表示丢番图方程

(x_{1}² + x_{2}² + . . . + x_{n}² - k = 0).

详情

当(n = 3)时,如果(k = 4^a(8m + 7)),其中(a, m \in Z),则没有解。参考[R883]获取更多详情。

示例

>>> from sympy.solvers.diophantine.diophantine import GeneralSumOfSquares
>>> from sympy.abc import a, b, c, d, e
>>> GeneralSumOfSquares(a**2 + b**2 + c**2 + d**2 + e**2 - 2345).solve()
{(15, 22, 22, 24, 24)} 

默认情况下仅返回 1 个解。使用关键字(limit)可获取更多:

>>> sorted(GeneralSumOfSquares(a**2 + b**2 + c**2 + d**2 + e**2 - 2345).solve(limit=3))
[(15, 22, 22, 24, 24), (16, 19, 24, 24, 24), (16, 20, 22, 23, 26)] 

参考文献

[R883] (1,2)

将整数表示为三个平方数的和,[在线],可参见:www.proofwiki.org/wiki/Integer_as_Sum_of_Three_Squares

class sympy.solvers.diophantine.diophantine.GeneralPythagorean(equation, free_symbols=None)

表示一般的毕达哥拉斯方程,(a_{1}²x_{1}² + a_{2}²x_{2}² + . . . + a_{n}²x_{n}² - a_{n + 1}²x_{n + 1}² = 0)。

示例

>>> from sympy.solvers.diophantine.diophantine import GeneralPythagorean
>>> from sympy.abc import a, b, c, d, e, x, y, z, t
>>> GeneralPythagorean(a**2 + b**2 + c**2 - d**2).solve()
{(t_0**2 + t_1**2 - t_2**2, 2*t_0*t_2, 2*t_1*t_2, t_0**2 + t_1**2 + t_2**2)}
>>> GeneralPythagorean(9*a**2 - 4*b**2 + 16*c**2 + 25*d**2 + e**2).solve(parameters=[x, y, z, t])
{(-10*t**2 + 10*x**2 + 10*y**2 + 10*z**2, 15*t**2 + 15*x**2 + 15*y**2 + 15*z**2, 15*t*x, 12*t*y, 60*t*z)} 
class sympy.solvers.diophantine.diophantine.CubicThue(equation, free_symbols=None)

表示一个三次丢番图方程。

一个三次丢番图方程是一个形式为(f(x, y) = r)的三次多项式,其中(x)和(y)是整数,(r)是有理数。

目前还没有为这种方程类型实现求解器。

示例

>>> from sympy.abc import x, y
>>> from sympy.solvers.diophantine.diophantine import CubicThue
>>> c1 = CubicThue(x**3 + y**2 + 1)
>>> c1.matches()
True 
class sympy.solvers.diophantine.diophantine.GeneralSumOfEvenPowers(equation, free_symbols=None)

表示丢番图方程

(x_{1}^e + x_{2}^e + . . . + x_{n}^e - k = 0)

其中(e)是一个偶数整数幂。

示例

>>> from sympy.solvers.diophantine.diophantine import GeneralSumOfEvenPowers
>>> from sympy.abc import a, b
>>> GeneralSumOfEvenPowers(a**4 + b**4 - (2**4 + 3**4)).solve()
{(2, 3)} 

不等式求解器

原文:docs.sympy.org/latest/modules/solvers/inequalities.html

对于一般情况应使用reduce_inequalities()。其他函数是专用操作的子类别,将根据需要由reduce_inequalities内部调用。

注意

对于一个以解代数方式减少一个或多个不等式的单变量友好指南,请参阅减少不等式的解数学含义。

注意

以下一些示例使用poly(),它只是将表达式转换为多项式;它不改变表达式的数学含义。

sympy.solvers.inequalities.solve_rational_inequalities(eqs)

用有理系数解有理不等式系统。

示例

>>> from sympy.abc import x
>>> from sympy import solve_rational_inequalities, Poly 
>>> solve_rational_inequalities([[
... ((Poly(-x + 1), Poly(1, x)), '>='),
... ((Poly(-x + 1), Poly(1, x)), '<=')]])
{1} 
>>> solve_rational_inequalities([[
... ((Poly(x), Poly(1, x)), '!='),
... ((Poly(-x + 1), Poly(1, x)), '>=')]])
Union(Interval.open(-oo, 0), Interval.Lopen(0, 1)) 

参见

solve_poly_inequality

sympy.solvers.inequalities.solve_poly_inequality(poly, rel)

用有理系数解多项式不等式。

示例

>>> from sympy import solve_poly_inequality, Poly
>>> from sympy.abc import x 
>>> solve_poly_inequality(Poly(x, x, domain='ZZ'), '==')
[{0}] 
>>> solve_poly_inequality(Poly(x**2 - 1, x, domain='ZZ'), '!=')
[Interval.open(-oo, -1), Interval.open(-1, 1), Interval.open(1, oo)] 
>>> solve_poly_inequality(Poly(x**2 - 1, x, domain='ZZ'), '==')
[{-1}, {1}] 

参见

solve_poly_inequalities

sympy.solvers.inequalities.solve_poly_inequalities(polys)

用有理系数解多项式不等式。

示例

>>> from sympy import Poly
>>> from sympy.solvers.inequalities import solve_poly_inequalities
>>> from sympy.abc import x
>>> solve_poly_inequalities(((
... Poly(x**2 - 3), ">"), (
... Poly(-x**2 + 1), ">")))
Union(Interval.open(-oo, -sqrt(3)), Interval.open(-1, 1), Interval.open(sqrt(3), oo)) 
sympy.solvers.inequalities.reduce_rational_inequalities(exprs, gen, relational=True)

用有理系数解有理不等式系统。

示例

>>> from sympy import Symbol
>>> from sympy.solvers.inequalities import reduce_rational_inequalities 
>>> x = Symbol('x', real=True) 
>>> reduce_rational_inequalities([[x**2 <= 0]], x)
Eq(x, 0) 
>>> reduce_rational_inequalities([[x + 2 > 0]], x)
-2 < x
>>> reduce_rational_inequalities([[(x + 2, ">")]], x)
-2 < x
>>> reduce_rational_inequalities([[x + 2]], x)
Eq(x, -2) 

此函数找到非无限解集,因此如果未知符号声明为扩展实数而不是实数,则结果可能包括有限性条件:

>>> y = Symbol('y', extended_real=True)
>>> reduce_rational_inequalities([[y + 2 > 0]], y)
(-2 < y) & (y < oo) 
sympy.solvers.inequalities.reduce_abs_inequality(expr, rel, gen)

解嵌套绝对值不等式。

示例

>>> from sympy import reduce_abs_inequality, Abs, Symbol
>>> x = Symbol('x', real=True) 
>>> reduce_abs_inequality(Abs(x - 5) - 3, '<', x)
(2 < x) & (x < 8) 
>>> reduce_abs_inequality(Abs(x + 2)*3 - 13, '<', x)
(-19/3 < x) & (x < 7/3) 

参见

reduce_abs_inequalities

sympy.solvers.inequalities.reduce_abs_inequalities(exprs, gen)

解嵌套绝对值不等式系统。

示例

>>> from sympy import reduce_abs_inequalities, Abs, Symbol
>>> x = Symbol('x', extended_real=True) 
>>> reduce_abs_inequalities([(Abs(3*x - 5) - 7, '<'),
... (Abs(x + 25) - 13, '>')], x)
(-2/3 < x) & (x < 4) & (((-oo < x) & (x < -38)) | ((-12 < x) & (x < oo))) 
>>> reduce_abs_inequalities([(Abs(x - 4) + Abs(3*x - 5) - 7, '<')], x)
(1/2 < x) & (x < 4) 

参见

reduce_abs_inequality

sympy.solvers.inequalities.reduce_inequalities(inequalities, symbols=[])

用有理系数解不等式系统。

示例

>>> from sympy.abc import x, y
>>> from sympy import reduce_inequalities 
>>> reduce_inequalities(0 <= x + 3, [])
(-3 <= x) & (x < oo) 
>>> reduce_inequalities(0 <= x + y*2 - 1, [x])
(x < oo) & (x >= 1 - 2*y) 
sympy.solvers.inequalities.solve_univariate_inequality(expr, gen, relational=True, domain=Reals, continuous=False)

解实数单变量不等式。

参数:

表达式:关系型

目标不等式

gen:符号

解不等式的变量

关系型:布尔值

预期输出为关系类型或否

定义域:集合

解方程的定义域

连续: 布尔值

如果已知表达式在给定域上连续(因此不需要调用 continuous_domain()),则返回 True。

异常:

未实现错误

由于sympy.solvers.solveset.solvify()的限制,无法确定不等式的解。

注释

目前,由于 sympy.solvers.solveset.solvify() 的限制,我们无法解决所有不等式。此外,对于三角不等式返回的解受其周期间隔的限制。

示例

>>> from sympy import solve_univariate_inequality, Symbol, sin, Interval, S
>>> x = Symbol('x') 
>>> solve_univariate_inequality(x**2 >= 4, x)
((2 <= x) & (x < oo)) | ((-oo < x) & (x <= -2)) 
>>> solve_univariate_inequality(x**2 >= 4, x, relational=False)
Union(Interval(-oo, -2), Interval(2, oo)) 
>>> domain = Interval(0, S.Infinity)
>>> solve_univariate_inequality(x**2 >= 4, x, False, domain)
Interval(2, oo) 
>>> solve_univariate_inequality(sin(x) > 0, x, relational=False)
Interval.open(0, pi) 

参见

sympy.solvers.solveset.solvify

solver 返回 solveset 解决方案与 solve 的输出 API