傅红光的三角化简#

Fu等人对trigsimp算法的实现。

Fu算法的思想是使用学生在预科微积分课程中学习的一系列规则。这些规则是启发式的,它使用贪婪算法同时应用多个规则并选择叶数最少的结果。

有一些转换规则,其中一个规则应用于表达式树。以下只是助记符;请参阅docstrings中的示例。

  • TR0() -简化表达式

  • TR1() -sec csc到cos sin

  • TR2() -棕褐色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.TR0(rv)[源代码]#

有理多项式的简化,试图简化表达式,例如结合3 x+2 x、 等等。。。。

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 maxpow .

实例

>>> 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 maxpow .

实例

>>> 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)[源代码]#

总和 cossin 作为产品的术语 cossin .

实例

>>> 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)[源代码]#

单独金额 cossin .

实例

>>> 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)[源代码]#

改变产品 tancot .

实例

>>> 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 maxpow .

实例

>>> 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 maxpow .

实例

>>> 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 maxpow .

实例

>>> 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中。

工具书类#