傅红光的三角化简#
Fu等人对trigsimp算法的实现。
Fu算法的思想是使用学生在预科微积分课程中学习的一系列规则。这些规则是启发式的,它使用贪婪算法同时应用多个规则并选择叶数最少的结果。
有一些转换规则,其中一个规则应用于表达式树。以下只是助记符;请参阅docstrings中的示例。
TR0()
-简化表达式TR1()
-sec csc到cos sinTR2()
-棕褐色cot与sin cos之比TR2i()
-正反比TR3()
-角规范化TR4()
-特殊角度的功能TR5()
-罪的能力到罪的能力TR6()
-罪的权能TR7()
-降低cos功率(增加角度)TR8()
-将sin-cos的乘积展开为和TR9()
-sincos对产品的合同金额TR10()
-分离sin-cos参数TR10i()
-收集sin-cos参数TR11()
-减少双重角度TR12()
-单独的棕褐色参数TR12i()
-收集tan参数TR13()
-棕褐色胶辊的扩大产品TRmorrie()
-生产成本(x 2 i), (i, 0, k - 1)) -> sin(2 k x) /(2) **k* 罪(x))TR14()
-罪的因数幂TR15()
-罪的负向力量TR16()
-cos对tan幂的负幂TR22()
-sec csc功能的负幂函数TR111()
-消极罪过对csc sec cot的权力
从CTR4中选择了几个最简单的变换(CTR4)组合,其中CTR4是从几个最简单的变换中选择的。
最后,有两个规则列表(RL1和RL2),它们应用一系列转换和组合转换,以及 fu
算法本身,它应用规则和规则列表并选择最佳表达式。还有一个功能 L
它计算表达式中出现的三角函数的数量。
除了TR0,表达式的重写不是由转换完成的。e、 TR10i在一个和中找到一对项,其形式如下 cos(x)*cos(y) + sin(x)*sin(y)
. 这样的表达式在自下而上的表达式遍历中是目标,但不会试图进行任何操作以使它们出现。例如,
为以下示例设置:
>>> from sympy.simplify.fu import fu, L, TR9, TR10i, TR11
>>> from sympy import factor, sin, cos, powsimp
>>> from sympy.abc import x, y, z, a
>>> from time import time
>>> eq = cos(x + y)/cos(x)
>>> TR10i(eq.expand(trig=True))
-sin(x)*sin(y)/cos(x) + cos(y)
如果表达式以“正常”形式(具有共同的分母),则转换成功:
>>> TR10i(_.normal())
cos(x + y)/cos(x)
TR11的行为类似。它将双角度重写为较小的角度,但不会对结果进行任何简化。
>>> TR11(sin(2)**a*cos(1)**(-a), 1)
(2*sin(1)*cos(1))**a/cos(1)**a
>>> powsimp(_)
(2*sin(1))**a
诱惑是试图让这些TR规则“更聪明”,但这确实应该在更高的层次上实现;TR规则应该尝试维护“做好一件事”的原则。不过,有一个例外。在TR10i和TR9中,即使将它们各自乘以一个公共因子,也可以识别:
>>> fu(a*cos(x)*cos(y) + a*sin(x)*sin(y))
a*cos(x - y)
保理 factor_terms
被使用,但它是“JIT”式的,被延迟到认为有必要的时候。此外,如果因子分解对简化没有帮助,它就不会被保留,所以 a*cos(x)*cos(y) + a*sin(x)*sin(z)
不会变成一个系数化(但在三角意义上没有简化)的表达式:
>>> fu(a*cos(x)*cos(y) + a*sin(x)*sin(z))
a*sin(x)*sin(z) + a*cos(x)*cos(y)
在某些情况下,因子分解可能是一个好主意,但是用户可以自行决定。例如:
>>> expr=((15*sin(2*x) + 19*sin(x + y) + 17*sin(x + z) + 19*cos(x - z) +
... 25)*(20*sin(2*x) + 15*sin(x + y) + sin(y + z) + 14*cos(x - z) +
... 14*cos(y - z))*(9*sin(2*y) + 12*sin(y + z) + 10*cos(x - y) + 2*cos(y -
... z) + 18)).expand(trig=True).expand()
在扩展状态下,有近1000个trig函数:
>>> L(expr)
932
If the expression were factored first, this would take time but the resulting expression would be transformed very quickly:
>>> def clock(f, n=2):
... t=time(); f(); return round(time()-t, n)
...
>>> clock(lambda: factor(expr))
0.86
>>> clock(lambda: TR10i(expr), 3)
0.016
如果使用未展开的表达式,则转换所需时间较长,但不会像对其进行因子化然后再对其进行转换所需的时间:
>>> clock(lambda: TR10i(expr), 2)
0.28
所以在 TR10i
:如果表达式已被分解(或部分分解),则使用 trig=True
会破坏已经知道的内容并花费更长的时间;如果表达式被展开,因子分解可能比简单地应用转换本身花费更长的时间。
虽然这些算法应该是规范的,总是给出相同的结果,但它们可能不会产生最佳结果。一般来说,这就是简化的本质,搜索所有可能的转换路径非常昂贵。这里有一个简单的例子。共有6个术语:
>>> expr = (sin(x)**2*cos(y)*cos(z) + sin(x)*sin(y)*cos(x)*cos(z) +
... sin(x)*sin(z)*cos(x)*cos(y) + sin(y)*sin(z)*cos(x)**2 + sin(y)*sin(z) +
... cos(y)*cos(z))
>>> args = expr.args
偶然地,傅给出了最好的结果:
>>> fu(expr)
3*cos(y - z)/2 - cos(2*x + y + z)/2
但是,如果将不同的项组合起来,可能会得到一个不太理想的结果,这需要一些额外的工作来获得更好的简化,但仍然不是最优的。以下显示的是 expr
一旦采取了给定的步骤,它就会抵制最佳简化,因为这会导致死胡同:
>>> TR9(-cos(x)**2*cos(y + z) + 3*cos(y - z)/2 +
... cos(y + z)/2 + cos(-2*x + y + z)/4 - cos(2*x + y + z)/4)
sin(2*x)*sin(y + z)/2 - cos(x)**2*cos(y + z) + 3*cos(y - z)/2 + cos(y + z)/2
下面是一个较小的表达式,它显示了相同的行为:
>>> a = sin(x)*sin(z)*cos(x)*cos(y) + sin(x)*sin(y)*cos(x)*cos(z)
>>> TR10i(a)
sin(x)*sin(y + z)*cos(x)
>>> newa = _
>>> TR10i(expr - a) # this combines two more of the remaining terms
sin(x)**2*cos(y)*cos(z) + sin(y)*sin(z)*cos(x)**2 + cos(y - z)
>>> TR10i(_ + newa) == _ + newa # but now there is no more simplification
True
如果没有幸运或尝试所有可能的参数对,最终结果可能不太理想,如果没有更好的启发式或对所有可能性的暴力试验,就不可能找到最终结果。
规则#
- sympy.simplify.fu.TR1(rv)[源代码]#
将sec,csc替换为1/cos,1/sin
实例
>>> from sympy.simplify.fu import TR1, sec, csc >>> from sympy.abc import x >>> TR1(2*csc(x) + sec(x)) 1/cos(x) + 2/sin(x)
- sympy.simplify.fu.TR2(rv)[源代码]#
用sin/cos和cos/sin替换tan和cot
实例
>>> from sympy.simplify.fu import TR2 >>> from sympy.abc import x >>> from sympy import tan, cot, sin, cos >>> TR2(tan(x)) sin(x)/cos(x) >>> TR2(cot(x)) cos(x)/sin(x) >>> TR2(tan(tan(x) - sin(x)/cos(x))) 0
- sympy.simplify.fu.TR2i(rv, half=False)[源代码]#
- 将涉及正弦和余弦的比率转换如下:
sin(x)/cos(x)->tan(x)sin(x)/(cos(x)+1)->tan(x/2),如果一半=真
实例
>>> from sympy.simplify.fu import TR2i >>> from sympy.abc import x, a >>> from sympy import sin, cos >>> TR2i(sin(x)/cos(x)) tan(x)
分子和分母的幂也是公认的
>>> TR2i(sin(x)**2/(cos(x) + 1)**2, half=True) tan(x/2)**2
除非假设允许(即分子和分母的基数必须为正或指数必须为整数),否则转换不会发生
>>> TR2i(sin(x)**a/(cos(x) + 1)**a) sin(x)**a/(cos(x) + 1)**a
- sympy.simplify.fu.TR3(rv)[源代码]#
归纳式:例sin(-a)=-sin(a)
实例
>>> from sympy.simplify.fu import TR3 >>> from sympy.abc import x, y >>> from sympy import pi >>> from sympy import cos >>> TR3(cos(y - x*(y - x))) cos(x*(x - y) + y) >>> cos(pi/2 + x) -sin(x) >>> cos(30*pi/2 + x) -cos(x)
- sympy.simplify.fu.TR4(rv)[源代码]#
确定特殊角度的值。
A=0π/6π/4π/3π/2
sin(a) 0 1/2 sqrt(2)/2 sqrt(3)/2 1 cos(a) 1 sqrt(3)/2 sqrt(2)/2 1/2 0 tan(a) 0 sqt(3)/3 1 sqrt(3) --
实例
>>> from sympy import pi >>> from sympy import cos, sin, tan, cot >>> for s in (0, pi/6, pi/4, pi/3, pi/2): ... print('%s %s %s %s' % (cos(s), sin(s), tan(s), cot(s))) ... 1 0 0 zoo sqrt(3)/2 1/2 sqrt(3)/3 sqrt(3) sqrt(2)/2 sqrt(2)/2 1 1 1/2 sqrt(3)/2 sqrt(3) sqrt(3)/3 0 1 zoo 0
- sympy.simplify.fu.TR5(rv, max=4, pow=False)[源代码]#
罪的替代 2 with 1 - cos(x) 2.第二步。
有关高级用法,请参阅u TR56 docstring
max
和pow
.实例
>>> from sympy.simplify.fu import TR5 >>> from sympy.abc import x >>> from sympy import sin >>> TR5(sin(x)**2) 1 - cos(x)**2 >>> TR5(sin(x)**-2) # unchanged sin(x)**(-2) >>> TR5(sin(x)**4) (1 - cos(x)**2)**2
- sympy.simplify.fu.TR6(rv, max=4, pow=False)[源代码]#
更换cos 2 with 1 - sin(x) 2.第二步。
有关高级用法,请参阅u TR56 docstring
max
和pow
.实例
>>> from sympy.simplify.fu import TR6 >>> from sympy.abc import x >>> from sympy import cos >>> TR6(cos(x)**2) 1 - sin(x)**2 >>> TR6(cos(x)**-2) #unchanged cos(x)**(-2) >>> TR6(cos(x)**4) (1 - sin(x)**2)**2
- sympy.simplify.fu.TR7(rv)[源代码]#
Lowering the degree of cos(x)**2.
实例
>>> from sympy.simplify.fu import TR7 >>> from sympy.abc import x >>> from sympy import cos >>> TR7(cos(x)**2) cos(2*x)/2 + 1/2 >>> TR7(cos(x)**2 + 1) cos(2*x)/2 + 3/2
- sympy.simplify.fu.TR8(rv, first=True)[源代码]#
转换产品
cos
和/或sin
等于或等于cos
和或sin
条款。实例
>>> from sympy.simplify.fu import TR8 >>> from sympy import cos, sin >>> TR8(cos(2)*cos(3)) cos(5)/2 + cos(1)/2 >>> TR8(cos(2)*sin(3)) sin(5)/2 + sin(1)/2 >>> TR8(sin(2)*sin(3)) -cos(5)/2 + cos(1)/2
- sympy.simplify.fu.TR9(rv)[源代码]#
总和
cos
或sin
作为产品的术语cos
或sin
.实例
>>> from sympy.simplify.fu import TR9 >>> from sympy import cos, sin >>> TR9(cos(1) + cos(2)) 2*cos(1/2)*cos(3/2) >>> TR9(cos(1) + 2*sin(1) + 2*sin(2)) cos(1) + 4*sin(3/2)*cos(1/2)
If no change is made by TR9, no re-arrangement of the expression will be made. For example, though factoring of common term is attempted, if the factored expression was not changed, the original expression will be returned:
>>> TR9(cos(3) + cos(3)*cos(2)) cos(3) + cos(2)*cos(3)
- sympy.simplify.fu.TR10(rv, first=True)[源代码]#
单独金额
cos
和sin
.实例
>>> from sympy.simplify.fu import TR10 >>> from sympy.abc import a, b, c >>> from sympy import cos, sin >>> TR10(cos(a + b)) -sin(a)*sin(b) + cos(a)*cos(b) >>> TR10(sin(a + b)) sin(a)*cos(b) + sin(b)*cos(a) >>> TR10(sin(a + b + c)) (-sin(a)*sin(b) + cos(a)*cos(b))*sin(c) + (sin(a)*cos(b) + sin(b)*cos(a))*cos(c)
- sympy.simplify.fu.TR10i(rv)[源代码]#
求和函数的乘积和。
实例
>>> from sympy.simplify.fu import TR10i >>> from sympy import cos, sin, sqrt >>> from sympy.abc import x
>>> TR10i(cos(1)*cos(3) + sin(1)*sin(3)) cos(2) >>> TR10i(cos(1)*sin(3) + sin(1)*cos(3) + cos(3)) cos(3) + sin(4) >>> TR10i(sqrt(2)*cos(x)*x + sqrt(6)*sin(x)*x) 2*sqrt(2)*x*sin(x + pi/6)
- sympy.simplify.fu.TR11(rv, base=None)[源代码]#
双角度对乘积的作用。这个
base
参数可用于指示什么是未加倍的参数,例如如果3 pi/7 is the base then cosine and sine functions with argument 6 pi/7将被替换。实例
>>> from sympy.simplify.fu import TR11 >>> from sympy import cos, sin, pi >>> from sympy.abc import x >>> TR11(sin(2*x)) 2*sin(x)*cos(x) >>> TR11(cos(2*x)) -sin(x)**2 + cos(x)**2 >>> TR11(sin(4*x)) 4*(-sin(x)**2 + cos(x)**2)*sin(x)*cos(x) >>> TR11(sin(4*x/3)) 4*(-sin(x/3)**2 + cos(x/3)**2)*sin(x/3)*cos(x/3)
如果参数只是整数,则除非提供基数,否则不会进行任何更改:
>>> TR11(cos(2)) cos(2) >>> TR11(cos(4), 2) -sin(2)**2 + cos(2)**2
这里有一个微妙的问题,自动简化会将一些较高的角度转换为较低的角度
>>> cos(6*pi/7) + cos(3*pi/7) -cos(pi/7) + cos(3*pi/7)
6 pi/7 angle is now pi/7 but can be targeted with TR11 by supplying the 3 pi/7底座:
>>> TR11(_, 3*pi/7) -sin(3*pi/7)**2 + cos(3*pi/7)**2 + cos(3*pi/7)
- sympy.simplify.fu.TR12(rv, first=True)[源代码]#
单独金额
tan
.实例
>>> from sympy.abc import x, y >>> from sympy import tan >>> from sympy.simplify.fu import TR12 >>> TR12(tan(x + y)) (tan(x) + tan(y))/(-tan(x)*tan(y) + 1)
- sympy.simplify.fu.TR12i(rv)[源代码]#
Combine tan arguments as (tan(y) + tan(x))/(tan(x)*tan(y) - 1) -> -tan(x + y).
实例
>>> from sympy.simplify.fu import TR12i >>> from sympy import tan >>> from sympy.abc import a, b, c >>> ta, tb, tc = [tan(i) for i in (a, b, c)] >>> TR12i((ta + tb)/(-ta*tb + 1)) tan(a + b) >>> TR12i((ta + tb)/(ta*tb - 1)) -tan(a + b) >>> TR12i((-ta - tb)/(ta*tb - 1)) tan(a + b) >>> eq = (ta + tb)/(-ta*tb + 1)**2*(-3*ta - 3*tc)/(2*(ta*tc - 1)) >>> TR12i(eq.expand()) -3*tan(a + b)*tan(a + c)/(2*(tan(a) + tan(b) - 1))
- sympy.simplify.fu.TR13(rv)[源代码]#
改变产品
tan
或cot
.实例
>>> from sympy.simplify.fu import TR13 >>> from sympy import tan, cot >>> TR13(tan(3)*tan(2)) -tan(2)/tan(5) - tan(3)/tan(5) + 1 >>> TR13(cot(3)*cot(2)) cot(2)*cot(5) + 1 + cot(3)*cot(5)
- sympy.simplify.fu.TRmorrie(rv)[源代码]#
返回cos(x) 成本(2 十) ... 成本(2 (k-1)*x) -> sin(2 K x)/(2 k 罪(x))
实例
>>> from sympy.simplify.fu import TRmorrie, TR8, TR3 >>> from sympy.abc import x >>> from sympy import Mul, cos, pi >>> TRmorrie(cos(x)*cos(2*x)) sin(4*x)/(4*sin(x)) >>> TRmorrie(7*Mul(*[cos(x) for x in range(10)])) 7*sin(12)*sin(16)*cos(5)*cos(7)*cos(9)/(64*sin(1)*sin(3))
有时,自动简化会导致一种能力无法识别。e、 g.在下面,cos(4 pi/7) automatically simplifies to -cos(3 pi/7),因此3个术语中只有2个被识别:
>>> TRmorrie(cos(pi/7)*cos(2*pi/7)*cos(4*pi/7)) -sin(3*pi/7)*cos(3*pi/7)/(4*sin(pi/7))
TR8的触摸将表达式解析为有理数
>>> TR8(_) -1/8
在这种情况下,如果eq不简化,则直接得到答案:
>>> eq = cos(pi/9)*cos(2*pi/9)*cos(3*pi/9)*cos(4*pi/9) >>> TRmorrie(eq) 1/16
但是,如果用TR3使角度成为标准,那么没有进一步的工作,答案就不会简化:
>>> TR3(eq) sin(pi/18)*cos(pi/9)*cos(2*pi/9)/2 >>> TRmorrie(_) sin(pi/18)*sin(4*pi/9)/(8*sin(pi/9)) >>> TR8(_) cos(7*pi/18)/(16*sin(pi/9)) >>> TR3(_) 1/16
原始表达式将直接使用TR8解析为1/16,但是:
>>> TR8(eq) 1/16
工具书类
- sympy.simplify.fu.TR14(rv, first=True)[源代码]#
将sin和cos恒等式的因数幂转换为更简单的表达式。
实例
>>> from sympy.simplify.fu import TR14 >>> from sympy.abc import x, y >>> from sympy import cos, sin >>> TR14((cos(x) - 1)*(cos(x) + 1)) -sin(x)**2 >>> TR14((sin(x) - 1)*(sin(x) + 1)) -cos(x)**2 >>> p1 = (cos(x) + 1)*(cos(x) - 1) >>> p2 = (cos(y) - 1)*2*(cos(y) + 1) >>> p3 = (3*(cos(y) - 1))*(3*(cos(y) + 1)) >>> TR14(p1*p2*p3*(x - 1)) -18*(x - 1)*sin(x)**2*sin(y)**4
- sympy.simplify.fu.TR15(rv, max=4, pow=False)[源代码]#
Convert sin(x)**-2 to 1 + cot(x)**2.
有关高级用法,请参阅u TR56 docstring
max
和pow
.实例
>>> from sympy.simplify.fu import TR15 >>> from sympy.abc import x >>> from sympy import sin >>> TR15(1 - 1/sin(x)**2) -cot(x)**2
- sympy.simplify.fu.TR16(rv, max=4, pow=False)[源代码]#
Convert cos(x)**-2 to 1 + tan(x)**2.
有关高级用法,请参阅u TR56 docstring
max
和pow
.实例
>>> from sympy.simplify.fu import TR16 >>> from sympy.abc import x >>> from sympy import cos >>> TR16(1 - 1/cos(x)**2) -tan(x)**2
- sympy.simplify.fu.TR111(rv)[源代码]#
转换f(x) -i to g(x) 我在哪
i
为整数或底数为正,f,g为:tan,cot;sin,csc;或cos,sec。实例
>>> from sympy.simplify.fu import TR111 >>> from sympy.abc import x >>> from sympy import tan >>> TR111(1 - 1/tan(x)**2) 1 - cot(x)**2
- sympy.simplify.fu.TR22(rv, max=4, pow=False)[源代码]#
转换tan(x) 2秒(x) 2-1和cot(x) 2至csc(x) 2-1。
有关高级用法,请参阅u TR56 docstring
max
和pow
.实例
>>> from sympy.simplify.fu import TR22 >>> from sympy.abc import x >>> from sympy import tan, cot >>> TR22(1 + tan(x)**2) sec(x)**2 >>> TR22(1 + cot(x)**2) csc(x)**2
- sympy.simplify.fu.TRpower(rv)[源代码]#
转换sin(x) n和cos(x) n与正n之和。
实例
>>> from sympy.simplify.fu import TRpower >>> from sympy.abc import x >>> from sympy import cos, sin >>> TRpower(sin(x)**6) -15*cos(2*x)/32 + 3*cos(4*x)/16 - cos(6*x)/32 + 5/16 >>> TRpower(sin(x)**3*cos(2*x)**4) (3*sin(x)/4 - sin(3*x)/4)*(cos(4*x)/2 + cos(8*x)/8 + 3/8)
工具书类
[R853]https://en.wikipedia.org/wiki/List_三角函数身份-约化公式
- sympy.simplify.fu.fu(rv, measure=<function <lambda>>)[源代码]#
尝试使用Fu等人在算法中给出的转换规则来简化表达式。
fu()
尽量使目标函数最小化measure
. 默认情况下,这首先最小化trig项的数量,然后最小化操作总数。实例
>>> from sympy.simplify.fu import fu >>> from sympy import cos, sin, tan, pi, S, sqrt >>> from sympy.abc import x, y, a, b
>>> fu(sin(50)**2 + cos(50)**2 + sin(pi/6)) 3/2 >>> fu(sqrt(6)*cos(x) + sqrt(2)*sin(x)) 2*sqrt(2)*sin(x + pi/3)
CTR1示例
>>> eq = sin(x)**4 - cos(y)**2 + sin(y)**2 + 2*cos(x)**2 >>> fu(eq) cos(x)**4 - 2*cos(y)**2 + 2
CTR2示例
>>> fu(S.Half - cos(2*x)/2) sin(x)**2
CTR3示例
>>> fu(sin(a)*(cos(b) - sin(b)) + cos(a)*(sin(b) + cos(b))) sqrt(2)*sin(a + b + pi/4)
CTR4示例
>>> fu(sqrt(3)*cos(x)/2 + sin(x)/2) sin(x + pi/3)
例1
>>> fu(1-sin(2*x)**2/4-sin(y)**2-cos(x)**4) -cos(x)**2 + cos(y)**2
例2
>>> fu(cos(4*pi/9)) sin(pi/18) >>> fu(cos(pi/9)*cos(2*pi/9)*cos(3*pi/9)*cos(4*pi/9)) 1/16
例3
>>> fu(tan(7*pi/18)+tan(5*pi/18)-sqrt(3)*tan(5*pi/18)*tan(7*pi/18)) -sqrt(3)
目标函数示例
>>> fu(sin(x)/cos(x)) # default objective function tan(x) >>> fu(sin(x)/cos(x), measure=lambda x: -x.count_ops()) # maximize op count sin(x)/cos(x)
工具书类
笔记#
这项工作是由Dimitar Vlahovski在技术学校“电子系统”(2011年11月30日)开始的。
除了TR13之外,其他规则不是来自原始文件,而是扩展到SymPy中。