符号运算系统最有用的一项特性就是数学表达式的化简。SymPy中有许多能够进行不同类型表达式化简的函数。其中,有一个通用的函数名为simplify,它能够试图以一种智能的方式应用这些化简函数,并最终得到表达式的最简形式。

下面给出一个simplify的例子:

>>> simplify(sin(x)**2 + cos(x)**2)
>>> simplify((x**3 + x**2 - x - 1)/(x**2 + 2*x + 1))
x - 1
>>> simplify(gamma(x)/gamma(x - 2))
(x - 2)*(x - 1)

simplify有一个缺陷,由于表达式“最简化”并没有一个良好的定义,SymPy只能使用库中已有的化简操作,使用启发式方法来决定其认为的“最简化”结果。

举例来说,对于表达式x^2+2x+1,使用simplify函数并不能化简成(x+1)^2

simplify的另外一个缺陷是,由于它要尝试使用不同的化简方法,并选择最佳的那个,这个过程要花费一些时间。如果你事先已经你确定要进行那一种化简,那么直接调用特定的化简函数,这是更佳的方法,能节省一些时间。指定化简函数,而不使用通用的simplify函数还有一个好处,就是可以保证输出的形式。例如,对于`factor`函数,如果施加到有理系数多项式上,那么得到的结果一定是最简因式。而simplify没有这种保证,因为它是完全启发式的,有时会错过可能的化简类型。

何时使用simplify比较好?当你在交互式的环境里,调用simplify函数,想看看它能把表达式化简到什么程度,然后你再选择几个特定的化简函数,看看是否还能再进一步简化。

展开表达式

表达式展开是SymPy中最常用的化简操作,对应的函数为expand。 很多数学理论都有展开的概念,我们在这里特指对多项式的展开。

>>> expand((x + 1)**2)
x**2 + 2*x + 1
>>> expand((x + 2)*(x - 3))
x**2 - x - 6

它能为我们完成两件事:展开,合并同类项。

因式化对应的函数是factor,它能够将一个多项式约成几个最简整式的积的形式,也就是因式分解。

>>> factor(x**3 - x**2 + x - 1)
(x - 1)*(x**2 + 1)
>>> factor(x**2*z + 4*x*y*z + 4*y**2*z)
z*(x + 2*y)**2

factor函数的实现采用了一种完整的有理数多变量因式分解算法,能够保证因式为最简。
使用factor_list函数,能够将因式分解后得到的因式作为一个列表(List)返回。例如:

>>> factor_list(x**2*z + 4*x*y*z + 4*y**2*z)
(1, [(z, 1), (x + 2*y, 2)])

合并同类项

合并同类项对应的函数为collect,能将多项式中同类项合成一项。
例如:

>>> expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3
x**3 - x**2*z + 2*x**2 + x*y + x - 3
>>> collected_expr = collect(expr, x)
>>> collected_expr
x**3 + x**2*(-z + 2) + x*(y + 1) - 3

分式化简函数的名称是 cancel ,它能化简任何分式函数,并能将其约到最简形式。

下面给出几个例子:

>>> cancel((x**2 + 2*x + 1)/(x**2 + x))
(x + 1)/x
>>> expr = 1/x + (3*x/2 - 2)/(x - 4)
(3*x/2 - 2)/(x - 4) + 1/x
>>> cancel(expr)
(3*x**2 - 2*x - 8)/(2*x**2 - 8*x)
>>> expr = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1)
(x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1)
>>> cancel(expr)
(y**2 - 2*y*z + z**2)/(x - 1)

分式裂项函数的名称是apart,它能将一个分式分解为几个分式的和、差。且分解出来的分式,都是最简形式。
例如:

>>> expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)
(4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)
>>> apart(expr)
(2*x - 1)/(x**2 + x + 1) - 1/(x + 4) + 3/x

由三角函数组成的表达式,可以使用trigsimp函数来化简。
下面给出三个例子:

>>> trigsimp(sin(x)**2 + cos(x)**2)
>>> trigsimp(sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4)
cos(4*x)/2 + 1/2
>>> trigsimp(sin(x)*tan(x)/sec(x))
sin(x)**2

trigsimp函数也能够化简双曲三角函数:

>>> trigsimp(cosh(x)**2 + sinh(x)**2)
cosh(2*x)
>>> trigsimp(sinh(x)/tanh(x))
cosh(x)

与simplify相似的是,trigsimp对输入的表达式应用多种三角变换公式,使用启发式的方法来返回“最好”的那一个。

要展开三角函数,可以使用 expand_trig 函数,它能够使用三角恒等式,将三角表达式展开。

>>> expand_trig(sin(x + y)) 
sin(x)*cos(y) + sin(y)*cos(x)
>>> expand_trig(tan(2*x)) 
2*tan(x)/(-tan(x)**2 + 1) 

若表达式中存在指数可以化解的情况,可以使用powsimp函数。 指数化简包含合并指数和合并基底两种情况。

>>> powsimp(x**a*x**b) 
x**(a + b) 
>>> powsimp(x**a*y**a) 
(x*y)**a 

注意,对于示例中的第二条语句(合并基底),要满足一定的条件才能够进行。首先,x,y需为正,且a需为实数。因此,我们在创建symbols的时候,必须指定:

x, y = symbols('x y', positive=True)
a, b = symbols('a b', real=True) 

这样,示例中的语句二才能进行合并基底,否则,将显示原表达式,不做任何处理。

与上一节的指数化简相对的,是指数展开,同样地,指数展开包含两个部分,指数展开与基底展开。
其中,指数展开对应的函数为expand_power_exp,基底展开对应的函数为expand_power_base。

>>> expand_power_exp(x**(a + b)) 
x**a*x**b 
>>> expand_power_base((x*y)**a) 
x**a*y**a 

对于语句二,symbols要与上一节中的基底合并满足同样的条件,才能得正确得到结果。

化简指数的指数

对于表达式(x**a)**b,含有两层指数,通过使用powdenest函数,能将其简化为一层的结构。

首先,这种化简需要满足下列的条件,才能正确进行:

x = symbols('x', positive=True)

也就是基底x要大于0。

>>> powdenest((x**a)**b) 
x**(a*b)

首先要说明一点,在数学中,log和ln是不同的概念,而在SymPy中,两个是等同的,都指自然对数。
对数成立需要满足一定条件,我们与要定义满足条件的变量:

x, y = symbols('x y', positive=True)
n = symbols('n', real=True) 

指数展开函数为expand_log,能够套用指数展开公式来完成展开操作。

>>> expand_log(log(x*y)) 
log(x) + log(y) 
>>> expand_log(log(x/y)) 
log(x) – log(y) 
>>> expand_log(log(x**2)) 
2*log(x) 
>>> expand_log(log(x**n)) 
n*log(x) 

与对数展开相对应地,是对数合并操作,函数名称为logcombine。
变量需要满足与上一节中同样的条件。

>>> logcombine(log(x) + log(y)) 
log(x*y) 
>>> logcombine(n*log(x)) 
log(x**n)
符号运算系统最有用的一项特性就是数学表达式的化简。SymPy中有许多能够进行不同类型表达式化简的函数。其中,有一个通用的函数名为simplify,它能够试图以一种智能的方式应用这些化简函数,并最终得到表达式的最简形式。下面给出一个simplify的例子:>>> simplify(sin(x)**2 + cos(x)**2)1>>> simplify... 所有 SymPy 浮点数都成为可训练的参数。 所有 SymPy 符号都是模块的输入。 pip install git+https://github.com/patrick-kidger/ sympy torch.git import sympy , torch , sympy torch x = sympy . symbols ( 'x_name' ) cosx = 1.0 * sympy . cos ( x ) sinx = 2.0 * sympy . sin ( x ) mod = sympy torch . SymPy Module ( expressions = [ cosx , sinx ]) x_ = torch . rand ( 3 ) out = mod ( x_name = x_ ) # out has 所有 SymPy 浮点数都将成为可训练的输入参数。 SymPy 符号成为传递矩阵的列。 pip install git+https://github.com/MilesCranmer/ sympy 2jax.git import sympy from sympy import symbols import jax import jax . numpy as jnp from jax import random from sympy 2jax import sympy 2jax 让我们在 SymPy 中创建一个 表达式 : x , y = symbols ( 'x y' ) expression = 1.0 * sympy . cos ( x ) + 3.2 * y 让我们获取JAX版本。 我们传递方程式和所 SymPad 是一个简单的单脚本图形 符号计算 器/便笺簿, 使用 SymPy 进行 数学运算, 使用 MathJax 在浏览器中显示, 使用 matplotlib 进行 绘图。 用户输入旨在快速、简单和直观,并在输入时以符号形式显示。 Sympad 将接受 Python 表达式 、LaTeX 格式、unicode 数学符号和用于快速输入的本机速记,或所有这些的混合。 输入将以符号或数字方式评估,结果以 Python 或 LaTeX 格式复制/粘贴,因此它也充当翻译器。 以下是 SymPad 的有效输入示例: cos -pi N cos**-1 -\log_2 sqrt[4] 16 \lim_{x\to\infty} 1/x \sum_{n=0}**oo x^n / n! d**6 / dx dy**2 dz**3 x^3 y^3 z^3 \int_0^\pi \int_0^{2pi} \i 在 GPU 上计算 表达式 的简单方法 后端不可知性评估(当前支持numpy和cupy,将来可能会添加clpy或其他数字后端) 支持处理 表达式 组的工具(评估、绘图、替换参数、共享变​​量) 数值方法(现在在 n 维域上集成) Numpy/Scipy 评估与 Sympy 一起开箱即用, 使用 lambdify 功能。 为了在 GPU 上做同样的事情,SEEING 的第一个开发工作只依赖于 Cupy,因此你需要有一个支持 CUDA 的 GPU 才能 使用 它。
simplify()可以对数学 表达式 进行 化简 ,调用 sympy 内部的多种 表达式 变换函数来对其 化简 1.radsimp() radsimp()对 表达式 的分母 进行 有理化,结果中的分母部分不含无理数. 也可以以对带符号的 表达式 进行 处理 2.ratsimp() ratsimp()对 表达式 中的分母 进行 通分运算,即将 表达式 转换为分子除分母的形式 3.fraction() fraction()返回...
可以 使用 Python 中的数学库,例如numpy或 sympy ,来表达数学 表达式 。例如,可以 使用 sympy 库中的symbols函数来定义变量,然后 使用 sympy 中的其他函数来创建 表达式 。例如,以下代码可以创建一个简单的数学 表达式 : import sympy x = sympy .symbols('x') expr = x**2 + 2*x + 1 这将创建一个 表达式 x^2 + 2x + 1,其中x是一个符号变量。可以 使用 sympy 中的其他函数来操作和评估这个 表达式