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

82 阅读1小时+

SymPy 1.13 中文文档(二十一)

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

核心

原文:docs.sympy.org/latest/modules/core.html

sympify

sympy.core.sympify.sympify(a, locals=None, convert_xor=True, strict=False, rational=False, evaluate=None)

将任意表达式转换为可以在 SymPy 内部使用的类型。

参数:

a:

  • SymPy 中定义的任何对象
  • 标准的数字 Python 类型:intlongfloatDecimal
  • 字符串(如"0.09""2e-19"'sin(x)'
  • 布尔值,包括None(将None保持不变)
  • 包含上述任何内容的字典、列表、集合或元组

convert_xor:布尔型,可选

如果为真,则将^视为指数运算。如果为假,则将^视为 XOR 本身。仅在输入为字符串时使用。

locals:SymPy 中定义的任何对象,可选

为了使字符串被识别,可以导入到命名空间字典中并作为本地传递。

strict:布尔型,可选

如果严格选项设置为True,则仅对已定义显式转换的类型进行转换。在其他情况下,将引发SympifyError

rational:布尔型,可选

如果为True,则将浮点数转换为Rational。如果为False,则让浮点数保持原样。仅在输入为字符串时使用。

evaluate:布尔型,可选

如果为 False,则算术和运算符将转换为它们的 SymPy 等效项。如果为 True,则将评估表达式并返回结果。

解释

它将 Python 整数转换为Integer的实例,浮点数转换为Float的实例等。它还能够强制转换从Basic继承的符号表达式。这在与 SAGE 合作时非常有用。

警告

请注意,此函数使用eval,因此不应用于未经过滤的输入。

如果参数已经是 SymPy 理解的类型,则不会执行任何操作,只会返回该值。这可以用于函数开始时确保使用正确的类型。

示例

>>> from sympy import sympify 
>>> sympify(2).is_integer
True
>>> sympify(2).is_real
True 
>>> sympify(2.0).is_real
True
>>> sympify("2.0").is_real
True
>>> sympify("2e-45").is_real
True 

如果无法转换表达式,则会引发SympifyError

>>> sympify("x***2")
Traceback (most recent call last):
...
SympifyError: SympifyError: "could not parse 'x***2'" 

当尝试使用sympify解析非 Python 语法时,会引发SympifyError

>>> sympify("2x+1")
Traceback (most recent call last):
...
SympifyError: Sympify of expression 'could not parse '2x+1'' failed 

要解析非 Python 语法,请使用sympy.parsing.sympy_parser中的parse_expr

>>> from sympy.parsing.sympy_parser import parse_expr
>>> parse_expr("2x+1", transformations="all")
2*x + 1 

有关transformations的更多详细信息,请参见parse_expr()

本地

sympify 发生时可以访问通过from sympy import *加载的所有内容;在字符串中使用的任何未由该导入定义的内容都将转换为符号。在以下示例中,bitcount函数被视为符号,O被解释为Order对象(与级数一起使用),在错误使用时将引发错误:

>>> s = 'bitcount(42)'
>>> sympify(s)
bitcount(42)
>>> sympify("O(x)")
O(x)
>>> sympify("O + 1")
Traceback (most recent call last):
...
TypeError: unbound method... 

为了让bitcount被识别,可以将其导入到命名空间字典中,并作为局部变量传递:

>>> ns = {}
>>> exec('from sympy.core.evalf import bitcount', ns)
>>> sympify(s, locals=ns)
6 

为了将O解释为符号,在命名空间字典中将其标识为符号。有多种方法可以做到这一点;以下三种都是可能的方式:

>>> from sympy import Symbol
>>> ns["O"] = Symbol("O")  # method 1
>>> exec('from sympy.abc import O', ns)  # method 2
>>> ns.update(dict(O=Symbol("O")))  # method 3
>>> sympify("O + 1", locals=ns)
O + 1 

如果您希望所有单字母和希腊字母变量都是符号,那么可以使用那里定义的冲突符号字典作为私有变量: _clash1(单字母变量), _clash2(多字母希腊名称)或 _clash(在abc中定义的单字母和多字母名称)。

>>> from sympy.abc import _clash1
>>> set(_clash1)  # if this fails, see issue #23903
{'E', 'I', 'N', 'O', 'Q', 'S'}
>>> sympify('I & Q', _clash1)
I & Q 

严格

如果选项strict设置为True,则仅转换已定义显式转换的类型。在其他情况下,将引发 SympifyError。

>>> print(sympify(None))
None
>>> sympify(None, strict=True)
Traceback (most recent call last):
...
SympifyError: SympifyError: None 

自版本 1.6 起弃用:当所有其他转换方法失败时,sympify(obj)自动退回到str(obj),但这已被弃用。strict=True将禁用此弃用行为。请参阅在 sympify()中的字符串回退。

评估

如果选项evaluate设置为False,则算术和运算符将转换为它们的 SymPy 等效项,并添加evaluate=False选项。嵌套的AddMul将首先解嵌套。这通过 AST 转换完成,替换运算符为它们的 SymPy 等效项,因此如果操作数重新定义任何这些操作,则不会使用重新定义的运算符。如果参数 a 不是字符串,则在传递给 sympify 之前对数学表达式进行评估,因此添加evaluate=False仍将返回表达式的评估结果。

>>> sympify('2**2 / 3 + 5')
19/3
>>> sympify('2**2 / 3 + 5', evaluate=False)
2**2/3 + 5
>>> sympify('4/2+7', evaluate=True)
9
>>> sympify('4/2+7', evaluate=False)
4/2 + 7
>>> sympify(4/2+7, evaluate=False)
9.00000000000000 

扩展

要将sympify扩展为转换自定义对象(不是从Basic派生),只需为您的类定义一个_sympy_方法。即使是对您不拥有的类也可以通过子类化或在运行时添加该方法来完成。

>>> from sympy import Matrix
>>> class MyList1(object):
...     def __iter__(self):
...         yield 1
...         yield 2
...         return
...     def __getitem__(self, i): return list(self)[i]
...     def _sympy_(self): return Matrix(self)
>>> sympify(MyList1())
Matrix([
[1],
[2]]) 

如果您无法控制类定义,也可以使用全局字典converter。键是类,值是一个接受单个参数并返回所需 SymPy 对象的函数,例如converter[MyList] = lambda x: Matrix(x)

>>> class MyList2(object):   # XXX Do not do this if you control the class!
...     def __iter__(self):  #     Use _sympy_!
...         yield 1
...         yield 2
...         return
...     def __getitem__(self, i): return list(self)[i]
>>> from sympy.core.sympify import converter
>>> converter[MyList2] = lambda x: Matrix(x)
>>> sympify(MyList2())
Matrix([
[1],
[2]]) 

注意

当输入为字符串时,关键字rationalconvert_xor仅在使用时使用。

Convert_xor

>>> sympify('x^y',convert_xor=True)
x**y
>>> sympify('x^y',convert_xor=False)
x ^ y 

有理数

>>> sympify('0.1',rational=False)
0.1
>>> sympify('0.1',rational=True)
1/10 

有时,在 sympification 期间的自动简化会导致表达式在结构上与输入时大不相同。直到不再进行此类自动简化为止,kernS函数可能有些用处。在下面的示例中,您可以看到如何通过使用kernS来将表达式简化为(-1),而在自动简化时则不会这样做。

>>> from sympy.core.sympify import kernS
>>> from sympy.abc import x
>>> -2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1
-1
>>> s = '-2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1'
>>> sympify(s)
-1
>>> kernS(s)
-2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1 
```  ## 假设

本模块包含处理假设的机制。还请考虑指南假设。

所有符号对象都有假设属性,可以通过`.is_<assumption name>`属性访问。

假设确定符号对象的某些属性,并且可能有 3 个可能的值:`True`、`False`、`None`。如果对象具有该属性,则返回 `True`,如果不具有或不能确定(即不合适),则返回 `False`:

```py
>>> from sympy import I
>>> I.is_algebraic
True
>>> I.is_real
False
>>> I.is_prime
False 

当属性无法确定(或者方法未实现)时,将返回 None。例如,一个通用符号 x 可能是正数也可能不是,因此对于 x.is_positive 返回 None

默认情况下,所有符号值都属于给定上下文中最大的集合,而不指定属性。例如,具有整数属性的符号也是实数、复数等。

以下是可能的假设名称列表:

可交换的

对象在乘法操作中与任何其他对象都是可交换的。参见 [12]

complex

对象只能取复数集合中的值。参见 [13]

虚数

对象的值是可以写成实数乘以虚数单位 I 的数。参见 [R112]。请注意,0 不被视为虚数,请参见 issue #7649

实数

对象只能取实数集合中的值。

extended_real

对象只能取实数、oo-oo 集合中的值。

整数

对象只能取整数集合中的值。

奇数

偶数

对象只能取奇(偶)整数集合中的值 [R111]

质数

对象是一个大于 1 且没有除了 1 和自身以外正除数的自然数。参见 [R115]

复合数

对象是一个正整数,至少有一个除了 1 或该数本身以外的正除数。参见 [R113]

zero

对象的值为 0。

非零

对象是一个非零的实数。

有理数

对象只能取有理数集合中的值。

algebraic

对象只能取代数数集合中的值 [11]

超越数

对象只能取超越数集合中的值 [10]

无理数

对象的值不能用 Rational 精确表示,参见 [R114]

有限的

无穷大

对象的绝对值是有界的(任意大)。参见 [R116][R117][R118]

负数

非负数

对象只能取负(非负)值 [R110]

正数

nonpositive

对象只能取正(非正)值。

extended_negative

extended_nonnegative

extended_positive

extended_nonpositive

extended_nonzero

与没有扩展部分相同,但也包括具有相应符号的无穷大,例如,extended_positive 包括 oo

Hermite

反埃尔米特

对象属于埃尔米特(反埃尔米特)算子的领域。

示例

>>> from sympy import Symbol
>>> x = Symbol('x', real=True); x
x
>>> x.is_real
True
>>> x.is_complex
True 

参见

另见

sympy.core.numbers.ImaginaryUnit sympy.core.numbers.Zero sympy.core.numbers.One sympy.core.numbers.Infinity sympy.core.numbers.NegativeInfinity sympy.core.numbers.ComplexInfinity

注释

任何 SymPy 表达式的完全解析假设可以按如下方式获取:

>>> from sympy.core.assumptions import assumptions
>>> x = Symbol('x',positive=True)
>>> assumptions(x + I)
{'commutative': True, 'complex': True, 'composite': False, 'even':
False, 'extended_negative': False, 'extended_nonnegative': False,
'extended_nonpositive': False, 'extended_nonzero': False,
'extended_positive': False, 'extended_real': False, 'finite': True,
'imaginary': False, 'infinite': False, 'integer': False, 'irrational':
False, 'negative': False, 'noninteger': False, 'nonnegative': False,
'nonpositive': False, 'nonzero': False, 'odd': False, 'positive':
False, 'prime': False, 'rational': False, 'real': False, 'zero':
False} 

开发者注意事项

当前(可能是不完整的)值存储在obj._assumptions dictionary中;访问对象/类的属性或属性方法的查询将返回值并更新字典。

>>> eq = x**2 + I
>>> eq._assumptions
{}
>>> eq.is_finite
True
>>> eq._assumptions
{'finite': True, 'infinite': False} 

对于Symbol,可能感兴趣的假设有两个位置。assumptions0属性给出从给定初始假设导出的完整假设集。后者的假设存储在Symbol._assumptions_orig中。

>>> Symbol('x', prime=True, even=True)._assumptions_orig
{'even': True, 'prime': True} 

_assumptions_orig 不一定是规范化的,也没有经过任何过滤:它记录了用于实例化符号的假设,并(为了存储目的)表示需要重建符号的全部假设的更紧凑表示形式。

参考文献

[R110]

en.wikipedia.org/wiki/Negative_number

[R111]

en.wikipedia.org/wiki/Parity_%28mathematics%29

[R112]

en.wikipedia.org/wiki/Imaginary_number

[R113]

en.wikipedia.org/wiki/Composite_number

[R114]

en.wikipedia.org/wiki/Irrational_number

[R115]

en.wikipedia.org/wiki/Prime_number

[R116]

en.wikipedia.org/wiki/Finite

[R117]

docs.python.org/3/library/math.html#math.isfinite

[R118]

numpy.org/doc/stable/reference/generated/numpy.isfinite.html ## 缓存

sympy.core.cache.__cacheit(maxsize)

缓存装饰器。

重要:缓存函数的结果必须是不可变的

示例

>>> from sympy import cacheit
>>> @cacheit
... def f(a, b):
...    return a+b 
>>> @cacheit
... def f(a, b): # noqa: F811
...    return [a, b] # <-- WRONG, returns mutable object 

要强制cacheit检查返回结果的可变性和一致性,请将环境变量SYMPY_USE_CACHE设置为‘debug’ ## 基本

class sympy.core.basic.Basic(*args)

所有 SymPy 对象的基类。

注释与约定

  1. 当访问某个实例的参数时,始终使用.args
>>> from sympy import cot
>>> from sympy.abc import x, y 
>>> cot(x).args
(x,) 
>>> cot(x).args[0]
x 
>>> (x*y).args
(x, y) 
>>> (x*y).args[1]
y 
  1. 永远不要使用内部方法或变量(以_为前缀的那些):
>>> cot(x)._args    # do not use this, use cot(x).args instead
(x,) 
  1. 通过“SymPy 对象”,我们指的是可以由sympify返回的东西。但并非所有使用 SymPy 遇到的对象都是 Basic 的子类。例如,可变对象不是:

    >>> from sympy import Basic, Matrix, sympify
    >>> A = Matrix([[1, 2], [3, 4]]).as_mutable()
    >>> isinstance(A, Basic)
    False 
    
    >>> B = sympify(A)
    >>> isinstance(B, Basic)
    True 
    
property args: tuple[Basic, ...]

返回‘self’的参数的元组。

示例

>>> from sympy import cot
>>> from sympy.abc import x, y 
>>> cot(x).args
(x,) 
>>> cot(x).args[0]
x 
>>> (x*y).args
(x, y) 
>>> (x*y).args[1]
y 

注意

永远不要使用 self._args,总是使用 self.args。只有在创建新函数时,在 new 中使用 _args。不要覆盖 Basic 的 .args()(以便在需要时容易更改接口)。

as_content_primitive(radical=False, clear=True)

一个存根,允许在计算表达式的内容和基本组成部分时跳过 Basic args(如 Tuple)。

另见

sympy.core.expr.Expr.as_content_primitive

as_dummy()

返回表达式,其中具有结构绑定符号的任何对象都被替换为该对象中唯一的、规范的符号,并且仅具有默认的交换性假设为 True。当应用于符号时,将返回一个具有相同交换性的新符号。

示例

>>> from sympy import Integral, Symbol
>>> from sympy.abc import x
>>> r = Symbol('r', real=True)
>>> Integral(r, (r, x)).as_dummy()
Integral(_0, (_0, x))
>>> _.variables[0].is_real is None
True
>>> r.as_dummy()
_r 

注意事项

任何具有结构绑定变量的对象应该有一个属性,(bound_symbols),返回出现在对象中的那些符号。

property assumptions0

返回对象 (type) 的假设。

例如:

Symbol('x', real=True) Symbol('x', integer=True)

是不同的对象。换句话说,除了 Python 类型(本例中为 Symbol)之外,初始假设也形成它们的类型信息。

示例

>>> from sympy import Symbol
>>> from sympy.abc import x
>>> x.assumptions0
{'commutative': True}
>>> x = Symbol("x", positive=True)
>>> x.assumptions0
{'commutative': True, 'complex': True, 'extended_negative': False,
 'extended_nonnegative': True, 'extended_nonpositive': False,
 'extended_nonzero': True, 'extended_positive': True, 'extended_real':
 True, 'finite': True, 'hermitian': True, 'imaginary': False,
 'infinite': False, 'negative': False, 'nonnegative': True,
 'nonpositive': False, 'nonzero': True, 'positive': True, 'real':
 True, 'zero': False} 
atoms(*types)

返回形成当前对象的原子。

默认情况下,仅返回真正原子且不能分解为更小部分的对象:符号、数字和诸如 I 和 pi 之类的数字符号。但是,可以请求任何类型的原子,如下所示。

示例

>>> from sympy import I, pi, sin
>>> from sympy.abc import x, y
>>> (1 + x + 2*sin(y + I*pi)).atoms()
{1, 2, I, pi, x, y} 

如果给出了一个或多个类型,则结果将仅包含那些类型的原子。

>>> from sympy import Number, NumberSymbol, Symbol
>>> (1 + x + 2*sin(y + I*pi)).atoms(Symbol)
{x, y} 
>>> (1 + x + 2*sin(y + I*pi)).atoms(Number)
{1, 2} 
>>> (1 + x + 2*sin(y + I*pi)).atoms(Number, NumberSymbol)
{1, 2, pi} 
>>> (1 + x + 2*sin(y + I*pi)).atoms(Number, NumberSymbol, I)
{1, 2, I, pi} 

注意,I(虚数单位)和 zoo(复杂无穷大)是特殊类型的数字符号,不属于 NumberSymbol 类。

也可以隐式地给出类型:

>>> (1 + x + 2*sin(y + I*pi)).atoms(x) # x is a Symbol
{x, y} 

使用隐式选项时,请检查您的假设。例如,S(1).is_Integer = True,但type(S(1))One,SymPy 原子的特殊类型,而type(S(2))Integer类型,并将在表达式中找到所有整数:

>>> from sympy import S
>>> (1 + x + 2*sin(y + I*pi)).atoms(S(1))
{1} 
>>> (1 + x + 2*sin(y + I*pi)).atoms(S(2))
{1, 2} 

最后,atoms() 的参数可以选择超出原子的原子:可以列出任何 SymPy 类型(加载在 core/init.py 中),并且在递归扫描表达式参数时找到那些类型的“原子”:

>>> from sympy import Function, Mul
>>> from sympy.core.function import AppliedUndef
>>> f = Function('f')
>>> (1 + f(x) + 2*sin(y + I*pi)).atoms(Function)
{f(x), sin(y + I*pi)}
>>> (1 + f(x) + 2*sin(y + I*pi)).atoms(AppliedUndef)
{f(x)} 
>>> (1 + x + 2*sin(y + I*pi)).atoms(Mul)
{I*pi, 2*sin(y + I*pi)} 
property canonical_variables

返回一个字典,将定义在 self.bound_symbols 中的任何变量映射到表达式中不与任何自由符号冲突的符号。

示例

>>> from sympy import Lambda
>>> from sympy.abc import x
>>> Lambda(x, 2*x).canonical_variables
{x: _0} 
classmethod class_key()

类的良好顺序。

compare(other)

如果对象在规范意义上小于、等于或大于其他对象,则返回-1、0、1。非 Basic 总是大于 Basic。如果比较的类名都出现在(ordering_of_classes)中,则比较将取决于它们在该列表中的出现顺序。如果其中任何一个不出现在该列表中,则基于类名进行比较。如果类名相同,则基于可散列内容的长度进行比较。相同长度的内容项目然后按照相同规则依次比较。如果从未有过差异,则返回 0。

示例

>>> from sympy.abc import x, y
>>> x.compare(y)
-1
>>> x.compare(x)
0
>>> y.compare(x)
1 
count(query)

统计匹配子表达式的数量。

count_ops(visual=None)

count_ops 的包装器,返回操作计数。

doit(**hints)

评估默认情况下不评估的对象,如限制、积分、求和和乘积。所有这类对象将被递归评估,除非通过'hints'排除了某些类型,或者除非设置了'deep'提示为'False'。

>>> from sympy import Integral
>>> from sympy.abc import x 
>>> 2*Integral(x, x)
2*Integral(x, x) 
>>> (2*Integral(x, x)).doit()
x**2 
>>> (2*Integral(x, x)).doit(deep=False)
2*Integral(x, x) 
dummy_eq(other, symbol=None)

比较两个表达式并处理虚拟符号。

示例

>>> from sympy import Dummy
>>> from sympy.abc import x, y 
>>> u = Dummy('u') 
>>> (u**2 + 1).dummy_eq(x**2 + 1)
True
>>> (u**2 + 1) == (x**2 + 1)
False 
>>> (u**2 + y).dummy_eq(x**2 + y, x)
True
>>> (u**2 + y).dummy_eq(x**2 + y, y)
False 
find(query, group=False)

找到所有与查询匹配的子表达式。

property free_symbols: set[Basic]

从 self 的原子中返回那些是自由符号。

并非所有的自由符号都是 Symbol。例如:IndexedBase('I')[0].free_symbols

对于大多数表达式,所有符号都是自由符号。对于某些类,情况并非如此。例如,积分使用作为绑定变量的符号,因此积分有一个方法可以返回除这些符号外的所有符号。导数还跟踪它将执行导数的符号;这些也是绑定变量,因此它有自己的 free_symbols 方法。

任何使用绑定变量的其他方法都应实现一个 free_symbols 方法。

classmethod fromiter(args, **assumptions)

从可迭代对象创建一个新对象。

这是一个便利函数,允许从任何可迭代对象创建对象,而无需首先转换为列表或元组。

示例

>>> from sympy import Tuple
>>> Tuple.fromiter(i for i in range(5))
(0, 1, 2, 3, 4) 
property func

表达式中的顶级函数。

对于所有对象,应该满足以下条件:

>> x == x.func(*x.args) 

示例

>>> from sympy.abc import x
>>> a = 2*x
>>> a.func
<class 'sympy.core.mul.Mul'>
>>> a.args
(2, x)
>>> a.func(*a.args)
2*x
>>> a == a.func(*a.args)
True 
has(*patterns)

测试是否有任何子表达式与任何模式匹配。

示例

>>> from sympy import sin
>>> from sympy.abc import x, y, z
>>> (x**2 + sin(x*y)).has(z)
False
>>> (x**2 + sin(x*y)).has(x, y, z)
True
>>> x.has(x)
True 

注意has是一个结构算法,不涉及数学知识。考虑以下半开区间:

>>> from sympy import Interval
>>> i = Interval.Lopen(0, 5); i
Interval.Lopen(0, 5)
>>> i.args
(0, 5, True, False)
>>> i.has(4)  # there is no "4" in the arguments
False
>>> i.has(0)  # there *is* a "0" in the arguments
True 

相反,使用contains来确定一个数字是否在区间内:

>>> i.contains(4)
True
>>> i.contains(0)
False 

注意,expr.has(*patterns)any(expr.has(p) for p in patterns)完全等效。特别是当模式列表为空时返回False

>>> x.has()
False 
has_free(*patterns)

如果 self 作为自由表达式具有对象 x,则返回 True,否则返回 False。

示例

>>> from sympy import Integral, Function
>>> from sympy.abc import x, y
>>> f = Function('f')
>>> g = Function('g')
>>> expr = Integral(f(x), (f(x), 1, g(y)))
>>> expr.free_symbols
{y}
>>> expr.has_free(g(y))
True
>>> expr.has_free(*(x, f(x)))
False 

这也适用于子表达式和类型:

>>> expr.has_free(g)
True
>>> (x + y + 1).has_free(y + 1)
True 
has_xfree(s: set[Basic])

如果 self 的任何模式作为自由参数存在,则返回 True,否则返回 False。这类似于(Basic.has_free),但只会报告精确的参数匹配。

示例

>>> from sympy import Function
>>> from sympy.abc import x, y
>>> f = Function('f')
>>> f(x).has_xfree({f})
False
>>> f(x).has_xfree({f(x)})
True
>>> f(x + 1).has_xfree({x})
True
>>> f(x + 1).has_xfree({x + 1})
True
>>> f(x + y + 1).has_xfree({x + 1})
False 
property is_comparable

如果 self 可以计算为实数(或已经是实数),则返回 True,否则返回 False。

示例

>>> from sympy import exp_polar, pi, I
>>> (I*exp_polar(I*pi/2)).is_comparable
True
>>> (I*exp_polar(I*pi*2)).is_comparable
False 

结果错误并不意味着 (self) 不能重写成一个可比较的形式。例如,下面计算的差异为零,但在简化之前不能精确计算为零:

>>> e = 2**pi*(1 + 2**pi)
>>> dif = e - e.expand()
>>> dif.is_comparable
False
>>> dif.n(2)._prec
1 
is_same(b, approx=None)

如果 approx 被提供,则返回 True,如果 a 和 b 在结构上相同,否则返回 False。默认情况下,只有相同类型的数字才会比较相等,因此 S.Half != Float(0.5)。

示例

在 SymPy 中(不像 Python),如果两个数字的类型不同,则它们不会比较相同:

>>> from sympy import S
>>> 2.0 == S(2)
False
>>> 0.5 == S.Half
False 

通过提供一个比较两个数字的函数,可以忽略这样的差异。例如,equal_valued 将为具有 2 的次幂分母的十进制数返回 True,而不考虑精度。

>>> from sympy import Float
>>> from sympy.core.numbers import equal_valued
>>> (S.Half/4).is_same(Float(0.125, 1), equal_valued)
True
>>> Float(1, 2).is_same(Float(1, 10), equal_valued)
True 

但是,没有 2 的次幂分母的十进制数将比较为不相同。

>>> Float(0.1, 9).is_same(Float(0.1, 10), equal_valued)
False 

但是可以通过提供一个函数来忽略任意差异,以测试两个数字的等价性:

>>> import math
>>> Float(0.1, 9).is_same(Float(0.1, 10), math.isclose)
True 

即使类型不同,其他对象可能会比较相同。此例程仅在两个表达式在类类型上完全相同时返回 True。

>>> from sympy import eye, Basic
>>> eye(1) == S(eye(1))  # mutable vs immutable
True
>>> Basic.is_same(eye(1), S(eye(1)))
False 
match(pattern, old=False)

模式匹配。

通配符匹配全部。

当表达式(self)与模式不匹配时返回 None。否则返回一个字典,如下所示:

pattern.xreplace(self.match(pattern)) == self 

示例

>>> from sympy import Wild, Sum
>>> from sympy.abc import x, y
>>> p = Wild("p")
>>> q = Wild("q")
>>> r = Wild("r")
>>> e = (x+y)**(x+y)
>>> e.match(p**p)
{p_: x + y}
>>> e.match(p**q)
{p_: x + y, q_: x + y}
>>> e = (2*x)**2
>>> e.match(p*q**r)
{p_: 4, q_: x, r_: 2}
>>> (p*q**r).xreplace(e.match(p*q**r))
4*x**2 

结构绑定符号在匹配过程中被忽略:

>>> Sum(x, (x, 1, 2)).match(Sum(y, (y, 1, p)))
{p_: 2} 

但如果需要的话,它们可以被识别出来:

>>> Sum(x, (x, 1, 2)).match(Sum(q, (q, 1, p)))
{p_: 2, q_: x} 

old 标志将提供旧式模式匹配,在这种匹配中,表达式和模式本质上是为了给出匹配而解决的。除非 old=True,否则以下两个都会返回 None:

>>> (x - 2).match(p - x, old=True)
{p_: 2*x - 2}
>>> (2/x).match(p*x, old=True)
{p_: 2/x**2} 
matches(expr, repl_dict=None, old=False)

selfexpr 中的通配符匹配的帮助方法。

示例

>>> from sympy import symbols, Wild, Basic
>>> a, b, c = symbols('a b c')
>>> x = Wild('x')
>>> Basic(a + x, x).matches(Basic(a + b, c)) is None
True
>>> Basic(a + x, x).matches(Basic(a + b + c, b + c))
{x_: b + c} 
rcall(*args)

递归地应用于表达式树中的参数。

该方法用于模拟操作符的常见滥用符号。例如,在 SymPy 中,以下内容将无法工作:

(x+Lambda(y, 2*y))(z) == x+2*z,

然而,您可以使用:

>>> from sympy import Lambda
>>> from sympy.abc import x, y, z
>>> (x + Lambda(y, 2*y)).rcall(z)
x + 2*z 
refine(assumption=True)

请参见 sympy.assumptions 中的 refine 函数。

replace(query, value, map=False, simultaneous=True, exact=None)

value替换self中匹配的子表达式。

如果 map = True,则还返回映射 {old: new},其中 old 是通过查询找到的子表达式,new 是其替换值。如果表达式本身与查询不匹配,则返回的值将是 self.xreplace(map),否则应该是 self.subs(ordered(map.items()))

遍历表达式树并从树底部到树顶部执行匹配子表达式的替换。默认方法是同时进行替换,因此所做的更改仅针对一次。如果不希望或引起问题,则可以将 simultaneous 设置为 False。

此外,如果使用包含多个通配符号的表达式来匹配子表达式,并且 exact 标志为 None,则将其设置为 True,因此仅当每个出现在匹配模式中的通配符都收到非零值时,匹配才会成功。将其设置为 False 接受匹配 0;而设置为 True 则接受所有具有 0 的匹配。有关注意事项,请参见下面的示例。

列出了查询和替换值的可能组合列表:

示例

初始设置

>>> from sympy import log, sin, cos, tan, Wild, Mul, Add
>>> from sympy.abc import x, y
>>> f = log(sin(x)) + tan(sin(x**2)) 

1.1. 类型 -> 类型

obj.replace(type, newtype)

当找到类型为 type 的对象时,用其参数传递给 newtype 的结果替换它。

>>> f.replace(sin, cos)
log(cos(x)) + tan(cos(x**2))
>>> sin(x).replace(sin, cos, map=True)
(cos(x), {sin(x): cos(x)})
>>> (x*y).replace(Mul, Add)
x + y 

1.2. 类型 -> 函数

obj.replace(type, func)

当找到类型为 type 的对象时,将 func 应用于其参数。 func 必须编写以处理 type 的参数数量。

>>> f.replace(sin, lambda arg: sin(2*arg))
log(sin(2*x)) + tan(sin(2*x**2))
>>> (x*y).replace(Mul, lambda *args: sin(2*Mul(*args)))
sin(2*x*y) 

2.1. 模式 -> 表达式

obj.replace(pattern(wild), expr(wild))

使用带有通配符号的 pattern 替换子表达式为表达式。

>>> a, b = map(Wild, 'ab')
>>> f.replace(sin(a), tan(a))
log(tan(x)) + tan(tan(x**2))
>>> f.replace(sin(a), tan(a/2))
log(tan(x/2)) + tan(tan(x**2/2))
>>> f.replace(sin(a), a)
log(x) + tan(x**2)
>>> (x*y).replace(a*x, a)
y 

默认情况下,当使用多个通配符号进行匹配时,匹配是精确的:除非匹配对所有通配符号都给出非零值,否则匹配失败:

>>> (2*x + y).replace(a*x + b, b - a)
y - 2
>>> (2*x).replace(a*x + b, b - a)
2*x 

当设置为 False 时,结果可能不直观:

>>> (2*x).replace(a*x + b, b - a, exact=False)
2/x 

2.2. 模式 -> 函数

obj.replace(pattern(wild), lambda wild: expr(wild))

所有行为与 2.1 中相同,但现在使用的是基于模式变量的函数而不是表达式:

>>> f.replace(sin(a), lambda a: sin(2*a))
log(sin(2*x)) + tan(sin(2*x**2)) 

3.1. 函数 -> 函数

obj.replace(filter, func)

如果 filter(e) 为真,则用 func(e) 替换子表达式 e

>>> g = 2*sin(x**3)
>>> g.replace(lambda expr: expr.is_Number, lambda expr: expr**2)
4*sin(x**9) 

查询本身也是目标表达式的目标,但是以不做两次更改的方式进行。

>>> e = x*(x*y + 1)
>>> e.replace(lambda x: x.is_Mul, lambda x: 2*x)
2*x*(2*x*y + 1) 

当匹配单个符号时,(exact) 默认为 True,但这可能或可能不是所需的行为:

在这里,我们希望 (exact=False):

>>> from sympy import Function
>>> f = Function('f')
>>> e = f(1) + f(0)
>>> q = f(a), lambda a: f(a + 1)
>>> e.replace(*q, exact=False)
f(1) + f(2)
>>> e.replace(*q, exact=True)
f(0) + f(2) 

但在这里,匹配的性质使得选择正确的设置变得棘手:

>>> e = x**(1 + y)
>>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, exact=False)
x
>>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, exact=True)
x**(-x - y + 1)
>>> (x**y).replace(x**(1 + a), lambda a: x**-a, exact=False)
x
>>> (x**y).replace(x**(1 + a), lambda a: x**-a, exact=True)
x**(1 - y) 

最好使用描述目标表达式更精确的查询形式:

>>> (1 + x**(1 + y)).replace(
... lambda x: x.is_Pow and x.exp.is_Add and x.exp.args[0] == 1,
... lambda x: x.base**(1 - (x.exp - 1)))
...
x**(1 - y) + 1 

另见

subs

替换由对象本身定义的子表达式。

xreplace

在表达树中进行精确的节点替换;还能够使用匹配规则

rewrite(*args, deep=True, **hints)

使用定义的规则重写 self

重写将一个表达式转换为另一个,在数学上是等效的但结构不同的表达式。例如,您可以将三角函数重写为复指数函数或将组合函数重写为伽马函数。

此方法采用 模式规则 作为位置参数。 模式 是可选参数,定义将进行转换的表达式类型。如果未传递,则将重新编写所有可能的表达式。 规则 定义如何重新编写表达式。

参数:

args : 表达式

一个 规则模式规则。 - 模式 是一种类型或可迭代类型。 - 规则 可以是任何对象。

deep : 布尔值,可选

如果为True,则子表达式会递归转换。默认为True

示例

如果未指定 pattern,则将转换所有可能的表达式。

>>> from sympy import cos, sin, exp, I
>>> from sympy.abc import x
>>> expr = cos(x) + I*sin(x)
>>> expr.rewrite(exp)
exp(I*x) 

模式可以是类型或类型的可迭代对象。

>>> expr.rewrite(sin, exp)
exp(I*x)/2 + cos(x) - exp(-I*x)/2
>>> expr.rewrite([cos,], exp)
exp(I*x)/2 + I*sin(x) + exp(-I*x)/2
>>> expr.rewrite([cos, sin], exp)
exp(I*x) 

可通过定义 _eval_rewrite() 方法实现重写行为。

>>> from sympy import Expr, sqrt, pi
>>> class MySin(Expr):
...     def _eval_rewrite(self, rule, args, **hints):
...         x, = args
...         if rule == cos:
...             return cos(pi/2 - x, evaluate=False)
...         if rule == sqrt:
...             return sqrt(1 - cos(x)**2)
>>> MySin(MySin(x)).rewrite(cos)
cos(-cos(-x + pi/2) + pi/2)
>>> MySin(x).rewrite(sqrt)
sqrt(1 - cos(x)**2) 

支持为了向后兼容性原因定义 _eval_rewrite_as_[...]() 方法。这可能在将来会被移除,不推荐使用它。

>>> class MySin(Expr):
...     def _eval_rewrite_as_cos(self, *args, **hints):
...         x, = args
...         return cos(pi/2 - x, evaluate=False)
>>> MySin(x).rewrite(cos)
cos(-x + pi/2) 
simplify(**kwargs)

参见 sympy.simplify 中的 simplify 函数

sort_key(order=None)

返回排序关键字。

示例

>>> from sympy import S, I 
>>> sorted([S(1)/2, I, -I], key=lambda x: x.sort_key())
[1/2, -I, I] 
>>> S("[x, 1/x, 1/x**2, x**2, x**(1/2), x**(1/4), x**(3/2)]")
[x, 1/x, x**(-2), x**2, sqrt(x), x**(1/4), x**(3/2)]
>>> sorted(_, key=lambda x: x.sort_key())
[x**(-2), 1/x, x**(1/4), sqrt(x), x, x**(3/2), x**2] 
subs(*args, **kwargs)

在 sympify args 之后,在表达式中用 new 替换 old。

(args) 可能是:

  • 两个参数,例如 foo.subs(old, new)

  • 一个可迭代的参数,例如 foo.subs(iterable)。可迭代对象可以是

    一个可迭代的容器,包含 (old, new) 对。在这种情况下,

    替换按给定顺序处理,后续模式可能会影响已进行的替换。

    一个字典或集合,其键/值项对应于旧/新对。

    在这种情况下,旧/新对将按 op 计数排序,并在平局时按参数数量和默认排序关键字排序。然后处理结果排序后的列表作为可迭代容器(见前述)。

如果关键字 simultaneous 设置为 True,则子表达式将在所有替换完成后再进行评估。

示例

>>> from sympy import pi, exp, limit, oo
>>> from sympy.abc import x, y
>>> (1 + x*y).subs(x, pi)
pi*y + 1
>>> (1 + x*y).subs({x:pi, y:2})
1 + 2*pi
>>> (1 + x*y).subs([(x, pi), (y, 2)])
1 + 2*pi
>>> reps = [(y, x**2), (x, 2)]
>>> (x + y).subs(reps)
6
>>> (x + y).subs(reversed(reps))
x**2 + 2 
>>> (x**2 + x**4).subs(x**2, y)
y**2 + y 

仅替换 x2 而不替换 x4,使用 xreplace:

>>> (x**2 + x**4).xreplace({x**2: y})
x**4 + y 

若要延迟评估直到所有替换完成,请将关键字 simultaneous 设置为 True:

>>> (x/y).subs([(x, 0), (y, 0)])
0
>>> (x/y).subs([(x, 0), (y, 0)], simultaneous=True)
nan 

这还具有不允许后续替换影响已进行替换的额外功能:

>>> ((x + y)/y).subs({x + y: y, y: x + y})
1
>>> ((x + y)/y).subs({x + y: y, y: x + y}, simultaneous=True)
y/(x + y) 

为了获得规范结果,无序可迭代对象会按照长度、参数数量和默认排序关键字进行排序,以打破任何平局。所有其他可迭代对象保持不排序状态。

>>> from sympy import sqrt, sin, cos
>>> from sympy.abc import a, b, c, d, e 
>>> A = (sqrt(sin(2*x)), a)
>>> B = (sin(2*x), b)
>>> C = (cos(2*x), c)
>>> D = (x, d)
>>> E = (exp(x), e) 
>>> expr = sqrt(sin(2*x))*sin(exp(x)*x)*cos(2*x) + sin(2*x) 
>>> expr.subs(dict([A, B, C, D, E]))
a*c*sin(d*e) + b 

结果表达式表示旧参数与新参数的字面替换。这可能不反映表达式的极限行为:

>>> (x**3 - 3*x).subs({x: oo})
nan 
>>> limit(x**3 - 3*x, x, oo)
oo 

如果替换后将进行数值评估,则最好将替换传递给 evalf,如

>>> (1/x).evalf(subs={x: 3.0}, n=21)
0.333333333333333333333 

而不是

>>> (1/x).subs({x: 3.0}).evalf(21)
0.333333333333333314830 

因为前者将确保获得所需的精度水平。

另请参阅

replace

能够进行类似通配符匹配、匹配解析和条件替换的替换功能

xreplace

在表达式树中确切节点替换;还能够使用匹配规则

sympy.core.evalf.EvalfMixin.evalf

计算给定公式到所需的精度水平

xreplace(rule)

在表达式中替换对象的出现。

参数:

rule:类似字典

表示替换规则

返回:

xreplace:替换的结果

示例

>>> from sympy import symbols, pi, exp
>>> x, y, z = symbols('x y z')
>>> (1 + x*y).xreplace({x: pi})
pi*y + 1
>>> (1 + x*y).xreplace({x: pi, y: 2})
1 + 2*pi 

仅当在表达式树中匹配到整个节点时才进行替换:

>>> (x*y + z).xreplace({x*y: pi})
z + pi
>>> (x*y*z).xreplace({x*y: pi})
x*y*z
>>> (2*x).xreplace({2*x: y, x: z})
y
>>> (2*2*x).xreplace({2*x: y, x: z})
4*z
>>> (x + y + 2).xreplace({x + y: 2})
x + y + 2
>>> (x + 2 + exp(x + 2)).xreplace({x + 2: y})
x + exp(y) + 2 

xreplace 不区分自由符号和绑定符号。在以下情况下,subs(x, y)不会改变 x,因为它是一个绑定符号,但 xreplace 会:

>>> from sympy import Integral
>>> Integral(x, (x, 1, 2*x)).xreplace({x: y})
Integral(y, (y, 1, 2*y)) 

尝试用一个表达式替换 x 会引发错误:

>>> Integral(x, (x, 1, 2*x)).xreplace({x: 2*y}) 
ValueError: Invalid limits given: ((2*y, 1, 4*y),) 

另请参阅

replace

替换能够进行类似通配符的匹配,匹配解析和条件替换

subs

根据对象本身定义的子表达式的替换。

class sympy.core.basic.Atom(*args)

一个原子事物的父类。原子是没有子表达式的表达式。

示例

符号,数字,有理数,整数,...但不包括:Add,Mul,Pow,... ## 单例

class sympy.core.singleton.SingletonRegistry

单例类的注册表(可作为S访问)。

解释

此类作为两个单独的事物。

第一件事是SingletonRegistry。在 SymPy 中有几个类经常出现,它们被单例化,也就是说,通过一些元编程,它们被设计成只能实例化一次(详见sympy.core.singleton.Singleton类的详细信息)。例如,每次创建Integer(0)时,都会返回相同的实例,sympy.core.numbers.Zero。所有单例实例都是S对象的属性,因此Integer(0)也可以作为S.Zero访问。

单例化提供了两个优点:它节省内存,并允许快速比较。它节省内存,因为无论单例化对象在内存中出现多少次,它们都指向内存中的同一个单一实例。快速比较来自于在 Python 中可以使用is来比较确切的实例(通常情况下,需要使用==来比较)。is通过内存地址比较对象,并且非常快速。

示例

>>> from sympy import S, Integer
>>> a = Integer(0)
>>> a is S.Zero
True 

在大多数情况下,某些对象被设计为单例化是一个用户不需要担心的实现细节。在 SymPy 库代码中,通常使用is比较是为了性能目的。对于最终用户来说,S的主要优点是方便访问某些难以输入的实例,如S.Half(而不是Rational(1, 2))。

当使用is比较时,请确保参数已经过符号化。例如,

>>> x = 0
>>> x is S.Zero
False 

当使用==时,这个问题并不是一个问题,这在大多数用例中是推荐的:

>>> 0 == S.Zero
True 

第二件事 Ssympy.core.sympify.sympify() 的快捷方式。sympy.core.sympify.sympify() 是将 Python 对象(如 int(1))转换为 SymPy 对象(如 Integer(1))的函数。它还将表达式的字符串形式转换为 SymPy 表达式,例如 sympify("x**2") -> Symbol("x")**2S(1)sympify(1) 是相同的(基本上,S.__call__ 被定义为调用 sympify)。

这是为了方便起见,因为 S 是一个单字母。这对定义有理数特别有用。考虑一个表达式 x + 1/2。如果你直接在 Python 中输入这个表达式,它会评估 1/2 并给出 0.5,因为两个参数都是整数(另请参见 两个终极注意事项:^ 和 /)。然而,在 SymPy 中,你通常希望两个整数的商能够精确地得到一个有理数。Python 评估的方式是,至少一侧的操作数需要是 SymPy 对象才能进行 SymPy 评估。你可以将这写成 x + Rational(1, 2),但这样键入的量比较多。一个更短的版本是 x + S(1)/2。由于 S(1) 返回 Integer(1),除法将返回一个 Rational 类型,因为它会调用 Integer.__truediv__,它知道如何返回一个 Rational

class sympy.core.singleton.Singleton(*args, **kwargs)

单例类的元类。

解释

单例类只有一个实例,每次实例化类时都会返回这个实例。此外,可以通过全局注册对象 S 作为 S.<class_name> 来访问这个实例。

示例

>>> from sympy import S, Basic
>>> from sympy.core.singleton import Singleton
>>> class MySingleton(Basic, metaclass=Singleton):
...     pass
>>> Basic() is Basic()
False
>>> MySingleton() is MySingleton()
True
>>> S.MySingleton is MySingleton()
True 

注意事项

实例的创建被延迟到第一次访问该值时。(SymPy 版本在 1.0 之前会在类创建时创建实例,这可能导致导入循环。) ## 表达式

class sympy.core.expr.Expr(*args)

代数表达式的基类。

解释

所有需要定义算术操作的内容应该继承这个类,而不是 BasicBasic 应该仅用于参数存储和表达式操作,即模式匹配、替换等)。

如果你想要重写表达式的比较:应该使用 _eval_is_ge 进行不等式比较,或者使用多重分发的 _eval_is_eq。_eval_is_ge 如果 x >= y 则返回 true,如果 x < y 则返回 false,如果两种类型不可比较或比较不确定则返回 None。

另请参阅

sympy.core.basic.Basic

apart(x=None, **args)

参见 sympy.polys 中的 apart 函数。

args_cnc(cset=False, warn=True, split_1=True)

返回 self 的 [可交换因子,非可交换因子]。

解释

self 被视为一个乘积,并且保持因子的顺序。如果 cset 为 True,可交换因子将返回为一个集合。如果有重复因子(如可能发生在未评估的乘积中),则除非显式将 warn 设置为 False,否则会引发错误。

注意:-1 与数字始终分开,除非 split_1 为 False。

示例

>>> from sympy import symbols, oo
>>> A, B = symbols('A B', commutative=0)
>>> x, y = symbols('x y')
>>> (-2*x*y).args_cnc()
[[-1, 2, x, y], []]
>>> (-2.5*x).args_cnc()
[[-1, 2.5, x], []]
>>> (-2*x*A*B*y).args_cnc()
[[-1, 2, x, y], [A, B]]
>>> (-2*x*A*B*y).args_cnc(split_1=False)
[[-2, x, y], [A, B]]
>>> (-2*x*y).args_cnc(cset=True)
[{-1, 2, x, y}, []] 

参数始终被视为 Mul:

>>> (-2 + x + A).args_cnc()
[[], [x - 2 + A]]
>>> (-oo).args_cnc() # -oo is a singleton
[[-1, oo], []] 
as_coeff_Add(rational=False) → tuple['Number', Expr]

高效地提取求和的系数。

as_coeff_Mul(rational: bool = False) → tuple['Number', Expr]

高效地提取乘积的系数。

as_coeff_add(*deps) → tuple[Expr, tuple[Expr, ...]]

返回元组(c, args),其中 self 被写成 Add,a

c 应该是一个 Rational,加到 Add 的任何独立于 deps 的项上。

args 应该是a的所有其他项的元组;如果 self 是一个 Number 或者 self 独立于 deps(当给定时),args 为空。

当你不确定 self 是否是 Add,但你想要将 self 视为 Add,或者你想要处理 self 尾部的各个参数作为 Add 时,应该使用这个方法。

  • 如果你知道 self 是一个 Add 并且只想要头部,使用 self.args[0];

  • 如果你不想处理尾部的参数但需要尾部,则使用 self.as_two_terms(),它会给出头部和尾部。

  • 如果你想要将 self 分成独立部分和依赖部分,请使用self.as_independent(*deps)

>>> from sympy import S
>>> from sympy.abc import x, y
>>> (S(3)).as_coeff_add()
(3, ())
>>> (3 + x).as_coeff_add()
(3, (x,))
>>> (3 + x + y).as_coeff_add(x)
(y + 3, (x,))
>>> (3 + y).as_coeff_add(x)
(y + 3, ()) 
as_coeff_exponent(x) → tuple[Expr, Expr]

c*x**e -> c,e,其中 x 可以是任何符号表达式。

as_coeff_mul(*deps, **kwargs) → tuple[Expr, tuple[Expr, ...]]

返回元组(c, args),其中 self 被写成 Mul,m

c 应该是一个 Rational,乘以任何独立于 deps 的 Mul 的因子。

args 应该是 m 的所有其他因子的元组;如果 self 是一个 Number 或者 self 独立于 deps(当给定时),args 为空。

当你不确定 self 是否是 Mul,但你想要将 self 视为 Mul,或者你想要处理 self 尾部的各个参数作为 Mul 时,应该使用这个方法。

  • 如果你知道 self 是一个 Mul 并且只想要头部,使用 self.args[0];

  • 如果你不想处理尾部的参数但需要尾部,则使用 self.as_two_terms(),它会给出头部和尾部;

  • 如果你想要将 self 分成独立部分和依赖部分,请使用self.as_independent(*deps)

>>> from sympy import S
>>> from sympy.abc import x, y
>>> (S(3)).as_coeff_mul()
(3, ())
>>> (3*x*y).as_coeff_mul()
(3, (x, y))
>>> (3*x*y).as_coeff_mul(x)
(3*y, (x,))
>>> (3*y).as_coeff_mul(x)
(3*y, ()) 
as_coefficient(expr)

在给定表达式中提取符号系数。换句话说,这个函数将‘self’分解为‘expr’和‘expr’-free 系数的乘积。如果无法进行这种分解,它将返回 None。

示例

>>> from sympy import E, pi, sin, I, Poly
>>> from sympy.abc import x 
>>> E.as_coefficient(E)
1
>>> (2*E).as_coefficient(E)
2
>>> (2*sin(E)*E).as_coefficient(E) 

两个项中都有 E,所以返回一个和。(如果希望得到与 E 完全匹配的项的系数,则可以选择返回表达式中的常数。或者,为了更高的精度,可以使用 Poly 的方法指示所需的项,从中获取系数。)

>>> (2*E + x*E).as_coefficient(E)
x + 2
>>> _.args[0]  # just want the exact match
2
>>> p = Poly(2*E + x*E); p
Poly(x*E + 2*E, x, E, domain='ZZ')
>>> p.coeff_monomial(E)
2
>>> p.nth(0, 1)
2 

由于以下内容无法写成包含 E 作为因子的乘积,因此返回 None。(如果需要系数2*x,则应该使用coeff方法。)

>>> (2*E*x + x).as_coefficient(E)
>>> (2*E*x + x).coeff(E)
2*x 
>>> (E*(x + 1) + x).as_coefficient(E) 
>>> (2*pi*I).as_coefficient(pi*I)
2
>>> (2*I).as_coefficient(pi*I) 

另请参阅

coeff

返回具有给定因子的项的和

as_coeff_Add

将一个表达式中的加法常数与表达式分开

as_coeff_Mul

将一个表达式中的乘法常数与表达式分开

as_independent

将依赖于 x 的项/因子与其他项分开

sympy.polys.polytools.Poly.coeff_monomial

高效地找到 Poly 中单项式的单一系数。

sympy.polys.polytools.Poly.nth

类似于coeff_monomial,但使用了单项式项的幂。

as_coefficients_dict(*syms)

返回一个将项映射到它们的有理系数的字典。由于字典是默认字典,对于不存在的项的查询将返回系数为 0。

如果提供了符号syms,则独立于它们的任何乘法项将被视为系数,并将返回一个常规字典,其键为依赖于syms的生成器,值为它们对应的系数。

示例

>>> from sympy.abc import a, x, y
>>> (3*x + a*x + 4).as_coefficients_dict()
{1: 4, x: 3, a*x: 1}
>>> _[a]
0
>>> (3*a*x).as_coefficients_dict()
{a*x: 3}
>>> (3*a*x).as_coefficients_dict(x)
{x: 3*a}
>>> (3*a*x).as_coefficients_dict(y)
{1: 3*a*x} 
as_content_primitive(radical=False, clear=True)

此方法应递归地从所有参数中移除有理数,并返回该(内容)和新的self(primitive)。内容应始终为正,并且Mul(*foo.as_content_primitive()) == foo。如果可能,原始形式不需要处于规范形式,并且应尽量保留底层结构(即不应将expand_mul应用于self)。

示例

>>> from sympy import sqrt
>>> from sympy.abc import x, y, z 
>>> eq = 2 + 2*x + 2*y*(3 + 3*y) 

as_content_primitive函数是递归的,并保留结构:

>>> eq.as_content_primitive()
(2, x + 3*y*(y + 1) + 1) 

整数幂将从基数中提取有理数:

>>> ((2 + 6*x)**2).as_content_primitive()
(4, (3*x + 1)**2)
>>> ((2 + 6*x)**(2*y)).as_content_primitive()
(1, (2*(3*x + 1))**(2*y)) 

一旦它们的as_content_primitives被添加,术语可能最终会合并:

>>> ((5*(x*(1 + y)) + 2*x*(3 + 3*y))).as_content_primitive()
(11, x*(y + 1))
>>> ((3*(x*(1 + y)) + 2*x*(3 + 3*y))).as_content_primitive()
(9, x*(y + 1))
>>> ((3*(z*(1 + y)) + 2.0*x*(3 + 3*y))).as_content_primitive()
(1, 6.0*x*(y + 1) + 3*z*(y + 1))
>>> ((5*(x*(1 + y)) + 2*x*(3 + 3*y))**2).as_content_primitive()
(121, x**2*(y + 1)**2)
>>> ((x*(1 + y) + 0.4*x*(3 + 3*y))**2).as_content_primitive()
(1, 4.84*x**2*(y + 1)**2) 

原始的激进内容也可以从原始中分解出来:

>>> (2*sqrt(2) + 4*sqrt(10)).as_content_primitive(radical=True)
(2, sqrt(2)*(1 + 2*sqrt(5))) 

如果clear=False(默认为 True),则不会从加法中删除内容,如果可以分布以留下一个或多个具有整数系数的项。

>>> (x/2 + y).as_content_primitive()
(1/2, x + 2*y)
>>> (x/2 + y).as_content_primitive(clear=False)
(1, x/2 + y) 
as_expr(*gens)

将多项式转换为 SymPy 表达式。

示例

>>> from sympy import sin
>>> from sympy.abc import x, y 
>>> f = (x**2 + x*y).as_poly(x, y)
>>> f.as_expr()
x**2 + x*y 
>>> sin(x).as_expr()
sin(x) 
as_independent(*deps, **hint) → tuple[Expr, Expr]

对乘积或加法进行大多数简单的分离,其参数不依赖于deps。要尽可能完整地分离变量,请首先使用分离方法,例如:

  • separatevars()将乘法、加法和幂(包括指数)转换为乘法

  • .expand(mul=True)将加法或乘法转换为加法

  • .expand(log=True) 将对数表达式转换为加法。

这里唯一非朴素的事情是尊重变量的非交换顺序,并且无论提示如何,对于零的self始终返回(0, 0)。

对于非零的self,返回的元组(id)有以下解释:

  • i将没有出现在deps中的变量。

  • self为加法时,d将包含包含在deps中的变量的项,或者等于 0(当self为加法时)或 1(当self为乘法时)。

  • 如果self是一个加法,则self = i + d

  • 如果self是一个乘法,则self = i*d

  • 否则返回(selfS.One)或(S.Oneself)。

要强制表达式被视为加法,使用提示as_Add=True

示例

self是一个加法

>>> from sympy import sin, cos, exp
>>> from sympy.abc import x, y, z 
>>> (x + x*y).as_independent(x)
(0, x*y + x)
>>> (x + x*y).as_independent(y)
(x, x*y)
>>> (2*x*sin(x) + y + x + z).as_independent(x)
(y + z, 2*x*sin(x) + x)
>>> (2*x*sin(x) + y + x + z).as_independent(x, y)
(z, 2*x*sin(x) + x + y) 

self 是一个乘积。

>>> (x*sin(x)*cos(y)).as_independent(x)
(cos(y), x*sin(x)) 

self为乘法时,非交换术语并非总是可以分离出来

>>> from sympy import symbols
>>> n1, n2, n3 = symbols('n1 n2 n3', commutative=False)
>>> (n1 + n1*n2).as_independent(n2)
(n1, n1*n2)
>>> (n2*n1 + n1*n2).as_independent(n2)
(0, n1*n2 + n2*n1)
>>> (n1*n2*n3).as_independent(n1)
(1, n1*n2*n3)
>>> (n1*n2*n3).as_independent(n2)
(n1, n2*n3)
>>> ((x-n1)*(x-y)).as_independent(x)
(1, (x - y)*(x - n1)) 

self是其他任何东西:

>>> (sin(x)).as_independent(x)
(1, sin(x))
>>> (sin(x)).as_independent(y)
(sin(x), 1)
>>> exp(x+y).as_independent(x)
(1, exp(x + y)) 

– 强制self被视为加法:

>>> (3*x).as_independent(x, as_Add=True)
(0, 3*x) 

– 强制self被视为乘法:

>>> (3+x).as_independent(x, as_Add=False)
(1, x + 3)
>>> (-3+x).as_independent(x, as_Add=False)
(1, x - 3) 

注意以下与上面不同的地方在于使依赖项术语上的常数为正。

>>> (y*(-3+x)).as_independent(x)
(y, x - 3) 

– 对真独立性测试使用 .as_independent()

.has() 的例子。前者仅考虑自由符号中的符号,而后者考虑所有符号

>>> from sympy import Integral
>>> I = Integral(x, (x, 1, 2))
>>> I.has(x)
True
>>> x in I.free_symbols
False
>>> I.as_independent(x) == (I, 1)
True
>>> (I + x).as_independent(x) == (I, x)
True 

注意:在尝试获取独立项时,可能需要先使用分离方法。在这种情况下,重要的是跟踪您发送到此例程的内容,以便知道如何解释返回的值

>>> from sympy import separatevars, log
>>> separatevars(exp(x+y)).as_independent(x)
(exp(y), exp(x))
>>> (x + x*y).as_independent(y)
(x, x*y)
>>> separatevars(x + x*y).as_independent(y)
(x, y + 1)
>>> (x*(1 + y)).as_independent(y)
(x, y + 1)
>>> (x*(1 + y)).expand(mul=True).as_independent(y)
(x, x*y)
>>> a, b=symbols('a b', positive=True)
>>> (log(a*b).expand(log=True)).as_independent(b)
(log(a), log(b)) 

另请参阅

separatevars, expand_log, sympy.core.add.Add.as_two_terms, sympy.core.mul.Mul.as_two_terms, as_coeff_mul

as_leading_term(*symbols, logx=None, cdir=0)

返回 self 的主导(非零)系列展开项。

_eval_as_leading_term 例程用于此目的,并且它们必须始终返回非零值。

示例

>>> from sympy.abc import x
>>> (1 + x + x**2).as_leading_term(x)
1
>>> (1/x**2 + x + x**2).as_leading_term(x)
x**(-2) 
as_numer_denom()

返回表达式的分子和分母。

表达式 -> a/b -> a, b

这只是一个存根,应由对象的类方法定义以获取任何其他内容。

另请参阅

normal

返回 a/b 而不是 (a, b)

as_ordered_factors(order=None)

返回有序因子列表(如果是 Mul),否则返回 [self]。

as_ordered_terms(order=None, data=False)

将表达式转换为项的有序列表。

示例

>>> from sympy import sin, cos
>>> from sympy.abc import x 
>>> (sin(x)**2*cos(x) + sin(x)**2 + 1).as_ordered_terms()
[sin(x)**2*cos(x), sin(x)**2, 1] 
as_poly(*gens, **args)

self 转换为多项式或返回 None

解释

>>> from sympy import sin
>>> from sympy.abc import x, y 
>>> print((x**2 + x*y).as_poly())
Poly(x**2 + x*y, x, y, domain='ZZ') 
>>> print((x**2 + x*y).as_poly(x, y))
Poly(x**2 + x*y, x, y, domain='ZZ') 
>>> print((x**2 + sin(y)).as_poly(x, y))
None 
as_powers_dict()

将 self 作为因子的字典返回,其中每个因子都被视为一个幂。键是因子的基数,而值是相应的指数。如果表达式是 Mul 并包含非交换因子,则应谨慎使用结果字典,因为它们出现的顺序将在字典中丢失。

另请参阅

as_ordered_factors

用于非交换应用的替代方法,返回因子的有序列表。

args_cnc

类似于 as_ordered_factors,但保证将交换和非交换因子分开。

as_real_imag(deep=True, **hints)

self 执行复杂展开,并返回一个包含实部和虚部的元组。此方法不能与 re() 和 im() 函数混淆,后者在评估时不进行复杂展开。

然而,可以展开 re() 和 im() 函数,并且与调用此函数一次获得完全相同的结果。

>>> from sympy import symbols, I 
>>> x, y = symbols('x,y', real=True) 
>>> (x + y*I).as_real_imag()
(x, y) 
>>> from sympy.abc import z, w 
>>> (z + w*I).as_real_imag()
(re(z) - im(w), re(w) + im(z)) 
as_terms()

将表达式转换为项列表。

aseries(x=None, n=6, bound=0, hir=False)

自我的渐近级数展开。这相当于 self.series(x, oo, n)

参数:

self : 表达式

要展开其级数的表达式。

x : 符号

它是要计算的表达式的变量。

n : 值

用于表示以x**n为单位的顺序的值,直到展开系列。

hir:布尔值

将此参数设置为 True 以生成分层系列。它在早期阶段停止递归,并可能提供更漂亮和更有用的结果。

bound:值,整数

使用bound参数来给出其规范形式中重写系数的限制。

返回:

表达式

表达式的渐近级数展开。

示例

>>> from sympy import sin, exp
>>> from sympy.abc import x 
>>> e = sin(1/x + exp(-x)) - sin(1/x) 
>>> e.aseries(x)
(1/(24*x**4) - 1/(2*x**2) + 1 + O(x**(-6), (x, oo)))*exp(-x) 
>>> e.aseries(x, n=3, hir=True)
-exp(-2*x)*sin(1/x)/2 + exp(-x)*cos(1/x) + O(exp(-3*x), (x, oo)) 
>>> e = exp(exp(x)/(1 - 1/x)) 
>>> e.aseries(x)
exp(exp(x)/(1 - 1/x)) 
>>> e.aseries(x, bound=3) 
exp(exp(x)/x**2)*exp(exp(x)/x)*exp(-exp(x) + exp(x)/(1 - 1/x) - exp(x)/x - exp(x)/x**2)*exp(exp(x)) 

对于有理表达式,此方法可能返回原始表达式而不带有 Order 项。 >>> (1/x).aseries(x, n=8) 1/x

注意

此算法直接来源于 Gruntz 提供的限制计算算法,主要使用 mrv 和 rewrite 子例程。该算法的整体思想首先是查找给定表达式 f 的最快变化子表达式 w,然后在 w 的系列中展开 f。然后同样的事情递归地在主导系数上进行,直到获得常数系数。

如果给定表达式 f 的最快变化子表达式是 f 本身,则算法尝试找到 mrv 集的规范表示,并使用此规范表示重写 f。

如果展开包含顺序项,则其将是O(x ** (-n))O(w ** (-n)),其中w属于self的最快变化表达式。

参见

Expr.aseries

请参阅此包装器的文档字符串以获取完整详细信息。

参考资料

[R119]

Gruntz, Dominik. A new algorithm for computing asymptotic series. In: Proc. 1993 Int. Symp. Symbolic and Algebraic Computation. 1993. pp. 239-244.

[R120]

Gruntz thesis - p90

[R121]

en.wikipedia.org/wiki/Asymptotic_expansion

cancel(*gens, **args)

请参阅 sympy.polys 中的 cancel 函数

coeff(x, n=1, right=False, _first=True)

返回包含x**n的术语中的系数。如果n为零,则将返回所有独立于x的术语。

解释

x是非交换时,可以返回x左侧(默认)或右侧的系数。当x是交换时,关键字‘right’被忽略。

示例

>>> from sympy import symbols
>>> from sympy.abc import x, y, z 

您可以选择具有明确负数的项:

>>> (-x + 2*y).coeff(-1)
x
>>> (x - 2*y).coeff(-1)
2*y 

您可以选择没有有理系数的项:

>>> (x + 2*y).coeff(1)
x
>>> (3 + 2*x + 4*x**2).coeff(1)
0 

您可以通过将 n=0 使 x 独立选择项;在这种情况下,将返回 expr.as_independent(x)[0](而不是 None 将返回 0):

>>> (3 + 2*x + 4*x**2).coeff(x, 0)
3
>>> eq = ((x + 1)**3).expand() + 1
>>> eq
x**3 + 3*x**2 + 3*x + 2
>>> [eq.coeff(x, i) for i in reversed(range(4))]
[1, 3, 3, 2]
>>> eq -= 2
>>> [eq.coeff(x, i) for i in reversed(range(4))]
[1, 3, 3, 0] 

您可以选择具有数字项的项:

>>> (-x - 2*y).coeff(2)
-y
>>> from sympy import sqrt
>>> (x + sqrt(2)*x).coeff(sqrt(2))
x 

匹配是精确的:

>>> (3 + 2*x + 4*x**2).coeff(x)
2
>>> (3 + 2*x + 4*x**2).coeff(x**2)
4
>>> (3 + 2*x + 4*x**2).coeff(x**3)
0
>>> (z*(x + y)**2).coeff((x + y)**2)
z
>>> (z*(x + y)**2).coeff(x + y)
0 

此外,没有进行因式分解,因此1 + z*(1 + y)不是从以下获得的:

>>> (x + z*(x + x*y)).coeff(x)
1 

如果需要进行此类因式分解,可以先使用 factor_terms:

>>> from sympy import factor_terms
>>> factor_terms(x + z*(x + x*y)).coeff(x)
z*(y + 1) + 1 
>>> n, m, o = symbols('n m o', commutative=False)
>>> n.coeff(n)
1
>>> (3*n).coeff(n)
3
>>> (n*m + m*n*m).coeff(n) # = (1 + m)*n*m
1 + m
>>> (n*m + m*n*m).coeff(n, right=True) # = (1 + m)*n*m
m 

如果存在多个可能的系数,则返回 0:

>>> (n*m + m*n).coeff(n)
0 

如果只有一个可能的系数,则返回它:

>>> (n*m + x*m*n).coeff(m*n)
x
>>> (n*m + x*m*n).coeff(m*n, right=1)
1 

参见

as_coefficient

将表达式分解为系数和因子

as_coeff_Add

将一个表达式中的加法常数与其分开

as_coeff_Mul

将乘法常数与表达式分开

as_independent

将 x 相关的项/因子与其他项分开

sympy.polys.polytools.Poly.coeff_monomial

在 Poly 中高效地找到单项式的单一系数

sympy.polys.polytools.Poly.nth

类似于 coeff_monomial,但使用单项式项的幂

collect(syms, func=None, evaluate=True, exact=False, distribute_order_term=True)

查看 sympy.simplify 中的 collect 函数

combsimp()

查看 sympy.simplify 中的 combsimp 函数

compute_leading_term(x, logx=None)

弃用的函数,用于计算系列的主导项。

as_leading_term 仅允许用于.series()的结果,这是计算系列的包装器。

conjugate()

返回‘self’的复共轭。

could_extract_minus_sign()

如果自身具有-1 作为主要因子或者在求和中负号的字面意义比正号多,则返回 True,否则返回 False。

示例

>>> from sympy.abc import x, y
>>> e = x - y
>>> {i.could_extract_minus_sign() for i in (e, -e)}
{False, True} 

虽然y - x被视为-(x - y),因为它在没有-1 主要因子的情况下是一个乘积,所以下面的结果是错误的:

>>> (x*(y - x)).could_extract_minus_sign()
False 

要将某物放入与符号相关的规范形式,请使用(signsimp):

>>> from sympy import signsimp
>>> signsimp(x*(y - x))
-x*(x - y)
>>> _.could_extract_minus_sign()
True 
equals(other, failing_expression=False)

如果 self == other,则返回 True,如果不是,则返回 False 或 None。如果 failing_expression 为 True,则会返回未简化为 0 的表达式,而不是 None。

解释

如果self是一个非零的数(或复数),则结果为 False。

如果self是一个数字且未评估为零,则将使用 evalf 来测试表达式是否评估为零。如果是这样,并且结果具有显著性(即精度为-1,用于有理数结果,或大于 1),则将使用 evalf 值来返回 True 或 False。

expand(deep=True, modulus=None, power_base=True, power_exp=True, mul=True, log=True, multinomial=True, basic=True, **hints)

使用提示扩展表达式。

查看 sympy.core.function 中 expand()函数的文档字符串以获取更多信息。

property expr_free_symbols

类似于free_symbols,但仅在它们包含在表达式节点中时返回自由符号。

示例

>>> from sympy.abc import x, y
>>> (x + y).expr_free_symbols 
{x, y} 

如果表达式包含在非表达式对象中,则不返回自由符号。比较:

>>> from sympy import Tuple
>>> t = Tuple(x + y)
>>> t.expr_free_symbols 
set()
>>> t.free_symbols
{x, y} 
extract_additively(c)

如果可以从 self 中减去 c 并使所有匹配系数向零移动,则返回 self - c,否则返回 None。

示例

>>> from sympy.abc import x, y
>>> e = 2*x + 3
>>> e.extract_additively(x + 1)
x + 2
>>> e.extract_additively(3*x)
>>> e.extract_additively(4)
>>> (y*(x + 1)).extract_additively(x + 1)
>>> ((x + 1)*(x + 2*y + 1) + 3).extract_additively(x + 1)
(x + 1)*(x + 2*y) + 3 

另请参阅

extract_multiplicativelycoeffas_coefficient

extract_branch_factor(allow_half=False)

尝试以良好的方式将 self 写成exp_polar(2*pi*I*n)*z。返回(z, n)。

>>> from sympy import exp_polar, I, pi
>>> from sympy.abc import x, y
>>> exp_polar(I*pi).extract_branch_factor()
(exp_polar(I*pi), 0)
>>> exp_polar(2*I*pi).extract_branch_factor()
(1, 1)
>>> exp_polar(-pi*I).extract_branch_factor()
(exp_polar(I*pi), -1)
>>> exp_polar(3*pi*I + x).extract_branch_factor()
(exp_polar(x + I*pi), 1)
>>> (y*exp_polar(-5*pi*I)*exp_polar(3*pi*I + 2*pi*x)).extract_branch_factor()
(y*exp_polar(2*pi*x), -1)
>>> exp_polar(-I*pi/2).extract_branch_factor()
(exp_polar(-I*pi/2), 0) 

如果 allow_half 为 True,则还提取 exp_polar(I*pi):

>>> exp_polar(I*pi).extract_branch_factor(allow_half=True)
(1, 1/2)
>>> exp_polar(2*I*pi).extract_branch_factor(allow_half=True)
(1, 1)
>>> exp_polar(3*I*pi).extract_branch_factor(allow_half=True)
(1, 3/2)
>>> exp_polar(-I*pi).extract_branch_factor(allow_half=True)
(1, -1/2) 
extract_multiplicatively(c)

如果无法以一种良好的方式使 self 成为 c * something 的形式(即保留 self 参数的性质),则返回 None。

示例

>>> from sympy import symbols, Rational 
>>> x, y = symbols('x,y', real=True) 
>>> ((x*y)**3).extract_multiplicatively(x**2 * y)
x*y**2 
>>> ((x*y)**3).extract_multiplicatively(x**4 * y) 
>>> (2*x).extract_multiplicatively(2)
x 
>>> (2*x).extract_multiplicatively(3) 
>>> (Rational(1, 2)*x).extract_multiplicatively(3)
x/6 
factor(*gens, **args)

参见 sympy.polys.polytools 中的 factor() 函数

fourier_series(limits=None)

计算 self 的 Fourier 正/余弦级数。

参见 sympy.series.fourier 中的 fourier_series() 的文档字符串,详见。

fps(x=None, x0=0, dir=1, hyper=True, order=4, rational=True, full=False)

计算 self 的形式幂级数。

参见 fps() 函数的文档字符串,详见 sympy.series.formal。

gammasimp()

参见 sympy.simplify 中的 gammasimp 函数

getO()

如果存在加法 O(..) 符号则返回,否则返回 None。

getn()

返回表达式的次序。

说明

次序由 O(…) 项决定。如果没有 O(…) 项,则返回 None。

示例

>>> from sympy import O
>>> from sympy.abc import x
>>> (1 + x + O(x**2)).getn()
2
>>> (1 + x).getn() 
integrate(*args, **kwargs)

参见 sympy.integrals 中的 integrate 函数

invert(g, *gens, **args)

返回 selfg 的模乘逆,其中 self(和 g)可能是符号表达式。

参见也

sympy.core.intfunc.mod_inverse, sympy.polys.polytools.invert

is_algebraic_expr(*syms)

测试给定表达式在给定符号 syms 中是否是代数的。当未给定 syms 时,将使用所有自由符号。有理函数不必以展开或任何规范形式出现。

对于具有符号指数的“代数表达式”,此函数返回 False。这是对 is_rational_function 的简单扩展,包括有理数指数。

示例

>>> from sympy import Symbol, sqrt
>>> x = Symbol('x', real=True)
>>> sqrt(1 + x).is_rational_function()
False
>>> sqrt(1 + x).is_algebraic_expr()
True 

该函数不会尝试进行任何非平凡简化,这可能会导致一个看起来不是代数表达式的表达式变成代数表达式。

>>> from sympy import exp, factor
>>> a = sqrt(exp(x)**2 + 2*exp(x) + 1)/(exp(x) + 1)
>>> a.is_algebraic_expr(x)
False
>>> factor(a).is_algebraic_expr()
True 

参见也

is_rational_function

参考文献

[R122]

en.wikipedia.org/wiki/Algebraic_expression

is_constant(*wrt, **flags)

如果 self 是常数则返回 True,如果不是则返回 False,如果无法确定是否常数则返回 None。

说明

如果一个表达式没有自由符号则它是一个常数。如果有自由符号则可能是一个常数,也许(但不一定)是零。为了测试这样的表达式,尝试了几种策略:

  1. 在两个随机点的数值评估。如果两个评估给出不同的值,并且这些值的精度大于 1,则 self 不是常数。如果评估结果一致或无法获得任何精度,则不做决定。只有在 wrt 与自由符号不同时才进行数值测试。

2)相对于‘wrt’中的变量(或者如果省略,则相对于所有自由符号)的微分,以查看表达式是否恒定。即使表达式是恒定的(请参见 test_expr.py 中添加的测试),这也不总是导致一个表达式为零。如果所有导数都为零,则 self 相对于给定符号是常数。

3)找出具有自由符号的分母表达式的零点。如果有零点,则它将不是常数。对于不是常数的表达式,它给出更多的负面答案。

如果既不能评估也不能区分表达式是否恒定,则返回 None,除非两个数值恰好相同且标志failing_number为 True – 在这种情况下,将返回数值。

如果传递了标志 simplify=False,self 将不会被简化;默认值为 True,因为在测试之前应该简化 self。

示例

>>> from sympy import cos, sin, Sum, S, pi
>>> from sympy.abc import a, n, x, y
>>> x.is_constant()
False
>>> S(2).is_constant()
True
>>> Sum(x, (x, 1, 10)).is_constant()
True
>>> Sum(x, (x, 1, n)).is_constant()
False
>>> Sum(x, (x, 1, n)).is_constant(y)
True
>>> Sum(x, (x, 1, n)).is_constant(n)
False
>>> Sum(x, (x, 1, n)).is_constant(x)
True
>>> eq = a*cos(x)**2 + a*sin(x)**2 - a
>>> eq.is_constant()
True
>>> eq.subs({x: pi, a: 2}) == eq.subs({x: pi, a: 3}) == 0
True 
>>> (0**x).is_constant()
False
>>> x.is_constant()
False
>>> (x**x).is_constant()
False
>>> one = cos(x)**2 + sin(x)**2
>>> one.is_constant()
True
>>> ((one - 1)**(x + 1)).is_constant() in (True, False) # could be 0 or 1
True 
is_meromorphic(x, a)

这测试一个表达式在给定符号x在点a处作为函数是否是亚黎函数。

此方法旨在作为一个快速测试,如果没有简化或更详细的分析,将返回 None。

示例

>>> from sympy import zoo, log, sin, sqrt
>>> from sympy.abc import x 
>>> f = 1/x**2 + 1 - 2*x**3
>>> f.is_meromorphic(x, 0)
True
>>> f.is_meromorphic(x, 1)
True
>>> f.is_meromorphic(x, zoo)
True 
>>> g = x**log(3)
>>> g.is_meromorphic(x, 0)
False
>>> g.is_meromorphic(x, 1)
True
>>> g.is_meromorphic(x, zoo)
False 
>>> h = sin(1/x)*x**2
>>> h.is_meromorphic(x, 0)
False
>>> h.is_meromorphic(x, 1)
True
>>> h.is_meromorphic(x, zoo)
True 

多值函数被认为是亚黎函数,当它们的分支是亚黎函数时。因此,大多数函数在除了基本奇异点和分支点以外的任何地方都是亚黎函数。特别是,在分支切线上也将是亚黎函数,除了在其端点处。

>>> log(x).is_meromorphic(x, -1)
True
>>> log(x).is_meromorphic(x, 0)
False
>>> sqrt(x).is_meromorphic(x, -1)
True
>>> sqrt(x).is_meromorphic(x, 0)
False 
property is_number

如果self没有自由符号和未定义函数(具体是 AppliedUndef),则返回 True。这将比if not self.free_symbols更快,因为一旦遇到自由符号或未定义函数,is_number将失败。

示例

>>> from sympy import Function, Integral, cos, sin, pi
>>> from sympy.abc import x
>>> f = Function('f') 
>>> x.is_number
False
>>> f(1).is_number
False
>>> (2*x).is_number
False
>>> (2 + Integral(2, x)).is_number
False
>>> (2 + Integral(2, (x, 1, 2))).is_number
True 

并非所有的数字在 SymPy 的意义上都是数字:

>>> pi.is_number, pi.is_Number
(True, False) 

如果某个东西是一个数,它应该评估为一个具有实部和虚部的数;然而,结果可能不可比较,因为结果的实部和/或虚部可能没有精度。

>>> cos(1).is_number and cos(1).is_comparable
True 
>>> z = cos(1)**2 + sin(1)**2 - 1
>>> z.is_number
True
>>> z.is_comparable
False 

参见

sympy.core.basic.Basic.is_comparable

is_polynomial(*syms)

如果 self 是 syms 中的一个多项式,则返回 True,否则返回 False。

这检查 self 是否是 syms 中的一个精确多项式。对于具有符号指数的“多项式”表达式,此函数返回 False。因此,你应该能够对返回 True 的表达式应用多项式算法,并且如果 expr.is_polynomial(*syms)返回 True,则 Poly(expr, *syms)应该工作。多项式不必处于展开形式。如果没有给出符号,则表达式中的所有自由符号都将被使用。

这不是假设系统的一部分。你不能做 Symbol(‘z’, polynomial=True)。

示例

>>> from sympy import Symbol, Function
>>> x = Symbol('x')
>>> ((x**2 + 1)**4).is_polynomial(x)
True
>>> ((x**2 + 1)**4).is_polynomial()
True
>>> (2**x + 1).is_polynomial(x)
False
>>> (2**x + 1).is_polynomial(2**x)
True
>>> f = Function('f')
>>> (f(x) + 1).is_polynomial(x)
False
>>> (f(x) + 1).is_polynomial(f(x))
True
>>> (1/f(x) + 1).is_polynomial(f(x))
False 
>>> n = Symbol('n', nonnegative=True, integer=True)
>>> (x**n + 1).is_polynomial(x)
False 

此函数不会尝试任何可能导致一个表达式成为多项式但看起来不是多项式的非平凡简化。

>>> from sympy import sqrt, factor, cancel
>>> y = Symbol('y', positive=True)
>>> a = sqrt(y**2 + 2*y + 1)
>>> a.is_polynomial(y)
False
>>> factor(a)
y + 1
>>> factor(a).is_polynomial(y)
True 
>>> b = (y**2 + 2*y + 1)/(y + 1)
>>> b.is_polynomial(y)
False
>>> cancel(b)
y + 1
>>> cancel(b).is_polynomial(y)
True 

参见 .is_rational_function()

is_rational_function(*syms)

测试函数是否为给定符号 syms 中的两个多项式的比率。当未给出 syms 时,将使用所有自由符号。有理函数不必处于扩展或任何规范形式中。

对于具有符号指数的“有理函数”表达式,此函数返回 False。因此,您应该能够调用.as_numer_denom()并对结果应用多项式算法,以便对此返回 True 的表达式进行操作。

这不是假设系统的一部分。您无法执行 Symbol('z',rational_function=True)。

示例

>>> from sympy import Symbol, sin
>>> from sympy.abc import x, y 
>>> (x/y).is_rational_function()
True 
>>> (x**2).is_rational_function()
True 
>>> (x/sin(y)).is_rational_function(y)
False 
>>> n = Symbol('n', integer=True)
>>> (x**n + 1).is_rational_function(x)
False 

此函数不尝试对可能导致表达式不是有理函数的非平凡简化进行任何简化。

>>> from sympy import sqrt, factor
>>> y = Symbol('y', positive=True)
>>> a = sqrt(y**2 + 2*y + 1)/y
>>> a.is_rational_function(y)
False
>>> factor(a)
(y + 1)/y
>>> factor(a).is_rational_function(y)
True 

另请参见is_algebraic_expr()

leadterm(x, logx=None, cdir=0)

返回作为元组(a, b)的主导项a*x**b

示例

>>> from sympy.abc import x
>>> (1+x+x**2).leadterm(x)
(1, 0)
>>> (1/x**2+x+x**2).leadterm(x)
(1, -2) 
limit(x, xlim, dir='+')

计算极限 x->xlim。

lseries(x=None, x0=0, dir='+', logx=None, cdir=0)

系列的项的迭代器的系列的包装器。

注意:无限系列将产生无限迭代器。例如,以下示例将永远不会终止。它将继续打印 sin(x)系列的项:

for term in sin(x).lseries(x):
    print term 

lseries()nseries()的优点在于,很多时候你只是对系列中的下一个项感兴趣(即例如第一个项),但你不知道应该在nseries()中使用“n”参数询问多少个项。

另请参见nseries()

normal()

返回表达式作为分数。

表达式 -> a/b

另请参见

as_numer_denom

返回(a, b)而不是a/b

nseries(x=None, x0=0, n=6, dir='+', logx=None, cdir=0)

如果假设允许,则是到_eval_nseries的包装,否则到系列。

如果给定 x,x0 为 0,dir='+',并且 self 具有 x,则调用 _eval_nseries。这会在最内层表达式中计算“n”个项,然后通过“交叉乘法”构建最终系列。

可选的logx参数可用于在返回的系列中替换任何 log(x)为符号值,以避免在 0 处评估 log(x)。应提供用于替代 log(x)的符号。

优点 - 它很快,因为我们不必提前确定需要计算多少项。

缺点 - 您可能得到比预期更少的术语,但始终附加正确的 O(x**n)项,因此结果,尽管可能更短,也将是正确的。

如果这些假设中的任何一个不符合,则此功能将被视为对 series 的包装器,后者将尝试更努力返回正确数量的项。

另请参见lseries()

示例

>>> from sympy import sin, log, Symbol
>>> from sympy.abc import x, y
>>> sin(x).nseries(x, 0, 6)
x - x**3/6 + x**5/120 + O(x**6)
>>> log(x+1).nseries(x, 0, 5)
x - x**2/2 + x**3/3 - x**4/4 + O(x**5) 

处理logx参数 - 在以下示例中,展开失败,因为sin在-oo 处没有渐近展开(当 log(x)作为 x 趋近于 0 的极限时):

>>> e = sin(log(x))
>>> e.nseries(x, 0, 6)
Traceback (most recent call last):
...
PoleError: ...
...
>>> logx = Symbol('logx')
>>> e.nseries(x, 0, 6, logx=logx)
sin(logx) 

在下面的例子中,展开有效,但只有在使用logx参数时才返回自身:

>>> e = x**y
>>> e.nseries(x, 0, 2)
x**y
>>> e.nseries(x, 0, 2, logx=logx)
exp(logx*y) 
nsimplify(constants=(), tolerance=None, full=False)

请参阅 sympy.simplify 中的 nsimplify 函数

powsimp(*args, **kwargs)

请参阅 sympy.simplify 中的 powsimp 函数

primitive()

返回可以从每个项中非递归提取的正有理数(即,将 self 视为 Add)。这类似于 as_coeff_Mul() 方法,但 primitive 总是提取正有理数(不提取负数或浮点数)。

示例

>>> from sympy.abc import x
>>> (3*(x + 1)**2).primitive()
(3, (x + 1)**2)
>>> a = (6*x + 2); a.primitive()
(2, 3*x + 1)
>>> b = (x/2 + 3); b.primitive()
(1/2, x + 6)
>>> (a*b).primitive() == (1, a*b)
True 
radsimp(**kwargs)

参见 sympy.simplify 中的 radsimp 函数

ratsimp()

参见 sympy.simplify 中的 ratsimp 函数

removeO()

如果存在,移除加法 O(..) 符号

round(n=None)

返回到给定小数位数的 x 的四舍五入值。

如果结果是复数,则对该数的实部和虚部应用 round。

示例

>>> from sympy import pi, E, I, S, Number
>>> pi.round()
3
>>> pi.round(2)
3.14
>>> (2*pi + E*I).round()
6 + 3*I 

round 方法具有截断效应:

>>> (2*pi + I/10).round()
6
>>> (pi/10 + 2*I).round()
2*I
>>> (pi/10 + E*I).round(2)
0.31 + 2.72*I 

注释

Python 的 round 函数使用 SymPy 的 round 方法,因此它始终返回 SymPy 数字(而不是 Python 的浮点数或整数):

>>> isinstance(round(S(123), -2), Number)
True 
separate(deep=False, force=False)

参见 sympy.simplify 中的 separate 函数

series(x=None, x0=0, n=6, dir='+', logx=None, cdir=0)

关于 x = x0 的“自我”级数展开,要么按需逐个给出级数项(当 n=None 时是懒惰级数),要么在 n != None 时一次性给出所有项。

返回以 x = x0 点为中心,关于 x 展开到 O((x - x0)**n, x, x0) 的级数展开(默认 n 为 6)。

如果 x=None 并且 self 是一元符号,则会提供该一元符号,否则会引发错误。

参数:

expr :表达式

要展开其级数的表达式。

x :符号

它是要计算的表达式的变量。

x0 :数值

计算 x 的值。可以是从 -oooo 的任何值。

n :数值

表示按 x**n 展开级数的阶数,展开到该阶数。

dir :字符串,可选

级数展开可以是双向的。如果 dir="+",则 (x->x0+)。如果 pydir="-", then (x->x0-). For infinite ``x0 (oo-oo),则 dir 参数从无穷大的方向确定(例如对于 oodir="-")。

logx :可选

用于将返回的级数中的任何 log(x) 替换为符号值,而不是计算实际值。

cdir :可选

它代表复杂方向,并指示需要从哪个方向评估展开。

返回:

Expr :表达式

关于 x0 的表达式的级数展开

异常:

TypeError

如果“n”和“x0”是无穷对象

PoleError

如果“x0”是一个无限对象

示例

>>> from sympy import cos, exp, tan
>>> from sympy.abc import x, y
>>> cos(x).series()
1 - x**2/2 + x**4/24 + O(x**6)
>>> cos(x).series(n=4)
1 - x**2/2 + O(x**4)
>>> cos(x).series(x, x0=1, n=2)
cos(1) - (x - 1)*sin(1) + O((x - 1)**2, (x, 1))
>>> e = cos(x + exp(y))
>>> e.series(y, n=2)
cos(x + 1) - y*sin(x + 1) + O(y**2)
>>> e.series(x, n=2)
cos(exp(y)) - x*sin(exp(y)) + O(x**2) 

如果 n=None,则将返回级数项的生成器。

>>> term=cos(x).series(n=None)
>>> [next(term) for i in range(2)]
[1, -x**2/2] 

对于 dir=+(默认),从右侧计算级数;对于 dir=-,从左侧计算级数。对于光滑函数,此标志不会改变结果。

>>> abs(x).series(dir="+")
x
>>> abs(x).series(dir="-")
-x
>>> f = tan(x)
>>> f.series(x, 2, 6, "+")
tan(2) + (1 + tan(2)**2)*(x - 2) + (x - 2)**2*(tan(2)**3 + tan(2)) +
(x - 2)**3*(1/3 + 4*tan(2)**2/3 + tan(2)**4) + (x - 2)**4*(tan(2)**5 +
5*tan(2)**3/3 + 2*tan(2)/3) + (x - 2)**5*(2/15 + 17*tan(2)**2/15 +
2*tan(2)**4 + tan(2)**6) + O((x - 2)**6, (x, 2)) 
>>> f.series(x, 2, 3, "-")
tan(2) + (2 - x)*(-tan(2)**2 - 1) + (2 - x)**2*(tan(2)**3 + tan(2))
+ O((x - 2)**3, (x, 2)) 

对于有理表达式,此方法可能返回原始表达式而不包括 Order 项。>>> (1/x).series(x, n=8) 1/x

taylor_term(n, x, *previous_terms)

泰勒级数项的通用方法。

该方法速度较慢,因为需要 n 次求导。子类可以重新定义此方法,通过使用“previous_terms”使其更快。

together(*args, **kwargs)

参见 sympy.polys 中的 together 函数

trigsimp(**args)

参见 sympy.simplify 中的 trigsimp 函数

class sympy.core.expr.UnevaluatedExpr(arg, **kwargs)

除非释放,否则不计算的表达式。

示例

>>> from sympy import UnevaluatedExpr
>>> from sympy.abc import x
>>> x*(1/x)
1
>>> x*UnevaluatedExpr(1/x)
x*1/x 
class sympy.core.expr.AtomicExpr(*args)

既是原子又是 Exprs 的对象的父类。

例如:Symbol, Number, Rational, Integer, … 但不包括:Add, Mul, Pow, … ## symbol

class sympy.core.symbol.Symbol(name, **assumptions)

Symbol 类用于创建符号变量。

参数:

AtomicExpr:变量名称

布尔值:带有布尔值(True 或 False)的假设

解释

符号变量是数学符号的占位符,可以表示数字、常数或任何其他数学实体,并可用于数学表达式和进行符号计算。

假设:

commutative = True positive = True real = True imaginary = True complex = True 完整列表的更多假设- 谓词

您可以在构造函数中覆盖默认假设。

示例

>>> from sympy import Symbol
>>> x = Symbol("x", positive=True)
>>> x.is_positive
True
>>> x.is_negative
False 

传入希腊字母:

>>> from sympy import Symbol
>>> alpha = Symbol('alpha')
>>> alpha 
α 

尾随数字会自动视为前面名称中的下标。向符号添加下标的一般格式:<var_name> = Symbol('<symbol_name>_')。

>>> from sympy import Symbol
>>> alpha_i = Symbol('alpha_i')
>>> alpha_i 
αᵢ 
class sympy.core.symbol.Wild(name, exclude=(), properties=(), **assumptions)

Wild 符号可以匹配任何东西,或者不包含明确排除的内容。

参数:

name : 字符串

Wild 实例的名称。

exclude : 可迭代对象,可选

exclude中的实例将不会被匹配。

properties : 函数的可迭代集合,可选

函数,每个函数以表达式作为输入并返回一个bool值。properties中的所有函数都需要返回True,以便 Wild 实例能够匹配表达式。

示例

>>> from sympy import Wild, WildFunction, cos, pi
>>> from sympy.abc import x, y, z
>>> a = Wild('a')
>>> x.match(a)
{a_: x}
>>> pi.match(a)
{a_: pi}
>>> (3*x**2).match(a*x)
{a_: 3*x}
>>> cos(x).match(a)
{a_: cos(x)}
>>> b = Wild('b', exclude=[x])
>>> (3*x**2).match(b*x)
>>> b.match(a)
{a_: b_}
>>> A = WildFunction('A')
>>> A.match(a)
{a_: A_} 

提示

使用 Wild 时,请确保使用 exclude 关键字使模式更精确。没有 exclude 模式,您可能会获得在技术上正确但不符合预期的匹配项。例如,使用上述情况而没有 exclude:

>>> from sympy import symbols
>>> a, b = symbols('a b', cls=Wild)
>>> (2 + 3*y).match(a*x + b*y)
{a_: 2/x, b_: 3} 

这在技术上是正确的,因为(2/x)x + 3y == 2 + 3*y,但您可能希望它根本不匹配。问题在于,您实际上不希望 a 和 b 包含 x 和 y,并且 exclude 参数允许您精确指定这一点。使用 exclude 参数,该模式将不会匹配。

>>> a = Wild('a', exclude=[x, y])
>>> b = Wild('b', exclude=[x, y])
>>> (2 + 3*y).match(a*x + b*y) 

Exclude 还有助于消除匹配的歧义。

>>> E = 2*x**3*y*z
>>> a, b = symbols('a b', cls=Wild)
>>> E.match(a*b)
{a_: 2*y*z, b_: x**3}
>>> a = Wild('a', exclude=[x, y])
>>> E.match(a*b)
{a_: z, b_: 2*x**3*y}
>>> a = Wild('a', exclude=[x, y, z])
>>> E.match(a*b)
{a_: 2, b_: x**3*y*z} 

Wild 也接受一个properties参数:

>>> a = Wild('a', properties=[lambda k: k.is_Integer])
>>> E.match(a*b)
{a_: 2, b_: x**3*y*z} 
class sympy.core.symbol.Dummy(name=None, dummy_index=None, **assumptions)

Dummy 符号是唯一的,即使它们具有相同的名称:

示例

>>> from sympy import Dummy
>>> Dummy("x") == Dummy("x")
False 

如果未提供名称,则将使用内部计数的字符串值。当需要临时变量且表达式中使用的变量名称不重要时,这很有用。

>>> Dummy() 
_Dummy_10 
sympy.core.symbol.symbols(names, *, cls=<class 'sympy.core.symbol.Symbol'>, **args) → Any

将字符串转换为Symbol类的实例。

symbols()函数返回从names参数获取名称的符号序列,该参数可以是逗号或空格分隔的字符串,或者是字符串序列:

>>> from sympy import symbols, Function

>>> x, y, z = symbols('x,y,z')
>>> a, b, c = symbols('a b c') 

输出类型取决于输入参数的属性:

>>> symbols('x')
x
>>> symbols('x,')
(x,)
>>> symbols('x,y')
(x, y)
>>> symbols(('a', 'b', 'c'))
(a, b, c)
>>> symbols(['a', 'b', 'c'])
[a, b, c]
>>> symbols({'a', 'b', 'c'})
{a, b, c} 

如果需要一个单一符号的可迭代容器,则将seq参数设置为True或在符号名称末尾加上逗号:

>>> symbols('x', seq=True)
(x,) 

为了减少输入,支持使用范围语法创建索引符号。范围由冒号表示,并且范围类型由冒号右侧的字符确定。如果该字符是数字,则将左侧所有连续的数字视为非负起始值(如果冒号左侧没有数字,则起始值为 0),将右侧所有连续的数字视为结束值加 1:

>>> symbols('x:10')
(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9)

>>> symbols('x5:10')
(x5, x6, x7, x8, x9)
>>> symbols('x5(:2)')
(x50, x51)

>>> symbols('x5:10,y:5')
(x5, x6, x7, x8, x9, y0, y1, y2, y3, y4)

>>> symbols(('x5:10', 'y:5'))
((x5, x6, x7, x8, x9), (y0, y1, y2, y3, y4)) 

如果冒号右侧的字符是字母,则左侧的单个字母(如果没有,则为‘a’)作为起始,并且使用字母范围中的所有字符直到右侧的字母作为范围:

>>> symbols('x:z')
(x, y, z)
>>> symbols('x:c')  # null range
()
>>> symbols('x(:c)')
(xa, xb, xc)

>>> symbols(':c')
(a, b, c)

>>> symbols('a:d, x:z')
(a, b, c, d, x, y, z)

>>> symbols(('a:d', 'x:z'))
((a, b, c, d), (x, y, z)) 

支持多个范围;应通过括号分隔连续的数值范围,以消除一个范围的结束数字与下一个范围的开始数字之间的歧义:

>>> symbols('x:2(1:3)')
(x01, x02, x11, x12)
>>> symbols(':3:2')  # parsing is from left to right
(00, 01, 10, 11, 20, 21) 

只有一个括号包围的范围被删除,因此要包含括号周围的范围,请将它们双倍。要包含空格、逗号或冒号,请使用反斜杠进行转义:

>>> symbols('x((a:b))')
(x(a), x(b))
>>> symbols(r'x(:1\,:2)')  # or r'x((:1)\,(:2))'
(x(0,0), x(0,1)) 

所有新创建的符号都根据args设置了假设:

>>> a = symbols('a', integer=True)
>>> a.is_integer
True

>>> x, y, z = symbols('x,y,z', real=True)
>>> x.is_real and y.is_real and z.is_real
True 

尽管其名称如此,symbols()可以创建类似符号的对象,如 Function 或 Wild 类的实例。要实现此目的,请将cls关键字参数设置为所需类型:

>>> symbols('f,g,h', cls=Function)
(f, g, h)

>>> type(_[0])
<class 'sympy.core.function.UndefinedFunction'> 
sympy.core.symbol.var(names, **args)

创建符号并将它们注入全局命名空间。

解释

这将使用相同的参数调用 symbols() 并将结果放入全局命名空间。建议在库代码中不使用 var(),而是使用 symbols()

.. rubric:: Examples 
>>> from sympy import var 
>>> var('x')
x
>>> x # noqa: F821
x 
>>> var('a,ab,abc')
(a, ab, abc)
>>> abc # noqa: F821
abc 
>>> var('x,y', real=True)
(x, y)
>>> x.is_real and y.is_real # noqa: F821
True 

详见 symbols() 文档,了解可以传递给 var() 的参数类型详细信息。 ## intfunc

sympy.core.intfunc.num_digits(n, base=10)

返回以给定基数表示 n 所需的位数。

参数:

n: 整数

被计算其位数的数字。

b: 整数

计算数字计算的基数。

示例

>>> from sympy.core.intfunc import num_digits
>>> num_digits(10)
2
>>> num_digits(10, 2)  # 1010 -> 4 digits
4
>>> num_digits(-100, 16)  # -64 -> 2 digits
2 

另请参阅

sympy.ntheory.digits.digits, sympy.ntheory.digits.count_digits

sympy.core.intfunc.trailing(n)

计算 n 的二进制表示中末尾零位数的数量,即确定能整除 n 的最大 2 的幂次数。

示例

>>> from sympy import trailing
>>> trailing(128)
7
>>> trailing(63)
0 

另请参阅

sympy.ntheory.factor_.multiplicity

sympy.core.intfunc.ilcm(*args)

计算整数的最小公倍数。

示例

>>> from sympy import ilcm
>>> ilcm(5, 10)
10
>>> ilcm(7, 3)
21
>>> ilcm(5, 10, 15)
30 
sympy.core.intfunc.igcd(*args)

计算非负整数的最大公约数。

解释

该算法基于著名的欧几里得算法[R123]。为了提高速度,igcd()具有自己的缓存机制。如果不需要缓存机制,可以使用sympy.external.gmpy.gcd

示例

>>> from sympy import igcd
>>> igcd(2, 4)
2
>>> igcd(5, 10, 15)
5 

参考文献

[R123] (1,2)

en.wikipedia.org/wiki/Euclidean_algorithm

sympy.core.intfunc.igcd_lehmer(a, b)

计算两个整数的最大公约数。

解释

欧几里德算法用于计算两个(正)整数 (a) 和 (b) 的最大公约数 gcd(a, b),基于除法恒等式 a=q×b+r a = q \times b + r,其中商 (q) 和余数 (r) 是整数,且 (0 \le r < b)。然后,(a) 和 (b) 的每个公约数都可以整除 (r),由此可知 gcd(a, b) == gcd(b, r)。该算法通过构造序列 r0, r1, r2, …,其中 r0 = a,r1 = b,并且每个 rn 都是前两个元素的余数来实现。

在 Python 中,q = a // br = a % b 分别通过地板除法和取余操作获得。这些是最昂贵的算术操作,特别是对于大的 a 和 b。

利用观察到的商 qn = r(n-1) // rn,即使 a 和 b 非常大,勒默算法 [R124] 中的商通常也是小整数。因此,这些商通常可以从相对较少的最显著位确定。

通过不计算欧几里德序列中的每个长余数来进一步提高算法效率。余数是从选定的最显著部分的 a 和 b 导出的整数系数的线性组合。只有当从 a 和 b 的最显著部分确定了商后,才计算出新的一对连续余数,并且算法从这一对重新开始。

参考文献

[R124] (1,2)

en.wikipedia.org/wiki/Lehmer%27s_GCD_algorithm

sympy.core.intfunc.igcdex(a, b)

返回 x, y, g,使得 g = xa + yb = gcd(a, b)。

示例

>>> from sympy.core.intfunc import igcdex
>>> igcdex(2, 3)
(-1, 1, 1)
>>> igcdex(10, 12)
(-1, 1, 2) 
>>> x, y, g = igcdex(100, 2004)
>>> x, y, g
(-20, 1, 4)
>>> x*100 + y*2004
4 
sympy.core.intfunc.isqrt(n)

返回不大于 (\sqrt{n}) 的最大整数。

参数:

n : 非负整数

返回:

整数 : (\left\lfloor\sqrt{n}\right\rfloor)

抛出:

数值错误

如果 n 为负数。

类型错误

如果 n 的类型无法与 int 比较。因此,对于 str 报错 TypeError,但对于 float 则不会。

示例

>>> from sympy.core.intfunc import isqrt
>>> isqrt(0)
0
>>> isqrt(9)
3
>>> isqrt(10)
3
>>> isqrt("30")
Traceback (most recent call last):
  ...
TypeError: '<' not supported between instances of 'str' and 'int'
>>> from sympy.core.numbers import Rational
>>> isqrt(Rational(-1, 2))
Traceback (most recent call last):
  ...
ValueError: n must be nonnegative 
sympy.core.intfunc.integer_nthroot(y, n)

返回一个元组,其中 x = (\left\lfloor y^{(1/n)} \right\rfloor),并返回一个布尔值,指示结果是否精确(即,是否满足 (x^n == y))。

示例

>>> from sympy import integer_nthroot
>>> integer_nthroot(16, 2)
(4, True)
>>> integer_nthroot(26, 2)
(5, False) 

若要简单确定一个数是否为完全平方数,应使用 is_square 函数:

>>> from sympy.ntheory.primetest import is_square
>>> is_square(26)
False 

另请参见

sympy.ntheory.primetest.is_square, integer_log

sympy.core.intfunc.integer_log(n, b)

返回 (e, bool),其中 e 是最大非负整数,使得 (|n| \geq |b^e|),并且 bool 为 True 如果 (n = b^e)。

示例

>>> from sympy import integer_log
>>> integer_log(125, 5)
(3, True)
>>> integer_log(17, 9)
(1, False) 

如果底数为正数且数字为负数,则返回值除了 2 以外始终相同:

>>> integer_log(-4, 2)
(2, False)
>>> integer_log(-16, 4)
(0, False) 

当底数为负时,仅当指数的奇偶性符合底数的符号时,返回的值才为 True:

>>> integer_log(4, -2)
(2, True)
>>> integer_log(8, -2)
(3, False)
>>> integer_log(-8, -2)
(3, True)
>>> integer_log(-4, -2)
(2, False) 

请参见

integer_nthrootsympy.ntheory.primetest.is_squaresympy.ntheory.factor_.multiplicitysympy.ntheory.factor_.perfect_power

sympy.core.intfunc.mod_inverse(a, m)

返回数 (c),使得 (a \times c = 1 \pmod{m}),其中 (c) 与 (m) 的符号相同。如果不存在这样的值,则引发 ValueError。

举例

>>> from sympy import mod_inverse, S 

假设我们希望找到模 11 下的数 3 的乘法逆元 (x)。这等同于找到 (x) 使得 (3x = 1 \pmod{11})。满足这个同余的一个 (x) 的值是 4。因为 (3 \times 4 = 12) 并且 (12 = 1 \pmod{11})。这是 mod_inverse 返回的值:

>>> mod_inverse(3, 11)
4
>>> mod_inverse(-3, 11)
7 

当 (a) 和 (m) 的分子之间有一个公因数时,逆元不存在:

>>> mod_inverse(2, 4)
Traceback (most recent call last):
...
ValueError: inverse of 2 mod 4 does not exist 
>>> mod_inverse(S(2)/7, S(5)/2)
7/2 

参考文献

[R125]

模数乘法逆元

[R126]

扩展欧几里得算法 ## numbers

class sympy.core.numbers.Number(*obj)

表示 SymPy 中的原子数。

解释

浮点数由 Float 类表示。任意大小的有理数由 Rational 类表示。任意大小的整数由 Integer 类表示。Float 和 Rational 是 Number 的子类;Integer 是 Rational 的子类。

例如,2/3 表示为 Rational(2, 3),它与使用 Python 除法 2/3 得到的浮点数是不同的对象。即使对于在二进制中精确表示的数字,如 Rational(1, 2)Float(0.5),它们在 SymPy 中的使用方式也有所不同。在符号计算中应优先选择有理数形式。

其他类型的数,如代数数 sqrt(2) 或复数 3 + 4*I,因为不是原子,所以不是 Number 类的实例。

请参见

FloatIntegerRational

as_coeff_Add(rational=False)

高效地提取求和的系数。

as_coeff_Mul(rational=False)

高效地提取乘积的系数。

cofactors(other)

计算 (self) 和 (other) 的最大公约数及其余因子。

gcd(other)

计算 (self) 和 (other) 的最大公约数。

lcm(other)

计算 (self) 和 (other) 的最小公倍数。

class sympy.core.numbers.Float(num, dps=None, precision=None)

表示任意精度浮点数。

举例

>>> from sympy import Float
>>> Float(3.5)
3.50000000000000
>>> Float(3)
3.00000000000000 

从字符串(以及 Python 的 intlong 类型)创建浮点数将给出至少 15 位数的精度,但精度将自动增加以捕获输入的所有数字。

>>> Float(1)
1.00000000000000
>>> Float(10**20)
100000000000000000000.
>>> Float('1e20')
100000000000000000000. 

然而,浮点数(Python 的 float 类型)只保留 15 位精度:

>>> Float(1e20)
1.00000000000000e+20
>>> Float(1.23456789123456789)
1.23456789123457 

最好将高精度的十进制数作为字符串输入:

>>> Float('1.23456789123456789')
1.23456789123456789 

也可以指定所需的数字位数:

>>> Float('1e-3', 3)
0.00100
>>> Float(100, 4)
100.0 

如果将空字符串发送给精度,Float 可以自动计算有效数字;空格或下划线也是允许的。(自动计数仅适用于字符串、整数和长整数)。

>>> Float('123 456 789.123_456', '')
123456789.123456
>>> Float('12e-3', '')
0.012
>>> Float(3, '')
3. 

如果一个数字用科学计数法写成,那么指数前的数字被认为是有效的,如果出现小数点,则“e”只表示如何移动小数点:

>>> Float('60.e2', '')  # 2 digits significant
6.0e+3
>>> Float('60e2', '')  # 4 digits significant
6000.
>>> Float('600e-2', '')  # 3 digits significant
6.00 

注释

浮点数本质上是不精确的,除非它们的值是二进制精确值。

>>> approx, exact = Float(.1, 1), Float(.125, 1) 

为了计算目的,evalf 需要能够更改精度,但这不会增加不精确值的准确性。以下是一个值为 0.1 的最准确的 5 位近似值,只有 1 位精度:

>>> approx.evalf(5)
0.099609 

相比之下,0.125 在二进制中是精确的(就像在十进制中一样),因此可以传递给 Float 或 evalf 以获得匹配精度的任意精度:

>>> Float(exact, 5)
0.12500
>>> exact.evalf(20)
0.12500000000000000000 

尝试从浮点数创建高精度的 Float 不是不允许的,但必须记住正在以高精度获得底层浮点数(而不是表面的十进制值)。例如,0.3 没有有限的二进制表示。最接近的有理数是分数 5404319552844595/2**54。因此,如果尝试获得 0.3 的 20 位精度的 Float,你将看不到与 0.3 后面跟着 19 个零的相同结果:

>>> Float(0.3, 20)
0.29999999999999998890 

如果你想要一个 20 位数值的十进制 0.3(而不是浮点数近似值 0.3),你应该将 0.3 作为字符串发送。底层表示仍然是二进制,但使用的精度高于 Python 的浮点数:

>>> Float('0.3', 20)
0.30000000000000000000 

尽管可以使用 Float 增加现有 Float 的精度,但这不会增加准确性 - 底层值不会改变:

>>> def show(f): # binary rep of Float
...     from sympy import Mul, Pow
...     s, m, e, b = f._mpf_
...     v = Mul(int(m), Pow(2, int(e), evaluate=False), evaluate=False)
...     print('%s at prec=%s' % (v, f._prec))
...
>>> t = Float('0.3', 3)
>>> show(t)
4915/2**14 at prec=13
>>> show(Float(t, 20)) # higher prec, not higher accuracy
4915/2**14 at prec=70
>>> show(Float(t, 2)) # lower prec
307/2**10 at prec=10 

当在 Float 上使用 evalf 时也会发生同样的情况:

>>> show(t.evalf(20))
4915/2**14 at prec=70
>>> show(t.evalf(2))
307/2**10 at prec=10 

最后,可以使用 mpf 元组(n,c,p)实例化 Float,以产生数字 (-1)nc2p:

>>> n, c, p = 1, 5, 0
>>> (-1)**n*c*2**p
-5
>>> Float((1, 5, 0))
-5.00000000000000 

实际的 mpf 元组还包含元组的最后一个元素中 c 的位数:

>>> _._mpf_
(1, 5, 0, 3) 

这对于实例化不是必需的,也不同于精度。mpf 元组和精度是 Float 跟踪的两个独立数量。

在 SymPy 中,Float 是可以用任意精度计算的数字。虽然浮点数 'inf' 和 'nan' 不是这样的数字,但 Float 可以创建这些数字:

>>> Float('-inf')
-oo
>>> _.is_Float
False 

浮点数中的零只有一个值。正零和负零的值不是分开的。

class sympy.core.numbers.Rational(p, q=None, gcd=None)

表示任意大小的有理数(p/q)。

示例

>>> from sympy import Rational, nsimplify, S, pi
>>> Rational(1, 2)
1/2 

Rational 在接受输入时是不偏见的。如果传递了一个浮点数,将返回二进制表示的底层值:

>>> Rational(.5)
1/2
>>> Rational(.2)
3602879701896397/18014398509481984 

如果希望获得浮点数的简化表示,则考虑将分母限制在所需值或将浮点数转换为字符串(这大致相当于将分母限制在 10**12):

>>> Rational(str(.2))
1/5
>>> Rational(.2).limit_denominator(10**12)
1/5 

当传递字符串字面值时,将获得任意精度的有理数:

>>> Rational("1.23")
123/100
>>> Rational('1e-2')
1/100
>>> Rational(".1")
1/10
>>> Rational('1e-2/3.2')
1/320 

其他类型的字符串可以通过 sympify() 函数进行转换,将浮点数转换为表达式或简单分数可以使用 nsimplify 处理:

>>> S('.[3]')  # repeating digits in brackets
1/3
>>> S('3**2/10')  # general expressions
9/10
>>> nsimplify(.3)  # numbers that have a simple form
3/10 

但如果输入不能简化为字面意义上的有理数,则会引发错误:

>>> Rational(pi)
Traceback (most recent call last):
...
TypeError: invalid input: pi 

低级

访问分子和分母如 .p 和 .q:

>>> r = Rational(3, 4)
>>> r
3/4
>>> r.p
3
>>> r.q
4 

注意 p 和 q 返回整数(而不是 SymPy 整数),因此在表达式中使用它们时需要注意:

>>> r.p/r.q
0.75 

如果需要一个未评估的有理数,可以传递 gcd=1,这将保留分子和分母的公因数,不会被消除。然而,不能在分母中留下负值。

>>> Rational(2, 4, gcd=1)
2/4
>>> Rational(2, -4, gcd=1).q
4 

另请参阅

sympy.core.sympify.sympifysympy.simplify.simplify.nsimplify

as_coeff_Add(rational=False)

高效地提取求和的系数。

as_coeff_Mul(rational=False)

高效地提取乘积的系数。

as_content_primitive(radical=False, clear=True)

返回元组 (R, self/R),其中 R 是从 self 提取的正有理数。

示例

>>> from sympy import S
>>> (S(-3)/2).as_content_primitive()
(3/2, -1) 

查看 Expr.as_content_primitive 的文档字符串以获取更多示例。

factors(limit=None, use_trial=True, use_rho=False, use_pm1=False, verbose=False, visual=False)

一个封装到 factorint 的包装器,返回小于限制值(或便宜计算的)的 self 的因子。默认情况下禁用特殊的因子分解方法,因此仅使用试除法。

limit_denominator(max_denominator=1000000)

最接近 self 的有理数,其分母最多为 max_denominator。

示例

>>> from sympy import Rational
>>> Rational('3.141592653589793').limit_denominator(10)
22/7
>>> Rational('3.141592653589793').limit_denominator(100)
311/99 
class sympy.core.numbers.Integer(i)

表示任意大小的整数。

示例

>>> from sympy import Integer
>>> Integer(3)
3 

如果传递浮点数或有理数给 Integer,则会丢弃其小数部分;效果相当于向零舍入。

>>> Integer(3.8)
3
>>> Integer(-3.8)
-3 

如果字符串可以解析为整数,则接受字符串作为输入:

>>> Integer("9" * 20)
99999999999999999999 

很少需要显式实例化 Integer,因为在 SymPy 表达式中使用 Python 整数时会自动转换为 Integer。

class sympy.core.numbers.AlgebraicNumber(expr, coeffs=None, alias=None, **args)

表示 SymPy 中代数数的类。

符号上,该类的一个实例表示一个元素 (\alpha \in \mathbb{Q}(\theta) \hookrightarrow \mathbb{C})。也就是说,代数数 (\alpha) 被表示为特定数域 (\mathbb{Q}(\theta)) 的一个元素,这个数域以一种特定的方式嵌入到复数域中。

形式上,原始元素 (\theta) 由两个数据点给出:(1)其最小多项式(定义了 (\mathbb{Q}(\theta))),以及(2)作为该多项式根的特定复数(定义了嵌入 (\mathbb{Q}(\theta) \hookrightarrow \mathbb{C}))。最后,我们表示的代数数 (\alpha) 是由 (\theta) 的多项式的系数给出的。

static __new__(cls, expr, coeffs=None, alias=None, **args)

构造一个属于数域 ( k = \mathbb{Q}(\theta) ) 的新代数数 (\alpha)。

有四个待确定的实例属性:

属性类型/含义
root表示(\theta)为复数的Expr
minpolyPoly,(\theta)的最小多项式
repDMP 将(\alpha)表示为(\theta)的多项式
aliasSymbol 代表(\theta),或者为None

参见参数部分以了解它们是如何确定的。

参数:

expr : Expr,或者是对((m, r))的一对

有三种不同的构造模式,具体取决于作为expr传递的内容。

(1) expr 是一个AlgebraicNumber:在这种情况下,我们首先从expr复制所有四个实例属性。如果也提供了coeffs,我们将组合这两个系数多项式(见下文)。如果提供了alias,则覆盖之。

(2) expr 是任何其他类型的Expr:那么root将等于expr。因此,它必须表达一个代数量,并且我们将计算其minpoly

(3) expr 是有序对((m, r)),给出minpoly (m),及其根root (r),二者共同定义了(\theta)。在这种情况下,(m)可以是一个单变量的Poly,或者任何表示相同含义的Expr,而(r)必须是某个表示(m)根的Expr,包括根据复数的明确表达式以及ComplexRootOfAlgebraicNumber的实例。

coeffs : 列表,ANP,默认为 None(可选)

这定义了rep,将代数数(\alpha)表示为(\theta)的多项式。

如果是列表,则元素应为整数或有理数。如果是ANP,则使用其to_list()方法获取其系数。如果为None,则系数列表默认为[1, 0],这意味着(\alpha = \theta)是域的原始元素。

如果 expr 是一个 AlgebraicNumber,让 (g(x)) 是它的 rep 多项式,让 (f(x)) 是由 coeffs 定义的多项式。那么 self.rep 将表示组合 ((f \circ g)(x))。

alias:字符串,Symbol,默认为 None,可选(默认值为 None

这是为原始元素提供名称的一种方法。我们描述了 expr 参数定义原始元素值的几种方式,但是没有一种方法给它起一个名字。例如,在这里,alias 可以设置为 Symbol('theta'),以便在打印 (\alpha) 或使用 as_poly() 方法渲染为多项式时出现该符号。

举例

请记住,我们正在构造一个代数数作为域元素 (\alpha \in \mathbb{Q}(\theta))。

>>> from sympy import AlgebraicNumber, sqrt, CRootOf, S
>>> from sympy.abc import x 

示例(1):(\alpha = \theta = \sqrt{2})

>>> a1 = AlgebraicNumber(sqrt(2))
>>> a1.minpoly_of_element().as_expr(x)
x**2 - 2
>>> a1.evalf(10)
1.414213562 

示例(2):(\alpha = 3 \sqrt{2} - 5), (\theta = \sqrt{2})。我们可以继续上一个示例:

>>> a2 = AlgebraicNumber(a1, [3, -5])
>>> a2.as_expr()
-5 + 3*sqrt(2) 

或者从头开始:

>>> a2 = AlgebraicNumber(sqrt(2), [3, -5])
>>> a2.as_expr()
-5 + 3*sqrt(2) 

示例(3):(\alpha = 6 \sqrt{2} - 11), (\theta = \sqrt{2})。同样,我们可以基于前一个示例,并且我们看到系数多项式是组合的:

>>> a3 = AlgebraicNumber(a2, [2, -1])
>>> a3.as_expr()
-11 + 6*sqrt(2) 

反映了事实,即 ((2x - 1) \circ (3x - 5) = 6x - 11)。

示例(4):(\alpha = \sqrt{2}),(\theta = \sqrt{2} + \sqrt{3})。最简单的方法是使用 to_number_field() 函数:

>>> from sympy import to_number_field
>>> a4 = to_number_field(sqrt(2), sqrt(2) + sqrt(3))
>>> a4.minpoly_of_element().as_expr(x)
x**2 - 2
>>> a4.to_root()
sqrt(2)
>>> a4.primitive_element()
sqrt(2) + sqrt(3)
>>> a4.coeffs()
[1/2, 0, -9/2, 0] 

但是如果你已经知道了正确的系数,你可以直接构造它:

>>> a4 = AlgebraicNumber(sqrt(2) + sqrt(3), [S(1)/2, 0, S(-9)/2, 0])
>>> a4.to_root()
sqrt(2)
>>> a4.primitive_element()
sqrt(2) + sqrt(3) 

示例(5):在第五旋轉数域中构造黄金比例作为一个元素,假设我们已经知道它的系数。这次我们引入别名 (\zeta) 作为该域的原始元素:

>>> from sympy import cyclotomic_poly
>>> from sympy.abc import zeta
>>> a5 = AlgebraicNumber(CRootOf(cyclotomic_poly(5), -1),
...                  [-1, -1, 0, 0], alias=zeta)
>>> a5.as_poly().as_expr()
-zeta**3 - zeta**2
>>> a5.evalf()
1.61803398874989 

(索引 -1CRootOf 选择具有最大实部和虚部的复数根,这种情况下是 (\mathrm{e}^{2i\pi/5})。参见 ComplexRootOf。)

示例(6):在上一个示例的基础上,构造数 (2 \phi \in \mathbb{Q}(\phi)),其中 (\phi) 是黄金比例:

>>> from sympy.abc import phi
>>> a6 = AlgebraicNumber(a5.to_root(), coeffs=[2, 0], alias=phi)
>>> a6.as_poly().as_expr()
2*phi
>>> a6.primitive_element().evalf()
1.61803398874989 

请注意,我们需要使用 a5.to_root(),因为将 a5 作为第一个参数传递会将数 (2 \phi) 构造为域 (\mathbb{Q}(\zeta)) 的一个元素:

>>> a6_wrong = AlgebraicNumber(a5, coeffs=[2, 0])
>>> a6_wrong.as_poly().as_expr()
-2*zeta**3 - 2*zeta**2
>>> a6_wrong.primitive_element().evalf()
0.309016994374947 + 0.951056516295154*I 
as_expr(x=None)

self 创建一个基本表达式。

as_poly(x=None)

self 创建一个 Poly 实例。

coeffs()

返回代数数的所有 SymPy 系数。

field_element(coeffs)

以同一数域的另一个元素形式。

参数:

coeffs:列表,ANP

类似于类 构造器coeffs 参数,将新元素定义为原始元素的多项式。

如果是列表,则其元素应为整数或有理数。如果是 ANP,我们使用其系数(使用其 to_list() 方法)。

解释

如果我们表示 (\alpha \in \mathbb{Q}(\theta)),构造另一个属于同一数域 (\mathbb{Q}(\theta)) 的元素 (\beta)。

示例

>>> from sympy import AlgebraicNumber, sqrt
>>> a = AlgebraicNumber(sqrt(5), [-1, 1])
>>> b = a.field_element([3, 2])
>>> print(a)
1 - sqrt(5)
>>> print(b)
2 + 3*sqrt(5)
>>> print(b.primitive_element() == a.primitive_element())
True 

另见

代数数

property is_aliased

如果设置了 alias,则返回 True

property is_primitive_element

判断此代数数 (\alpha \in \mathbb{Q}(\theta)) 是否等于其数域的原始元素 (\theta)。

minpoly_of_element()

计算此代数数的最小多项式。

解释

回想一下,我们表示一个元素 (\alpha \in \mathbb{Q}(\theta))。我们的实例属性 self.minpoly 是我们原始元素 (\theta) 的最小多项式。此方法计算 (\alpha) 的最小多项式。

native_coeffs()

返回一个代数数的所有本地系数。

primitive_element()

获取数域 (\mathbb{Q}(\theta)) 中此代数数 (\alpha) 所属的原始元素 (\theta)。

返回:

代数数

to_algebraic_integer()

self 转换为代数整数。

to_primitive_element(radicals=True)

self 转换为一个 代数数 实例,该实例等于其自身的原始元素。

参数:

根式:布尔值,可选(默认为 True)

如果为 True,则我们将尝试返回一个根式表达式中的 代数数。如果不可能(或者 radicalsFalse),则 root 将是 ComplexRootOf

返回:

代数数

解释

如果我们表示 (\alpha \in \mathbb{Q}(\theta)),(\alpha \neq \theta),构造一个新的 代数数 来表示 (\alpha \in \mathbb{Q}(\alpha))。

示例

>>> from sympy import sqrt, to_number_field
>>> from sympy.abc import x
>>> a = to_number_field(sqrt(2), sqrt(2) + sqrt(3)) 

代数数 a 在域 (\mathbb{Q}(\sqrt{2} + \sqrt{3})) 中代表数字 (\sqrt{2})。将 a 渲染为多项式,

>>> a.as_poly().as_expr(x)
x**3/2 - 9*x/2 

反映了 (\sqrt{2} = \theta³/2 - 9 \theta/2) 这一事实,其中 (\theta = \sqrt{2} + \sqrt{3})。

a 不等于其自身的原始元素。其最小多项式

>>> a.minpoly.as_poly().as_expr(x)
x**4 - 10*x**2 + 1 

是关于 (\theta) 的。

转换为一个原始元素,

>>> a_prim = a.to_primitive_element()
>>> a_prim.minpoly.as_poly().as_expr(x)
x**2 - 2 

我们得到一个 代数数,其 minpoly 与该数本身相同。

另见

is_primitive_element

to_root(radicals=True, minpoly=None)

转换为一个 Expr,而不是一个 AlgebraicNumber,具体来说,要么是 ComplexRootOf,或者在可能的情况下是一个根式表达式。

参数:

radicals:布尔值,可选(默认为 True)

如果为 True,则尝试返回根式表达式的根。如果不可能,将返回一个 ComplexRootOf

minpolyPoly

如果已经预先计算了 self 的最小多项式,则可以传入以节省时间。

class sympy.core.numbers.NumberSymbol
approximation(number_cls)

返回一个包含 NumberSymbol 值的 number_cls 端点的区间。如果未实现,则返回 None。

sympy.core.numbers.RealNumber

别名为 Float

sympy.core.numbers.seterr(divide=False)

SymPy 是否应在 0/0 时抛出异常或返回 NaN?

divide == True …. 抛出异常 divide == False … 返回 NaN

class sympy.core.numbers.Zero

数字零。

Zero 是一个单例,可以通过 S.Zero 访问。

示例

>>> from sympy import S, Integer
>>> Integer(0) is S.Zero
True
>>> 1/S.Zero
zoo 

参考文献

[R127]

en.wikipedia.org/wiki/Zero

class sympy.core.numbers.One

数字一。

One 是一个单例,可以通过 S.One 访问。

示例

>>> from sympy import S, Integer
>>> Integer(1) is S.One
True 

参考文献

[R128]

en.wikipedia.org/wiki/1_%28number%29

class sympy.core.numbers.NegativeOne

数字负一。

NegativeOne 是一个单例,可以通过 S.NegativeOne 访问。

示例

>>> from sympy import S, Integer
>>> Integer(-1) is S.NegativeOne
True 

参见

One

参考文献

[R129]

en.wikipedia.org/wiki/%E2%88%921_%28number%29

class sympy.core.numbers.Half

有理数 1/2。

Half 是一个单例,可以通过 S.Half 访问。

示例

>>> from sympy import S, Rational
>>> Rational(1, 2) is S.Half
True 

参考文献

[R130]

en.wikipedia.org/wiki/One_half

class sympy.core.numbers.NaN

非数字。

解释

这用作不定数的数值占位符。NaN 的大多数运算会产生另一个 NaN。大多数不定形式,如 0/0pyoo - oo` produce NaN.  Two exceptions are ``0**0oo**0,都会产生 1(这与 Python 的浮点数一致)。

NaN 与浮点数的 nan 松散相关,后者在 IEEE 754 浮点数标准中定义,并对应于 Python 的 float('nan')。下面会说明它们的差异。

NaN 在数学上与任何其他值都不相等,甚至不等于自身。这解释了下面示例中 Eq== 的最初反直觉结果。

NaN 不可比较,因此不等式会引发 TypeError。这与浮点数的 nan 不同,后者所有不等式均为假。

NaN 是一个单例,可以通过 S.NaN 访问,或者可以导入为 nan

例子

>>> from sympy import nan, S, oo, Eq
>>> nan is S.NaN
True
>>> oo - oo
nan
>>> nan + 1
nan
>>> Eq(nan, nan)   # mathematical equality
False
>>> nan == nan     # structural equality
True 

参考文献

[R131]

en.wikipedia.org/wiki/NaN

class sympy.core.numbers.Infinity

正无穷大量。

解释

在实分析中,符号 (\infty) 表示无界极限:(x\to\infty) 意味着 (x) 增长无限。

无穷大常被用来不仅定义极限,而且作为扩展实数系统中的一个值。标记为 (+\infty) 和 (-\infty) 的点可以添加到实数的拓扑空间中,从而产生实数的二点紧致化。在此基础上添加代数属性给我们扩展了的实数。

Infinity 是一个单例,可以通过 S.Infinity 访问,或者可以导入为 oo

例子

>>> from sympy import oo, exp, limit, Symbol
>>> 1 + oo
oo
>>> 42/oo
0
>>> x = Symbol('x')
>>> limit(exp(x), x, oo)
oo 

参见

NegativeInfinity, NaN

参考文献

[R132]

en.wikipedia.org/wiki/Infinity

class sympy.core.numbers.NegativeInfinity

负无穷大量。

NegativeInfinity 是一个单例,可以通过 S.NegativeInfinity 访问。

参见

Infinity

class sympy.core.numbers.ComplexInfinity

复数无穷大。

解释

在复分析中,符号 (\tilde\infty),称为“复无穷大”,表示具有无限大小但未确定复相位的量。

ComplexInfinity 是一个单例,可以通过 S.ComplexInfinity 访问,或者可以导入为 zoo

例子

>>> from sympy import zoo
>>> zoo + 42
zoo
>>> 42/zoo
0
>>> zoo + zoo
nan
>>> zoo*zoo
zoo 

参见

Infinity

class sympy.core.numbers.Exp1

(e) 常数。

解释

超越数 (e = 2.718281828\ldots) 是自然对数和指数函数的底数,(e = \exp(1))。有时称为欧拉数或纳皮尔常数。

Exp1 是一个单例,可以通过 S.Exp1 访问,或者可以导入为 E

例子

>>> from sympy import exp, log, E
>>> E is exp(1)
True
>>> log(E)
1 

参考文献

[R133]

en.wikipedia.org/wiki/E_%28mathematical_constant%29

class sympy.core.numbers.ImaginaryUnit

虚数单位,(i = \sqrt{-1})。

I 是一个单例,可以通过 S.I 访问,或者可以导入为 I

例子

>>> from sympy import I, sqrt
>>> sqrt(-1)
I
>>> I*I
-1
>>> 1/I
-I 

参考文献

[R134]

en.wikipedia.org/wiki/Imaginary_unit

class sympy.core.numbers.Pi

圆周率 (\pi) 常数。

解释

超越数 (\pi = 3.141592654\ldots) 表示圆周率与其直径的比率,单位圆的面积,三角函数的半周期以及数学中的许多其他内容。

圆周率是一个单例,可以通过 S.Pi 访问,或者可以导入为 pi

例子

>>> from sympy import S, pi, oo, sin, exp, integrate, Symbol
>>> S.Pi
pi
>>> pi > 3
True
>>> pi.is_irrational
True
>>> x = Symbol('x')
>>> sin(x + 2*pi)
sin(x)
>>> integrate(exp(-x**2), (x, -oo, oo))
sqrt(pi) 

参考文献

[R135]

en.wikipedia.org/wiki/Pi

class sympy.core.numbers.EulerGamma

欧拉-马斯切罗尼常数。

解释

(\gamma = 0.5772157\ldots)(也称为欧拉常数)是分析和数论中经常出现的数学常数。它被定义为调和级数与自然对数之间的极限差:

[\gamma = \lim\limits_{n\to\infty} \left(\sum\limits_{k=1}^n\frac{1}{k} - \ln n\right)]

欧拉-马斯谢罗常数是一个单例,可以通过 S.EulerGamma 访问。

示例

>>> from sympy import S
>>> S.EulerGamma.is_irrational
>>> S.EulerGamma > 0
True
>>> S.EulerGamma > 1
False 

参考

[R136]

en.wikipedia.org/wiki/Euler%E2%80%93Mascheroni_constant

class sympy.core.numbers.Catalan

卡塔兰常数。

解释

(G = 0.91596559\ldots) 是由无限级数给出的

[G = \sum_{k=0}^{\infty} \frac{(-1)^k}{(2k+1)²}]

卡塔兰常数是一个单例,可以通过 S.Catalan 访问。

示例

>>> from sympy import S
>>> S.Catalan.is_irrational
>>> S.Catalan > 0
True
>>> S.Catalan > 1
False 

参考

[R137]

en.wikipedia.org/wiki/Catalan%27s_constant

class sympy.core.numbers.GoldenRatio

黄金比例,(\phi)。

解释

(\phi = \frac{1 + \sqrt{5}}{2}) 是一个代数数。如果两个量的比率等于它们的和与较大量的比率,那么它们就处于黄金比例,即它们的最大量。

黄金比例是一个单例,可以通过 S.GoldenRatio 访问。

示例

>>> from sympy import S
>>> S.GoldenRatio > 1
True
>>> S.GoldenRatio.expand(func=True)
1/2 + sqrt(5)/2
>>> S.GoldenRatio.is_irrational
True 

参考

[R138]

en.wikipedia.org/wiki/Golden_ratio

class sympy.core.numbers.TribonacciConstant

三波那契常数。

解释

三波那契数类似于斐波那契数,但是不是从两个预定项开始,而是从三个预定项开始,后面的每一项是前三项的和。

三波那契常数是相邻三波那契数趋向的比率。它是多项式 (x³ - x² - x - 1 = 0) 的根,同时满足方程 (x + x^{-3} = 2)。

三波那契常数是一个单例,可以通过 S.TribonacciConstant 访问。

示例

>>> from sympy import S
>>> S.TribonacciConstant > 1
True
>>> S.TribonacciConstant.expand(func=True)
1/3 + (19 - 3*sqrt(33))**(1/3)/3 + (3*sqrt(33) + 19)**(1/3)/3
>>> S.TribonacciConstant.is_irrational
True
>>> S.TribonacciConstant.n(20)
1.8392867552141611326 

参考

[R139]

en.wikipedia.org/wiki/Generalizations_of_Fibonacci_numbers#Tribonacci_numbers

sympy.core.numbers.mod_inverse(a, m)

返回数 (c),使得 (a \times c = 1 \pmod{m}),其中 (c) 的符号与 (m) 相同。如果不存在这样的值,则引发 ValueError。

示例

>>> from sympy import mod_inverse, S 

假设我们希望找到模 11 下的数 3 的乘法逆元 (x)。这等同于找到满足 (3x = 1 \pmod{11}) 的 (x)。满足这个同余的一个值是 4。因为 (3 \times 4 = 12) 并且 (12 = 1 \pmod{11})。这是 mod_inverse 返回的值:

>>> mod_inverse(3, 11)
4
>>> mod_inverse(-3, 11)
7 

当分子 (a) 和 (m) 之间有公共因子时,逆元不存在:

>>> mod_inverse(2, 4)
Traceback (most recent call last):
...
ValueError: inverse of 2 mod 4 does not exist 
>>> mod_inverse(S(2)/7, S(5)/2)
7/2 

参考

[R140]

en.wikipedia.org/wiki/Modular_multiplicative_inverse

[R141]

en.wikipedia.org/wiki/Extended_Euclidean_algorithm

sympy.core.numbers.equal_valued(x, y)

比较将普通浮点数作为有理数处理的表达式。

示例

>>> from sympy import S, symbols, Rational, Float
>>> from sympy.core.numbers import equal_valued
>>> equal_valued(1, 2)
False
>>> equal_valued(1, 1)
True 

在 SymPy 表达式中,Floats 与对应的 Rationals 比较不相等:

>>> x = symbols('x')
>>> x**2 == x**2.0
False 

然而,单个 Float 与 Rational 比较相等:

>>> Rational(1, 2) == Float(0.5)
False 

在未来的 SymPy 版本中,这可能会改变,以使 Rational 和 Float 比较不相等。此函数提供了当前预期的==行为,以便在未来更改==行为时仍然可以使用。

>>> equal_valued(1, 1.0) # Float vs Rational
True
>>> equal_valued(S(1).n(3), S(1).n(5)) # Floats of different precision
True 

说明

在未来的 SymPy 版本中,Float 和 Rational 可能会比较不相等,不同精度的浮点数可能会比较不相等。在这种情况下,需要一个函数来检查一个数是否等于 1 或 0 等。这个想法是,不再测试if x == 1:如果我们想接受像1.0这样的浮点数,那么测试可以写成if equal_valued(x, 1):if equal_valued(x, 2):。由于这个函数旨在用于期望一个或两个操作数为具体数字(如 1 或 0)的情况,所以该函数不会递归通过任何复合表达式的参数来比较任何嵌套浮点数。

参考文献

[R142]

github.com/sympy/sympy/pull/20033 ## power

class sympy.core.power.Pow(b, e, evaluate=None)

定义表达式 x**y 为“x 的 y 次幂”

自版本 1.7 起不推荐使用:在核心操作符(MulAddPow)中使用非Expr子类的参数已被弃用。有关详情,请参阅 Core operators no longer accept non-Expr args。

单例定义涉及(0, 1, -1, oo, -oo, I, -I):

exprvaluereason
z**01尽管关于 0**0 的论点存在,参见[2]。
z**1z
(-oo)**(-1)0
(-1)**-1-1
S.Zero**-1zoo这并非严格正确,因为 0**-1 可能未定义,但在某些假设基数为正时很方便。
1**-11
oo**-10
0**oo0因为对于所有接近 0 的复数 z,z**oo -> 0。
0**-oozoo这并非严格正确,因为 0**oo 可能在复平面中正负值之间震荡或旋转。但是,当基数为正时,这是方便的。
1oo 1-oonan因为存在 lim(x(t),t)=1,lim(y(t),t)=oo(或-oo),但 lim(x(t)**y(t), t) != 1。参见[3]。
b**zoonan因为 b**z 在 z -> zoo 时没有极限。
(-1)oo (-1)(-oo)nan因为极限中存在振荡。
oo**oooo
oo**-oo0
(-oo)oo (-oo)-oonan
oo**I (-oo)**Inan可以将 ooe 最好视为 x 趋于 oo 时实数 xe 的极限。如果 e 是 I,则极限不存在,使用 nan 表示。
oo**(1+I) (-oo)**(1+I)zoo如果 e 的实部为正,则 abs(x**e) 的极限为 oo。因此极限值为 zoo。
oo**(-1+I) -oo**(-1+I)0如果 e 的实部为负,则极限为 0。

因为符号计算比浮点计算更灵活,并且我们更倾向于不返回不正确的答案,所以我们选择不遵循所有 IEEE 754 的约定。这有助于我们避免在计算极限时额外的测试案例代码。

另请参阅

sympy.core.numbers.Infinity, sympy.core.numbers.NegativeInfinity, sympy.core.numbers.NaN

参考

[R143]

en.wikipedia.org/wiki/Exponentiation

[R144]

en.wikipedia.org/wiki/Zero_to_the_power_of_zero

[R145]

en.wikipedia.org/wiki/Indeterminate_forms

as_base_exp()

返回 self 的基数和指数。

解释

如果基数小于 1,则返回 1/有理数,-exp。如果不需要此额外处理,则基数和 exp 属性将给出原始参数。

示例

>>> from sympy import Pow, S
>>> p = Pow(S.Half, 2, evaluate=False)
>>> p.as_base_exp()
(2, -2)
>>> p.args
(1/2, 2)
>>> p.base, p.exp
(1/2, 2) 
as_content_primitive(radical=False, clear=True)

返回元组 (R, self/R),其中 R 是从 self 中提取的正有理数。

示例

>>> from sympy import sqrt
>>> sqrt(4 + 4*sqrt(2)).as_content_primitive()
(2, sqrt(1 + sqrt(2)))
>>> sqrt(3 + 3*sqrt(2)).as_content_primitive()
(1, sqrt(3)*sqrt(1 + sqrt(2))) 
>>> from sympy import expand_power_base, powsimp, Mul
>>> from sympy.abc import x, y 
>>> ((2*x + 2)**2).as_content_primitive()
(4, (x + 1)**2)
>>> (4**((1 + y)/2)).as_content_primitive()
(2, 4**(y/2))
>>> (3**((1 + y)/2)).as_content_primitive()
(1, 3**((y + 1)/2))
>>> (3**((5 + y)/2)).as_content_primitive()
(9, 3**((y + 1)/2))
>>> eq = 3**(2 + 2*x)
>>> powsimp(eq) == eq
True
>>> eq.as_content_primitive()
(9, 3**(2*x))
>>> powsimp(Mul(*_))
3**(2*x + 2) 
>>> eq = (2 + 2*x)**y
>>> s = expand_power_base(eq); s.is_Mul, s
(False, (2*x + 2)**y)
>>> eq.as_content_primitive()
(1, (2*(x + 1))**y)
>>> s = expand_power_base(_[1]); s.is_Mul, s
(True, 2**y*(x + 1)**y) 

有关更多示例,请参阅 Expr.as_content_primitive 的文档字符串。 ## mul

class sympy.core.mul.Mul(*args, evaluate=None, _sympify=True)

表示代数场中乘法操作的表达式。

自版本 1.7 弃用:在核心运算符(MulAddPow)中使用非 Expr 子类的参数。有关详细信息,请参阅不再接受非 Expr 参数的核心运算符。

Mul() 的每个参数都必须是 Expr。在 SymPy 中大多数标量对象上的中缀运算符 * 都调用此类。

Mul() 的另一个用途是表示抽象乘法的结构,以便其参数可以被替换以返回不同的类。有关此内容,请参阅示例部分。

Mul() 会评估参数,除非传递了 evaluate=False。评估逻辑包括:

  1. 展平

    Mul(x, Mul(y, z)) -> Mul(x, y, z)

  2. 去除身份

    Mul(x, 1, y) -> Mul(x, y)

  3. 通过 .as_base_exp() 收集指数

    Mul(x, x**2) -> Pow(x, 3)

  4. 项排序

    Mul(y, x, 2) -> Mul(2, x, y)

由于乘法可以是矢量空间操作,参数可能具有不同的 sympy.core.kind.Kind()。结果对象的种类将自动推断。

示例

>>> from sympy import Mul
>>> from sympy.abc import x, y
>>> Mul(x, 1)
x
>>> Mul(x, x)
x**2 

如果传递了 evaluate=False,则结果不会被评估。

>>> Mul(1, 2, evaluate=False)
1*2
>>> Mul(x, x, evaluate=False)
x*x 

Mul() 也表示乘法操作的一般结构。

>>> from sympy import MatrixSymbol
>>> A = MatrixSymbol('A', 2,2)
>>> expr = Mul(x,y).subs({y:A})
>>> expr
x*A
>>> type(expr)
<class 'sympy.matrices.expressions.matmul.MatMul'> 

另请参见

MatMul

as_coeff_Mul(rational=False)

高效地提取乘积的系数。

as_content_primitive(radical=False, clear=True)

返回元组(R, self/R),其中 R 是从 self 中提取的正有理数。

示例

>>> from sympy import sqrt
>>> (-3*sqrt(2)*(2 - 2*sqrt(2))).as_content_primitive()
(6, -sqrt(2)*(1 - sqrt(2))) 

查看Expr.as_content_primitive的文档字符串以获取更多示例。

as_ordered_factors(order=None)

将表达式转换为因子的有序列表。

示例

>>> from sympy import sin, cos
>>> from sympy.abc import x, y 
>>> (2*x*y*sin(x)*cos(x)).as_ordered_factors()
[2, x, y, sin(x), cos(x)] 
as_two_terms()

返回 self 的头部和尾部。

这是获取表达式头部和尾部的最有效方式。

  • 如果只需要头部,请使用 self.args[0];

  • 如果要处理尾部的参数,则使用 self.as_coef_mul(),它在将其视为 Mul 时给出头部和包含尾部参数的元组。

  • 如果希望在将 self 视为 Add 时获取系数,请使用 self.as_coeff_add()[0]

示例

>>> from sympy.abc import x, y
>>> (3*x*y).as_two_terms()
(3, x*y) 
classmethod flatten(seq)

通过结合相关术语返回可交换、非可交换和顺序参数。

注意

  • 在类似a*b*c的表达式中,Python 将其通过 SymPy 处理为Mul(Mul(a, b), c)。这可能会产生不良后果。

    >>> from sympy import Mul, sqrt
    
> >>> from sympy.abc import x, y, z
> >>> 2*(x + 1) # this is the 2-arg Mul behavior
> 2*x + 2
> >>> y*(x + 1)*2
> 2*y*(x + 1)
> >>> 2*(x + 1)*y # 2-arg result will be obtained first
> y*(2*x + 2)
> >>> Mul(2, x + 1, y) # all 3 args simultaneously processed
> 2*y*(x + 1)
> >>> 2*((x + 1)*y) # parentheses can control this behavior
> 2*y*(x + 1) 
> ```

> 

> 具有复合基数的幂可能找不到单个基数来组合,除非所有参数一次处理。在这种情况下可能需要后处理。{参见 [`github.com/sympy/sympy/issues/5728`](https://github.com/sympy/sympy/issues/5728)}

> 

> ```py

> >>> a = sqrt(x*sqrt(y))
> >>> a**3
> (x*sqrt(y))**(3/2)
> >>> Mul(a,a,a)
> (x*sqrt(y))**(3/2)
> >>> a*a*a
> x*sqrt(y)*sqrt(x*sqrt(y))
> >>> _.subs(a.base, z).subs(z, a.base)
> (x*sqrt(y))**(3/2) 
> ```

+   如果正在相乘的术语超过两个,则所有先前的术语将对每个新的参数重新处理。因此,如果每个`a`、`b`和`c`都是`Mul`表达式,那么`a*b*c`(或通过`*=`逐步建立乘积)将会两次处理`a`和`b`的所有参数:一次是计算`a*b`时,另一次是乘以`c`时。

    使用`Mul(a, b, c)`将会处理所有参数一次。
  • Mul的结果会根据参数进行缓存,因此仅对Mul(a, b, c)调用一次flatten。如果可以结构化计算使得参数最有可能重复,那么可以节省计算答案的时间。例如,假设你有一个 Mul,M,希望除以d[i]并乘以n[i],并且你怀疑n中有许多重复。最好计算M*n[i]/d[i]而不是M/d[i]*n[i],因为每次n[i]重复时,乘积M*n[i]将返回而无需扁平化 – 将返回缓存的值。如果首先除以d[i](而这些与n[i]相比更独特),那么将创建一个新的 Mul,M/d[i]其参数将在乘以n[i]时再次遍历。

    {参见 github.com/sympy/sympy/issues/5706}

    如果缓存关闭,则此考虑无效。

上述说明的有效性取决于 Mul 和 flatten 的实现细节,这些细节可能随时更改。 因此,只有在您的代码非常关注性能时才应考虑它们。

从序列中删除 1 已由 AssocOp.new 处理。

sympy.core.mul.prod(a, start=1)

返回数组元素的乘积。从整数 1 开始,所以如果只有

ints 被包括在内,然后返回一个 int 结果。

示例

>>> from sympy import prod, S
>>> prod(range(3))
0
>>> type(_) is int
True
>>> prod([S(2), 3])
6
>>> _.is_Integer
True 

您可以从 1 以外的某个值开始产品:

>>> prod([1, 2], 3)
6 
```  ## add

```py
class sympy.core.add.Add(*args, evaluate=None, _sympify=True)

表示代数组的加法操作的表达式。

自版本 1.7 起不推荐使用:在核心运算符(MulAddPow)中使用非 Expr 参数已被弃用。 有关详细信息,请参阅 Core operators no longer accept non-Expr args。

Add()的每个参数都必须是Expr。 SymPy 中大多数标量对象上的中缀运算符+调用这个类。

Add()的另一个用途是表示抽象加法结构,以便可以替换其参数以返回不同的类。 有关此内容,请参阅示例部分。

如果未传递evaluate=False,则Add()会评估参数。 评估逻辑包括:

  1. 展平

    Add(x, Add(y, z)) -> Add(x, y, z)

  2. 去除标识

    Add(x, 0, y) -> Add(x, y)

  3. 通过.as_coeff_Mul()进行系数收集

    Add(x, 2*x) -> Mul(3, x)

  4. 项排序

    Add(y, x, 2) -> Add(2, x, y)

如果没有传递参数,则返回标识元素 0。 如果传递单个元素,则返回该元素。

请注意,Add(*args)sum(args)更有效,因为它会展平参数。 sum(a, b, c, ...)以递归方式添加参数,即a + (b + (c + ...)),具有二次复杂度。 另一方面,Add(a, b, c, d)不假设嵌套结构,使得复杂度为线性。

由于加法是组操作,每个参数都应具有相同的sympy.core.kind.Kind()

示例

>>> from sympy import Add, I
>>> from sympy.abc import x, y
>>> Add(x, 1)
x + 1
>>> Add(x, x)
2*x
>>> 2*x**2 + 3*x + I*y + 2*y + 2*x/5 + 1.0*y + 1
2*x**2 + 17*x/5 + 3.0*y + I*y + 1 

如果传递evaluate=False,结果不会被评估。

>>> Add(1, 2, evaluate=False)
1 + 2
>>> Add(x, x, evaluate=False)
x + x 

Add()还表示加法操作的一般结构。

>>> from sympy import MatrixSymbol
>>> A,B = MatrixSymbol('A', 2,2), MatrixSymbol('B', 2,2)
>>> expr = Add(x,y).subs({x:A, y:B})
>>> expr
A + B
>>> type(expr)
<class 'sympy.matrices.expressions.matadd.MatAdd'> 

请注意,打印机不会按照 args 的顺序显示。

>>> Add(x, 1)
x + 1
>>> Add(x, 1).args
(1, x) 

参见

MatAdd

as_coeff_Add(rational=False, deps=None)

高效地提取求和的系数。

as_coeff_add(*deps)

返回一个元组(coeff, args),其中 self 被视为 Add,coeff 是数字项,args 是所有其他项的元组。

示例

>>> from sympy.abc import x
>>> (7 + 3*x).as_coeff_add()
(7, (3*x,))
>>> (7*x).as_coeff_add()
(0, (7*x,)) 
as_content_primitive(radical=False, clear=True)

返回元组(R, self/R),其中 R 是从 self 中提取的正有理数。 如果 radical 为 True(默认为 False),则将删除常见的根,并将其包含为原始表达式的因子。

示例

>>> from sympy import sqrt
>>> (3 + 3*sqrt(2)).as_content_primitive()
(3, 1 + sqrt(2)) 

基本内容也可以从原始元素中分解出来:

>>> (2*sqrt(2) + 4*sqrt(10)).as_content_primitive(radical=True)
(2, sqrt(2)*(1 + 2*sqrt(5))) 

有关更多示例,请参阅 Expr.as_content_primitive 的文档字符串。

as_numer_denom()

将表达式分解为其分子部分和分母部分。

示例

>>> from sympy.abc import x, y, z
>>> (x*y/z).as_numer_denom()
(x*y, z)
>>> (x*(y + 1)/y**7).as_numer_denom()
(x*(y + 1), y**7) 

另见

sympy.core.expr.Expr.as_numer_denom

as_real_imag(deep=True, **hints)

返回表示复数的元组。

示例

>>> from sympy import I
>>> (7 + 9*I).as_real_imag()
(7, 9)
>>> ((1 + I)/(1 - I)).as_real_imag()
(0, 1)
>>> ((1 + 2*I)*(1 + 3*I)).as_real_imag()
(-5, 5) 
as_two_terms()

返回 self 的头部和尾部。

这是获取表达式头部和尾部的最有效方式。

  • 如果您只想获取头部,请使用self.args[0]

  • 如果您想处理尾部的参数,请使用self.as_coef_add(),它返回头部和作为 Add 处理时尾部参数的元组。

  • 如果您希望在将 self 视为 Mul 时获取系数,请使用self.as_coeff_mul()[0]

>>> from sympy.abc import x, y
>>> (3*x - 2*y + 5).as_two_terms()
(5, 3*x - 2*y) 
extract_leading_order(symbols, point=None)

返回主导项及其顺序。

示例

>>> from sympy.abc import x
>>> (x + 1 + 1/x**5).extract_leading_order(x)
((x**(-5), O(x**(-5))),)
>>> (1 + x).extract_leading_order(x)
((1, O(1)),)
>>> (x + x**2).extract_leading_order(x)
((x, O(x)),) 
classmethod flatten(seq)

获取嵌套 Add 的序列“seq”并返回一个扁平化列表。

返回:(可交换部分,非可交换部分,顺序符号)

应用结合性,所有术语均可相对于加法交换。

注意:去除 0 已由 AssocOp.new 处理。

另见

sympy.core.mul.Mul.flatten

primitive()

返回(R, self/R)其中R`self`的有理 GCD。

R仅从每个术语的主导系数中收集。

示例

>>> from sympy.abc import x, y 
>>> (2*x + 4*y).primitive()
(2, x + 2*y) 
>>> (2*x/3 + 4*y/9).primitive()
(2/9, 3*x + 2*y) 
>>> (2*x/3 + 4.2*y).primitive()
(1/3, 2*x + 12.6*y) 

不进行术语因子的子处理:

>>> ((2 + 2*x)*x + 2).primitive()
(1, x*(2*x + 2) + 2) 

递归处理可以使用as_content_primitive()方法完成:

>>> ((2 + 2*x)*x + 2).as_content_primitive()
(2, x*(x + 1) + 1) 

另见:polytools.py 中的 primitive()函数 ## mod

class sympy.core.mod.Mod(p, q)

表示符号表达式的模运算。

参数:

p : Expr

被除数。

q : Expr

除数。

注意

使用的约定与 Python 相同:余数始终与除数具有相同的符号。

许多对象在模n下的求值速度比直接(或根本)求值要快得多。为此,必须使用evaluate=False来防止急切求值:

>>> from sympy import binomial, factorial, Mod, Pow
>>> Mod(Pow(2, 10**16, evaluate=False), 97)
61
>>> Mod(factorial(10**9, evaluate=False), 10**9 + 9)
712524808
>>> Mod(binomial(10**18, 10**12, evaluate=False), (10**5 + 3)**2)
3744312326 

示例

>>> from sympy.abc import x, y
>>> x**2 % y
Mod(x**2, y)
>>> _.subs({x: 5, y: 6})
1 
```  ## 关系型

```py
class sympy.core.relational.Relational(lhs, rhs, rop=None, **assumptions)

所有关系类型的基类。

参数:

rop : str or None

指示实例化的子类。有效值可以在 Relational.ValidRelationOperator 的键中找到。

解释

Relational 的子类通常应直接实例化,但可以使用有效的rop值实例化 Relational 以分派到适当的子类。

示例

>>> from sympy import Rel
>>> from sympy.abc import x, y
>>> Rel(y, x + x**2, '==')
Eq(y, x**2 + x) 

可以使用rop参数在创建时定义关系类型。可以使用其rel_op属性获取现有表达式的关系类型。以下是所有关系类型的表格,以及它们的roprel_op值:

Relationroprel_op
Equality== or eq or None==
Unequality!= or ne!=
GreaterThan>= or ge>=
LessThan<= or le<=
StrictGreaterThan> or gt>
StrictLessThan< or lt<

例如,将rop设置为==会产生一个Equality关系,Eq()。设置ropeq或不指定rop也是如此。也就是说,下面的前三个Rel()都会产生相同的结果。使用表中不同行的rop,例如,将rop设置为lt会产生一个StrictLessThan不等式:

>>> from sympy import Rel
>>> from sympy.abc import x, y
>>> Rel(y, x + x**2, '==')
 Eq(y, x**2 + x)
>>> Rel(y, x + x**2, 'eq')
 Eq(y, x**2 + x)
>>> Rel(y, x + x**2)
 Eq(y, x**2 + x)
>>> Rel(y, x + x**2, 'lt')
 y < x**2 + x 

要获得现有表达式的关系类型,请获取其rel_op属性。例如,上述Equality关系的rel_op==,上述严格小于不等式的rel_op<

>>> from sympy import Rel
>>> from sympy.abc import x, y
>>> my_equality = Rel(y, x + x**2, '==')
>>> my_equality.rel_op
 '=='
>>> my_inequality = Rel(y, x + x**2, 'lt')
>>> my_inequality.rel_op
 '<' 
property canonical

通过在 rhs 上放置一个数字、规范地移除一个符号或以规范的顺序对 args 进行排序来返回关系的规范形式。不尝试进行其他简化。

示例

>>> from sympy.abc import x, y
>>> x < 2
x < 2
>>> _.reversed.canonical
x < 2
>>> (-y < x).canonical
x > -y
>>> (-y > x).canonical
x < -y
>>> (-y < -x).canonical
x < y 

规范化递归应用:

>>> from sympy import Eq
>>> Eq(x < y, y > x).canonical
True 
equals(other, failing_expression=False)

如果关系的两侧在数学上完全相同且关系类型相同,则返回 True。如果failing_expression为 True,则返回其真值未知的表达式。

property lhs

关系的左侧。

property negated

返回否定的关系。

示例

>>> from sympy import Eq
>>> from sympy.abc import x
>>> Eq(x, 1)
Eq(x, 1)
>>> _.negated
Ne(x, 1)
>>> x < 1
x < 1
>>> _.negated
x >= 1 

笔记

这与~/Not基本相同。不同之处在于,即使evaluate=Falsenegated也返回关系。因此,在代码中检查例如反向的关系时非常有用,因为它不受(evaluate)标志的影响。

property reversed

返回两侧关系颠倒。

示例

>>> from sympy import Eq
>>> from sympy.abc import x
>>> Eq(x, 1)
Eq(x, 1)
>>> _.reversed
Eq(1, x)
>>> x < 1
x < 1
>>> _.reversed
1 > x 
property reversedsign

返回带有符号反转的关系。

示例

>>> from sympy import Eq
>>> from sympy.abc import x
>>> Eq(x, 1)
Eq(x, 1)
>>> _.reversedsign
Eq(-x, -1)
>>> x < 1
x < 1
>>> _.reversedsign
-x > -1 
property rhs

关系的右侧。

property strict

返回严格版本的不等式或自身

示例

>>> from sympy.abc import x
>>> (x <= 1).strict
x < 1
>>> _.strict
x < 1 
property weak

返回非严格版本的不等式或自身

示例

>>> from sympy.abc import x
>>> (x < 1).weak
x <= 1
>>> _.weak
x <= 1 
sympy.core.relational.Rel

别名为Relational

sympy.core.relational.Eq

别名为Equality

sympy.core.relational.Ne

别名为Unequality

sympy.core.relational.Lt

别名为StrictLessThan

sympy.core.relational.Le

别名为LessThan

sympy.core.relational.Gt

别名为StrictGreaterThan

sympy.core.relational.Ge

别名为GreaterThan

class sympy.core.relational.Equality(lhs, rhs, **options)

两个对象之间的相等关系。

解释

表示两个对象相等。如果可以轻松地显示它们明确相等(或不相等),则会简化为 True(或 False)。否则,关系将保持为未评估的 Equality 对象。对此对象使用simplify函数以进行更复杂的等式关系评估。

通常,可以使用关键字参数evaluate=False来防止任何评估。

示例

>>> from sympy import Eq, simplify, exp, cos
>>> from sympy.abc import x, y
>>> Eq(y, x + x**2)
Eq(y, x**2 + x)
>>> Eq(2, 5)
False
>>> Eq(2, 5, evaluate=False)
Eq(2, 5)
>>> _.doit()
False
>>> Eq(exp(x), exp(x).rewrite(cos))
Eq(exp(x), sinh(x) + cosh(x))
>>> simplify(_)
True 

笔记

Python 将 1 和 True(以及 0 和 False)视为相等;SymPy 则不是。整数将始终与布尔值比较为不相等:

>>> Eq(True, 1), True == 1
(False, True) 

这个类与 == 操作符不同。== 操作符用于测试两个表达式之间的精确结构相等性;而这个类则是数学上比较表达式。

如果任何一个对象定义了 _eval_Eq 方法,则可以用它来替换默认算法。如果 lhs._eval_Eq(rhs)rhs._eval_Eq(lhs) 返回除 None 外的任何值,则该返回值将替换等式。如果 _eval_Eq 返回 None,则将像往常一样创建一个等式对象。

由于此对象已经是一个表达式,如果尝试从 Eq(x, y) 创建 (x - y),它不会响应 as_expr 方法。如果 eq = Eq(x, y),则写 (eq.lhs - eq.rhs) 可以得到 x - y

自版本 1.5 弃用:Eq(expr) 的单个参数是 Eq(expr, 0) 的简写,但这种行为已弃用,将在 SymPy 的未来版本中移除。

另见

sympy.logic.boolalg.Equivalent

用于表示两个布尔表达式之间的相等性

as_poly(*gens, **kwargs)

返回 lhs-rhs 作为多项式

示例

>>> from sympy import Eq
>>> from sympy.abc import x
>>> Eq(x**2, 1).as_poly(x)
Poly(x**2 - 1, x, domain='ZZ') 
integrate(*args, **kwargs)

参见 sympy.integrals 中的 integrate 函数

class sympy.core.relational.GreaterThan(lhs, rhs, **options)

表示不等式的类。

解释

*Than 类表示不等关系,其中左侧通常比右侧大或小。例如,GreaterThan 类表示不等关系,其中左侧至少与右侧一样大,如果不是更大的话。在数学符号中表示为:

lhs (\ge) rhs

总共有四个 *Than 类,用于表示四种不等式:

类名符号
GreaterThan>=
LessThan<=
StrictGreaterThan>
StrictLessThan<

所有类都接受两个参数,lhs 和 rhs。

签名示例数学等价物
GreaterThan(lhs, rhs)lhs (\ge) rhs
LessThan(lhs, rhs)lhs (\le) rhs
StrictGreaterThan(lhs, rhs)lhs (>) rhs
StrictLessThan(lhs, rhs)lhs (<) rhs

除了关系的正常 .lhs 和 .rhs 外,*Than 不等式对象还具有 .lts 和 .gts 属性,分别表示“小于侧”和“大于侧”的运算符。在算法中使用 .lts 和 .gts 而不是 .lhs 和 .rhs 作为不等方向的假设,会更明确地表达某一段代码的意图,并使其对客户端代码的更改更具鲁棒性:

>>> from sympy import GreaterThan, StrictGreaterThan
>>> from sympy import LessThan, StrictLessThan
>>> from sympy import And, Ge, Gt, Le, Lt, Rel, S
>>> from sympy.abc import x, y, z
>>> from sympy.core.relational import Relational 
>>> e = GreaterThan(x, 1)
>>> e
x >= 1
>>> '%s >= %s is the same as %s <= %s' % (e.gts, e.lts, e.lts, e.gts)
'x >= 1 is the same as 1 <= x' 

示例

通常不直接实例化这些类,而是使用各种便利方法:

>>> for f in [Ge, Gt, Le, Lt]:  # convenience wrappers
...     print(f(x, 2))
x >= 2
x > 2
x <= 2
x < 2 

另一个选择是直接使用 Python 的不等式运算符(>=><=<)。它们相对于 GeGtLeLt 的优势在于,可以编写更“数学化”的语句,而不是在数学中散布奇怪的函数调用。但是,还有一些需要注意的(次要)注意事项(请搜索下面的‘注意事项’)。

>>> x >= 2
x >= 2
>>> _ == Ge(x, 2)
True 

但是,也完全可以不那么简洁和方便地实例化一个 *Than 类:

>>> Rel(x, 1, ">")
x > 1
>>> Relational(x, 1, ">")
x > 1 
>>> StrictGreaterThan(x, 1)
x > 1
>>> GreaterThan(x, 1)
x >= 1
>>> LessThan(x, 1)
x <= 1
>>> StrictLessThan(x, 1)
x < 1 

注意事项

当使用 Python 的运算符时,有几个需要注意的地方。

第一个是你写的不一定是你得到的:

>>> 1 < x

x > 1 

由于 Python 解析语句的顺序,它可能不会立即找到两个可比较的对象。当评估 1 < x 时,Python 认识到数字 1 是本地数,而 x 不是。因为本地 Python 数字不知道如何与 SymPy 对象进行比较,Python 将尝试反射操作,x > 1,这是被评估的形式,因此返回。

如果语句的顺序很重要(例如对于控制台的视觉输出),可以通过以下几种方法来解决这个问题:

  1. 在比较之前“sympify”文字
>>> S(1) < x

1 < x 

(2) 使用其中一个包装器或上述 less 方法

>>> Lt(1, x)

1 < x

>>> Relational(1, x, "<")

1 < x 

第二个需要注意的地方涉及在文字关系涉及等式测试时写等式:

>>> e = x < 1; e

x < 1

>>> e == e  # neither side is a literal

True

>>> e == x < 1  # expecting True, too

False

>>> e != x < 1  # expecting False

x < 1

>>> x < 1 != x < 1  # expecting False or the same thing as before

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

解决此问题的方法是将文字关系用括号括起来:

>>> e == (x < 1)

True

>>> e != (x < 1)

False

>>> (x < 1) != (x < 1)

False 

第三个需要注意的地方涉及不涉及 ==!= 的链式不等式。偶尔,人们可能会尝试写成:

>>> e = x < y < z

Traceback (most recent call last):

...

TypeError: symbolic boolean expression has no truth value. 

由于 Python 的实现细节或决策 [R146],SymPy 无法使用该语法创建链式不等式,因此必须使用 And:

>>> e = And(x < y, y < z)

>>> type( e )

And

>>> e

(x < y) & (y < z) 

尽管这也可以使用‘&’运算符完成,但不能使用‘and’运算符完成:

>>> (x < y) & (y < z)

(x < y) & (y < z)

>>> (x < y) and (y < z)

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

[R146]

Python 的实现细节是,它没有可靠的方法来确定正在构建链式不等式。链式比较运算符按对分析,使用and逻辑进行评估(参见 docs.python.org/3/reference/expressions.html#not-in)。这样做是高效的,因此每个比较的对象只评估一次,比较可以短路。例如,Python 将 1 > 2 > 3 评估为 (1 > 2) and (2 > 3)and 运算符将每一侧强制转换为 bool,在短路时返回对象本身。由于 -Than 运算符会有意引发 TypeError,因为 SymPy 无法确定符号表达式的数学顺序。因此,如果我们计算 x > y > z,其中 xyz 是符号,Python 大致将语句转换为以下步骤:

  1. x > y > z
  2. (x > y) 和 (y > z)
  3. (GreaterThanObject) 和 (y > z)
  4. (GreaterThanObject.bool()) 和 (y > z)
  5. TypeError

由于第二步添加了 and,语句变成了一个弱三元语句,并且第一个对象的 __bool__ 方法会引发 TypeError。因此,创建链式不等式是不可能的。

在 Python 中,无法重写and运算符,或控制其短路的方式,因此无法使类似x > y > z的表达式起作用。曾经有一个 PEP 提议修改此行为,PEP 335,但该提议在 2012 年 3 月正式关闭。

class sympy.core.relational.LessThan(lhs, rhs, **options)

类不等式的表示。

解释

*Than类表示不等关系,其中左侧通常比右侧大或小。例如,GreaterThan 类表示一种不等关系,其中左侧至少与右侧一样大,如果不是更大。在数学符号中:

lhs (\ge) rhs

总共有四个*Than类,用于表示四种不等式:

类名符号
大于>=
小于<=
严格大于>
严格小于<

所有类都接受两个参数,lhs 和 rhs。

签名示例数学等效物
大于(lhs,rhs)lhs (\ge) rhs
小于(lhs,rhs)lhs (\le) rhs
严格大于(lhs,rhs)lhs (>) rhs
严格小于(lhs,rhs)lhs (<) rhs

除了 Relations 的正常.lhs 和.rhs 之外,*Than不等式对象还具有.lts 和.gts 属性,它们分别表示操作符的“小于侧”和“大于侧”。在算法中使用.lts 和.gts 而不是.lhs 和.rhs 作为不等方向的假设,将更明确地表达特定代码段的意图,并使其对客户端代码变更更加鲁棒:

>>> from sympy import GreaterThan, StrictGreaterThan
>>> from sympy import LessThan, StrictLessThan
>>> from sympy import And, Ge, Gt, Le, Lt, Rel, S
>>> from sympy.abc import x, y, z
>>> from sympy.core.relational import Relational 
>>> e = GreaterThan(x, 1)
>>> e
x >= 1
>>> '%s >= %s is the same as %s <= %s' % (e.gts, e.lts, e.lts, e.gts)
'x >= 1 is the same as 1 <= x' 

示例

通常不直接实例化这些类,而是使用各种便利方法:

>>> for f in [Ge, Gt, Le, Lt]:  # convenience wrappers
...     print(f(x, 2))
x >= 2
x > 2
x <= 2
x < 2 

另一种选择是直接使用 Python 的不等运算符(>=><=<)。它们相对于GeGtLeLt的优势在于可以编写更“数学化”的语句,而不是用奇怪的函数调用来弄乱数学表达。但是也有一些(轻微的)注意事项需要注意(在下面搜索“坑”)。

>>> x >= 2
x >= 2
>>> _ == Ge(x, 2)
True 

但也完全可以不那么简洁和方便地实例化*Than类:

>>> Rel(x, 1, ">")
x > 1
>>> Relational(x, 1, ">")
x > 1 
>>> StrictGreaterThan(x, 1)
x > 1
>>> GreaterThan(x, 1)
x >= 1
>>> LessThan(x, 1)
x <= 1
>>> StrictLessThan(x, 1)
x < 1 

注意事项

使用 Python 运算符时要注意的一些“坑”。

第一个问题是你所写的并不总是你得到的:

>>> 1 < x

x > 1 

由于 Python 解析语句的顺序,可能无法立即找到两个可比较的对象。当评估1 < x时,Python 认识到数字 1 是本机数字,而 x 不是。因为本机 Python 数字不知道如何与 SymPy 对象比较,Python 将尝试反射操作x > 1,这是评估的形式,因此返回。

如果语句的顺序很重要(例如用于控制台的可视输出),可以通过几种方式解决这个问题:

  1. 将字面量转换为符号进行比较
>>> S(1) < x

1 < x 

(2)使用上述包装器或较不简洁的方法之一

>>> Lt(1, x)

1 < x

>>> Relational(1, x, "<")

1 < x 

第二个需要注意的地方涉及在关系测试中写入一个或两个测试的文字关系时。

>>> e = x < 1; e

x < 1

>>> e == e  # neither side is a literal

True

>>> e == x < 1  # expecting True, too

False

>>> e != x < 1  # expecting False

x < 1

>>> x < 1 != x < 1  # expecting False or the same thing as before

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

对于这种情况的解决方法是将文字关系放在括号中:

>>> e == (x < 1)

True

>>> e != (x < 1)

False

>>> (x < 1) != (x < 1)

False 

第三个需要注意的地方涉及不涉及 ==!= 的链式不等式。有时会有人试图写成:

>>> e = x < y < z

Traceback (most recent call last):

...

TypeError: symbolic boolean expression has no truth value. 

由于 Python 的一个实现细节或决定[R147],SymPy 无法使用该语法创建链式不等式,因此必须使用 And:

>>> e = And(x < y, y < z)

>>> type( e )

And

>>> e

(x < y) & (y < z) 

尽管这也可以使用 ‘&’ 操作符完成,但不能使用 ‘and’ 操作符:

>>> (x < y) & (y < z)

(x < y) & (y < z)

>>> (x < y) and (y < z)

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

[R147]

Python 中的这个实现细节是,它没有可靠的方法来确定是否正在构建链式不等式。链式比较运算符会成对地进行评估,使用and逻辑(参见 docs.python.org/3/reference/expressions.html#not-in)。这样做的效率很高,因此每个比较的对象只评估一次,比较可以短路。例如,1 > 2 > 3 在 Python 中被评估为 (1 > 2) and (2 > 3)and 操作符会将每一侧强制转换为布尔值,在短路时返回对象本身。比较运算符的布尔值会故意引发 TypeError,因为 SymPy 无法确定符号表达式的数学顺序。因此,如果我们计算 x > y > z,其中 xyz 是符号,Python 大致将该语句转换为以下步骤:

  1. x > y > z
  2. (x > y) and (y > z)
  3. (GreaterThanObject) 和 (y > z)
  4. (GreaterThanObject.bool()) 和 (y > z)
  5. TypeError

在第 2 步添加了 and,语句被转换为弱三元语句,并且第一个对象的 __bool__ 方法将引发 TypeError。因此,创建链式不等式是不可能的。

在 Python 中,无法重写 and 操作符,或控制它如何短路,因此不可能使类似 x > y > z 的表达式工作。曾有一个 PEP 提议改变这一点,PEP 335,但它在 2012 年 3 月正式关闭。

class sympy.core.relational.Unequality(lhs, rhs, **options)

两个对象之间的不等关系。

解释

表示两个对象不相等。如果可以确定它们是相等的,则结果将减少为 False;如果确定它们不相等,则结果将减少为 True。否则,关系将保持为 Unequality 对象。

示例

>>> from sympy import Ne
>>> from sympy.abc import x, y
>>> Ne(y, x+x**2)
Ne(y, x**2 + x) 

注意

这个类与 != 操作符不同。!= 操作符测试两个表达式之间的结构完全相等性;而这个类则是数学上比较表达式。

这个类实际上是 Equality 的反义。因此,它使用相同的算法,包括任何可用的_eval_Eq 方法。

另请参见

Equality

class sympy.core.relational.StrictGreaterThan(lhs, rhs, **options)

不等式的类表示。

解释

*Than 类表示不等关系,其中左侧通常比右侧大或小。例如,GreaterThan 类表示一个不等关系,其中左侧至少与右侧一样大,如果不是更大的话。在数学符号中:

lhs (\ge) rhs

总共有四个 *Than 类,用于表示四种不等式:

类名符号
GreaterThan>=
LessThan<=
StrictGreaterThan>
StrictLessThan<

所有类都接受两个参数,lhs 和 rhs。

Signature ExampleMath Equivalent
GreaterThan(lhs, rhs)lhs (\ge) rhs
LessThan(lhs, rhs)lhs (\le) rhs
StrictGreaterThan(lhs, rhs)lhs (>) rhs
StrictLessThan(lhs, rhs)lhs (<) rhs

除了关系的正常 .lhs 和 .rhs 之外,*Than 不等式对象还具有 .lts 和 .gts 属性,分别表示操作符的“小于一侧”和“大于一侧”。在算法中使用 .lts 和 .gts 而不是 .lhs 和 .rhs 作为不等式方向的假设,将更明确地表达代码的意图,并使其对客户端代码的更改同样更健壮:

>>> from sympy import GreaterThan, StrictGreaterThan
>>> from sympy import LessThan, StrictLessThan
>>> from sympy import And, Ge, Gt, Le, Lt, Rel, S
>>> from sympy.abc import x, y, z
>>> from sympy.core.relational import Relational 
>>> e = GreaterThan(x, 1)
>>> e
x >= 1
>>> '%s >= %s is the same as %s <= %s' % (e.gts, e.lts, e.lts, e.gts)
'x >= 1 is the same as 1 <= x' 

示例

通常不直接实例化这些类,而是使用各种方便的方法:

>>> for f in [Ge, Gt, Le, Lt]:  # convenience wrappers
...     print(f(x, 2))
x >= 2
x > 2
x <= 2
x < 2 

另一种选择是直接使用 Python 的不等式操作符 (>=, >, <=, <)。它们相比于 Ge, Gt, Le, 和 Lt 类的主要优势在于可以编写更“数学化”的语句,而不是用怪异的函数调用来散布数学公式。但是,有一些(轻微的)需要注意的小问题(搜索以下的 ‘gotcha’)。

>>> x >= 2
x >= 2
>>> _ == Ge(x, 2)
True 

然而,也可以不那么简洁和方便地实例化 *Than 类:

>>> Rel(x, 1, ">")
x > 1
>>> Relational(x, 1, ">")
x > 1 
>>> StrictGreaterThan(x, 1)
x > 1
>>> GreaterThan(x, 1)
x >= 1
>>> LessThan(x, 1)
x <= 1
>>> StrictLessThan(x, 1)
x < 1 

注意

使用 Python 操作符时,有几个“gotcha”需要注意。

第一个是你所写的并不总是你所得到的:

>>> 1 < x

x > 1 

由于 Python 解析语句的顺序,可能不会立即找到两个可比较的对象。当评估 1 < x 时,Python 识别到数字 1 是本机数字,而 x 不是。因为本机 Python 数字不知道如何与 SymPy 对象比较,Python 将尝试反射操作 x > 1,这是评估的形式,因此返回。

如果语句的顺序很重要(例如视觉输出到控制台),可以通过几种方式来解决这个烦恼:

  1. 在比较之前“符号化”文字
>>> S(1) < x

1 < x 

(2) 使用以上描述的包装器或不那么简洁的方法之一

>>> Lt(1, x)

1 < x

>>> Relational(1, x, "<")

1 < x 

第二个“gotcha”涉及在文字关系涉及的测试之间写相等测试时,其中一个或两个测试的一侧涉及文字关系:

>>> e = x < 1; e

x < 1

>>> e == e  # neither side is a literal

True

>>> e == x < 1  # expecting True, too

False

>>> e != x < 1  # expecting False

x < 1

>>> x < 1 != x < 1  # expecting False or the same thing as before

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

对于这种情况的解决方案是将文字关系包裹在括号中:

>>> e == (x < 1)

True

>>> e != (x < 1)

False

>>> (x < 1) != (x < 1)

False 

第三个“gotcha”涉及链式不等式,不涉及 ==!=。偶尔,人们可能会想要写:

>>> e = x < y < z

Traceback (most recent call last):

...

TypeError: symbolic boolean expression has no truth value. 

由于 Python 的一个实现细节或决定[R148],SymPy 无法使用该语法创建链式不等式,因此必须使用 And:

>>> e = And(x < y, y < z)

>>> type( e )

And

>>> e

(x < y) & (y < z) 

尽管这也可以通过‘&’运算符来实现,但不能使用‘and’运算符:

>>> (x < y) & (y < z)

(x < y) & (y < z)

>>> (x < y) and (y < z)

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

[R148]

这个实现细节是 Python 没有可靠的方法来确定是否正在构建链式不等式。链式比较操作符会成对地使用and逻辑进行评估(参见docs.python.org/3/reference/expressions.html#not-in)。这是一种高效的方式,使得每个比较对象只被评估一次,并且可以短路。例如,Python 将1 > 2 > 3评估为(1 > 2) and (2 > 3)and运算符会将每一侧强制转换为 bool 值,在短路时返回对象本身。--Than 运算符的 bool 值将故意引发 TypeError,因为 SymPy 无法确定符号表达式的数学排序。因此,如果我们计算x > y > z,其中xyz是符号,Python 将大致将语句转换为以下步骤:

  1. x > y > z
  2. (x > y) and (y > z)
  3. (GreaterThanObject) and (y > z)
  4. (GreaterThanObject.bool()) and (y > z)
  5. TypeError

由于在第二步中添加了and,语句变成了一个弱三元语句,并且第一个对象的__bool__方法将引发 TypeError。因此,创建链式不等式是不可能的。

在 Python 中,没有办法重写and运算符,或者控制它如何短路,因此无法使类似于x > y > z的东西工作。曾经有一个 PEP 尝试改变这一点,PEP 335,但于 2012 年 3 月正式关闭。

class sympy.core.relational.StrictLessThan(lhs, rhs, **options)

不等式的类表示。

解释

*Than类表示不等关系,其中左侧通常大于或小于右侧。例如,GreaterThan 类表示一个不等关系,其中左侧至少与右侧一样大,如果不是更大。在数学符号中表示为:

lhs (\ge) rhs

总共有四个*Than类,用来表示四种不等式:

Class NameSymbol
GreaterThan>=
LessThan<=
StrictGreaterThan>
StrictLessThan<

所有类都接受两个参数,lhs 和 rhs。

Signature ExampleMath Equivalent
GreaterThan(lhs, rhs)lhs (\ge) rhs
LessThan(lhs, rhs)lhs (\le) rhs
StrictGreaterThan(lhs, rhs)lhs (>) rhs
StrictLessThan(lhs, rhs)lhs (<) rhs

除了常规的 .lhs 和 .rhs 关系外,*Than 不等式对象还具有 .lts 和 .gts 属性,分别表示运算符的“小于侧”和“大于侧”。在算法中使用 .lts 和 .gts 而不是 .lhs 和 .rhs 作为不等式方向的假设,将更明确地表达某段代码的意图,并使其对客户端代码更加鲁棒:

>>> from sympy import GreaterThan, StrictGreaterThan
>>> from sympy import LessThan, StrictLessThan
>>> from sympy import And, Ge, Gt, Le, Lt, Rel, S
>>> from sympy.abc import x, y, z
>>> from sympy.core.relational import Relational 
>>> e = GreaterThan(x, 1)
>>> e
x >= 1
>>> '%s >= %s is the same as %s <= %s' % (e.gts, e.lts, e.lts, e.gts)
'x >= 1 is the same as 1 <= x' 

示例

通常不直接实例化这些类,而是使用各种便利方法:

>>> for f in [Ge, Gt, Le, Lt]:  # convenience wrappers
...     print(f(x, 2))
x >= 2
x > 2
x <= 2
x < 2 

另一个选择是直接使用 Python 的不等式运算符(>=, >, <=, <)。它们与 Ge, Gt, Le, Lt 等对应的主要优势在于,可以编写更“数学化”的语句,而不是用奇怪的函数调用来弄乱数学表达式。但是,需要注意其中的某些(小)注意事项(下文搜索‘gotcha’)。

>>> x >= 2
x >= 2
>>> _ == Ge(x, 2)
True 

然而,实例化一个 *Than 类的方式虽然不太简洁且不太方便,但也是完全有效的:

>>> Rel(x, 1, ">")
x > 1
>>> Relational(x, 1, ">")
x > 1 
>>> StrictGreaterThan(x, 1)
x > 1
>>> GreaterThan(x, 1)
x >= 1
>>> LessThan(x, 1)
x <= 1
>>> StrictLessThan(x, 1)
x < 1 

注意

使用 Python 运算符时,需要注意几个“gotcha”。

第一个注意事项是,你写的内容并不总是你得到的内容:

>>> 1 < x

x > 1 

由于 Python 解析语句的顺序,可能不会立即找到两个可比较的对象。当评估 1 < x 时,Python 会识别数字 1 是本地数字,而 x 则不是。因为本地 Python 数字不知道如何与 SymPy 对象比较,Python 将尝试反射操作 x > 1,这是被评估和返回的形式。

如果语句的顺序很重要(例如用于控制台的可视输出),可以通过几种方法避免这种烦恼:

  1. 在比较之前“符号化”字面值
>>> S(1) < x

1 < x 

(2) 使用上述其中一个包装器或不太简洁的方法

>>> Lt(1, x)

1 < x

>>> Relational(1, x, "<")

1 < x 

第二个注意事项涉及在关系之间写等式测试时,当测试的一侧或两侧涉及字面关系时:

>>> e = x < 1; e

x < 1

>>> e == e  # neither side is a literal

True

>>> e == x < 1  # expecting True, too

False

>>> e != x < 1  # expecting False

x < 1

>>> x < 1 != x < 1  # expecting False or the same thing as before

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

对于这种情况的解决方案是,将字面不等式用括号括起来:

>>> e == (x < 1)

True

>>> e != (x < 1)

False

>>> (x < 1) != (x < 1)

False 

第三个注意事项涉及链式不等式,不涉及 ==!=。偶尔,你可能会想要写:

>>> e = x < y < z

Traceback (most recent call last):

...

TypeError: symbolic boolean expression has no truth value. 

由于 Python 的实现细节或决策 [R149],SymPy 无法使用该语法创建链式不等式,因此必须使用 And:

>>> e = And(x < y, y < z)

>>> type( e )

And

>>> e

(x < y) & (y < z) 

尽管可以使用 ‘&’ 运算符来完成此操作,但无法使用 ‘and’ 运算符:

>>> (x < y) & (y < z)

(x < y) & (y < z)

>>> (x < y) and (y < z)

Traceback (most recent call last):

...

TypeError: cannot determine truth value of Relational 

[R149]

这个实现细节是 Python 没有可靠的方法来确定是否正在构建一个链式不等式。链式比较运算符使用and逻辑成对评估(见docs.python.org/3/reference/expressions.html#not-in)。这样做是为了高效地,使得每个被比较的对象仅被评估一次,并且比较可以短路。例如,1 > 2 > 3在 Python 中被评估为(1 > 2) and (2 > 3)and运算符将每一侧强制转换为 bool,在短路时返回对象本身。--Than 运算符的 bool 故意引发类型错误,因为 SymPy 无法确定符号表达式的数学排序。因此,如果我们计算x > y > z,其中xyz是 Symbols,Python 大致将语句转换为以下步骤:

  1. x > y > z
  2. (x > y) and (y > z)
  3. (GreaterThanObject) and (y > z)
  4. (GreaterThanObject.bool()) and (y > z)
  5. 类型错误

由于第 2 步添加的and,语句变成了一个弱三元语句,并且第一个对象的__bool__方法将引发类型错误。因此,创建一个链式不等式是不可能的。

在 Python 中,无法重写and运算符,或控制其短路的方式,因此无法使类似x > y > z的语法生效。曾有一份 PEP 提案试图改变这一点,PEP 335,但于 2012 年 3 月正式关闭。 ## 多维

class sympy.core.multidimensional.vectorize(*mdargs)

将标量转为接受多维参数的函数。

例子

>>> from sympy import vectorize, diff, sin, symbols, Function
>>> x, y, z = symbols('x y z')
>>> f, g, h = list(map(Function, 'fgh')) 
>>> @vectorize(0)
... def vsin(x):
...     return sin(x) 
>>> vsin([1, x, y])
[sin(1), sin(x), sin(y)] 
>>> @vectorize(0, 1)
... def vdiff(f, y):
...     return diff(f, y) 
>>> vdiff([f(x, y, z), g(x, y, z), h(x, y, z)], [x, y, z])
[[Derivative(f(x, y, z), x), Derivative(f(x, y, z), y), Derivative(f(x, y, z), z)], [Derivative(g(x, y, z), x), Derivative(g(x, y, z), y), Derivative(g(x, y, z), z)], [Derivative(h(x, y, z), x), Derivative(h(x, y, z), y), Derivative(h(x, y, z), z)]] 
```  ## 函数

```py
class sympy.core.function.Lambda(signature, expr)

Lambda(x, expr)表示一个类似 Python 中的‘lambda x: expr’的 lambda 函数。具有多个变量的函数写作为 Lambda((x, y, …), expr)。

例子

一个简单的例子:

>>> from sympy import Lambda
>>> from sympy.abc import x
>>> f = Lambda(x, x**2)
>>> f(4)
16 

对于多变量函数,请使用:

>>> from sympy.abc import y, z, t
>>> f2 = Lambda((x, y, z, t), x + y**z + t**z)
>>> f2(1, 2, 3, 4)
73 

也可以解包元组参数:

>>> f = Lambda(((x, y), z), x + y + z)
>>> f((1, 2), 3)
6 

多个参数的便捷快捷方式:

>>> p = x, y, z
>>> f = Lambda(p, x + y*z)
>>> f(*p)
x + y*z 
property bound_symbols

用于函数内部表示的变量

property expr

函数的返回值

property is_identity

如果这个Lambda是一个恒等函数,则返回True

property signature

要解包为变量的参数的预期形式

property variables

用于函数内部表示的变量

class sympy.core.function.WildFunction(*args)

WildFunction 函数匹配任何函数(及其参数)。

例子

>>> from sympy import WildFunction, Function, cos
>>> from sympy.abc import x, y
>>> F = WildFunction('F')
>>> f = Function('f')
>>> F.nargs
Naturals0
>>> x.match(F)
>>> F.match(F)
{F_: F_}
>>> f(x).match(F)
{F_: f(x)}
>>> cos(x).match(F)
{F_: cos(x)}
>>> f(x, y).match(F)
{F_: f(x, y)} 

要匹配具有给定参数数量的函数,请在实例化时将nargs设置为所需的值:

>>> F = WildFunction('F', nargs=2)
>>> F.nargs
{2}
>>> f(x).match(F)
>>> f(x, y).match(F)
{F_: f(x, y)} 

要匹配具有一系列参数的函数,请将nargs设置为包含所需参数数量的元组,例如,如果nargs = (1, 2),则将匹配具有 1 个或 2 个参数的函数。

>>> F = WildFunction('F', nargs=(1, 2))
>>> F.nargs
{1, 2}
>>> f(x).match(F)
{F_: f(x)}
>>> f(x, y).match(F)
{F_: f(x, y)}
>>> f(x, y, 1).match(F) 
class sympy.core.function.Derivative(expr, *variables, **kwargs)

对给定表达式进行关于符号的微分。

例子

>>> from sympy import Derivative, Function, symbols, Subs
>>> from sympy.abc import x, y
>>> f, g = symbols('f g', cls=Function) 
>>> Derivative(x**2, x, evaluate=True)
2*x 

导数去嵌套保留变量的顺序:

>>> Derivative(Derivative(f(x, y), y), x)
Derivative(f(x, y), y, x) 

连续相同符号合并为给定符号和计数的元组:

>>> Derivative(f(x), x, x, y, x)
Derivative(f(x), (x, 2), y, x) 

如果无法执行导数,并且 evaluate 为 True,则将分化变量的顺序设置为规范:

>>> Derivative(f(x, y), y, x, evaluate=True)
Derivative(f(x, y), x, y) 

可以计算对未定义函数的导数:

>>> Derivative(f(x)**2, f(x), evaluate=True)
2*f(x) 

当链规则用于评估导数时,这样的导数会显示出来:

>>> f(g(x)).diff(x)
Derivative(f(g(x)), g(x))*Derivative(g(x), x) 

替换用于表示带有非符号或函数参数的函数的导数:

>>> f(2*x + 3).diff(x) == 2*Subs(f(y).diff(y), y, 2*x + 3)
True 

注意

高阶导数的简化:

因为在执行多次差异化时可以进行大量简化,所以结果将以相当保守的方式自动简化,除非关键字 simplify 设置为 False。

>>> from sympy import sqrt, diff, Function, symbols
>>> from sympy.abc import x, y, z
>>> f, g = symbols('f,g', cls=Function) 
>>> e = sqrt((x + 1)**2 + x)
>>> diff(e, (x, 5), simplify=False).count_ops()
136
>>> diff(e, (x, 5)).count_ops()
30 

变量的顺序:

如果 evaluate 设置为 True 并且无法评估表达式,则差异化符号列表将被排序,即假设表达式具有连续的导数直到所要求的顺序。

对非符号的导数:

大多数情况下,不可对非符号进行差异化。例如,我们不允许对 (xy) 进行差异化,因为在表达式中定义 (xy) 出现的多种方式:非常严格的定义会使得 (xyz).diff(x*y) == 0。也不允许对定义的函数(如 cos(x))进行导数计算:

>>> (x*y*z).diff(x*y)
Traceback (most recent call last):
...
ValueError: Can't calculate derivative wrt x*y. 

为了更容易处理变分计算,允许对 AppliedUndef 和 Derivatives 进行导数计算。例如,在欧拉-拉格朗日方法中,可以写成 F(t, u, v),其中 u = f(t) 且 v = f’(t)。这些变量可以明确地写成时间的函数:

>>> from sympy.abc import t
>>> F = Function('F')
>>> U = f(t)
>>> V = U.diff(t) 

对于 f(t) 的导数可以直接得到:

>>> direct = F(t, U, V).diff(U) 

当尝试对非符号进行差异化时,将非符号暂时转换为符号,同时执行差异化,并获得相同的答案:

>>> indirect = F(t, U, V).subs(U, x).diff(x).subs(x, U)
>>> assert direct == indirect 

此非符号替换的含义是,所有函数都被视为独立于其他函数,并且符号独立于包含它们的函数:

>>> x.diff(f(x))
0
>>> g(x).diff(f(x))
0 

这也意味着假设导数仅依赖于差异化变量,而不依赖于被差异化表达式中的任何内容:

>>> F = f(x)
>>> Fx = F.diff(x)
>>> Fx.diff(F)  # derivative depends on x, not F
0
>>> Fxx = Fx.diff(x)
>>> Fxx.diff(Fx)  # derivative depends on x, not Fx
0 

最后一个例子可以通过显示 Fx 在 Fxx 中用 y 替换来明确:

>>> Fxx.subs(Fx, y)

Derivative(y, x) 

由于这本身将评估为零,不同 iating wrt Fx 也将是零:

>>> _.doit()

0 

用具体表达式替换未定义的函数

必须小心地用包含与函数定义和差异化变量一致的变量的表达式替换未定义的函数,否则将得到不一致的结果。考虑以下例子:

>>> eq = f(x)*g(y)
>>> eq.subs(f(x), x*y).diff(x, y).doit()
y*Derivative(g(y), y) + g(y)
>>> eq.diff(x, y).subs(f(x), x*y).doit()
y*Derivative(g(y), y) 

结果不同,因为 (f(x)) 被替换为涉及差异化变量的表达式。在抽象情况下,对 (y) 的 (f(x)) 的差异化为 0;在具体情况下,(y) 的存在使得该导数非零,并产生额外的 (g(y)) 项。

定义对象的差异化

对象必须定义 ._eval_derivative(symbol) 方法,该方法返回微分结果。此函数仅需要考虑表达式包含符号的非平凡情况,并且应在内部调用 diff() 方法(而不是 _eval_derivative);Derivative 应是唯一调用 _eval_derivative 的对象。

任何类都可以允许相对于自身进行导数操作(同时指示其标量性质)。请参阅 Expr._diff_wrt 的文档字符串。

另请参阅

_sort_variable_count

property _diff_wrt

表达式可能相对于导数进行微分,如果它处于基本形式中。

示例

>>> from sympy import Function, Derivative, cos
>>> from sympy.abc import x
>>> f = Function('f') 
>>> Derivative(f(x), x)._diff_wrt
True
>>> Derivative(cos(x), x)._diff_wrt
False
>>> Derivative(x + 1, x)._diff_wrt
False 

如果评估,Derivative 可能是将不是有效的差异化变量的未评估形式。例如,

>>> Derivative(f(f(x)), x).doit()
Derivative(f(x), x)*Derivative(f(f(x)), f(x)) 

这样的表达式将出现与处理任何其他乘积时相同的歧义,比如 2*x,因此 _diff_wrt 为 False:

>>> Derivative(f(f(x)), x)._diff_wrt
False 
classmethod _sort_variable_count(vc)

将(变量,计数)对排序为规范顺序,同时保留在微分过程中不对易变量的顺序:

  • 符号和函数彼此交换

  • 导数彼此对易

  • 导数不与包含的任何内容对易

  • 如果它与另一个对象具有共同的自由符号,则不允许任何其他对象对易

示例

>>> from sympy import Derivative, Function, symbols
>>> vsort = Derivative._sort_variable_count
>>> x, y, z = symbols('x y z')
>>> f, g, h = symbols('f g h', cls=Function) 

连续项目折叠成一个对:

>>> vsort([(x, 1), (x, 1)])
[(x, 2)]
>>> vsort([(y, 1), (f(x), 1), (y, 1), (f(x), 1)])
[(y, 2), (f(x), 2)] 

排序是规范的。

>>> def vsort0(*v):
...     # docstring helper to
...     # change vi -> (vi, 0), sort, and return vi vals
...     return [i[0] for i in vsort([(i, 0) for i in v])] 
>>> vsort0(y, x)
[x, y]
>>> vsort0(g(y), g(x), f(y))
[f(y), g(x), g(y)] 

符号尽可能向左移动,但绝不移动到具有其变量中相同符号的导数左侧;对于始终在符号后排序的 AppliedUndef,同样适用:

>>> dfx = f(x).diff(x)
>>> assert vsort0(dfx, y) == [y, dfx]
>>> assert vsort0(dfx, x) == [dfx, x] 
as_finite_difference(points=1, x0=None, wrt=None)

将 Derivative 实例表达为有限差分。

参数:

points:序列或系数,可选

如果序列:用于生成有限差分权重的独立变量的离散值(长度>= order+1)。如果它是系数,则将用作围绕 x0 的长度为 order+1 的等距序列的步长。默认值:1(步长 1)

x0:数字或符号,可选

独立变量的值(wrt)是导数近似的值。默认情况下与 wrt 相同。

wrt:符号,可选

“关于”用于近似(部分)导数的变量。如果未提供,则要求导数是普通的。默认值:None

示例

>>> from sympy import symbols, Function, exp, sqrt, Symbol
>>> x, h = symbols('x h')
>>> f = Function('f')
>>> f(x).diff(x).as_finite_difference()
-f(x - 1/2) + f(x + 1/2) 

默认步长和点数为 1 和order + 1。我们可以通过将符号作为参数传递来更改步长:

>>> f(x).diff(x).as_finite_difference(h)
-f(-h/2 + x)/h + f(h/2 + x)/h 

我们还可以指定用于序列中使用的离散化值:

>>> f(x).diff(x).as_finite_difference([x, x+h, x+2*h])
-3*f(x)/(2*h) + 2*f(h + x)/h - f(2*h + x)/(2*h) 

该算法不限于使用等距间隔,也不需要围绕 x0 进行近似,但我们可以得到一个表达式,估计在偏移处的导数:

>>> e, sq2 = exp(1), sqrt(2)
>>> xl = [x-h, x+h, x+e*h]
>>> f(x).diff(x, 1).as_finite_difference(xl, x+h*sq2)  
2*h*((h + sqrt(2)*h)/(2*h) - (-sqrt(2)*h + h)/(2*h))*f(E*h + x)/... 

要使用非等距间隔步骤近似 Derivative 环绕 x0,算法支持将未定义函数分配给 points

>>> dx = Function('dx')
>>> f(x).diff(x).as_finite_difference(points=dx(x), x0=x-h)
-f(-h + x - dx(-h + x)/2)/dx(-h + x) + f(-h + x + dx(-h + x)/2)/dx(-h + x) 

也支持偏导数:

>>> y = Symbol('y')
>>> d2fdxdy=f(x,y).diff(x,y)
>>> d2fdxdy.as_finite_difference(wrt=x)
-Derivative(f(x - 1/2, y), y) + Derivative(f(x + 1/2, y), y) 

我们可以在复合表达式中对 Derivative 实例应用 as_finite_difference,使用 replace

>>> (1 + 42**f(x).diff(x)).replace(lambda arg: arg.is_Derivative,
...     lambda arg: arg.as_finite_difference())
42**(-f(x - 1/2) + f(x + 1/2)) + 1 

另请参阅

sympy.calculus.finite_diff.apply_finite_diff, sympy.calculus.finite_diff.differentiate_finite, sympy.calculus.finite_diff.finite_diff_weights

doit_numerically(z0)

在数值上评估导数在 z 处的值。

当我们能够表示点上的导数时,这应该折叠到普通的 evalf 中。目前,我们需要一个特殊的方法。

sympy.core.function.diff(f, *symbols, **kwargs)

对符号求解 f 的导数。

解释

这只是一个包装器,用于统一 .diff()Derivative 类;其接口类似于 integrate()。您可以像对待 Derivative 一样对多个变量使用相同的快捷方式。例如,diff(f(x), x, x, x)diff(f(x), x, 3) 都返回 f(x) 的三阶导数。

您可以传递 evaluate=False 以获取未评估的 Derivative 类。请注意,如果没有符号(例如 diff(f(x), x, 0)),则结果将是函数(零阶导数),即使 evaluate=False

示例

>>> from sympy import sin, cos, Function, diff
>>> from sympy.abc import x, y
>>> f = Function('f') 
>>> diff(sin(x), x)
cos(x)
>>> diff(f(x), x, x, x)
Derivative(f(x), (x, 3))
>>> diff(f(x), x, 3)
Derivative(f(x), (x, 3))
>>> diff(sin(x)*cos(y), x, 2, y, 2)
sin(x)*cos(y) 
>>> type(diff(sin(x), x))
cos
>>> type(diff(sin(x), x, evaluate=False))
<class 'sympy.core.function.Derivative'>
>>> type(diff(sin(x), x, 0))
sin
>>> type(diff(sin(x), x, 0, evaluate=False))
sin 
>>> diff(sin(x))
cos(x)
>>> diff(sin(x*y))
Traceback (most recent call last):
...
ValueError: specify differentiation variables to differentiate sin(x*y) 

注意 diff(sin(x)) 的语法仅用于交互式会话的便利性,应避免在库代码中使用。

另请参阅

Derivative

idiff

隐式计算导数

参考

[R150]

reference.wolfram.com/legacy/v5_2/Built-inFunctions/AlgebraicComputation/Calculus/D.html

class sympy.core.function.FunctionClass(*args, **kwargs)

函数类的基类。FunctionClasstype 的子类。

使用 Function('<function name>' [, 签名]) 创建未定义函数类。

property nargs

返回函数允许的参数数量的集合。

示例

>>> from sympy import Function
>>> f = Function('f') 

如果函数可以接受任意数量的参数,则返回整数集合:

>>> Function('f').nargs
Naturals0 

如果函数被初始化为接受一个或多个参数,则将返回相应的集合:

>>> Function('f', nargs=1).nargs
{1}
>>> Function('f', nargs=(2, 1)).nargs
{1, 2} 

在应用后,未定义的函数也具有 nargs 属性;通过检查 args 属性始终可以获得实际的参数数量:

>>> f = Function('f')
>>> f(1).nargs
Naturals0
>>> len(f(1).args)
1 
class sympy.core.function.Function(*args)

应用数学函数的基类。

它还充当未定义函数类的构造函数。

有关如何子类化 Function 和可以定义哪些方法的详细信息,请参见编写自定义函数指南。

示例

未定义函数

要创建一个未定义的函数,请将函数名称的字符串传递给 Function

>>> from sympy import Function, Symbol
>>> x = Symbol('x')
>>> f = Function('f')
>>> g = Function('g')(x)
>>> f
f
>>> f(x)
f(x)
>>> g
g(x)
>>> f(x).diff(x)
Derivative(f(x), x)
>>> g.diff(x)
Derivative(g(x), x) 

假设可以像Symbol一样传递给Function。或者,您可以使用带有函数名称和假设的Symbol来命名函数,并且函数将继承与Symbol相关联的名称和假设:

>>> f_real = Function('f', real=True)
>>> f_real(x).is_real
True
>>> f_real_inherit = Function(Symbol('f', real=True))
>>> f_real_inherit(x).is_real
True 

注意函数上的假设与调用它的变量的假设无关。如果要添加关系,请子类化Function并定义自定义假设处理方法。请参阅 Assumptions 部分的编写自定义函数指南获取更多详细信息。

自定义函数子类

编写自定义函数指南有几个完整示例,展示了如何子类化Function以创建自定义函数。

as_base_exp()

返回方法作为 2 元组(基数,指数)。

fdiff(argindex=1)

返回函数的第一阶导数。

classmethod is_singular(a)

检查参数是否是本质奇点或分支点,或者函数是非全纯的。

注意

并非所有函数都相同

SymPy 定义了许多函数(如cosfactorial)。它还允许用户创建作为参数持有者的通用函数。此类函数的创建方式与符号相同:

>>> from sympy import Function, cos
>>> from sympy.abc import x
>>> f = Function('f')
>>> f(2) + f(x)
f(2) + f(x) 

如果您想查看表达式中出现的函数,可以使用 atoms 方法:

>>> e = (f(x) + cos(x) + 2)
>>> e.atoms(Function)
{f(x), cos(x)} 

如果您只想要您定义的函数,而不是 SymPy 函数,请搜索 AppliedUndef:

>>> from sympy.core.function import AppliedUndef
>>> e.atoms(AppliedUndef)
{f(x)} 
class sympy.core.function.Subs(expr, variables, point, **assumptions)

表示表达式的未评估替换。

Subs(expr, x, x0)表示在 expr 中用 x0 替换 x 后得到的表达式。

参数:

expr:Expr

一个表达式。

x:元组,变量

一个变量或不同变量的列表。

x0:元组或元组列表

与这些变量相对应的点或评估点列表。

示例

>>> from sympy import Subs, Function, sin, cos
>>> from sympy.abc import x, y, z
>>> f = Function('f') 

当特定替换无法进行时创建 Subs。在导数中的 x 无法替换为 0,因为 0 不是一个有效的差异化变量:

>>> f(x).diff(x).subs(x, 0)
Subs(Derivative(f(x), x), x, 0) 

一旦 f 已知,就可以进行导数计算和在 0 处的评估:

>>> _.subs(f, sin).doit() == sin(x).diff(x).subs(x, 0) == cos(0)
True 

Subs 也可以直接使用一个或多个变量创建:

>>> Subs(f(x)*sin(y) + z, (x, y), (0, 1))
Subs(z + f(x)*sin(y), (x, y), (0, 1))
>>> _.doit()
z + f(0)*sin(1) 

注意

Subs对象通常用于表示在某一点计算的未评估导数。

变量可以是表达式,但它们受 subs()的限制,因此通常最好仅对变量使用符号,因为在这种情况下不会有歧义。

没有自动展开 - 使用方法.doit()来影响对象及其表达式内部的所有可能的替换。

在评估非符号点处的导数时,将返回一个 Subs 对象。还可以计算 Subs 对象的导数 - 在这种情况下,表达式总是会被展开(对于未评估的形式,请使用 Derivative())。

为了允许表达式在执行时结合,内部使用 Subs 表达式的表示来使表面上不同的表达式进行比较:

>>> a, b = Subs(x, x, 0), Subs(y, y, 0)
>>> a + b
2*Subs(x, x, 0) 

使用像(has)这样的方法时可能会导致意外后果,因为它们被缓存:

>>> s = Subs(x, x, 0)
>>> s.has(x), s.has(y)
(True, False)
>>> ss = s.subs(x, y)
>>> ss.has(x), ss.has(y)
(True, False)
>>> s, ss
(Subs(x, x, 0), Subs(y, y, 0)) 
property bound_symbols

要评估的变量

property expr

替换操作的表达式

property point

用于替换变量的值

property variables

要评估的变量

sympy.core.function.expand(e, deep=True, modulus=None, power_base=True, power_exp=True, mul=True, log=True, multinomial=True, basic=True, **hints)

使用给定的提示方法展开表达式。

解释

除非显式设置为 False,否则将评估以下提示:basiclogmultinomialmulpower_basepower_exp。以下提示受支持但仅在设置为 True 时应用:complexfunctrig。此外,其他提示也支持一些或所有其他提示的元提示:fracnumerdenommodulusforce。所有提示都支持deep。此外,Expr 的子类还可以定义自己的提示或元提示。

basic提示用于在调用expand时自动完成对象的任何特殊重写(以及像mul这样的其他提示)。这是一个捕获所有提示的提示,用于处理可能不被现有提示名称描述的任何扩展。要使用此提示,对象应重写_eval_expand_basic方法。对象还可以定义其自己的展开方法,这些方法不会默认运行。请参阅下面的 API 部分。

如果将deep设置为True(默认值),诸如函数参数之类的东西将被递归展开。使用deep=False仅在顶层展开。

如果使用了force提示,将忽略关于变量的假设以进行展开。

提示

这些提示默认情况下会运行

Mul

在加法上分配乘法:

>>> from sympy import cos, exp, sin
>>> from sympy.abc import x, y, z
>>> (y*(x + z)).expand(mul=True)
x*y + y*z 

多项式

展开(x + y + …)**n,其中 n 是正整数。

>>> ((x + y + z)**2).expand(multinomial=True)
x**2 + 2*x*y + 2*x*z + y**2 + 2*y*z + z**2 

Power_exp

将指数中的加法展开为乘以基数。

>>> exp(x + y).expand(power_exp=True)
exp(x)*exp(y)
>>> (2**(x + y)).expand(power_exp=True)
2**x*2**y 

Power_base

将乘以基数的幂分开。

这仅在默认情况下发生,如果假设允许,或者使用force元提示:

>>> ((x*y)**z).expand(power_base=True)
(x*y)**z
>>> ((x*y)**z).expand(power_base=True, force=True)
x**z*y**z
>>> ((2*y)**z).expand(power_base=True)
2**z*y**z 

注意,在某些情况下,SymPy 会自动执行此展开:

>>> (x*y)**2
x**2*y**2 

对数

将参数的幂作为系数提取出来,并将对数乘积分成对数和的和。

注意,这些仅在对数函数的参数具有适当假设(参数必须为正数,指数必须为实数)或者force提示必须为 True 时才有效:

>>> from sympy import log, symbols
>>> log(x**2*y).expand(log=True)
log(x**2*y)
>>> log(x**2*y).expand(log=True, force=True)
2*log(x) + log(y)
>>> x, y = symbols('x,y', positive=True)
>>> log(x**2*y).expand(log=True)
2*log(x) + log(y) 

Basic

此提示主要用于自定义子类以便默认情况下启用扩展。

这些提示默认情况下不运行:

复杂

将表达式分成实部和虚部。

>>> x, y = symbols('x,y')
>>> (x + y).expand(complex=True)
re(x) + re(y) + I*im(x) + I*im(y)
>>> cos(x).expand(complex=True)
-I*sin(re(x))*sinh(im(x)) + cos(re(x))*cosh(im(x)) 

注意,这只是对as_real_imag()的包装。大多数希望重新定义_eval_expand_complex()的对象应考虑重新定义as_real_imag()

函数

展开其他函数。

>>> from sympy import gamma
>>> gamma(x + 1).expand(func=True)
x*gamma(x) 

三角

进行三角展开。

>>> cos(x + y).expand(trig=True)
-sin(x)*sin(y) + cos(x)*cos(y)
>>> sin(2*x).expand(trig=True)
2*sin(x)*cos(x) 

注意 sin(n*x)cos(n*x) 关于 sin(x)cos(x) 的形式并不唯一,这是由于恒等式 (\sin²(x) + \cos²(x) = 1)。当前实现使用从切比雪夫多项式获得的形式,但这可能会改变。请参阅 这篇 MathWorld 文章 获取更多信息。

注意事项

  • 您可以关闭不需要的方法:

    >>> (exp(x + y)*(x + y)).expand()
    x*exp(x)*exp(y) + y*exp(x)*exp(y)
    >>> (exp(x + y)*(x + y)).expand(power_exp=False)
    x*exp(x + y) + y*exp(x + y)
    >>> (exp(x + y)*(x + y)).expand(mul=False)
    (x + y)*exp(x)*exp(y) 
    
  • 使用 deep=False 仅在顶层扩展:

    >>> exp(x + exp(x + y)).expand()
    exp(x)*exp(exp(x)*exp(y))
    >>> exp(x + exp(x + y)).expand(deep=False)
    exp(x)*exp(exp(x + y)) 
    
  • 提示以任意但一致的顺序应用(在当前实现中,它们按字母顺序应用,但 multinomial 在 mul 之前,但这可能会改变)。因此,某些提示可能会通过首先应用它们来阻止其他提示的扩展。例如,mul 可能会分配乘法并阻止 logpower_base 扩展它们。此外,如果 mulpymultinomial`, the expression might not be fully distributed. The solution is to use the various ``expand_hint 帮助函数之前应用,或者要使用 hint=False 来精确控制哪些提示应用于此函数。以下是一些示例:

    >>> from sympy import expand, expand_mul, expand_power_base
    >>> x, y, z = symbols('x,y,z', positive=True)
    
    >>> expand(log(x*(y + z)))
    log(x) + log(y + z) 
    

    在这里,我们看到 logmul 之前被应用。要获取 mul 的展开形式,可以使用以下任一方法:

    >>> expand_mul(log(x*(y + z)))
    log(x*y + x*z)
    >>> expand(log(x*(y + z)), log=False)
    log(x*y + x*z) 
    

    类似的情况也可能发生在 power_base 提示中:

    >>> expand((x*(y + z))**x)
    (x*y + x*z)**x 
    

    要获取 power_base 的展开形式,可以使用以下任一方法:

    >>> expand((x*(y + z))**x, mul=False)
    x**x*(y + z)**x
    >>> expand_power_base((x*(y + z))**x)
    x**x*(y + z)**x
    
    >>> expand((x + y)*y/x)
    y + y**2/x 
    

    可以针对有理表达式的部分进行目标化:

    >>> expand((x + y)*y/x/(x + 1), frac=True)
    (x*y + y**2)/(x**2 + x)
    >>> expand((x + y)*y/x/(x + 1), numer=True)
    (x*y + y**2)/(x*(x + 1))
    >>> expand((x + y)*y/x/(x + 1), denom=True)
    y*(x + y)/(x**2 + x) 
    
  • modulus 元提示可用于在扩展后减少表达式的系数:

    >>> expand((3*x + 1)**2)
    9*x**2 + 6*x + 1
    >>> expand((3*x + 1)**2, modulus=5)
    4*x**2 + x + 1 
    
  • expand() 函数或 .expand() 方法都可以使用。两者是等效的:

    >>> expand((x + 1)**2)
    x**2 + 2*x + 1
    >>> ((x + 1)**2).expand()
    x**2 + 2*x + 1 
    

Api

对象可以通过定义 _eval_expand_hint() 来定义其自己的扩展提示。该函数应采用以下形式:

def _eval_expand_hint(self, **hints):
    # Only apply the method to the top-level expression
    ... 

另请参阅下面的示例。对象应仅在特定对象适用于该提示时定义 _eval_expand_hint() 方法。在 Expr 中定义的通用 _eval_expand_hint() 方法将处理无操作的情况。

每个提示都应该负责扩展该提示。此外,扩展应该仅应用于顶层表达式。expand() 负责处理 deep=True 时发生的递归。

只有在您确信对象具有该方法时,才可以直接调用 _eval_expand_hint() 方法,否则可能会得到意外的结果 pyAttributeError``s.  Note, again, that you do not need to recursively apply the hint to args of your object: this is handled automatically by ``expand()。通常情况下,应完全避免使用 _eval_expand_hint()。如果您想在另一个方法内应用特定的扩展,请使用公共的 expand() 函数、方法或 expand_hint() 函数。

为了使扩展正常工作,对象必须能够通过它们的参数进行重建,即 obj.func(*obj.args) == obj 必须成立。

扩展方法传递 **hints,因此扩展提示可以使用“元提示”——控制如何应用不同扩展方法的提示。例如,force=True 提示会导致 expand(log=True) 忽略假设,这是一种元提示。deep 元提示仅由 expand() 处理,不会传递给 _eval_expand_hint() 方法。

请注意,扩展提示通常应该是执行某种“扩展”的方法。对于简单重写表达式的提示,请使用.rewrite() API。

示例

>>> from sympy import Expr, sympify
>>> class MyClass(Expr):
...     def __new__(cls, *args):
...         args = sympify(args)
...         return Expr.__new__(cls, *args)
...
...     def _eval_expand_double(self, *, force=False, **hints):
...  '''
...         Doubles the args of MyClass.
...
...         If there more than four args, doubling is not performed,
...         unless force=True is also used (False by default).
...         '''
...         if not force and len(self.args) > 4:
...             return self
...         return self.func(*(self.args + self.args))
...
>>> a = MyClass(1, 2, MyClass(3, 4))
>>> a
MyClass(1, 2, MyClass(3, 4))
>>> a.expand(double=True)
MyClass(1, 2, MyClass(3, 4, 3, 4), 1, 2, MyClass(3, 4, 3, 4))
>>> a.expand(double=True, deep=False)
MyClass(1, 2, MyClass(3, 4), 1, 2, MyClass(3, 4)) 
>>> b = MyClass(1, 2, 3, 4, 5)
>>> b.expand(double=True)
MyClass(1, 2, 3, 4, 5)
>>> b.expand(double=True, force=True)
MyClass(1, 2, 3, 4, 5, 1, 2, 3, 4, 5) 

另请参阅

expand_logexpand_mulexpand_multinomialexpand_complexexpand_trigexpand_power_baseexpand_power_expexpand_funcsympy.simplify.hyperexpand.hyperexpand

class sympy.core.function.PoleError
sympy.core.function.count_ops(expr, visual=False)

返回 expr 中操作的表示(整数或表达式)。

参数:

expr:Expr

如果 expr 是可迭代的,则将返回项的操作计数的总和。

visual:bool,可选

如果False(默认),则返回可视化表达式的系数之和。如果True,则显示每种操作类型的数量,每种核心类类型(或其虚拟等效)乘以其出现次数。

示例

>>> from sympy.abc import a, b, x, y
>>> from sympy import sin, count_ops 

虽然没有 SUB 对象,减号被解释为否定或减法之一:

>>> (x - y).count_ops(visual=True)
SUB
>>> (-x).count_ops(visual=True)
NEG 

在这里,有两个 Adds 和一个 Pow:

>>> (1 + a + b**2).count_ops(visual=True)
2*ADD + POW 

在以下示例中,有一个 Add,Mul,Pow 和两个函数:

>>> (sin(x)*x + sin(x)**2).count_ops(visual=True)
ADD + MUL + POW + 2*SIN 

总共为 5:

>>> (sin(x)*x + sin(x)**2).count_ops(visual=False)
5 

注意,“你输入的内容”并非总是你得到的内容。表达式 1/x/y 被 sympy 翻译为 1/(x*y),因此它会给出 DIV 和 MUL,而不是两个 DIV:

>>> (1/x/y).count_ops(visual=True)
DIV + MUL 

可视选项可用于展示不同形式表达式的操作差异。在此处,Horner 表示法与多项式的展开形式进行比较:

>>> eq=x*(1 + x*(2 + x*(3 + x)))
>>> count_ops(eq.expand(), visual=True) - count_ops(eq, visual=True)
-MUL + 3*POW 

count_ops 函数还处理可迭代对象:

>>> count_ops([x, sin(x), None, True, x + 2], visual=False)
2
>>> count_ops([x, sin(x), None, True, x + 2], visual=True)
ADD + SIN
>>> count_ops({x: sin(x), x + 2: y + 1}, visual=True)
2*ADD + SIN 
sympy.core.function.expand_mul(expr, deep=True)

包装器,仅使用 mul 提示的扩展。

示例

>>> from sympy import symbols, expand_mul, exp, log
>>> x, y = symbols('x,y', positive=True)
>>> expand_mul(exp(x+y)*(x+y)*log(x*y**2))
x*exp(x + y)*log(x*y**2) + y*exp(x + y)*log(x*y**2) 
sympy.core.function.expand_log(expr, deep=True, force=False, factor=False)

包装器,仅使用 log 提示的扩展。有关更多信息,请参阅扩展 docstring。

示例

>>> from sympy import symbols, expand_log, exp, log
>>> x, y = symbols('x,y', positive=True)
>>> expand_log(exp(x+y)*(x+y)*log(x*y**2))
(x + y)*(log(x) + 2*log(y))*exp(x + y) 
sympy.core.function.expand_func(expr, deep=True)

包装器,仅使用 func 提示的扩展。有关更多信息,请参阅扩展 docstring。

示例

>>> from sympy import expand_func, gamma
>>> from sympy.abc import x
>>> expand_func(gamma(x + 2))
x*(x + 1)*gamma(x) 
sympy.core.function.expand_trig(expr, deep=True)

包装器,仅使用 trig 提示的扩展。有关更多信息,请参阅扩展 docstring。

示例

>>> from sympy import expand_trig, sin
>>> from sympy.abc import x, y
>>> expand_trig(sin(x+y)*(x+y))
(x + y)*(sin(x)*cos(y) + sin(y)*cos(x)) 
sympy.core.function.expand_complex(expr, deep=True)

包装器,仅使用 complex 提示的扩展。有关更多信息,请参阅扩展 docstring。

示例

>>> from sympy import expand_complex, exp, sqrt, I
>>> from sympy.abc import z
>>> expand_complex(exp(z))
I*exp(re(z))*sin(im(z)) + exp(re(z))*cos(im(z))
>>> expand_complex(sqrt(I))
sqrt(2)/2 + sqrt(2)*I/2 

另请参阅

sympy.core.expr.Expr.as_real_imag

sympy.core.function.expand_multinomial(expr, deep=True)

包装器,仅使用多项式提示的扩展。有关更多信息,请参阅扩展 docstring。

示例

>>> from sympy import symbols, expand_multinomial, exp
>>> x, y = symbols('x y', positive=True)
>>> expand_multinomial((x + exp(x + 1))**2)
x**2 + 2*x*exp(x + 1) + exp(2*x + 2) 
sympy.core.function.expand_power_exp(expr, deep=True)

包装器,仅使用 power_exp 提示。

更多信息请参见 expand 文档字符串。

示例

>>> from sympy import expand_power_exp, Symbol
>>> from sympy.abc import x, y
>>> expand_power_exp(3**(y + 2))
9*3**y
>>> expand_power_exp(x**(y + 2))
x**(y + 2) 

如果 x = 0,表达式的值取决于 y 的值;如果展开表达式,结果将为 0。因此,仅当 x != 0 时才进行展开:

>>> expand_power_exp(Symbol('x', zero=False)**(y + 2))
x**2*x**y 
sympy.core.function.expand_power_base(expr, deep=True, force=False)

在仅使用 power_base 提示的情况下扩展的包装器。

将使一个以 Mul 为基数的幂展开(仅当关于幂的基数和指数的假设允许时),而不进行任何其他展开。

deep=False(默认为 True)仅适用于顶级表达式。

force=True(默认为 False)将导致展开忽略关于基数和指数的假设。当为 False 时,仅在基数为非负数或指数为整数时才会展开。

>>> from sympy.abc import x, y, z
>>> from sympy import expand_power_base, sin, cos, exp, Symbol 
>>> (x*y)**2
x**2*y**2 
>>> (2*x)**y
(2*x)**y
>>> expand_power_base(_)
2**y*x**y 
>>> expand_power_base((x*y)**z)
(x*y)**z
>>> expand_power_base((x*y)**z, force=True)
x**z*y**z
>>> expand_power_base(sin((x*y)**z), deep=False)
sin((x*y)**z)
>>> expand_power_base(sin((x*y)**z), force=True)
sin(x**z*y**z) 
>>> expand_power_base((2*sin(x))**y + (2*cos(x))**y)
2**y*sin(x)**y + 2**y*cos(x)**y 
>>> expand_power_base((2*exp(y))**x)
2**x*exp(y)**x 
>>> expand_power_base((2*cos(x))**y)
2**y*cos(x)**y 

请注意,和式保持不变。如果这不是期望的行为,请将完整的 expand() 应用于表达式:

>>> expand_power_base(((x+y)*z)**2)
z**2*(x + y)**2
>>> (((x+y)*z)**2).expand()
x**2*z**2 + 2*x*y*z**2 + y**2*z**2 
>>> expand_power_base((2*y)**(1+z))
2**(z + 1)*y**(z + 1)
>>> ((2*y)**(1+z)).expand()
2*2**z*y**(z + 1) 

未展开的幂可以在 y != 0 时安全展开,否则可能会得到表达式的不同值:

>>> prev = _ 

如果我们指出 y 是正数,但在展开后将其替换为 0,则表达式变为 0:

>>> p = Symbol('p', positive=True)
>>> prev.subs(y, p).expand().subs(p, 0)
0 

但是如果 z = -1,表达式将不为零:

>>> prev.subs(y, 0).subs(z, -1)
1 

另请参阅

expand

sympy.core.function.nfloat(expr, n=15, exponent=False, dkeys=False)

使 expr 中所有有理数成为浮点数,除了指数中的那些(除非将 exponents 标志设置为 True)和未定义函数中的那些。在处理字典时,请不要修改键,除非 dkeys=True

示例

>>> from sympy import nfloat, cos, pi, sqrt
>>> from sympy.abc import x, y
>>> nfloat(x**4 + x/2 + cos(pi/3) + 1 + sqrt(y))
x**4 + 0.5*x + sqrt(y) + 1.5
>>> nfloat(x**4 + sqrt(y), exponent=True)
x**4.0 + y**0.5 

容器类型不被修改:

>>> type(nfloat((1, 2))) is tuple
True 
```  ## evalf

```py
class sympy.core.evalf.EvalfMixin

添加 evalf 能力的混合类。

evalf(n=15, subs=None, maxn=100, chop=False, strict=False, quad=None, verbose=False)

将给定的公式评估到 n 位数的精度。

参数:

subs : 字典,可选

用于符号的数值替换,例如 subs={x:3, y:1+pi}。替换必须以字典形式给出。

maxn : 整数,可选

允许最大临时工作精度为 maxn 位数。

chop : 布尔值或数字,可选

指定如何将子结果中微小的实部或虚部替换为精确的零。

True 时,chop 值默认为标准精度。

否则,chop 值用于确定“小”的量级以进行切除。

>>> from sympy import N

>>> x = 1e-4

>>> N(x, chop=True)

0.000100000000000000

>>> N(x, chop=1e-5)

0.000100000000000000

>>> N(x, chop=1e-4)

0 

strict : 布尔值,可选

如果任何子结果未能在可用的最大精度下完全准确评估,则引发 PrecisionExhausted

quad : 字符串,可选

选择数值积分的算法。默认情况下,使用双曲正弦积分法。对于无限区间上的振荡积分,尝试 quad='osc'

verbose : 布尔值,可选

打印调试信息。

注意

当浮点数被天真地替换到表达式中时,精度误差可能会对结果产生不利影响。例如,将 1e16(一个浮点数)加到 1 时会截断为 1e16;如果随后减去 1e16,则结果将为 0。以下正是发生的情况:

>>> from sympy.abc import x, y, z
>>> values = {x: 1e16, y: 1, z: 1e16}
>>> (x + y - z).subs(values)
0 

使用 evalf 的 subs 参数是评估此类表达式的准确方法:

>>> (x + y - z).evalf(subs=values)
1.00000000000000 
n(n=15, subs=None, maxn=100, chop=False, strict=False, quad=None, verbose=False)

将给定的公式评估到 n 位数的精度。

参数:

subs : 字典,可选

替换符号的数值值,例如 subs={x:3, y:1+pi}。替换必须作为字典给出。

maxn:int,可选

允许最大临时工作精度达到 maxn 位数。

chop:bool 或 number,可选

指定如何用精确的零替换子结果中微小的实部或虚部。

True 时,chop 值默认为标准精度。

否则,将使用截断值来确定“小数”的量级。

>>> from sympy import N

>>> x = 1e-4

>>> N(x, chop=True)

0.000100000000000000

>>> N(x, chop=1e-5)

0.000100000000000000

>>> N(x, chop=1e-4)

0 

strict:bool,可选

如果任何子结果未能在给定的 maxprec 下完全精确计算,则抛出 PrecisionExhausted

quad:str,可选

选择数值积分的算法。默认情况下,使用 tanh-sinh 积分。对于在无穷区间上的振荡积分,尝试 quad='osc'

verbose:bool,可选

打印调试信息。

注意

当 Floats 被天真地替换到表达式中时,精度误差可能会对结果产生不利影响。例如,将 1e16(一个 Float)加到 1 中将截断为 1e16;如果然后减去 1e16,则结果将为 0。这正是以下情况发生的:

>>> from sympy.abc import x, y, z
>>> values = {x: 1e16, y: 1, z: 1e16}
>>> (x + y - z).subs(values)
0 

对于 evalf 的子参数,使用此方法来准确评估这样的表达式:

>>> (x + y - z).evalf(subs=values)
1.00000000000000 
class sympy.core.evalf.PrecisionExhausted
sympy.core.evalf.N(x, n=15, **options)

调用 x.evalf(n, **options)。

解释

.n()N() 都等同于 .evalf();使用你喜欢的那个。另请参阅 .evalf() 的文档字符串,了解选项信息。

示例

>>> from sympy import Sum, oo, N
>>> from sympy.abc import k
>>> Sum(1/k**k, (k, 1, oo))
Sum(k**(-k), (k, 1, oo))
>>> N(_, 4)
1.291 
```  ## containers

```py
class sympy.core.containers.Tuple(*args, **kwargs)

封装内置的 tuple 对象。

参数:

sympify:bool

若为 False,则不在 args 上调用 sympify。这可用于对已知元素为 SymPy 对象的非常大的 tuple 进行加速。

解释

Tuple 是 Basic 的子类,因此在 SymPy 框架中能很好地运行。包装后的 tuple 可作为 self.args 使用,但也可以使用 [:] 语法访问元素或切片。

示例

>>> from sympy import Tuple, symbols
>>> a, b, c, d = symbols('a b c d')
>>> Tuple(a, b, c)[1:]
(b, c)
>>> Tuple(a, b, c).subs(a, d)
(d, b, c) 
index(value, start=None, stop=None)

搜索并返回值的第一个索引。

property kind

Tuple 实例的种类。

Tuple 的种类始终为 TupleKind,但由元素数量和每个元素的种类参数化。

示例

>>> from sympy import Tuple, Matrix
>>> Tuple(1, 2).kind
TupleKind(NumberKind, NumberKind)
>>> Tuple(Matrix([1, 2]), 1).kind
TupleKind(MatrixKind(NumberKind), NumberKind)
>>> Tuple(1, 2).kind.element_kind
(NumberKind, NumberKind) 

参见

sympy.matrices.kind.MatrixKind, sympy.core.kind.NumberKind

tuple_count(value) → int

返回值的出现次数。

class sympy.core.containers.TupleKind(*args)

TupleKind 是 Kind 的子类,用于定义 Tuple 的种类。

TupleKind 的参数将是 Tuples 中所有参数的种类,例如

参数:

args:tuple(element_kind)

element_kind 是元素的种类。args 是元素种类的 tuple

示例

>>> from sympy import Tuple
>>> Tuple(1, 2).kind
TupleKind(NumberKind, NumberKind)
>>> Tuple(1, 2).kind.element_kind
(NumberKind, NumberKind) 

参见

sympy.core.kind.NumberKind, MatrixKind, sympy.sets.sets.SetKind

class sympy.core.containers.Dict(*args)

封装了内置的 dict 对象。

解释

DictBasic 的子类,因此它在 SymPy 框架中表现良好。由于它是不可变的,可以包含在集合中,但其值必须在实例化时全部给定,并且不能后续更改。否则,其行为与 Python 的 dict 完全相同。

示例

>>> from sympy import Dict, Symbol 
>>> D = Dict({1: 'one', 2: 'two'})
>>> for key in D:
...    if key == 1:
...        print('%s  %s' % (key, D[key]))
1 one 

参数被 sympify,所以 1 和 2 是整数,而值是符号。查询自动 sympify 参数,因此以下操作有效:

>>> 1 in D
True
>>> D.has(Symbol('one')) # searches keys and values
True
>>> 'one' in D # not in the keys
False
>>> D[1]
one 
get(key, default=None)

如果键在字典中,则返回键的值。

items()

返回提供字典条目视图的类似集合的对象。

keys()

返回字典键的列表。

values()

返回字典值的列表。 ## exprtools

sympy.core.exprtools.gcd_terms(terms, isprimitive=False, clear=True, fraction=True)

计算 terms 的最大公约数并将它们放在一起。

参数:

terms : 表达式

可以是一个表达式或非 Basic 序列的表达式,这将被处理为一个求和项。

isprimitive : 布尔值,可选

如果 isprimitive 为 True,则 _gcd_terms 不会在项上运行原始方法。

clear : 布尔值,可选

它控制从 Add 表达式的分母中移除整数的操作。当为 True(默认)时,将清除所有数值分母;当为 False 时,仅当所有项的数值分母不为 1 时,才清除分母。

fraction : 布尔值,可选

当为 True(默认)时,将表达式置于通用分母之上。

示例

>>> from sympy import gcd_terms
>>> from sympy.abc import x, y 
>>> gcd_terms((x + 1)**2*y + (x + 1)*y**2)
y*(x + 1)*(x + y + 1)
>>> gcd_terms(x/2 + 1)
(x + 2)/2
>>> gcd_terms(x/2 + 1, clear=False)
x/2 + 1
>>> gcd_terms(x/2 + y/2, clear=False)
(x + y)/2
>>> gcd_terms(x/2 + 1/x)
(x**2 + 2)/(2*x)
>>> gcd_terms(x/2 + 1/x, fraction=False)
(x + 2/x)/2
>>> gcd_terms(x/2 + 1/x, fraction=False, clear=False)
x/2 + 1/x 
>>> gcd_terms(x/2/y + 1/x/y)
(x**2 + 2)/(2*x*y)
>>> gcd_terms(x/2/y + 1/x/y, clear=False)
(x**2/2 + 1)/(x*y)
>>> gcd_terms(x/2/y + 1/x/y, clear=False, fraction=False)
(x/2 + 1/x)/y 

在这种情况下,clear 标志被忽略,因为返回的表达式是一个有理数表达式,而不是一个简单的求和。

另请参见

factor_termssympy.polys.polytools.terms_gcd

sympy.core.exprtools.factor_terms(expr, radical=False, clear=False, fraction=False, sign=True)

从所有参数的项中去除公共因子,而不改变表达式的基本结构。不进行展开或简化(也不处理非交换元素)。

参数:

radical: 布尔值,可选

如果 radical=True,则所有项的常见根号将从表达式的任何 Add 子表达式中因式分解出来。

clear : 布尔值,可选

如果 clear=False(默认值),则不会从单个 Add 中分离系数,如果可以分布到一个或多个具有整数系数的项中。

fraction : 布尔值,可选

如果 fraction=True(默认为 False),则将为表达式构造一个通用分母。

sign : 布尔值,可选

如果 sign=True(默认值),即使唯一的共同因子是 -1,它也会从表达式中因式分解出来。

示例

>>> from sympy import factor_terms, Symbol
>>> from sympy.abc import x, y
>>> factor_terms(x + x*(2 + 4*y)**3)
x*(8*(2*y + 1)**3 + 1)
>>> A = Symbol('A', commutative=False)
>>> factor_terms(x*A + x*A + x*y*A)
x*(y*A + 2*A) 

clear 为 False 时,如果 Add 表达式的所有项的系数都是分数,则仅从中因式分解出一个有理数:

>>> factor_terms(x/2 + 1, clear=False)
x/2 + 1
>>> factor_terms(x/2 + 1, clear=True)
(x + 2)/2 

如果 -1 是唯一可以因式分解的内容,则 因式分解它,sign 标志必须为 False:

>>> factor_terms(-x - y)
-(x + y)
>>> factor_terms(-x - y, sign=False)
-x - y
>>> factor_terms(-2*x - 2*y, sign=False)
-2*(x + y) 

参见

gcd_termssympy.polys.polytools.terms_gcd ## 类型

class sympy.core.kind.Kind(*args)

种类的基类。

对象的种类表示实体所属的数学分类。函数和类应当通过其种类来识别和过滤参数。

每个对象的种类必须谨慎选择,以表明设计意图。根据其参数的种类,表达式可能有不同的种类。例如,Add的参数必须具有共同的种类,因为加法是群操作符,而生成的Add()也具有相同的种类。

为了性能,每种种类尽可能广泛,并且不基于集合理论。例如,NumberKind不仅包括复数,还包括包含非严格数字S.InfinityS.NaN的表达式。

种类可以作为参数具有参数。例如,MatrixKind()可以用一个元素构造,该元素表示其元素的种类。

Kind表现得像单例模式。相同的签名将返回相同的对象。

sympy.core.kind.NumberKind

NumberKind的别名

sympy.core.kind.UndefinedKind

UndefinedKind的别名

sympy.core.kind.BooleanKind

BooleanKind的别名

排序

sympy.core.sorting.default_sort_key(item, order=None)

返回可用于排序的关键字。

关键字的结构如下:

(class_key, (len(args), args), exponent.sort_key(), coefficient)

item是 Basic 对象或符号化为 Basic 对象的对象(而不是字符串)时,此关键字由 Basic 对象的sort_key例程提供。否则,此函数将生成关键字。

order参数传递给sort_key例程,并用于确定表达式中项的顺序。 (请参见下面的示例)order选项包括:'lex','grlex','grevlex'和相同的反向值(例如'rev-lex')。默认的order值为 None(即'lex')。

示例

>>> from sympy import S, I, default_sort_key, sin, cos, sqrt
>>> from sympy.core.function import UndefinedFunction
>>> from sympy.abc import x 

获取对象关键字的等效方法如下:

>>> x.sort_key() == default_sort_key(x)
True 

以下是生成的关键字的一些示例:

>>> default_sort_key(UndefinedFunction('f'))
((0, 0, 'UndefinedFunction'), (1, ('f',)), ((1, 0, 'Number'),
 (0, ()), (), 1), 1)
>>> default_sort_key('1')
((0, 0, 'str'), (1, ('1',)), ((1, 0, 'Number'), (0, ()), (), 1), 1)
>>> default_sort_key(S.One)
((1, 0, 'Number'), (0, ()), (), 1)
>>> default_sort_key(2)
((1, 0, 'Number'), (0, ()), (), 2) 

虽然sort_key是 SymPy 对象专有的方法,但default_sort_key将接受任何参数作为参数,因此作为排序关键字更加健壮。对于下面的例子,使用key=lambda i: i.sort_key()会失败,因为 2 没有sort_key方法;这就是为什么使用default_sort_key。请注意,它还处理非字符串项(如整数)的符号化:

>>> a = [2, I, -I]
>>> sorted(a, key=default_sort_key)
[2, -I, I] 

返回的关键字可用于函数中可以指定关键字的任何位置,例如排序、最小值、最大值等:

>>> a.sort(key=default_sort_key); a[0]
2
>>> min(a, key=default_sort_key)
2 

注意事项

返回的关键字可用于按照平台通用的规范顺序获取项目。它并不直接用于对表达式列表进行排序:

>>> a, b = x, 1/x 

由于a只有 1 个项,其sort_key值不受order的影响:

>>> a.sort_key() == a.sort_key('rev-lex')
True 

如果合并ab,则关键字将不同,因为可以排序的项有所不同:

>>> eq = a + b
>>> eq.sort_key() == eq.sort_key('rev-lex')
False
>>> eq.as_ordered_terms()
[x, 1/x]
>>> eq.as_ordered_terms('rev-lex')
[1/x, x] 

但由于每个项的关键字都独立于order的值,因此当它们单独出现在列表中时,它们不会按不同的顺序排序:

>>> sorted(eq.args, key=default_sort_key)
[1/x, x]
>>> sorted(eq.args, key=lambda i: default_sort_key(i, order='rev-lex'))
[1/x, x] 

使用这些关键字时获得的项的顺序是在一个乘积中作为因子时获得的顺序。

尽管它对于快速将表达式放入规范顺序很有用,但它不根据操作数量、变量的幂次和其他定义的复杂性对表达式进行排序:

>>> sorted([sin(x)*cos(x), sin(x)], key=default_sort_key)
[sin(x)*cos(x), sin(x)]
>>> sorted([x, x**2, sqrt(x), x**3], key=default_sort_key)
[sqrt(x), x, x**2, x**3] 

另见

有序,sympy.core.expr.Expr.as_ordered_factors,sympy.core.expr.Expr.as_ordered_terms

sympy.core.sorting.ordered(seq, keys=None, default=True, warn=False)

返回一个序列的迭代器,其中键被保守地用于打破平局:如果应用一个键后没有平局,则不会计算其他键。

如果未提供键或给定键未解决所有平局(但仅当default为 True 时),将应用两个默认键:_nodes(将较小的表达式放在前面)和default_sort_key(如果对象的sort_key正确定义,则应解决任何平局)。此策略类似于Basic.compare所做的排序,但不同之处在于ordered从不基于对象名称做决定。

如果warn为 True,则如果没有剩余的键来打破平局,则会引发错误。如果预期不应该有非相同项目之间的平局,则可以使用此功能。

示例

>>> from sympy import ordered, count_ops
>>> from sympy.abc import x, y 

count_ops不足以在此列表中打破平局,并且前两个项目以其原始顺序出现(即排序是稳定的):

>>> list(ordered([y + 2, x + 2, x**2 + y + 3],
...    count_ops, default=False, warn=False))
...
[y + 2, x + 2, x**2 + y + 3] 

default_sort_key允许打破平局:

>>> list(ordered([y + 2, x + 2, x**2 + y + 3]))
...
[x + 2, y + 2, x**2 + y + 3] 

在这里,序列按长度排序,然后按总和排序:

>>> seq, keys = [[[1, 2, 1], [0, 3, 1], [1, 1, 3], [2], [1]], [
...    lambda x: len(x),
...    lambda x: sum(x)]]
...
>>> list(ordered(seq, keys, default=False, warn=False))
[[1], [2], [1, 2, 1], [0, 3, 1], [1, 1, 3]] 

如果warn为 True,则如果没有足够的键来打破平局,则会引发错误:

>>> list(ordered(seq, keys, default=False, warn=True))
Traceback (most recent call last):
...
ValueError: not enough keys to break ties 

装饰排序是希望特定项目比较的一种最快排序序列的方式之一:序列被装饰,根据装饰进行排序(例如将所有字母变成小写),然后取消装饰。如果想要打破具有相同装饰值项目的平局,则可以使用第二个键。但是如果计算第二个键很昂贵,那么使用两个键来装饰所有项目是低效的:只有具有相同第一个键值的项目才需要装饰。该函数仅在需要打破平局时连续应用键。通过生成迭代器,使用打破平局者被尽可能延迟使用。

当预期使用第一个键作为良好的哈希函数时,此函数最好用于案例;如果从键的应用中没有唯一的哈希,则不应该使用该键。但例外情况是,即使有许多碰撞,如果第一组较小并且不需要处理列表中的所有项,则不会浪费时间对不感兴趣的内容进行排序。例如,如果要在列表中查找最小值,并且有几个标准用于定义排序顺序,那么如果第一组候选人相对于正在处理的项目数较小,则此功能将快速返回结果。

随机

当您需要在 SymPy 库代码中使用随机数时,请从这里导入,以便为 SymPy 仅工作一个生成器。从这里导入应该与从 Python 的随机模块导入的行为相同。但这里仅包括当前在 SymPy 中使用的例程。要使用其他例程,请导入rng并直接访问方法。例如,要捕获生成器的当前状态,请使用rng.getstate()

这里有意没有 Random 可供导入。如果要控制生成器的状态,请导入seed并调用它,可以带参数也可以不带参数来设置状态。

示例

>>> from sympy.core.random import random, seed
>>> assert random() < 1
>>> seed(1); a = random()
>>> b = random()
>>> seed(1); c = random()
>>> assert a == c
>>> assert a != b  # remote possibility this will fail 
sympy.core.random.random_complex_number(a=2, b=-1, c=3, d=1, rational=False, tolerance=None)

返回一个随机复数。

为了减少命中分支切割或任何东西的机会,我们保证 b <= Im z <= d,a <= Re z <= c

当 rational 为 True 时,可以在指定的容差范围内获得对随机数的有理逼近。

sympy.core.random.verify_numerically(f, g, z=None, tol=1e-06, a=2, b=-1, c=3, d=1)

数值上测试在参数 z 处评估时 f 和 g 是否一致。

如果 z 为 None,则将测试所有符号。此例程不测试是否存在精度高于 15 位的浮点数,因此如果有,则由于舍入误差,您的结果可能不符合预期。

示例

>>> from sympy import sin, cos
>>> from sympy.abc import x
>>> from sympy.core.random import verify_numerically as tn
>>> tn(sin(x)**2 + cos(x)**2, 1, x)
True 
sympy.core.random.test_derivative_numerically(f, z, tol=1e-06, a=2, b=-1, c=3, d=1)

数值上测试 f 对 z 的符号计算导数是否正确。

此例程不测试是否存在精度高于 15 位的浮点数,因此如果有,则由于舍入误差,您的结果可能不符合预期。

示例

>>> from sympy import sin
>>> from sympy.abc import x
>>> from sympy.core.random import test_derivative_numerically as td
>>> td(sin(x), x)
True 
sympy.core.random._randrange(seed=None)

返回一个 randrange 生成器。

seed可以

  • None - 返回随机种子生成器

  • int - 返回用 int 种子的生成器

  • list - 将返回的值按给定顺序从列表中取出;不修改提供的列表。

示例

>>> from sympy.core.random import _randrange
>>> rr = _randrange()
>>> rr(1000) 
999
>>> rr = _randrange(3)
>>> rr(1000) 
238
>>> rr = _randrange([0, 5, 1, 3, 4])
>>> rr(3), rr(3)
(0, 1) 
sympy.core.random._randint(seed=None)

返回一个 randint 生成器。

seed可以

  • None - 返回随机种子生成器

  • int - 返回用 int 种子的生成器

  • list - 将返回的值按给定顺序从列表中取出;不修改提供的列表。

示例

>>> from sympy.core.random import _randint
>>> ri = _randint()
>>> ri(1, 1000) 
999
>>> ri = _randint(3)
>>> ri(1, 1000) 
238
>>> ri = _randint([0, 5, 1, 2, 4])
>>> ri(1, 3), ri(1, 3)
(1, 2) 
```  ## 遍历

```py
sympy.core.traversal.bottom_up(rv, F, atoms=False, nonbasic=False)

对表达式树中的所有表达式从底向上应用F。如果atoms为 True,则即使没有参数也应用F;如果nonbasic为 True,则尝试将F应用于非基本对象。

sympy.core.traversal.postorder_traversal(node, keys=None)

对树进行后序遍历。

此生成器以后序方式递归地生成已访问的节点。也就是说,它通过深度优先方式下降以生成所有节点子节点的后序遍历,然后才生成节点本身。

参数:

node:SymPy 表达式

遍历表达式。

keys:(默认为 None)排序键

用于排序 Basic 对象的键。当为 None 时,处理 Basic 对象的 args 的顺序是任意的。如果定义了 key,则它将作为唯一的键传递给 ordered();如果 key 简单地为 True,则将使用 ordered 的默认键(节点计数和默认排序键)。

生成:

子树:SymPy 表达式

树中的所有子树。

示例

>>> from sympy import postorder_traversal
>>> from sympy.abc import w, x, y, z 

节点按照遇到的顺序返回,除非提供了关键字;仅传递 key=True 将确保遍历是唯一的。

>>> list(postorder_traversal(w + (x + y)*z)) 
[z, y, x, x + y, z*(x + y), w, w + z*(x + y)]
>>> list(postorder_traversal(w + (x + y)*z, keys=True))
[w, z, x, y, x + y, z*(x + y), w + z*(x + y)] 
sympy.core.traversal.preorder_traversal(node, keys=None)

对树进行先序遍历。

此迭代器以先序方式递归地生成已访问的节点。也就是说,它生成当前节点,然后以广度优先方式下降以生成所有节点子节点的先序遍历。

对于表达式,遍历的顺序取决于 .args 的顺序,在许多情况下可以是任意的。

参数:

node:SymPy 表达式

遍历表达式。

keys:(默认为 None)排序键

用于排序 Basic 对象的键。当为 None 时,处理 Basic 对象的 args 的顺序是任意的。如果定义了 key,则它将作为唯一的键传递给 ordered();如果 key 简单地为 True,则将使用 ordered 的默认键。

生成:

子树:SymPy 表达式

树中的所有子树。

示例

>>> from sympy import preorder_traversal, symbols
>>> x, y, z = symbols('x y z') 

节点按照遇到的顺序返回,除非提供了关键字;仅传递 key=True 将确保遍历是唯一的。

>>> list(preorder_traversal((x + y)*z, keys=None)) 
[z*(x + y), z, x + y, y, x]
>>> list(preorder_traversal((x + y)*z, keys=True))
[z*(x + y), z, x + y, x, y] 
sympy.core.traversal.use(expr, func, level=0, args=(), kwargs={})

使用 func 在给定级别转换 expr

示例

>>> from sympy import use, expand
>>> from sympy.abc import x, y 
>>> f = (x + y)**2*x + 1 
>>> use(f, expand, level=2)
x*(x**2 + 2*x*y + y**2) + 1
>>> expand(f)
x**3 + 2*x**2*y + x*y**2 + 1 
sympy.core.traversal.walk(e, *target)

遍历给定类型的参数并返回遍历过的参数列表;不是指定类型的参数不会遍历。

示例

>>> from sympy.core.traversal import walk
>>> from sympy import Min, Max
>>> from sympy.abc import x, y, z
>>> list(walk(Min(x, Max(y, Min(1, z))), Min))
[Min(x, Max(y, Min(1, z)))]
>>> list(walk(Min(x, Max(y, Min(1, z))), Min, Max))
[Min(x, Max(y, Min(1, z))), Max(y, Min(1, z)), Min(1, z)] 

参见

bottom_up