Be sure you have read, or at least skimmed, the assigned readings for classes through 9/19.
Do the following programming problems. You will end up with at least one code file per problem. Submit your program source (and any other needed files) by sending mail to bmassing@cs.trinity.edu with each file as an attachment. Please use a subject line that mentions the course and the assignment (e.g., ``csci 1120 hw 4'' or ``LL hw 4''). You can develop your programs on any system that provides the needed functionality, but I will test them on one of the department's Linux machines, so you should probably make sure they work in that environment before turning them in.
Newton's method for computing the square root of a non-negative number starts with an initial guess and then repeatedly refines it using the formula
(1) | |||
(2) | |||
(3) | |||
(4) | |||
(5) | |||
(6) | |||
(7) |
Write a C program that implements this algorithm and compares its results to those obtained with the library function sqrt(). Have the program prompt for , the threshold value, and a maximum number of iterations; do the above-described computation; and print the result, the actual number of iterations, the square root of as computed using library function sqrt(), and the difference between the value you compute and the one you get from sqrt(). Also have the program print an error message if the input is invalid (non-numeric or negative -- but notice that zero is okay).
Here are some sample executions
(assuming you call your program newton and compile with make)
[bmassing@diasw04]$ ./newton enter values for input, threshold, maximum iterations 2 .0001 10 square root of 2: with newton's method (threshold 0.0001): 1.41422 (3 iterations) using library function: 1.41421 difference: 2.1239e-06 [bmassing@diasw04]$ ./newton enter values for input, threshold, maximum iterations 2 .000001 10 square root of 2: with newton's method (threshold 1e-06): 1.41421 (4 iterations) using library function: 1.41421 difference: 1.59472e-12
Hints:
C, like many programming languages, has a library function (rand()) that can be used to generate a ``random'' sequence of numbers (quotes because it's not truly random -- more in class). Many languages have a similar function that generates ``random'' numbers in some specified range, useful if for example you're trying to simulate rolling a 6-sided die. C doesn't have such a function, but you can get the same effect using rand() and a little additional code. rand() itself generates a number between 0 and the library-defined constant value RAND_MAX, so to get a value in a smaller range you have to somehow map the larger range to the smaller one. The somewhat obvious way to do this is by computing a remainder (e.g., to map to two possible values, assign even values to 0 and odd values to 1). (I'll call this the ``remainder method''.) But with some implementations of rand() this gives results that aren't very good. The conventional wisdom is therefore to instead try to do a more-direct map (e.g., to map to two possible values, assign values from 0 through RAND_MAX/2 to 0 and the remaining values to 1). (I'll call this the ``quotient method''.)
Your mission for this problem is to complete a C program that, given a number of samples N and a number of ``bins'' B generates a sequence of N ``random'' numbers, uses both methods (remainder and quotient) to map each generated number to a number between 0 and B-1 inclusive, and counts for each method how many elements of the sequence fall into each bin (e.g., for each method bin 0 is how many elements of the sequence map to 0), and prints the result, as in the sample output below. To help you (I hope!) I'm providing a starter program, link below, which you should use as your starting point. Code at the bottom of the program shows how to apply both methods to something returned by rand(). The remainder method is straightforward; the quotient method is less so, but see the footnote1for an explanation.
One other thing to know about rand() is that by default it always starts with the same value (and produces the same sequence). To make it start with a different value, you can call srand() with an integer ``seed'', so your program should prompt for one of those too.
Sample execution
(assuming you call your program rands and compile with make):
[bmassing@diasw04]$ ./rands seed? 5 how many samples? 1000 how many bins? 6 counts using remainder method: (0) 154 (1) 188 (2) 171 (3) 161 (4) 155 (5) 171 counts using quotient method: (0) 172 (1) 175 (2) 183 (3) 150 (4) 168 (5) 152If you feel ambitious you could also have the program print maximum and minimum counts and the difference between them, as a crude measure of how uniform the distribution is:
[bmassing@diasw04]$ ./rands seed? 5 how many samples? 1000 how many bins? 6 counts using remainder method: (0) 154 (1) 188 (2) 171 (3) 161 (4) 155 (5) 171 min = 154, max = 188, difference 34 counts using quotient method: (0) 172 (1) 175 (2) 183 (3) 150 (4) 168 (5) 152 min = 150, max = 183, difference 33(You will get an extra-credit point for doing this.)
Here is a starter program that prompts for the seed, generates a few ``random'' numbers, and illustrates the two methods of mapping to a specified range: rands.c.
Of course, your program should check to make sure all the inputs are positive integers. (Yes, error checking is a pain, but it's an incentive to get better at copy-and-paste?)
Hints:
Include the Honor Code pledge or just the word ``pledged'', plus at least one of the following about collaboration and help (as many as apply).2Text in italics is explanatory or something for you to fill in. For programming assignments, this should go in the body of the e-mail or in a plain-text file honor-code.txt (no word-processor files please).
Include a brief essay (a sentence or two is fine, though you can write as much as you like) telling me what about the assignment you found interesting, difficult, or otherwise noteworthy. For programming assignments, it should go in the body of the e-mail or in a plain-text file essay.txt (no word-processor files please).