泰勒级数的正弦函数的时间复杂度是多少?

what could be the time complexity of sine function by taylor's series?

我确实到处搜索,甚至在 SO 上。 google 上的学术文章远远超出了我的智力范围。 This 已经很接近了,但没有回答我的问题。 就我所寻找的而言,没有答案。相信我。 (但请随时证明我错了)

我有一个作业问题是使用 sine(x) 函数的泰勒展开来计算 sine 函数的时间复杂度。 我不是要泰勒级数或泰勒级数函数程序,而是它的时间复杂度。 我知道泰勒展开式的下一项是:

Term in x^n = (Term in x^n-2) * x * x / n / (n-1)

函数片段是这样的:

double sine(double x) {
int n;
double sum, term;
n = 3;
sum = x;
term = x;
while(isgreater(fabs(term), 0.0000000001)) {
    term = (term * x * x) / ( n * (n -1));
        if(n % 4 == 3)
            sum -= term;
    else
            sum += term;
         n = n + 2;
}   
return sum;
}

fabs() 是取绝对值的函数 0.0000000001 是所需的精度。 如果我的理解是正确的,当最后计算的项的值小于 than/equal 到精度浮点集时,代码将停止。

到目前为止我的推论是时间复杂度可能取决于 x^2/n^2 ? 或者它是不可推导的,因为我们不知道在哪个特定 index/number 燕鸥将小于精度浮点数?

我数学不强,幸好有像你这样的大师:)

终止条件似乎很简单

abs(x^n/n!) < eps.

不那么直接的是为 n 解决这个问题。即使使用 Sterling 近似,您仍然需要求解

abs(e*x/n)^n < eps

您可以做一些简化假设以获得上限,例如 n > 6*abs(x) 这样您就必须解决

(e/6)^n < eps  =>  n > log(eps)/log(e/6).

然而,在这个 n = O(abs(x)) 真正开始计算之前很久就被取消错误所扼杀,因为 n=round(abs(x)) 的大小为 e^n 并且周围的条款必须减少它为小于 1 的绝对值。在 x=35 这意味着您丢失了总和的所有数字以进行取消。

what could be the time complexity of sine function by Taylor's series?
Math is not strong with me

作为 精细分析的辅助手段,有时完整性检查和 视觉 简单测试代码提供了对时间复杂度的洞察力。

#define N 1000000
clock_t test_sine(double x) {
  clock_t c1 = clock();
  for (int i = 0; i < N; i++) {
    sine(x);
  }
  clock_t c2 = clock();
  return c2 - c1;
}

void test_sines(void) {
  double x0 = 0;
  double x1 = 70;
  double dx = 0.2;
  for (double x = x0; x <= x1; x += dx) {
    printf("%f \t %d\n", x, (int) test_sine(x));
    fflush(stdout);
  }
}

int main(void) {
  test_sines();
}

示例输出

0   16
0.2 78
0.4 93
0.6 94
0.8 94
1   124
...

一旦 x > 3.

绘制它就相当线性了

仔细观察,我们会看到每个幂的时间步长,使用趋势看起来非常接近 t = pow(x,1/3.)

void test_sines(void) {
  double x0 = 0.0000000001/2;
  double x1 = 1;
  double dx = pow(2, 1.0/5);
  for (double x = x0; x <= x1; x *= dx) {


使用 clock() 相当粗糙,但提供了可视化的分析。

对于 x * x,我原以为 term 会影响每个 sqrt(x)isgreater(),因为这将迫使另一个循环迭代。

结论:小值的时间复杂度约为 power(x,1.0/d) (2.0 <= d <= 3.1),大值的时间复杂度为线性。


请注意,OP sine() 的质量存在许多问题,导致其结果对许多 x 来说很弱。对于许多 x > 900 的值,sine(x) 是一个无限循环。

在现实世界中,您将使用函数的周期性并保留有限数量的项,因此 O(1)。

在理论世界中,由于 x^n 的指数增长,您需要越来越大的数字,乘法的复杂性开始发挥作用。正如 LutzL 所解释的,项数必须超过 x,并且全局复杂度必须类似于 O(x M(log(x))),其中 M(k) 表示 k 位数字相乘的成本。 (O(k²) 用于简单的实现,O(k Log k Log Log k) 用于更有效的实现)。