Hutch
Hutch

Reputation: 31

Alternative way to do Taylor series in C

In my class my professor wants us to use functions to solve a Taylor series for sinX, cosX and expX.

I solved it relatively fast but when I went to turn it in he said he wanted me to use division first instead of multiplication, basically combining my power and fact functions. I have no idea why he wants it done this way because I am getting the correct answer but he won't accept the assignment until I do it.

I tried several times to get my head around the solution but I'm not a Comp Sci major, and haven't taken math in 6+ years so its turning the gears in my brain pretty hard. Any help would be much appreciated.

double power(double x, int n)
{
    int     i = 0;
    double  prod = 1.;

    for ( ; i++ < n; )
        prod = prod * x;

    return prod;
}

double fact (int n)
{
    int     i;
    double prod = 1.;

    for (i = 1; i <= n; i++)
        prod = prod * i;

    return prod;
}

double mySin(double x)
{
    int     i, sign;
    double  sum = 0;

    for (i = 0, sign = 1; i < 21; i++, sign = -sign)
        sum = sum + sign * power(x, 2 * i + 1)/ fact(2 * i + 1);
    return sum;
}

double myCos(double x)
{
    int     i, sign;
    double  sum = 0;

    for(i = 0, sign = 1; i < 21; i++, sign = -sign)
        sum = sum + sign *power(x,2 * i)/ fact(2 * i);
    return sum;
}

double myExp(double x)
{
    int     i, sign;
    double  sum = 0;

    for(i = 0, sign = 1; i < 21; i++, sign = sign)
        sum = sum + sign * power(x, i)/ fact(i);
    return sum;
 }

Upvotes: 3

Views: 273

Answers (1)

dbush
dbush

Reputation: 225737

The use of the power and factorial functions is inefficient. For each term, you're calculating the same set of products each time. You're also building large numbers that can lead to loss of precision.

Take a look at the definition of each series (here ^ denotes power and ! denotes factorial):

e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! + ...
sin(x) = x - x^3/3! + x^5/5! - + x^7/7! + ...
cos(x) = 1 - x^2/2! + x^4/4! - + x^6/6! + ...

For e^x, each term is x/n times the last, where n is the term number. Similarly, for sin(x) and cos(x), each term is - x^2/((2n-1)*2n) times the last. Use that instead of a power function and a factorial function to compute each successive term.

There's also a nice trick which involves a comparison which mathematically doesn't make sense but works because of the limited precision of floating point numbers to know when to stop calculating terms. See if you can figure it out.

Upvotes: 4

Related Questions