v22.0310-003: Homework 1

Original Due date: Monday, September 21, midnight. New Due date: Wednesday, September 23, midnight.

Hand in both parts by email to me, been@cs.nyu.edu. Include the entire assignment in a single email message. Please use plain text. Do not send attachments or anything like that. If you are using pine, you can include your program files into the message body as plain text by using the ^R command. For the first question, you might want to use some mathematical symbols in your proof, which can be awkward in plain text. You don't need to do anything fancy; just be clear. For example, you can use ``x**n'' to mean ``x to the nth power''.


  1. You may recall that the trigonometric sine and cosine functions can be computed, for all real values x, by the following infinite series:

    sin(x) = x - x3/3! + x5/5! - x7/7! + ... + (-1)ix2i+1/(2i+1)! + ...

    cos(x) = 1 - x2/2! + x4/4! - x6/6! + ... + (-1)ix2i/(2i)! + ...

    We would like to approximate these functions by taking only the first n terms in the series, for some n, but we want to be able to guarantee that this approximation will not have too big of an error. (The error is the sum of all the terms after the first n terms. There are an infinite number of such terms.)

    Prove that, for the sine series, if 2n >= |x|, and if we approximate sin(x) by the first n terms in the series (i.e., terms i=0 through i=n-1), then the absolute value of the error is no bigger than the absolute value of the next term in the series (term i=n), which is |x2n+1/(2n+1)!|.

    Show, by a similar argument, that, for the cosine series, if 2n-1 >= |x|, then we can approximate cos(x) by the first n terms in the series, with error no greater than |x2n/(2n)!|.

    Hint: Use a simple fact from basic calculus: if S is the infinite series

    S = a1 - a2 + a3 - a4 + a5 - ...
    with alternating signs, and the ai's are positive and decreasing
    a1 > a2 > a3 > ...
    then a1 > S.
  2. Programming problem: The goal of this question is to use the results from Question 1 to write a program that computes sine and cosine up to a given error tolerance. The algorithm is to keep computing and adding terms until n, the number of terms added, satisfies the inequality 2n >= |x| for sine, or 2n-1 >= |x|, for cosine, and the absolute value of the next term that would be added is within the acceptable error tolerance.

    For this assignment you must accomplish this by making some modifications and extensions to the Progression class on page 15 of your textbook. The following paragraphs will explain this in greater detail.

    First, modify the Progression class by adding a currentSum() method which returns the sum of all the values in the progression reported so far. This will probably also require adding another variable, in addition to cur, and modifying the nextValue() method. Also, make the values be of type double instead of int; so the variable cur will be of type double, and the methods currentValue(), currentSum(), first(), nextValue(), and valueAt() should have return type double. (The parameter for valueAt() will still be of type int.)

    Next, write two classes that extend (inherit from) that modified Progression class. Call them CosProgression and SinProgression. These will be used to compute the terms and running sums in an infinite series for the cosine and sine function. These will be somewhat similar to the GeomProgression class on page 17. You will need variables to keep track of the index of the current term (``i'' in the above formulas), as well as x, the value that we will take the sine or cosine of. x should be set in the constructor, like b, the base in GeomProgression. Then you will need to override first() and nextValue(), as in GeomProgression, to compute the correct values for the particular progression (sine or cosine).

    Also, each class, SinProgression and CosProgression, should add a public method called eval, which will take one double parameter, and return a double value. The parameter will be the error tolerance, and the return value will be the sine (or cosine) of x to within that error tolerance. The computation will be done by the method developed in Question 1; that is, eval() will call first() to get the progression started, and then repeatedly call nextValue() until the conditions for stopping are met, and then the currentSum() can be returned as the value of the sine or cosine.

    So, the idea is that some routine or main program can compute the cosine of a number, x, by creating a CosProgression object for x, and that object can then be used to compute the cosine of x several times, for different error tolerances. (Similarly for sine.) Here is some sample code to demonstrate use of the CosProgression object. (This code hasn't been tested, so there might be bugs!)

    double smallAngle = 0.7;
    double bigAngle = 1.4;
    CosProgression cosSmallAngleProgression = new CosProgression(smallAngle);
    CosProgression cosBigAngleProgression = new CosProgression(bigAngle);
    double cosSmallAngle = cosSmallAngleProgression.eval(0.01);
    double cosBigAngle = cosBigAngleProgression.eval(0.01);
    double accurateCosBigAngle = cosBigAngleProgression.eval(0.0001);
    

    Finally, write a main program, analogous to class Tester on page 19, that will use the CosProgression and SinProgression classes to compute the cosine and sine of pi/3, pi/2, 2.0, 5.0, and 12.0. Compute the results for two error bounds: 0.01 and 0.0001. Print out the results. Also, print out the values for the sine and cosine of the above angles returned by the java functions Math.sin and Math.cos. In java, you can get the value of pi by using Math.PI. (PI is a constant declared in class Math, in package java.lang, but you don't have to know that for now.) Java also provides the function Math.abs(), for computing the absolute value.