活跃弃用列表¶
本页面列出了 SymPy 代码库中所有活跃的弃用项。有关 SymPy 弃用政策的描述以及贡献者如何弃用内容的说明,请参阅 弃用政策 页面。
特别是,SymPy 的弃用政策规定,弃用至少在包含该弃用的第一个主要版本发布后 1年 内有效。在此期间之后,被弃用的功能可能会从 SymPy 中移除,代码需要更新以使用替代功能以继续工作。
在弃用期间,每当使用已弃用的功能时,将打印一条 SymPyDeprecationWarning
消息。建议用户更新他们的代码,使其不再使用已弃用的功能,如下文所述,针对每个弃用功能。
静默 SymPy 弃用警告¶
要屏蔽 SymPy 的弃用警告,请使用 warnings
模块添加一个过滤器。例如:
import warnings
from sympy.utilities.exceptions import SymPyDeprecationWarning
warnings.filterwarnings(
# replace "ignore" with "error" to make the warning raise an exception.
# This useful if you want to test you aren't using deprecated code.
"ignore",
# message may be omitted to filter all SymPyDeprecationWarnings
message=r"(?s).*<regex matching the warning message>",
category=SymPyDeprecationWarning,
module=r"<regex matching your module>"
)
这里 (?s).*<匹配警告消息的正则表达式>
是一个匹配警告消息的正则表达式。例如,要过滤关于 sympy.printing
的警告,您可能会使用 message=r"(?s).*sympy\.printing"
。前面的 (?s).*
是因为 warnings 模块将 message
与警告消息的开头进行匹配,并且因为典型的警告消息跨越多行。
<regex matching your module>
应该是一个匹配使用已弃用代码的模块的正则表达式。建议包含此项,以免同时屏蔽无关模块的相同警告。
这个相同的模式也可以用来将 SymPyDeprecationWarning
转换为错误,以便你可以测试你是否没有使用已弃用的代码。为此,在上面的例子中,将 "ignore"
替换为 "error"
。你也可以省略 message
,使这适用于所有 SymPyDeprecationWarning
警告。
如果你使用的是 pytest,你可以使用 pytest 的警告过滤功能 来忽略 SymPyDeprecationWarning
或将它们转换为错误。
备注
Python 的 -W
标志 和 PYTHONWARNINGS
环境变量 将无法用于过滤 SymPy 的弃用警告(详情请参见 Ned Batchelder 的 这篇博客文章 和 这个 SymPy 问题)。你需要添加如上所述的 warnings
过滤器,或者使用 pytest 来过滤 SymPy 的弃用警告。
版本 1.14¶
SymPy 1.14 目前没有弃用的功能。
版本 1.13¶
已弃用的机械体类¶
sympy.physics.mechanics
模块中的 Body
类已被弃用。它最初是为了支持关节框架而引入的。然而,由于它同时代表刚体和粒子,导致了一些问题。Body
现在已被 RigidBody
和 Particle
完全取代。以前,可以通过仅使用 Body
类来创建一个简单的刚体或粒子:
>>> from sympy import symbols
>>> from sympy.physics.mechanics import Body
>>> Body("rigid_body")
rigid_body
>>> Body("particle", mass=symbols("m"))
particle
现在它们应该使用 RigidBody
和 Particle
类来创建:
>>> from sympy.physics.mechanics import RigidBody, Particle
>>> RigidBody("rigid_body")
rigid_body
>>> Particle("particle")
particle
已弃用的机械连接 JointsMethod¶
sympy.physics.mechanics
模块中的 JointsMethod
类已被弃用。它最初是为了支持关节框架而引入的,但由于其设计上的局限性,已被完全取代。以前,可以仅由刚体和关节构建系统,然后由 JointsMethod
解析到后端,如 KanesMethod
以形成运动方程。
>>> from sympy import symbols
>>> from sympy.physics.mechanics import (
... Body, JointsMethod, PinJoint, PrismaticJoint)
>>> g, l = symbols("g l")
>>> wall = Body("wall")
>>> cart = Body("cart")
>>> pendulum = Body("Pendulum")
>>> slider = PrismaticJoint("s", wall, cart, joint_axis=wall.x)
>>> pin = PinJoint("j", cart, pendulum, joint_axis=cart.z,
... child_point=l * pendulum.y)
>>> pendulum.masscenter.set_vel(pendulum.frame, 0)
>>> cart.apply_force(-g * cart.mass * wall.y)
>>> pendulum.apply_force(-g * pendulum.mass * wall.y)
>>> method = JointsMethod(wall, slider, pin)
>>> method.form_eoms()
Matrix([
[ Pendulum_mass*l*u_j(t)**2*sin(q_j(t)) - Pendulum_mass*l*cos(q_j(t))*Derivative(u_j(t), t) - (Pendulum_mass + cart_mass)*Derivative(u_s(t), t)],
[-Pendulum_mass*g*l*sin(q_j(t)) - Pendulum_mass*l*cos(q_j(t))*Derivative(u_s(t), t) - (Pendulum_izz + Pendulum_mass*l**2)*Derivative(u_j(t), t)]])
JointsMethod
的替代品是 System
,它可以用来形成与以下相同的推车摆杆的运动方程:
>>> from sympy import symbols
>>> from sympy.physics.mechanics import (
... Particle, PinJoint, PrismaticJoint, RigidBody, System)
>>> g, l = symbols("g l")
>>> wall = RigidBody("wall")
>>> cart = RigidBody("cart")
>>> pendulum = RigidBody("Pendulum")
>>> slider = PrismaticJoint("s", wall, cart, joint_axis=wall.x)
>>> pin = PinJoint("j", cart, pendulum, joint_axis=cart.z,
... child_point=l * pendulum.y)
>>> system = System.from_newtonian(wall)
>>> system.add_joints(slider, pin)
>>> system.apply_uniform_gravity(-g * wall.y)
>>> system.form_eoms()
Matrix([
[ Pendulum_mass*l*u_j(t)**2*sin(q_j(t)) - Pendulum_mass*l*cos(q_j(t))*Derivative(u_j(t), t) - (Pendulum_mass + cart_mass)*Derivative(u_s(t), t)],
[-Pendulum_mass*g*l*sin(q_j(t)) - Pendulum_mass*l*cos(q_j(t))*Derivative(u_s(t), t) - (Pendulum_izz + Pendulum_mass*l**2)*Derivative(u_j(t), t)]])
已弃用的矩阵混合类¶
矩阵混合类已被弃用。以前,Matrix
类(也称为 MutableDenseMatrix
)是通过一个继承层次结构创建的,看起来像:
class MatrixRequired:
class MatrixShaping(MatrixRequired):
class MatrixSpecial(MatrixRequired):
class MatrixProperties(MatrixRequired):
class MatrixOperations(MatrixRequired):
class MatrixArithmetic(MatrixRequired):
class MatrixCommon(
MatrixArithmetic,
MatrixOperations,
MatrixProperties,
MatrixSpecial,
MatrixShaping):
class MatrixDeterminant(MatrixCommon):
class MatrixReductions(MatrixDeterminant):
class MatrixSubspaces(MatrixReductions):
class MatrixEigen(MatrixSubspaces)
class MatrixCalculus(MatrixCommon):
class MatrixDeprecated(MatrixCommon):
class MatrixBase(MatrixDeprecated,
MatrixCalculus,
MatrixEigen,
MatrixCommon,
Printable):
class RepMatrix(MatrixBase):
class DenseMatrix(RepMatrix):
class MutableRepMatrix(RepMatrix):
class MutableDenseMatrix(DenseMatrix, MutableRepMatrix):
从 SymPy 1.13 开始,这已经简化,所有高于 MatrixBase
的类都被合并在一起,因此层次结构看起来像:
class MatrixBase(Printable):
class RepMatrix(MatrixBase):
class DenseMatrix(RepMatrix):
class MutableRepMatrix(RepMatrix):
class MutableDenseMatrix(DenseMatrix, MutableRepMatrix):
像 MatrixRequired
等矩阵混合类仍然可用,因为下游代码可能正在子类化这些类,但这些类都已弃用,并将在SymPy的未来版本中移除。子类化这些类已弃用,任何这样做的代码都应该修改为不子类化它们。
使用这些类与 isinstance
如 isinstance(M, MatrixCommon)
也是不推荐的。任何这样做的代码都应该改为使用 isinstance(M, Matrixbase)
,这样也可以兼容之前的 SymPy 版本。
更一般地说,从定义了这些类的 sympy.matrices.common
或 sympy.matrices.matrices
模块中导入任何内容已被弃用。这些模块将在未来的 SymPy 版本中被移除。
这一更改的原因是,复杂的继承层次结构使得在仍然提供所有这些可以被继承的类的同时,难以改进 Matrix
以满足大多数用户的需求。由于这些混合类不再作为 Matrix
的一部分使用,它们在 SymPy 中不再发挥任何作用,移除这些现在未使用的代码将简化代码库。
sympify()
中的字符串回退¶
sympify
函数以前会将无法识别的对象转换为字符串并重试符号化。这在 SymPy 1.6 中已被弃用,并在 SymPy 1.13 中被移除。
sympify
的行为是 sympify(expr)
尝试各种方法将 expr
转换为 SymPy 对象。以前,如果所有这些方法都失败,它会取 str(expr)
并尝试使用 parse_expr()
进行解析。这个字符串回退功能在 SymPy 1.6 中被弃用,并在 SymPy 1.13 中被移除。
这种行为有几个问题:
这可能会以重大方式影响性能。例如,参见问题 #18056 和 #15416,其中它导致了高达100倍的减速。问题在于SymPy函数自动在其参数上调用
sympify
。每当一个函数传递给sympify
不知道如何转换为SymPy对象的东西时,例如,一个Python函数类型,它将字符串传递给parse_expr()
。这比默认情况下发生的直接转换要慢得多。这种情况特别发生在库代码中使用sympify()
而不是_sympify()
(或等效地sympify(strict=True)
)时,但目前这种情况很常见。使用strict=True
将在某个时候成为所有库代码的默认设置,但这是一个更难的改变。由于字符串会被求值,对象可以在其
__repr__
中返回任何字符串,这可能会导致安全问题。另见 https://github.com/sympy/sympy/pull/12524。一开始它确实不是很有用。仅仅因为一个对象的字符串形式可以被解析为一个 SymPy 表达式,并不意味着它应该被那样解析。对于自定义数值类型来说,这通常是正确的,但一个对象的 repr 可以是任何东西。例如,如果一个对象的字符串形式看起来像一个有效的 Python 标识符,它将被解析为一个
Symbol
。
在 sympify()
内部有许多方法可以使自定义对象工作。
首先,如果一个对象旨在与其他 SymPy 表达式一起工作,它应该从
Basic
(或Expr
)子类化。如果是这样,sympify()
将直接返回它而不做改变,因为它已经是一个有效的 SymPy 对象。对于你控制的对象,你可以添加
_sympy_
方法。sympify 文档字符串 中有一个这方面的示例。对于你不控制的物体,你可以向
sympy.core.sympify.converter
字典添加一个自定义转换器。sympify()
文档字符串中也有一个这样的例子。
弃用 DMP.rep 属性。¶
Poly
的内部类型是 DMP
类,以前可以像列表一样访问多项式的系数,例如:
>>> from sympy import symbols, Poly
>>> x = symbols('x')
>>> p = Poly(x**2 + 2*x + 3)
>>> p
Poly(x**2 + 2*x + 3, x, domain='ZZ')
>>> p.rep
DMP([1, 2, 3], ZZ)
>>> p.rep.rep
[1, 2, 3]
从 SymPy 1.13 开始,DMP
类型可能由两个子类之一实现:
DMP_Python
类似于之前的DMP
类型,并且其内部表示为一个列表。DUP_Flint
包装了来自 python-flint 的 Flint 多项式。
DUP_Flint
类型没有类似于 DMP_Python
的列表属性。访问 .rep
仍将生成一个列表,但现在会给出弃用警告。
使用 DMP.to_list()
方法代替 .rep
,该方法返回一个等效的列表:
>>> p.rep.to_list()
[1, 2, 3]
.to_list()
方法在 SymPy 的早期版本中也可用,其行为保持不变。
弃用 pkgdata 模块¶
sympy.utilities.pkdata
模块已被弃用,并将在未来被移除。它不再在 SymPy 的任何地方使用,也不适合任何下游代码使用。请改用标准库 importlib.resources
模块。
弃用 Eq.rewrite(Add)¶
将 eq = Eq(x, y)
重写为 eq.rewrite(Add)
以得到 x - y
的功能已被弃用,取而代之的是使用 eq.lhs - eq.rhs
。鉴于 lhs
和 rhs
的显式使用带来的清晰性,以及这种功能在重写机制中的包含会导致在将期望布尔值的节点重写为 Expr 时失败,因此没有必要提供替代的属性/方法。
弃用 Plot 类的标记、注释、填充、矩形¶
属性 markers, annotations, fill, rectangles
(包含用户提供的要添加到图表中的数值数据)已被弃用。新的实现将用户提供的数值数据保存到适当的数据系列中,这些数据系列可以很容易地由 MatplotlibBackend
处理。用户应将同名关键字参数传递给绘图函数,而不是直接设置这些属性。
支持的行为是将关键字参数传递给绘图函数,这对于所有版本的 SymPy(1.13 之前和之后)都适用:
p = plot(x,
markers=[{"args":[[0, 1], [0, 1]], "marker": "*", "linestyle": "none"}],
annotations=[{"text": "test", "xy": (0, 0)}],
fill={"x": [0, 1, 2, 3], "y1": [0, 1, 2, 3]},
rectangles=[{"xy": (0, 0), "width": 5, "height": 1}])
在绘图对象上设置属性已被弃用,并将引发警告:
p = plot(x, show=False)
p.markers = [{"args":[[0, 1], [0, 1]], "marker": "*", "linestyle": "none"}]
p.annotations = [{"text": "test", "xy": (0, 0)}]
p.fill = {"x": [0, 1, 2, 3], "y1": [0, 1, 2, 3]}
p.rectangles = [{"xy": (0, 0), "width": 5, "height": 1}]
p.show()
此次弃用的动机:Plot
类的实现表明,在 MatplotlibBackend
类中添加属性和硬编码的 if 语句以为用户提供的数值数据提供越来越多的功能(例如添加水平线、垂直线或条形图等)是可以的。然而,这样做实际上是在重复造轮子:绘图库已经实现了必要的 API。没有必要硬编码这些功能。绘图模块应该促进符号表达式的可视化。添加自定义数值数据的最佳方式是获取绘图模块创建的图形,并使用特定绘图库的 API。例如:
# plot symbolic expression
p = plot(cos(x))
# retrieve Matplotlib's figure and axes object
fig, ax = p._backend.fig, p._backend.ax[0]
# add the desired numerical data using Matplotlib's API
ax.plot([0, 1, 2], [0, 1, -1], "*")
ax.axhline(0.5)
# visualize the figure
fig
移动机械函数¶
随着 sympy.physics.mechanics
模块中引入了一些新对象,如 Inertia
和负载对象,sympy.physics.mechanics.functions
模块中的一些函数已被移动到新的模块中。这消除了一些循环导入错误,并使得浏览源代码变得更加容易,因为函数名与模块名之间保持了一致性。以下函数已被移动:
inertia
已被移动到sympy.physics.mechanics.inertia
inertia_of_point_mass
已被移动到sympy.physics.mechanics.inertia
gravity
已被移动到sympy.physics.mechanics.loads
之前你可以从 sympy.physics.mechanics.functions
导入函数:
>>> from sympy.physics.mechanics.functions import inertia, inertia_of_point_mass, gravity
现在它们应该从 sympy.physics.mechanics
导入:
>>> from sympy.physics.mechanics import inertia, inertia_of_point_mass
>>> from sympy.physics.mechanics.loads import gravity
像 a < b
这样的有序比较与模整数¶
SymPy 的 GF
域表示模整数。以前可以使用 a < b
这样的有序比较来比较这些整数:
>>> from sympy import GF
>>> F5 = GF(5)
>>> F5(2) < F5(3)
True
当基础类型设置为 flint
时,这将导致 TypeError
错误。当基础类型不是 flint
时,这些比较操作现在已被弃用:它们仍然可以使用,但在使用时会给出弃用警告。
模整数或有限域的有序比较没有意义,因为这些不是有序域:
>>> e = F5(4)
>>> e + 1 > e
False
ModularInteger.to_int()
方法¶
SymPy 的 GF
域用于模整数,例如 GF(n)
用于模 n
的整数,并且可以像这样使用:
>>> from sympy import GF
>>> K = GF(5)
>>> a = K(7)
>>> a
2 mod 5
模块化整数域的元素有一个自 SymPy 1.13 起被弃用的 to_int()
方法:
>>> # this is deprecated:
>>> a.to_int()
2
相反,实现等效行为的推荐方法是使用域上的方法(在 SymPy 1.13 中添加),或者调用 int
可能更好:
>>> K.to_int(a)
2
>>> int(a)
2
这两种转换为 int
的方法并不等价。域 GF(p)
可以用 symmetric=True
或 symmetric=False
来定义。这种差异会影响 to_int
方法的行为:
>>> KS = GF(5, symmetric=True)
>>> KU = GF(5, symmetric=False)
>>> [KS.to_int(KS(n)) for n in range(10)]
[0, 1, 2, -2, -1, 0, 1, 2, -2, -1]
>>> [KU.to_int(KU(n)) for n in range(10)]
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
>>> [int(KS(n)) for n in range(10)]
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
>>> [int(KU(n)) for n in range(10)]
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
因此,如果 symmetric=True
(这是默认设置),那么 to_int
方法有时会返回负整数。如果 symmetric=False
或者使用 int(a)
方法,返回的结果总是一个非负整数。还要注意,int(a)
的行为在 SymPy 1.13 中发生了变化:在之前的版本中,它等同于 a.to_int()
。为了编写在所有 SymPy 版本中行为一致的代码,你可以:
使用
symmetric=False
并使用int(a)
。定义一个函数,例如
def to_int(K, a): if hasattr(K, 'to_int'): return K.to_int(a) else: return a.to_int()
这一更改的原因是,它使得可以使用 python-flint 的 nmod
作为 GF(p)
元素的替代(快得多)实现。无法向 python-flint 的 nmod
类型添加 to_int
方法,也无法通过在 nmod
实例中存储数据来捕获 symmetric=True/False
的等效内容。弃用并移除 to_int
方法并更改 int
方法的行为意味着元素实例没有任何行为取决于域是否被认为是“对称”的。相反,“对称”的概念现在纯粹是域对象本身的属性,而不是元素的属性,因此依赖于此的 to_int
方法必须是域方法而不是元素方法。
将符号函数从 ntheory
移动到 functions
¶
以下 ntheory
中的符号函数已移至 functions
中:
sympy.ntheory.factor_.divisor_sigma
sympy.ntheory.factor_.primenu
sympy.ntheory.factor_.primeomega
sympy.ntheory.factor_.reduce_totient
sympy.ntheory.factor_.totient
sympy.ntheory.generate.primepi
sympy.partitions_.npartitions
sympy.ntheory.residue_ntheory.jacobi_symbol
sympy.ntheory.residue_ntheory.legendre_symbol
sympy.ntheory.residue_ntheory.mobius
从顶层导入这些函数的代码,例如 from sympy import mobius
,将继续正常工作。然而,从完全限定模块导入这些函数的代码,例如 from sympy.ntheory import mobius
或 from sympy.ntheory.residue_ntheory import mobius
,现在将会看到一个弃用警告。这些函数的新位置在 sympy.functions
中,但导入它们的预期方式仍然是像 from sympy import mobius
这样从顶层导入。
以下 ntheory
中的符号函数已移至 functions
,但不能在顶层导入。
sympy.ntheory.factor_.udivisor_sigma
以下函数已从 functions
移动到 ntheory
,因为它们是数值函数。
sympy.functions.combinatorial.numbers.carmichael.is_carmichael
sympy.functions.combinatorial.numbers.carmichael.find_carmichael_numbers_in_range
sympy.functions.combinatorial.numbers.carmichael.find_first_n_carmichaels
如果你正在使用这些功能,请进行更改:
>>> from sympy import carmichael
>>> carmichael.is_carmichael(561)
True
到
>>> from sympy import is_carmichael
>>> is_carmichael(561)
True
版本 1.12¶
ManagedProperties
元类¶
ManagedProperties
元类以前是 Basic
的元类。现在 Basic
不使用元类,因此它的元类只是 type
。任何以前继承 Basic
并希望使用元类的代码都需要继承 ManagedProperties
以使用相关的元类。ManagedProperties
的唯一相关方法已被移动到 Basic.__init_subclass__
。由于 ManagedProperties
不再用作 Basic
的元类,并且不再执行任何有用操作,因此对于此类代码,可以直接继承 type
作为任何元类。
新的关节坐标格式¶
sympy.physics.mechanics
模块中关节的广义坐标和广义速度的格式(即类型和自动生成的名称)已更改。数据类型已从 list
更改为 Matrix
,这与 KanesMethod
中广义坐标的类型相同。PinJoint
和 PrismaticJoint
的广义坐标和广义速度的自动命名也已更改为 q_<joint.name>
和 u_<joint.name>
。以前,这些关节中的每一个都有独特的模板来自动生成这些名称。
新的关节中间帧¶
sympy.physics.mechanics
模块中关节轴的定义已经改变。不再使用 parent_axis
和 child_axis
参数来自动确定关节轴和中间参考系,现在关节使用中间帧参数来表示父体和子体,即 parent_interframe
和 child_interframe
。这意味着你现在可以完全定义两个物体之间的关节连接,包括点和框架。此外,如果像 PinJoint
这样的关节有特定的关节轴,例如旋转发生的轴,那么可以使用 joint_axis
参数来指定该轴。这种设置的一个优点是可以更准确地定义从父体到子体的变换。
例如,假设你想要一个围绕 parent.z
轴和 -child.z
轴旋转子体的 PinJoint
。之前指定这种关节的方式是:
>>> from sympy.physics.mechanics import Body, PinJoint
>>> parent, child = Body('parent'), Body('child')
>>> pin = PinJoint('pin', parent, child, parent_axis=parent.z,
... child_axis=-child.z)
>>> parent.dcm(child)
Matrix([
[-cos(q_pin(t)), -sin(q_pin(t)), 0],
[-sin(q_pin(t)), cos(q_pin(t)), 0],
[ 0, 0, -1]])
检查此矩阵时,您会注意到当 theta_pin = 0
时,子体绕 parent.y
轴旋转了 \(\pi\) 弧度。在新定义中,您可以看到我们得到了相同的结果,但这次我们还明确指定了这一旋转:
>>> from sympy import pi
>>> from sympy.physics.mechanics import Body, PinJoint, ReferenceFrame
>>> parent, child, = Body('parent'), Body('child')
>>> int_frame = ReferenceFrame('int_frame')
>>> int_frame.orient_axis(child.frame, child.y, pi)
>>> pin = PinJoint('pin', parent, child, joint_axis=parent.z,
... child_interframe=int_frame)
>>> parent.dcm(child)
Matrix([
[-cos(q_pin(t)), -sin(q_pin(t)), 0],
[-sin(q_pin(t)), cos(q_pin(t)), 0],
[ 0, 0, -1]])
然而,如果你喜欢被弃用的参数为你对齐框架的事实,那么你仍然可以通过提供向量给 parent_interframe
和 child_interframe
来利用这个特性,这些向量随后会被定向,使得中间框架中表达的关节轴与给定的向量对齐:
>>> from sympy.physics.mechanics import Body, PinJoint
>>> parent, child = Body('parent'), Body('child')
>>> pin = PinJoint('pin', parent, child, parent_interframe=parent.z,
... child_interframe=-child.z)
>>> parent.dcm(child)
Matrix([
[-cos(q_pin(t)), -sin(q_pin(t)), 0],
[-sin(q_pin(t)), cos(q_pin(t)), 0],
[ 0, 0, -1]])
关节附着点参数的变化¶
在 sympy.physics.mechanics
中指定关节附着点的参数名称,即 parent_joint_pos
和 child_joint_pos
,已更改为 parent_point
和 child_point
。这是因为这些参数现在也可以是 Point
对象,因此它们可以与 parent_point
和 child_point
属性完全相同。
例如,假设你想在父对象中将 PinJoint
定位在相对于质心的 parent.frame.x
处,而在子对象中定位在 -child.frame.x
处。以前指定这种方式是:
>>> from sympy.physics.mechanics import Body, PinJoint
>>> parent, child = Body('parent'), Body('child')
>>> pin = PinJoint('pin', parent, child, parent_joint_pos=parent.frame.x,
... child_joint_pos=-child.frame.x)
>>> pin.parent_point.pos_from(parent.masscenter)
parent_frame.x
>>> pin.child_point.pos_from(child.masscenter)
- child_frame.x
现在你可以用同样的方式进行操作。
>>> from sympy.physics.mechanics import Body, PinJoint
>>> parent, child = Body('parent'), Body('child')
>>> pin = PinJoint('pin', parent, child, parent_point=parent.frame.x,
... child_point=-child.frame.x)
>>> pin.parent_point.pos_from(parent.masscenter)
parent_frame.x
>>> pin.child_point.pos_from(child.masscenter)
- child_frame.x
或
>>> from sympy.physics.mechanics import Body, PinJoint, Point
>>> parent, child = Body('parent'), Body('child')
>>> parent_point = parent.masscenter.locatenew('parent_point', parent.frame.x)
>>> child_point = child.masscenter.locatenew('child_point', -child.frame.x)
>>> pin = PinJoint('pin', parent, child, parent_point=parent_point,
... child_point=child_point)
>>> pin.parent_point.pos_from(parent.masscenter)
parent_frame.x
>>> pin.child_point.pos_from(child.masscenter)
- child_frame.x
版本 1.11¶
模块 sympy.tensor.array.expressions.conv_*
已重命名为 sympy.tensor.array.expressions.from_*
¶
为了避免与名称相似的模块名称可能导致的命名和制表符补全冲突,sympy.tensor.array.expressions
中所有名称以 conv_*
开头的模块已重命名为 from_*
。
新的 Mathematica 代码解析器¶
模块 sympy.parsing.mathematica
中定义的旧 mathematica 代码解析器 mathematica
已被弃用。应改用具有新且更全面解析器功能的 parse_mathematica
函数。
Mathematica 解析器的 additional_translations
参数在 parse_mathematica
中不可用。将 Mathematica 表达式转换为 SymPy 表达式的额外翻译规则应在转换后使用 SymPy 的 .replace( )
或 .subs( )
方法在输出表达式上指定。如果翻译器无法识别 Mathematica 表达式的逻辑意义,将返回类似于 Mathematica 完整形式的表达式,使用 SymPy 的 Function
对象来编码语法树的节点。
例如,假设你想让 F
成为一个函数,该函数返回最大值乘以最小值,之前指定这种转换的方式是:
>>> from sympy.parsing.mathematica import mathematica
>>> mathematica('F[7,5,3]', {'F[*x]': 'Max(*x)*Min(*x)'})
21
现在你可以用同样的方式来
>>> from sympy.parsing.mathematica import parse_mathematica
>>> from sympy import Function, Max, Min
>>> parse_mathematica("F[7,5,3]").replace(Function("F"), lambda *x: Max(*x)*Min(*x))
21
carmichael
中的冗余静态方法¶
~.carmichael
中的许多静态方法只是其他函数的包装器。不要使用 carmichael.is_perfect_square
,而是使用 sympy.ntheory.primetest.is_square
,不要使用 carmichael.is_prime
,而是使用 ~.isprime
。最后,carmichael.divides
可以用检查来替代。
n % p == 0
HadamardProduct
、MatAdd
和 MatMul
的 check
参数¶
此参数可用于向 ~.HadamardProduct
、~.MatAdd
和 ~.MatMul
传递不正确的值,从而导致后续问题。check
参数将被移除,参数将始终被检查以确保正确性,即参数是矩阵或矩阵符号。
版本 1.10¶
一些遍历函数已被移动¶
一些遍历函数已经移动。具体来说,这些函数
bottom_up
interactive_traversal
postorder_traversal
preorder_traversal
使用
已移动到不同的 SymPy 子模块。
这些函数应该从顶层的 sympy
命名空间中使用,例如
sympy.preorder_traversal
或
from sympy import preorder_traversal
通常,终端用户应使用顶级的 sympy
命名空间来访问其中的任何函数。如果一个名称位于顶层命名空间中,则不应依赖其特定的 SymPy 子模块,因为由于内部重构,函数可能会移动。
sympy.core.trace
¶
跟踪对象 sympy.core.trace.Tr()
被移动到 sympy.physics.quantum.trace.Tr()
。这是因为它仅在 sympy.physics.quantum
子模块中使用,因此将其放在那里比放在核心中更为合适。
sympy.core.compatibility
子模块¶
sympy.core.compatibility
子模块已被弃用。
这个子模块原本仅用于内部使用。既然 SymPy 不再支持 Python 2,这个模块就不再需要了,剩余的辅助函数已经被移动到 SymPy 代码库中更方便的地方。
本模块中的一些函数可以从 SymPy 的顶层命名空间中获得,即,
sympy.ordered
sympy.default_sort_key
或
from sympy import ordered, default_sort_key
通常,终端用户应使用顶级的 sympy
命名空间来访问其中的任何函数。如果一个名称位于顶层命名空间中,则不应依赖其特定的 SymPy 子模块,因为由于内部重构,函数可能会移动。
sympy.core.compatibility
中剩余的函数仅用于内部 SymPy 使用,不应被用户代码使用。
此外,这两个函数,ordered
和 default_sort_key
,也曾经在 sympy.utilities.iterables
中,但它们也已经被移走了。
版本 1.9¶
expr_free_symbols
¶
各种 SymPy 对象的 expr_free_symbols
属性已被弃用。
expr_free_symbols
旨在表示诸如 MatrixElement
和 Indexed
之类的索引对象为自由符号。这是为了让自由符号的导数能够工作。然而,现在不需要使用该方法也能实现这一点:
>>> from sympy import Indexed, MatrixSymbol, diff
>>> a = Indexed("A", 0)
>>> diff(a**2, a)
2*A[0]
>>> X = MatrixSymbol("X", 3, 3)
>>> diff(X[0, 0]**2, X[0, 0])
2*X[0, 0]
这是一个为了解决一个非常具体的问题而添加的通用属性,但它增加了一层在一般情况下不必要的抽象层。
已经具有结构“非表达”节点的对象,如果需要,允许用户专注于表达节点,例如。
>>> from sympy import Derivative, symbols, Function >>> x = symbols('x') >>> f = Function('f') >>> Derivative(f(x), x).expr f(x)
此属性的引入在请求 free_symbols 时鼓励了不精确的思考,因为它允许从对象的特定节点获取符号,而无需指定节点。
该属性被错误地添加到
AtomicExpr
中,因此数字作为expr_free_symbols
返回:>>> S(2).expr_free_symbols 2
该概念的应用被错误地用于定义
Subs.expr_free_symbols
:它在expr_free_symbols
中添加了点的内容,但该点是一个Tuple
,因此实际上没有添加任何内容。它在代码库中没有在其他地方使用,除了在区分
Subs
对象的上下文中,这表明它不是通用用途的东西,这一点也通过以下事实得到证实,除了为引入的 Subs 对象的导数进行的测试外,没有添加具体的测试。
更多讨论请参见问题 #21494。
sympy.stats.sample(numsamples=n)
¶
numsamples
参数在 sympy.stats.sample()
中已被弃用。
numsamples
使 sample()
返回一个大小为 numsamples
的列表,例如
>>> from sympy.stats import Die, sample
>>> X = Die('X', 6)
>>> sample(X, numsamples=3)
[3, 2, 3]
然而,用户可以通过列表推导轻松实现此功能
>>> [sample(X) for i in range(3)]
[5, 4, 3]
此外,它与 size
参数冗余,该参数使得 sample
返回具有给定形状的 NumPy 数组。
>>> sample(X, size=(3,))
array([6, 6, 1])
历史上,sample
在 SymPy 1.7 中被修改,使其返回一个迭代器而不是样本值。由于返回的是迭代器,因此添加了一个 numsamples 参数来指定迭代器的长度。
然而,如在问题 #21563 中讨论的那样,这种新行为被认为令人困惑,因此被恢复了。现在,如果需要迭代器,应使用 sample_iter
。因此,sample()
不再需要 numsamples
参数。
sympy.polys.solvers.RawMatrix
¶
RawMatrix
类已被弃用。RawMatrix
类是 Matrix
的子类,它使用域元素而不是 Expr
作为矩阵的元素。这打破了 Matrix
的一个关键内部不变性,并且这种子类化限制了对 Matrix
类的改进。
SymPy 中唯一记录了 RawMatrix
类使用的是 Smith 标准形式代码,但现在已改为使用 DomainMatrix
。建议任何使用 RawMatrix
与之前的 Smith 标准形式代码的人应切换到使用 DomainMatrix
,如问题 #21402 所示。稍后将添加更好的 Smith 标准形式 API。
矩阵中的非Expr
对象¶
在 SymPy 1.8 及更早版本中,可以将非Expr
元素放入Matrix
中,矩阵元素可以是任何任意的Python对象:
>>> M = Matrix([[(1, 2), {}]])
这没有用,实际上不起作用,例如:
>>> M + M
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'Dict' and 'Dict'
实现这一功能的主要原因是,SymPy 代码库中有许多 Matrix
子类希望与 polys 模块中的对象一起工作,例如。
RawMatrix
(见 上文) 在solve_lin_sys
中使用,该函数是heurisch
的一部分,也被smith_normal_form
使用。NewMatrix
类使用域元素作为矩阵的元素,而不是Expr
。NewMatrix
在holonomic
模块中使用,并且也使用域元素作为矩阵元素PolyMatrix
使用了Poly
和Expr
的混合作为矩阵元素,并被risch
使用。
所有这些矩阵子类在不同方面都存在问题,而引入 DomainMatrix
(#20780, #20759, #20621, #19882, #18844) 为所有情况提供了更好的解决方案。之前的PR已经移除了这些其他用例对Matrix的依赖 (#21441, #21427, #21402),现在 #21496 已经弃用了在 Matrix
中使用非 Expr
的情况。
这一更改使得改进 Matrix 类的内部成为可能,但它可能影响一些下游用例,这些用例可能类似于 SymPy 代码库中使用非 Expr
元素的 Matrix
。如果代码使用了非 Expr
元素的 Matrix
,一个潜在的替代方案是 DomainMatrix
,前提是元素类似于域元素并且可以为它们提供一个域对象。或者,如果目标只是打印支持,那么可以使用 TableForm
。
在不了解具体使用场景的情况下,不清楚应该建议什么作为替代方案。如果你不确定如何更新你的代码,请 提交一个issue 或 写信到我们的邮件列表 以便我们讨论。
绘图对象的 get_segments
属性¶
在 Line2DBaseSeries
中实现的 get_segments
方法用于将两个坐标列表 x
和 y
转换为由 Matplotlib 的 LineCollection
用于绘制线条的线段列表。
由于段落列表仅由 Matplotlib 需要(例如,Bokeh、Plotly、Mayavi、K3D 仅需要坐标列表),因此这已被移至 MatplotlibBackend
类内部。
请注意,以前,方法 get_points()
总是返回均匀采样的点,这意味着在使用 get_points()
与 Matplotlib 绘图时,某些函数未能正确绘制。
为了避免这个问题,可以使用 get_segments()
方法,该方法使用了自适应采样,并且可以与 Matplotlib 的 LineCollection
一起使用。然而,这已经被更改,现在 get_points()
也可以使用自适应采样。get_data()
方法也可以使用。
sympy.physics.matrices
中的 mdft
函数¶
sympy.physics.matrices.mdft()
函数已被弃用。可以用 sympy.matrices.expressions.fourier
中的 DFT
类来替代。
特别是,将 mdft(n)
替换为 DFT(n).as_explicit()
。例如:
>>> from sympy.physics.matrices import mdft
>>> mdft(3) # DEPRECATED
Matrix([
[sqrt(3)/3, sqrt(3)/3, sqrt(3)/3],
[sqrt(3)/3, sqrt(3)*exp(-2*I*pi/3)/3, sqrt(3)*exp(2*I*pi/3)/3],
[sqrt(3)/3, sqrt(3)*exp(2*I*pi/3)/3, sqrt(3)*exp(-2*I*pi/3)/3]])
>>> from sympy.matrices.expressions.fourier import DFT
>>> DFT(3)
DFT(3)
>>> DFT(3).as_explicit()
Matrix([
[sqrt(3)/3, sqrt(3)/3, sqrt(3)/3],
[sqrt(3)/3, sqrt(3)*exp(-2*I*pi/3)/3, sqrt(3)*exp(2*I*pi/3)/3],
[sqrt(3)/3, sqrt(3)*exp(2*I*pi/3)/3, sqrt(3)*exp(-2*I*pi/3)/3]])
这一更改是因为 sympy.physics
子模块应该只包含与物理相关的内容,但离散傅里叶变换矩阵是一个更普遍的数学概念,因此它更适合位于 sympy.matrices
模块中。此外,DFT
类是一个 矩阵表达式,这意味着它可以保持未求值状态并支持符号形状。
私有属性 SparseMatrix._smat
和 DenseMatrix._mat
¶
._mat
属性在 Matrix
和 ._smat
属性在 SparseMatrix
中已被弃用。
Matrix
和 SparseMatrix
的内部表示在 #21626 中被更改为 DomainMatrix
,因此不再可能通过暴露可变列表/字典来改变 Matrix
。新的 .flat()
方法可以代替 ._mat
使用,该方法返回一个新列表,不能用于改变 Matrix
本身。新的 .todok()
方法可以代替 ._smat
使用,该方法返回一个新字典。
请注意,这些属性在 SymPy 1.9 中已经改为返回只读副本,因此任何依赖于修改它们的代码都将被破坏。此外,这些属性在技术上始终是私有的(它们以一个下划线开头),因此用户代码从一开始就不应该使用它们。
矩阵的拉普拉斯变换,noconds=False¶
在1.9版本之前,对一个 Matrix
调用 laplace_transform()
并设置 noconds=False
(这是默认设置),结果会是一个元组矩阵:
>>> from sympy import laplace_transform, symbols, eye
>>> t, z = symbols('t z')
>>> laplace_transform(eye(2), t, z)
Matrix([
[(1/z, 0, True), (0, 0, True)],
[ (0, 0, True), (1/z, 0, True)]])
然而,Matrix
仅设计用于与 Expr
对象一起工作(参见上面的 矩阵中的非Expr对象)。
为了避免这种情况,可以使用 noconds=True
来移除收敛条件
>>> laplace_transform(eye(2), t, z, noconds=True)
Matrix([
[1/z, 0],
[ 0, 1/z]])
或者使用 legacy_matrix=False
来返回新的行为,这将返回一个包含矩阵的单个元组,第一个参数是矩阵,收敛条件将合并为一个整体矩阵的单一条件。
>>> laplace_transform(eye(2), t, z, legacy_matrix=False)
(Matrix([
[1/z, 0],
[ 0, 1/z]]), 0, True)
当此弃用被移除时,legacy_matrix=False
的行为将成为默认行为,但该标志将保持不变以确保兼容性。
版本 1.8¶
sympy.printing.theanocode
¶
Theano 已经停止维护,并被分叉成一个名为 Aesara 的新项目。sympy.printing.theanocode
模块已被重命名为 sympy.printing.aesaracode
,并且所有相应的函数也已被重命名(例如,theano_code
已被重命名为 aesara_code()
,TheanoPrinter
已被重命名为 AesaraPrinter
,等等)。
版本 1.7.1¶
调用 sympy.stats.StochasticProcess.distribution
时使用 RandomIndexedSymbol
¶
sympy.stats
的 distribution
方法 随机过程 过去接受一个 RandomIndexedSymbol
(即,一个用时间戳索引的随机过程),但现在应该只用时间戳调用。
例如,如果你有
>>> from sympy import symbols
>>> from sympy.stats import WienerProcess
>>> W = WienerProcess('W')
>>> t = symbols('t', positive=True)
之前这会起作用
W.distribution(W(t)) # DEPRECATED
现在应该这样调用:
>>> W.distribution(t)
NormalDistribution(0, sqrt(t))
此更改是作为将 Basic
对象仅存储在 sympy.stats
.args
中的更改的一部分进行的。详情请参见问题 #20078。
版本 1.7¶
sympy.stats.DiscreteMarkovChain.absorbing_probabilites()
¶
absorbing_probabilites
方法名拼写错误。应使用正确的拼写 absorbing_probabilities()
(“absorbing probabilities”)。
sympy.utilities.misc.find_executable()
¶
函数 sympy.utilities.misc.find_executable()
已被弃用。请改用标准库中的 shutil.which()
函数,该函数自 Python 3.3 起就存在于标准库中,并且功能更为强大。
sympy.diffgeom
中的可变属性¶
已对 sympy.diffgeom
的几个部分进行了更新,使其不再可变,这更好地匹配了 SymPy 其余部分使用的不可变设计。
在
CoordSystem
中传递符号名称的字符串已被弃用。相反,你应该明确地传递带有适当假设的符号,例如,而不是CoordSystem(name, patch, ['x', 'y']) # DEPRECATED
使用
CoordSystem(name, patch, symbols('x y', real=True))
同样地,
names
关键字参数已重命名为symbols
,这应该是一个符号列表。Manifold.patches
属性已被弃用。补丁应单独跟踪。Patch.coord_systems
属性已弃用。坐标系应单独跟踪。CoordSystem.transforms
属性、CoordSystem.connect_to()
方法和CoordSystem.coord_tuple_transform_to()
方法已被弃用。请改用CoordSystem
类构造函数的relations
关键字以及CoordSystem.transformation()
和CoordSystem.transform()
方法(参见CoordSystem
的文档字符串以获取示例)。
unicode
参数和属性用于 sympy.printing.pretty.stringpict.prettyForm
和 sympy.printing.pretty.pretty_symbology.xstr
函数¶
sympy.printing.pretty.pretty_symbology.xstr
函数,以及 sympy.printing.pretty.stringpict.prettyForm
的 unicode
参数和属性,都是为了支持 Python 2 的 Unicode 行为。由于 Unicode 字符串在 Python 3 中是默认的,因此这些不再需要。xstr()
应替换为 str()
,prettyForm
的 unicode
参数应省略,prettyForm.unicode
属性应替换为 prettyForm.s
属性。
将参数传递给 lambdify
作为 集合
¶
将函数参数作为集合传递给 lambdify 已被弃用。相反,请将它们作为列表或元组传递。例如,不要像这样
lambdify({x, y}, x + 2*y) # WRONG
使用
lambdify((x, y), x + 2*y) # RIGHT
这是因为集合是无序的。例如,在上面的例子中,lambidfy
无法知道它是用 {x, y}
还是 {y, x}
调用的。因此,当将参数作为集合传递时,lambdify
必须猜测它们的顺序,如果猜测错误,这将导致函数不正确。
核心操作符不再接受非 Expr 参数¶
核心操作符类 Add
、Mul
和 Pow
不能再直接使用不是 Expr
子类的对象来构造。
Expr
是所有表示标量数值量的 SymPy 类的超类。例如,sin
、Symbol
和 Add
都是 Expr
的子类。然而,SymPy 中的许多对象并不是 Expr
,因为它们表示其他类型的数学对象。例如,Set
、Poly
和 Boolean
都不是 Expr
。这些对象在 Add
、Mul
和 Pow
中没有数学意义,因为这些类专门设计用于表示标量复数的加法、乘法和幂运算。
手动使用这样一个对象构造这些类是可能的,但它通常会创建一些随后会出错的东西。例如
Mul(1, Tuple(2)) # This is deprecated
工作并创建 Tuple(2)
,但这只是因为 Mul
被“欺骗”了,总是将 \(1 \cdot x = x\) 处理为 \(x\)。如果你尝试
Mul(2, Tuple(2)) # This is deprecated
它因异常而失败
AttributeError: 'Tuple' object has no attribute 'as_coeff_Mul'
因为它试图在 Tuple
对象上调用 Expr
的方法,而 Tuple
对象并没有 Expr
的所有方法(因为它不是 Expr
的子类)。
如果你想对非 Expr
对象使用 +
、*
或 **
操作,请直接使用操作符,而不是使用 Mul
、Add
或 Pow
。如果需要这些操作的功能版本,你可以使用 lambda
或 operator
模块。
版本 1.6¶
各种 sympy.utilities
子模块已移动¶
以下子模块已被重命名。
sympy.utilities.benchmarking
→sympy.testing.benchmarking
sympy.utilities.pytest
→sympy.testing.pytest
sympy.utilities.randtests
→sympy.core.random
sympy.utilities.runtests
→sympy.testing.runtests
sympy.utilities.tmpfiles
→sympy.testing.tmpfiles
sympy.testing.randtest
¶
sympy.testing.randtest
已被弃用。其中的函数已移至 sympy.core.random
。以下函数已被移动。
sympy.testing.randtest.random_complex_number
→sympy.core.random.random_complex_number
sympy.testing.randtest.verify_numerically
sympy.core.random.verify_numerically
sympy.testing.randtest.test_derivative_numerically
→sympy.core.random.test_derivative_numerically
sympy.testing.randtest._randrange
→sympy.core.random._randrange
sympy.testing.randtest._randint
→sympy.core.random._randint
在二元操作中混合 Poly
和非多项式表达式¶
在SymPy的早期版本中,Poly
是 Expr
的子类,但现在已经改为仅是 Basic
的子类。这意味着一些曾经与 Poly
一起使用的东西现在已被弃用,因为它们仅设计用于与 Expr
对象一起工作。
这包括将 Poly
与 Expr
对象使用二元操作进行组合,例如
Poly(x)*sin(x) # DEPRECATED
为此,可以根据你希望结果的类型,使用 Expr.as_poly()
将非 Poly
操作数显式转换为 Poly
,或者使用 Poly.as_expr()
将 Poly
操作数转换为 Expr
。
sympy.combinatorics.Permutation
的 print_cyclic
标志¶
sympy.combintorics.Permutation
的 print_cyclic
属性控制置换是以循环还是数组的形式打印。这可以通过设置 Permutation.print_cyclic = True
或 Permutation.print_cyclic = False
来实现。然而,这种控制打印的方法是糟糕的,因为它是一个全局标志,但打印不应该依赖于全局行为。
相反,用户应使用相应打印机的 perm_cyclic
标志。配置此标志的最简单方法是调用 init_printing()
时设置该标志,例如
>>> from sympy import init_printing
>>> init_printing(perm_cyclic=False) # Makes Permutation print in array form
>>> from sympy.combinatorics import Permutation
>>> Permutation(1, 2)(3, 4)
⎛0 1 2 3 4⎞
⎝0 2 1 4 3⎠
Permutation
文档字符串中包含有关 perm_cyclic
标志的更多详细信息。
使用 integrate
与 Poly
¶
在SymPy的早期版本中,Poly
是 Expr
的子类,但现在已经改为仅是 Basic
的子类。这意味着一些曾经与 Poly
一起使用的东西现在已被弃用,因为它们仅设计用于与 Expr
对象一起工作。
这包括使用 Poly
调用 integrate()
或 Integral
。
要集成一个 Poly
,使用 Poly.integrate()
方法。要计算积分作为一个 Expr
对象,首先调用 Poly.as_expr()
方法。
另请参见上文的 在二元操作中混合 Poly 和非多项式表达式。
使用 Eq
参数创建一个不定 积分
¶
传递一个Eq()
对象给integrate()
在不定积分的情况下已被弃用。这是因为如果\(f(x) = g(x)\),那么\(\int f(x)\,dx = \int g(x)\,dx\)通常不成立,这是由于任意常数(integrate
不包含这些常数)的存在。
如果你想表示不定积分的等式,请明确使用 Eq(integrate(f(x), x), integrate(g(x), x))
。
如果你已经有一个等式对象 eq
,你可以使用 Eq(integrate(eq.lhs, x), integrate(eq.rhs, x))
。
版本 1.5¶
Tensor.fun_eval
和 Tensor.__call__
¶
TensExpr.fun_eval
和 Tensor.__call__
(即调用张量来评估它)已被弃用。应使用 Tensor.substitute_indices()
方法。这一更改是因为 fun_eval
被认为是一个令人困惑的名称,并且使用函数评估被认为既令人困惑又危险。
TensorType
¶
TensorType
类已被弃用。请改用 tensor_heads()
。TensorType
类除了用于更简短地创建 TensorHead
对象外,没有其他用途。
另请参见下面的 tensorhead() 函数。
TensorIndexType
的 dummy_fmt
参数¶
dummy_fmt
关键字参数在 TensorIndexType
中已被弃用。设置 dummy_fmt='L'
会导致 _dummy_fmt='L_%d'
,这既令人困惑又使用了过时的字符串格式化。应改用 dummy_name
。这一更改是因为 dummy_name
是一个更清晰的名字。
TensorIndexType
的 metric
参数¶
metric
关键字参数在 TensorIndexType
中已被弃用。名称 “metric” 具有歧义,因为在某些地方它意味着 “度量对称性”,而在其他地方则意味着 “度量张量”。
应该使用 metric_symmetry
关键字或 TensorIndexType.set_metric()
方法。
TensorIndexType
的 get_kronecker_delta()
和 get_epsilon()
方法¶
get_kronecker_delta()
和 get_epsilon()
方法是 TensorIndexType
中已弃用的方法。请分别使用 TensorIndexType.delta
和 TensorIndexType.epsilon
属性代替。
tensorsymmetry()
函数¶
sympy.tensor
中的 tensorsymmetry()
函数已被弃用。请改用 TensorSymmetry
类构造函数。
TensorSymmetry
比 tensorsymmetry()
更受欢迎,因为后者
没有任何额外功能
涉及模糊的杨表
不是
TensorSymmetry
类的成员
tensorhead()
函数¶
tensorhead()
函数已被弃用,取而代之的是 tensor_heads()
。tensor_heads()
与其他 SymPy 名称(如 Symbol
和 symbols()
或 TensorIndex
和 tensor_indices()
)更加一致。它也不使用杨氏表来表示对称性。
集合的 is_EmptySet
属性¶
is_EmptySet
属性在 Set 对象中已被弃用。请改用
from sympy import S
s is S.EmptySet
或
s.is_empty
区别在于,如果无法确定集合是否为空,s.is_empty
可能会返回 None
。
ProductSet(iterable)
¶
将单个可迭代对象作为第一个参数传递给 ProductSet
已被弃用。从可迭代对象创建产品集应使用 ProductSet(*iterable)
,或作为每个单独的参数。例如
>>> from sympy import ProductSet
>>> sets = [{i} for i in range(3)]
>>> ProductSet(*sets)
ProductSet({0}, {1}, {2})
>>> ProductSet({1, 2}, {1})
ProductSet({1, 2}, {1})
这样做是因为集合本身可以是可迭代的,并且允许集合的集合。但从数学上讲,单个集合的乘积集应该是该集合本身(或者更准确地说,是该集合元素的1元组集合)。自动解嵌套单个可迭代对象使得无法表示此对象,并且在传递1个参数时使得 ProductSet
无法正确泛化。另一方面,如果第一个参数是集合而不是其他类型的可迭代对象(这是在已弃用的代码路径中当前所做的),则会导致混乱的行为。
sympy.physics.mechanics
中的 set_potential_energy
方法¶
set_potential_energy()
方法是 sympy.physics.mechanics.particle.Particle
和 sympy.physics.mechanics.rigidbody.RigidBody
中已弃用的方法。
相反,应该设置 Particle.potential_energy
和 RigidBody.potential_energy
属性来设置势能,例如
P.potential_energy = scalar
这一更改是为了更加符合 Python 风格,通过使用 @property
方法的设置器和获取器,而不是显式的 set_
方法。
在 ConditionSet
中使用集合作为条件¶
在 ConditionSet 中使用集合作为条件已被弃用。应改用布尔值。这是因为条件在数学上是一个布尔值,而在此上下文中集合的含义是不明确的。
要修复这个弃用警告,请替换
ConditionSet(symbol, set_condition)
与
ConditionSet(symbol, And(*[Eq(lhs, 0) for lhs in set_condition]))
例如,
ConditionSet((x, y), {x + 1, x + y}, S.Reals) # DEPRECATED
将会变成
ConditionSet((x, y), Eq(x + 1, 0) & Eq(x + y, 0), S.Reals)
sympy.polys.multivariate_resultants.DixonResultant
的 max_degree
和 get_upper_degree
属性¶
DixonResultant
的 max_degree
属性和 get_upper_degree()
方法已被弃用。详情请参见问题 #17749。
Lambda
的第一个参数为非元组的可迭代对象¶
使用非元组作为 Lambda
的第一个参数已被弃用。如果你有一个非元组,请先将其转换为元组,例如 Lambda(tuple(args), expr)
。
这样做是为了让 Lambda
能够支持一般的元组解包,例如
>>> from sympy import Lambda, symbols
>>> x, y, z = symbols('x y z')
>>> f = Lambda((x, (y, z)), x + y + z)
>>> f(1, (2, 3))
6
evaluate
标志用于 differentiate_finite
¶
对 differentiate_finite()
的 evaluate
标志已被弃用。
differentiate_finite(expr, x, evaluate=True)
在计算差分之前展开中间导数。但这通常不是你想要的,因为它不满足乘积法则。
如果你确实想要这种行为,你可以通过以下方式模拟它:
diff(expr, x).replace(
lambda arg: arg.is_Derivative,
lambda arg: arg.as_finite_difference())
参见关于问题 #17881 的讨论。