2

I have been struggling with this code and just do not seem to grasp what I am doing wrong.

The code is suppose to calculate : Sum of a series of "Cosine" with pattern [(-1)^i(x)^2i]/(2i)!

pattern

Here is my code thus far:

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

float factorial(int n){
    if (n==0)
        return 1;
    else
        return 2*n*factorial(n-1);
}

int main (){
    float i, n;
    float sum=0;
    printf("Enter desired interger: ");
    scanf("%f", &n);

    for (i=0; i<=1; i++) 
        sum = sum + (pow(-1,i)*pow(n,2*i))/(factorial(n));

    printf("The value is %f\n", sum);
    return 0;
}

I still working on it, any info or help will be much appreciated!

edit:

Just fixed it guys, this is new format I had to use for my professor:

#include <stdio.h>
#include <math.h>
int factorial(int n)
{
if (n==0) return 1;
else
return n*factorial(n-1);
}
float mycos(float x)
{
float sum=0;
int i;
for (i=0;i<=10;i++) sum = sum + (pow(-1,i)*pow(x,2*i))/factorial(2*i);
return sum;
}
int main()
{
int i=1;
printf("     x    mycos(x)   cos(x)\n");
for (i=1;i<=10;i++)
printf(" %f %f %f\n", i*.1, mycos(i*.1), cos(i*.1));
return 0;
}

Thank you all for your explanations, they helped out Immensely!

CC BY-SA 3.0
3
  • 2
    So this is the taylor expansion series for a cosine! What IS or ISNT working for you? Commented Feb 26, 2014 at 19:14
  • I think that my biggest issue was both understanding the problem and how to successfully translate in a format that the computer would understand. I just realized towards the end that I had to break it down to make it work properly.
    – Edward
    Commented Feb 26, 2014 at 21:01
  • You should also look at Ed Heal's comment under my answer, as he talks about a further refinement that is better performing by keeping a running denominator factorial as well! I don't know what the exact assignment is, but........ Commented Feb 26, 2014 at 21:27

6 Answers 6

3

One thing I see, is that your for loop within main only runs through 2 real iterations, once for i == 0, and again for i == 1.

For the taylor expansion to work fairly effectively, it needs to be run through more sequence terms (more loop iterations).

another thing I see, is that your denominator is the n! rather than (2 * n)!

For efficiency, I might also implement the factorial routine as follows:

unsigned int factorial(int n){
    unsigned int product = 1;

    for(int I = 1; I <= n; I++) product *= I;

    return product;
}

The above factorial routine is for a more EXACT factorial calculation, which perhaps you don't need for this purpose. For your purposes, perhaps the floating point variant might be good enough.

float factorial(int n){
    float product = 1;

    for(int I = 1; I <= n; I++) product *= (float)I;

    return product;
}

I should also note why I am stating to perform factorial in this manner. In general a loop construct will be more efficient than its recursive counterpart. Your current implementation is recursive, and thus the implementation I provide SHOULD be quite a bit more efficient from both performance, and memory utilization.

CC BY-SA 3.0
7
  • 1
    A problem with your revised factorial code is that it uses integer calculations instead of float, and you can't store more than 12! or thereabouts in an int. Commented Feb 26, 2014 at 19:25
  • @JonathanLeffler Actually this isn't really a problem, as a factorial is an INTEGER only mathematical function. A floating point from a factorial any larger than 12! is simply garbage (mathematically). However in this particular case, I see your point, that perhaps the floating point ESTIMATION could be good enough for calculation of cosine. I will update my answer! Commented Feb 26, 2014 at 19:31
  • 1
    More particularly, the problem is that the 'integer approximation to factorial' for values greater than 12 is (mathematically) garbage, because the mathematical value is too big to fit into a 32-bit integer. You warded off undefined behaviour by using unsigned int, but that leaves you with modulo 2^32 arithmetic on the value of the factorial. Commented Feb 26, 2014 at 19:38
  • @JonathanLeffler - Toshay :-) Commented Feb 26, 2014 at 20:24
  • I fail to understand why compute the factorial for each item in the series. seems rather wasteful. Also will overflow when that can be easily overcome.
    – Ed Heal
    Commented Feb 26, 2014 at 21:22
2

Considering computation expense, you need to stop calculating the series at a point. The more you go, the more precise the result will be, but the more your program spends time. How about this simple program:

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

#define ITERATIONS 10 //control how far you go

float factorial(int n){
    if (n==0)
        return 1;
    else
        return n*factorial(n-1);
}

int main (){
    float n;
    float sum=0;
    printf("Enter desired float: ");
    scanf("%f", &n);

    int c, i;
    for (i=0; i<=ITERATIONS; i++) {
        c = (i%2)==0? 1 : -1;
        sum = sum + (c*pow(n,2*i+1))/(factorial(2*i+1));
    }

    printf("The value is %f\n", sum);
    return 0;
}
CC BY-SA 3.0
3
  • This is the one that helped me out the most, thank you!
    – Edward
    Commented Feb 26, 2014 at 20:42
  • I used both answers to figure it out, yours helped me see the input error while the other one talked more about concept and helped me realize that my thought process was wrong. I can only choose one, but I still up-voted your response. (I wish I could check-mark both actually). I am sorry though if I offended you but thankful that you came across my plea of help.
    – Edward
    Commented Feb 26, 2014 at 21:12
  • No worries my friend ;) I like the other answer too. Wish you success on your C coding.
    – Farzad
    Commented Feb 26, 2014 at 21:15
1

1.) You are only multiplying even no.s in factorial function return 2*n*factorial(n-1); will give only even no.s. Instead you can replace n with 2n here- sum = sum + (pow(-1,i)*pow(n,2*i))/(factorial(2n)); This will give the correct (2n!). 2.) Check for the no, of iterations for (i=0; i<=1; i++) this will only run your loop twice. Try more no. of iterations for more accurate anwer.

CC BY-SA 3.0
1

Why are you calculating power etc for each item in the series? Also need to keep numbers in a suitable range for the data types

i.e. for cos

bool neg_sign = false;
float total = 1.0f;
float current = 1.0f;
for (int i = 0; i < length_of_series; ++i) {
    neg_sign = !neg_sign;
    current = current * (x / ((2 * i) + 1)) * (x / (( 2 * i) + 2));
    total += neg_sign ? -current : current;
}

EDIT

Please see http://codepad.org/swDIh8P5

CC BY-SA 3.0
4
  • sign = !sign, did you mean neg_sign ? Commented Feb 26, 2014 at 19:39
  • @Mhd.Tahawi - yes - was just fixing that
    – Ed Heal
    Commented Feb 26, 2014 at 19:40
  • It is part of the assignment, I needed to display values of "x" in both my own cosine function and that of math.h library and compare the results. The goal is to figure out how to write and create the necessary data to be able to plot. What you did was more advanced than my current level of mastery but I hope to be able to understand it soon (My experience includes about 4-6 weeks, I was thrown into the fire with this class hahaha). Thank you for your input!
    – Edward
    Commented Feb 26, 2014 at 23:03
  • @Edward - I just applied some algebra to the original summation. How do you make the nth factorial from the (n-2) factorial? How do you make x^n from x^(n-2)? Surely you can figure that out - bit of maths. Then just a bit of rearrangement to keep the multiplications of similar magnitude to reduce errors
    – Ed Heal
    Commented Feb 26, 2014 at 23:11
1
#include<stdio.h>
# define PRECISION 10                      /*the number of terms to be processed*/
main()
{
                 float x,term=1,s=1.0;
                 int i,a=2;
                 scanf("%f",&x);
                 x=x*x;
                 for(i=1;i<PRECISION;i++)
                 {
                           term=-term*x/(a*(a-1));
                           s+=term;
                           a+=2;
                 }
                 printf("result=%f",s);
}
CC BY-SA 3.0
0

Your factorial() function actually calculates 2n.n!, which probably isn't what you had in mind. To calculate (2n)!, you need to remove the 2* from the function body and invoke factorial(2*n).

CC BY-SA 3.0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.