我怎样才能说服 Sympy 对 1961 年麻省理工学院本科生微积分问题进行相同的简化?
How can I convince Sympy to come to the same simplification SAINT does for the 1961 MIT undergrad calculus problem?
James R Slagle麻省理工学院论文A heuristic program that solves symbolic integration problems in freshman calculus, symbolic automatic integrator (SAINT) 因成为第一个实用的“专家系统”符号积分器而出名,并且能够解决麻省理工学院本科生微积分测试中的所有问题(迂腐地,有几个问题被遗漏了,但它本可以解决它们;详细信息在这里in this excellent YouTube video)
他的论文可在此处免费获得:https://dspace.mit.edu/handle/1721.1/11997
我很高兴尝试使用 Sympy,因为它看起来平易近人,而且是一个相当困难的简化我碰巧已经有了答案..然而,Sympy 并没有将积分简化到如此好的(主观?)简化为 1961 年计划(尽管它确实 return 等效结果!)
疑问与猜测
如何说服 Sympy 简化为相同的方程式?
为什么它没有得出相同的、看似更简单的结果?
也许它选择了第一个可能的结果,或者tan**3
被确定为更糟?如果是这样,为什么它不简化 SAINT 的输出?)
也许当它找到一些匹配项时,它会沿着不同的分支出发 ?
试题3c
Sympy 简化
from sympy import *
x = symbols("x", real=True) # should this be assumed?
expr_inner = (x**4) / ((1 - x**2)**Rational(5,2))
expr_integral = integrate((expr_inner), x)
print(simplify(expr_integral))
(x**4*asin(x) + 4*x**3*sqrt(1 - x**2)/3 - 2*x**2*asin(x) - x*sqrt(1 - x**2) + asin(x))/(x**4 - 2*x**2 + 1)
平等证明
from sympy import *
x = symbols("x", real=True) # should this be assumed?
expr_saint = asin(x) + Rational(1,3)*tan(asin(x))**3 - tan(asin(x))
expr_sympy = (x**4*asin(x) + 4*x**3*sqrt(1 - x**2)/3 - 2*x**2*asin(x) - x*sqrt(1 - x**2) + asin(x))/(x**4 - 2*x**2 + 1)
expr_saint.equals(expr_sympy) # alternatively simplify(expr_saint - expr_sympy)
True
方程式显示
主要部分是分解 asin(x)
并将其从分数中分离出来。之后,sympy 可以证明两个表达式相等:
from sympy import *
from IPython.display import Math, display
x = symbols("x", real=True) # should this be assumed?
expr_saint = asin(x) + Rational(1,3)*tan(asin(x))**3 - tan(asin(x))
expr_sympy = (x**4*asin(x) + 4*x**3*sqrt(1 - x**2)/3 - 2*x**2*asin(x) - x*sqrt(1 - x**2) + asin(x))/(x**4 - 2*x**2 + 1)
r=[]
r.append(latex(expr_sympy))
expr_sympy = expr_sympy.collect(asin(x))
r.append(latex(expr_sympy))
expr_sympy = apart(expr_sympy,asin(x))
r.append(latex(expr_sympy))
display(Math(" \Longrightarrow ".join(r)))
display(simplify(expr_saint - expr_sympy))
输出:
@wsdookadr 给了我缺少的简化步骤;显示 apart()
可以很容易地自己得到 asin(x)
(这显然是一个公因数),因此创建一个非常相似但比 SAINT 输出更简化的形式。
沿着这些思路思考更多,SAINT 输出并没有尽可能地简化,因此在比较之前应该进一步简化(据我所知,SAINT 的设计并不是为了在集成后继续简化)
- 首先使用
ratsimp()
将结果强制为单个分数,推动 Sympy 清理分母(这结合了分数)
- 调用
apart()
将它们拆分回来,尽管它们仍然是简化的
这给出了更符合预期的匹配
James R Slagle麻省理工学院论文A heuristic program that solves symbolic integration problems in freshman calculus, symbolic automatic integrator (SAINT) 因成为第一个实用的“专家系统”符号积分器而出名,并且能够解决麻省理工学院本科生微积分测试中的所有问题(迂腐地,有几个问题被遗漏了,但它本可以解决它们;详细信息在这里in this excellent YouTube video)
他的论文可在此处免费获得:https://dspace.mit.edu/handle/1721.1/11997
我很高兴尝试使用 Sympy,因为它看起来平易近人,而且是一个相当困难的简化我碰巧已经有了答案..然而,Sympy 并没有将积分简化到如此好的(主观?)简化为 1961 年计划(尽管它确实 return 等效结果!)
疑问与猜测
如何说服 Sympy 简化为相同的方程式?
为什么它没有得出相同的、看似更简单的结果?
也许它选择了第一个可能的结果,或者tan**3
被确定为更糟?如果是这样,为什么它不简化 SAINT 的输出?)
也许当它找到一些匹配项时,它会沿着不同的分支出发
试题3c
Sympy 简化
from sympy import *
x = symbols("x", real=True) # should this be assumed?
expr_inner = (x**4) / ((1 - x**2)**Rational(5,2))
expr_integral = integrate((expr_inner), x)
print(simplify(expr_integral))
(x**4*asin(x) + 4*x**3*sqrt(1 - x**2)/3 - 2*x**2*asin(x) - x*sqrt(1 - x**2) + asin(x))/(x**4 - 2*x**2 + 1)
平等证明
from sympy import *
x = symbols("x", real=True) # should this be assumed?
expr_saint = asin(x) + Rational(1,3)*tan(asin(x))**3 - tan(asin(x))
expr_sympy = (x**4*asin(x) + 4*x**3*sqrt(1 - x**2)/3 - 2*x**2*asin(x) - x*sqrt(1 - x**2) + asin(x))/(x**4 - 2*x**2 + 1)
expr_saint.equals(expr_sympy) # alternatively simplify(expr_saint - expr_sympy)
True
方程式显示
主要部分是分解 asin(x)
并将其从分数中分离出来。之后,sympy 可以证明两个表达式相等:
from sympy import *
from IPython.display import Math, display
x = symbols("x", real=True) # should this be assumed?
expr_saint = asin(x) + Rational(1,3)*tan(asin(x))**3 - tan(asin(x))
expr_sympy = (x**4*asin(x) + 4*x**3*sqrt(1 - x**2)/3 - 2*x**2*asin(x) - x*sqrt(1 - x**2) + asin(x))/(x**4 - 2*x**2 + 1)
r=[]
r.append(latex(expr_sympy))
expr_sympy = expr_sympy.collect(asin(x))
r.append(latex(expr_sympy))
expr_sympy = apart(expr_sympy,asin(x))
r.append(latex(expr_sympy))
display(Math(" \Longrightarrow ".join(r)))
display(simplify(expr_saint - expr_sympy))
输出:
@wsdookadr 给了我缺少的简化步骤;显示 apart()
可以很容易地自己得到 asin(x)
(这显然是一个公因数),因此创建一个非常相似但比 SAINT 输出更简化的形式。
沿着这些思路思考更多,SAINT 输出并没有尽可能地简化,因此在比较之前应该进一步简化(据我所知,SAINT 的设计并不是为了在集成后继续简化)
- 首先使用
ratsimp()
将结果强制为单个分数,推动 Sympy 清理分母(这结合了分数) - 调用
apart()
将它们拆分回来,尽管它们仍然是简化的
这给出了更符合预期的匹配