三角函数从系列扩展中起作用

时间:2018-05-08 09:14:36

标签: python math trigonometry

我正在尝试编写模拟math.sinmath.tan的函数,但不使用math库,而是使用系列扩展执行计算。

公式来自数学SE,How would you calculate the Tangent without a calculator?

  

sin(x)= x - x ^ 3/3! + x ^ 5/5! -...

     

tan(x)= sin(x)/√(1-sin(x)^ 2)

这是我的尝试,但我无法弄清楚如何执行+ / - / + / ...部分扩展{{1 }}:

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 / +开关。我可以添加- / if条款,但这看起来很混乱。还有更好的方法吗?

注意:这个问题是昨天由@Lana发布的now deleted question的装饰版本。

2 个答案:

答案 0 :(得分:5)

您可以通过使用前一个计算下一个和的项来避免重新计算每个步骤的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

与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

如果我们一劳永逸地计算- 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

答案 1 :(得分:1)

你很亲密。以下是使用elsesum进行系列扩展的一种方式。

enumerate通过获取iterable的每个值并附加索引来工作,即第一个项为0,第二个项为1,等等。然后我们只需要测试索引是偶数还是奇数使用ternary statement

此外,您可以使用enumerate代替列出展开所需的奇数。

range

您可以完全避免使用三元语句和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))) def tan(x): return sin(x) / (1-(sin(x))**2)**0.5 print(tan(1.2)) # 2.572151622126318

enumerate

如果你手工写出前几个术语,那么等价就会变得清晰。

备注:

  • def sin(x, n=20): return sum((-1)**i * x**(2*i+1) / factorial(2*i+1) for i in range(n)) 功能的符号仅适用于第1和第4象限。这与您提供的公式一致。您可以对输入执行简单的转换以解决此问题。
  • 您可以通过增加参数tan来提高准确性。
  • 您也可以在没有图书馆的情况下计算因子,但我会将其作为练习。