C 误差最大为10^-3的泰勒级数

C 误差最大为10^-3的泰勒级数,c,taylor-series,function-approximation,C,Taylor Series,Function Approximation,我试图计算cos(x)的泰勒级数,误差最大为10^-3和所有x∈ [-pi/4,pi/4],这意味着我的错误需要小于0.001。我可以修改for循环中的x+=以获得不同的结果。我尝试了几个数字,但它从未变成小于0.001的错误 #include <stdio.h> #include <math.h> float cosine(float x, int j) { float val = 1; for (int k = j - 1; k >= 0; -

我试图计算
cos(x)
的泰勒级数,误差最大为
10^-3
和所有
x∈ [-pi/4,pi/4]
,这意味着我的错误需要小于
0.001
。我可以修改for循环中的x+=以获得不同的结果。我尝试了几个数字,但它从未变成小于0.001的错误

#include <stdio.h>
#include <math.h>

float cosine(float x, int j)
{
    float val = 1;
    for (int k = j - 1; k >= 0; --k)
        val = 1 - x*x/(2*k+2)/(2*k+1)*val;
    return val;
}

int main( void )
{
   for( double x = 0; x <= PI/4; x += 0.9999 )
   {

       if(cosine(x, 2) <= 0.001)
       {
           printf("cos(x) : %10g    %10g    %10g\n", x, cos(x), cosine(x, 2));
       }
       printf("cos(x) : %10g    %10g    %10g\n", x, cos(x), cosine(x, 2));
    }

    return 0;
}
但是每当我改变for循环中的项数时,它总是有一个大于1的错误。我该如何将其更改为错误小于
10^-3


谢谢 $e(x)=\sum\limits{n=0}{\infty}frac{x^n}{n!}$

我们可以考虑E(1)的扩展中的前几个术语:

你应该注意到两件事,首先,当我们添加更多的项时,我们正越来越接近e(1)的精确值,而且连续和之间的差值也越来越小

因此,e(x)的实现可以写成:

#include <stdbool.h>
#include <stdio.h>
#include <math.h>

typedef float (*term)(int, int);
float evalSum(int, int, int, term);
float expTerm(int, int);
int fact(int);
int mypow(int, int);
bool sgn(float);

const int maxTerm = 10;         // number of terms to evaluate in series
const float epsilon = 0.001;    // the accepted error

int main(void)
{
    // change these values to modify the range and increment 
    float   start = -2;
    float   end = 2;
    float   inc = 1;

    for(int x = start; x <= end; x += inc)
    {
        float value = 0;
        float prev = 0;

        for(int ndx = 0; ndx < maxTerm; ndx++)
        {
            value = evalSum(0, ndx, x, expTerm);

            float diff = fabs(value-prev);
            if((sgn(value) && sgn(prev)) && (diff < epsilon))
                 break;
            else
                 prev = value;
        }

        printf("the approximate value of exp(%d) is %f\n", x, value);
    }

    return 0;
}
这是我编写的一个实用函数,用于计算级数的前n项
start
是起始值(该代码始终为0),而
end
是结束值。最后一个参数是指向表示如何计算给定项的函数的指针。在这段代码中,fnct可以是指向任何函数的指针,该函数接受整数参数并返回浮点

float expTerm(int n, int x)
{
    return (float)mypow(x,n)/(float)fact(n);
}
埋没在这一行函数中的是大部分工作发生的地方。该函数表示e(n)的泰勒展开式的闭合形式。仔细查看上面的内容,您应该能够看到,我们正在为给定的x和n值计算$\fract{x^n}{n!}$。作为提示,对于余弦部分,您需要创建一个函数来计算cos的泰勒展开式中某个项的闭函数。这是由$(-1)^n\fact{x^{2n}}{(2n)!}$给出的

这只是阶乘函数的标准实现。这里没什么特别的

int mypow(int base, int exp)
{
    int result = 1;

    while(exp)
    {
        if(exp&1)              // b&1 quick check for odd power
        {
            result *= base;
        }

        exp >>=1;              // exp >>= 1 quick division by 2
        base *= base;
    }

    return result;
}
用于执行幂运算的自定义函数。我们当然可以使用
中的版本,但因为我知道我们只会使用整数幂,所以我们可以编写一个优化的版本。提示:在进行余弦运算时,您可能需要使用
中的版本来处理浮点基

bool sgn(float x)
{
    if(x < 0) return false;
    else return true;
}
使用bc给出的预期值为:

如您所见,这些值完全在您要求的公差范围内。我把做余弦部分作为练习

希望这有帮助,

我的理解是,为了提高精度,你需要在泰勒系列中考虑更多的术语。例如,考虑什么时候发生什么 尝试用泰勒级数计算e(1)

$e(x)=\sum\limits{n=0}{\infty}frac{x^n}{n!}$

我们可以考虑E(1)的扩展中的前几个术语:

你应该注意到两件事,首先,当我们添加更多的项时,我们正越来越接近e(1)的精确值,而且连续和之间的差值也越来越小

因此,e(x)的实现可以写成:

#include <stdbool.h>
#include <stdio.h>
#include <math.h>

typedef float (*term)(int, int);
float evalSum(int, int, int, term);
float expTerm(int, int);
int fact(int);
int mypow(int, int);
bool sgn(float);

const int maxTerm = 10;         // number of terms to evaluate in series
const float epsilon = 0.001;    // the accepted error

int main(void)
{
    // change these values to modify the range and increment 
    float   start = -2;
    float   end = 2;
    float   inc = 1;

    for(int x = start; x <= end; x += inc)
    {
        float value = 0;
        float prev = 0;

        for(int ndx = 0; ndx < maxTerm; ndx++)
        {
            value = evalSum(0, ndx, x, expTerm);

            float diff = fabs(value-prev);
            if((sgn(value) && sgn(prev)) && (diff < epsilon))
                 break;
            else
                 prev = value;
        }

        printf("the approximate value of exp(%d) is %f\n", x, value);
    }

    return 0;
}
这是我编写的一个实用函数,用于计算级数的前n项
start
是起始值(该代码始终为0),而
end
是结束值。最后一个参数是指向表示如何计算给定项的函数的指针。在这段代码中,fnct可以是指向任何函数的指针,该函数接受整数参数并返回浮点

float expTerm(int n, int x)
{
    return (float)mypow(x,n)/(float)fact(n);
}
埋没在这一行函数中的是大部分工作发生的地方。该函数表示e(n)的泰勒展开式的闭合形式。仔细查看上面的内容,您应该能够看到,我们正在为给定的x和n值计算$\fract{x^n}{n!}$。作为提示,对于余弦部分,您需要创建一个函数来计算cos的泰勒展开式中某个项的闭函数。这是由$(-1)^n\fact{x^{2n}}{(2n)!}$给出的

这只是阶乘函数的标准实现。这里没什么特别的

int mypow(int base, int exp)
{
    int result = 1;

    while(exp)
    {
        if(exp&1)              // b&1 quick check for odd power
        {
            result *= base;
        }

        exp >>=1;              // exp >>= 1 quick division by 2
        base *= base;
    }

    return result;
}
用于执行幂运算的自定义函数。我们当然可以使用
中的版本,但因为我知道我们只会使用整数幂,所以我们可以编写一个优化的版本。提示:在进行余弦运算时,您可能需要使用
中的版本来处理浮点基

bool sgn(float x)
{
    if(x < 0) return false;
    else return true;
}
使用bc给出的预期值为:

如您所见,这些值完全在您要求的公差范围内。我把做余弦部分作为练习

希望这有帮助,

-T

exp
cos
的幂级数在实线上处处收敛。对于任何有界区间,例如
[-pi/4,pi/4]
[-2,2]
,幂级数不仅逐点收敛,而且一致收敛到
exp
cos

逐点收敛意味着对于区域中的任何
x
和任何
epsilon>0
,可以选择足够大的
N
,以便从泰勒级数的第一个
N
项得到的近似值在真值的
epsilon
范围内。然而,在逐点收敛的情况下,
N
对于某些
x
而言可能较小,而对于其他
x
而言可能较大,并且由于存在无限多的
x
,因此可能没有有限的
N
来容纳它们。对于某些函数,有时确实会发生这种情况

一致收敛意味着对于任何
epsilon>0
,您可以选择足够大的
N
,以便该区域中每个
x
的近似值都在
epsilon
范围内。这就是你要寻找的近似值,你可以保证
******@crossbow:~/personal/projects$ gcc -std=c99 -pedantic -Wall series.c -o series
******@crossbow:~/personal/projects$ ./series
the approximate value of exp(-2) is 0.135097
the approximate value of exp(-1) is 0.367857
the approximate value of exp(0) is 1.000000
the approximate value of exp(1) is 2.718254
the approximate value of exp(2) is 7.388713
******@crossbow:~$ bc -l
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
e(-2)
.13533528323661269189
e(-1)
.36787944117144232159
e(0)
1.00000000000000000000
e(1)
2.71828182845904523536
e(2)
7.38905609893065022723