CS 2073, Spring 2006
 Program 10
 Infinite Series
 Due (on time): 2006-04-28  23:59:59
 Due (late):        2006-05-01  23:59:59

Program 10 must be emailed to: nrwagner@cs.utsa.edu
following directions for: running and submitting a C program, with deadlines:
  • 2006-04-28  23:59:59 (that's Monday, 28 April 2006, 11:59:59 pm) for full credit.
  • 2006-05-01  23:59:59 (that's Friday, 1 May 2006, 11:59:59 pm) for 75% credit.


Sorry, still under construction!


Introduction: For this program you are to use infinite series to calculate approximate values for certain functions, such as exp, sin, cos, arcsin, and arctan. I will give you a program for exp, and you are to write the programs for sin and for arctan, using the second and fifth formulas below for these functions:


Program to calculate exp: There are many ways to structure this. I have broken the calculations up below to make them easier to understand and to modify. This program uses separate variables for the power of x, the coefficient of this power, the term (product of the previous two), and the cumulative sum. In case the signs alternate, you could use yet another variable for the sign.

File: expon.c, exp(x) Results of two runs
#include <stdio.h> /* for I/O */
double expon(double x);

int main() {
   double x;
   printf("Enter value for x--->");
   scanf("%lf", &x);
   printf("exp(%0.4f) = %19.15f\n",
      x, expon(x));
}

double expon(double x) {
   double coeff, xpower, term, sum;
   int n = 0;  /* term number */
   coeff = 1;  /* coefficient on term */
   xpower = 1; /* power of x */
   sum = 1;    /* cumulative sum */
   
   while(1) {
      n++; /* nth term added in */
      coeff = coeff/n; /* new coefficient */
      xpower = xpower*x; /* new power of x */
      term = coeff*xpower; /* nth term */
      sum = sum + term;  /* cumulative sum */
      printf("Step %2i: ", n);
      printf("Term:%19.15f, Sum:%19.15f\n",
         term, sum);
      /* check if term has gotten small */
      if (fabs(term) < 1.0e-14) break;
   }
   return sum; /* this is exp(x) */
}
Enter value for x--->1.0
Step  1: Term:  1.000000000000000, Sum:  2.000000000000000
Step  2: Term:  0.500000000000000, Sum:  2.500000000000000
Step  3: Term:  0.166666666666667, Sum:  2.666666666666667
Step  4: Term:  0.041666666666667, Sum:  2.708333333333333
Step  5: Term:  0.008333333333333, Sum:  2.716666666666666
Step  6: Term:  0.001388888888889, Sum:  2.718055555555555
Step  7: Term:  0.000198412698413, Sum:  2.718253968253968
Step  8: Term:  0.000024801587302, Sum:  2.718278769841270
Step  9: Term:  0.000002755731922, Sum:  2.718281525573192
Step 10: Term:  0.000000275573192, Sum:  2.718281801146385
Step 11: Term:  0.000000025052108, Sum:  2.718281826198493
Step 12: Term:  0.000000002087676, Sum:  2.718281828286169
Step 13: Term:  0.000000000160590, Sum:  2.718281828446759
Step 14: Term:  0.000000000011471, Sum:  2.718281828458230
Step 15: Term:  0.000000000000765, Sum:  2.718281828458995
Step 16: Term:  0.000000000000048, Sum:  2.718281828459043
Step 17: Term:  0.000000000000003, Sum:  2.718281828459046
exp(1.0000) =   2.718281828459046

Enter value for x--->0.1
Step  1: Term:  0.100000000000000, Sum:  1.100000000000000
Step  2: Term:  0.005000000000000, Sum:  1.105000000000000
Step  3: Term:  0.000166666666667, Sum:  1.105166666666667
Step  4: Term:  0.000004166666667, Sum:  1.105170833333333
Step  5: Term:  0.000000083333333, Sum:  1.105170916666667
Step  6: Term:  0.000000001388889, Sum:  1.105170918055555
Step  7: Term:  0.000000000019841, Sum:  1.105170918075397
Step  8: Term:  0.000000000000248, Sum:  1.105170918075645
Step  9: Term:  0.000000000000003, Sum:  1.105170918075647
exp(0.1000) =   1.105170918075647

Another run
Enter value for x--->-1.0
Step  1: Term: -1.000000000000000, Sum:  0.000000000000000
Step  2: Term:  0.500000000000000, Sum:  0.500000000000000
Step  3: Term: -0.166666666666667, Sum:  0.333333333333333
Step  4: Term:  0.041666666666667, Sum:  0.375000000000000
Step  5: Term: -0.008333333333333, Sum:  0.366666666666667
Step  6: Term:  0.001388888888889, Sum:  0.368055555555556
Step  7: Term: -0.000198412698413, Sum:  0.367857142857143
Step  8: Term:  0.000024801587302, Sum:  0.367881944444444
Step  9: Term: -0.000002755731922, Sum:  0.367879188712522
Step 10: Term:  0.000000275573192, Sum:  0.367879464285714
Step 11: Term: -0.000000025052108, Sum:  0.367879439233606
Step 12: Term:  0.000000002087676, Sum:  0.367879441321282
Step 13: Term: -0.000000000160590, Sum:  0.367879441160691
Step 14: Term:  0.000000000011471, Sum:  0.367879441172162
Step 15: Term: -0.000000000000765, Sum:  0.367879441171397
Step 16: Term:  0.000000000000048, Sum:  0.367879441171445
Step 17: Term: -0.000000000000003, Sum:  0.367879441171442
exp(-1.0000) =   0.367879441171442


Details:
  1. sin function: Modify the code for the exp function so that it will calculate the sin function instead. Note that you will need to alternate signs with each term. Use the following for testing:

    1. Use the fact that sin(pi/2) = 1.0, so enter pi/2 = 1.570796326794896 as your value for x and see if your series for sin converges to 1.0.
    2. Use the fact that sin(pi/6) = 0.5, so enter pi/6 = 0.523598775598299 as your value for x and see if your series for sin converges to 0.5.
    3. Use the fact that sin(pi/4) = sqrt(2)/2, so enter pi/4 = 0.785398163397448 as your value for x and see if your series for sin converges to sqrt(2)/2 = 0.707106781186548.
    4. Use the fact that sin(pi/3) = sqrt(3)/2, so enter pi/3 = 1.047197551196597 as your value for x and see if your series for sin converges to sqrt(3)/2 = 0.866025403784439.

  2. arctan function: Very similar to sin and simpler.

    Use the fact that tan(pi/6) = 1/sqrt(3), or in other words arctan(sqrt(3)/3) = pi/6, so enter 0.577350269189626 as your value for x and see if your series for arctan converges to pi/6 = 0.523598775598299.


Slow Convergence: The series above all converge quickly for the given values. Let's try two examples of slow convergence:

  1. Use the fact that tan(pi/4) = 1, or in other words arctan(1) = pi/4, so enter 1.0 as your value for x and see if your series for arctan converges to pi/4 = 0.785398163397448. You must not check that the terms are getting very small before you terminate the loop, because this will not happen until n gets very large indeed. Also, do not print each term, but just print the final value, using n < 1000, then n < 1000000 and finally n < 100000000.


Use of C's pow function: You should not use the function pow ("raise to a power") from the C math library. This function may make it easier in some ways to write the functions of this assignment, but the idea of the assignment is to calculate these "transcendental" functions, without using the same or similar functions. The pow function might be implemented using exp and log, and exp is one of the functions we are implementing. If you are allowed to use the C math library, all these functions are already there, under the names: exp, sin, cos, asin, and atan.


What you should email: Refer to the submissions directions and to deadlines at the top of this page. The text file that you submit should first have Your Name, the Course Number, and the Program Number. The rest of the file should have the following in it, in the order below, and clearly labeled, including at the beginning the appropriate item letters: a, b, c, etc.

 Contents of email submission for Program 10:

Last Name, First Name; Course Number; Program Number.

  1. Source code for two functions: sin, and atan.
  2. Three runs of these functions as follows:
    • One of the 4 runs suggested under Item 1 above.
    • The run suggested under Item 2 above.
    • One of the 3 runs suggested under Item 3 above.


Extra credit for crazies: Try to use the following expression as a definition for arctan. (This complex-looking expression is called a continued fraction.)

This isn't as hard to evaluate as it might look. You need to fix a given size for the continued fraction. For example, if you leave off the three dots at the end, the above becomes a specific fraction. To evaluate this fraction, work from the bottom up to the top. So start with a variable r = 13. That's the very bottom of the fraction (without the 3 dots). Then set r = 11 + 36*x*x/r;, giving the next level up. Then set r = 9 + 25*x*x/r;, giving the next level up. Continue up the fraction in this way, until the next to the last step: r = 1 + x*x/r;, followed by a special final step r = x/r;.

More generally, let n be a variable in a for loop that starts at 6 and decrements down to 1. Each of the steps above can be written as a single assignment involving n, followed by the final special step.

This particular expression converges very fast for x = 1, so this it is an efficient way to calculate arctan(1) numerically, where the series we used above converges very slowly (and 100000000 terms yield only 12 digits of accuracy). The same series for arctan(2) gives

so that this series obviously doesn't converge (the terms are increasing in size).

The calculation illustrated three paragraphs above uses n = 6 for the number of steps. For calculation of each of the following:


Revision date: 2006-04-20. (Please use ISO 8601, the International Standard.)