jpp*_*jpp 0 python math trigonometry
我试图写一个模拟功能math.sin和math.tan但是,而不是使用math库,进行使用一系列扩展的计算.
这些公式来自数学SE,如何在没有计算器的情况下计算切线?:
sin(x)= x - x ^ 3/3!+ x ^ 5/5!-...
tan(x)= sin(x)/√(1 - sin(x)^ 2)
这是我的尝试,但我无法弄清楚如何执行符号翻转+/ -/ +/ ...系列扩展的一部分sin:
from math import factorial
res = 0
for i in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]:
res += 1**i/factorial(i)
print(res) # 1.1752011936438016
Run Code Online (Sandbox Code Playgroud)
结果不正确,因为我没有应用+/ -switch.我可以添加一个if/ else子句,但这看起来很乱.有没有更好的办法?
注意:这个问题是@Lana昨天发布的一个现已删除的问题的装饰版本.
您可以通过使用前一个计算下一个和的项来避免在每个步骤重新计算x**n和阶乘:
def sin2(x, n=20):
curr = x
res = curr
for i in range(2, n, 2):
curr *= - x**2/(i*(i+1))
res += curr
return res
Run Code Online (Sandbox Code Playgroud)
与jpp的版本相比,速度快了两倍:
from math import factorial
def sin(x, n=20):
return sum(x**j/factorial(j)*(1 if i%2==0 else -1)
for i, j in enumerate(range(1, n, 2)))
%timeit sin(0.7)
# 100000 loops, best of 3: 8.52 µs per loop
%timeit sin2(0.7)
# 100000 loops, best of 3: 4.54 µs per loop
Run Code Online (Sandbox Code Playgroud)
如果我们- x**2一劳永逸地计算它会变得更快:
def sin3(x, n=20):
curr = x
res = 0
minus_x_squared = - x**2
for i in range(2, n, 2):
res += curr
curr *= minus_x_squared/(i*(i+1))
return res
%timeit sin2(0.7)
# 100000 loops, best of 3: 4.6 µs per loop
%timeit sin3(0.7)
# 100000 loops, best of 3: 3.54 µs per loop
Run Code Online (Sandbox Code Playgroud)