sum-of-divisors procedure introduced in section 3.3 and
explore what effect these changes have on the procedure itself and on
procedures which call it.
In particular, you will write a second version of
sum-of-divisors.Using the techniques we learned in class,
you should do a theoretical analysis of each version to produce
predictions about how the time the computer takes to do a computation
changes with the size of the computation. Next, you will measure the
time the computer takes to do computations of varying sizes. (This is
known as empirical testing.) Then you can compare your theoretical
predictions with your empirical results. You will also write a
procedure that uses sum-of-divisors, and do a similar
analysis.
sum-of-divisors in class on Monday, October 9. We also highly
recommend you write a procedure to compute the relative frequency of
abundant and deficient numbers (problem 5 below) for
more practice programming. Note that this is after only one day of
working on this project in lab. On Tuesday, October 10, you will
choose a partners and work on the remaining portions of the lab in
groups of two (with perhaps one group of three, should that prove
necessary due to an odd number of students).
We warn you that working in a group of two does not mean that your work load will be halved; in fact, some groups may find that the amount of hassle will effectively increase the work. Our intention is that you gain experience in working in teams, since teamwork is very common in today's workplace. You should have a clear understanding of each other's responsibilities, and be dependable and punctual in carrying them out. Also, be sure that neither partner monopolizes the work, but rather that you share it as equally as possible. Finally, we strongly encourage you to set up a group meeting with a lab instructor after your first or second day of working together in lab (October 12), so that we can assess how the project is going and, if need be, suggest strategies for more successfully working together.
In writing this report, you will want to include not only the procedures you used and the measurements you made, but a clear analysis of the asymptotic orders of growth (in O-notation) for each of the two methods of doing each of the two computations. In particular, for each method, you will need to
Use tables and/or graphs to more clearly show your results. Keep in mind that tables (or graphs) are most clear if headings (or axes) are clearly labeled with both the variable being measured and the units. Also, if your goal is to compare the results of two experiments, it's best if the data from both can be placed in the same table or graph. It's confusing for the reader if the data appear on separate pages.
You might also want to make some additional predictions that go beyond your measurements. Suppose you were interested in pursuing the abundant/deficient ratio study well beyond n=3200, perhaps to n=102400. How long would you expect each method to take? Would you want to experimentally verify this? A harder (optional) question is, how large an n would the computer be able to handle in a day? a week? a year?
When you write the project report, remember that your audience is generally knowledgeable about computer science and Scheme, but not about what you did.
As with project 1, you should also consult the document entitled Suggestions for clear reports in computer science courses.
run-time
for timing how long computations take, copy the following expression:
(load "~mc27/public/time.scm")into your definition window and execute it. To get the text's definitions of
sum-of-divisors and divides?, copy the procedures
in the following file into your definitions window and execute them:
~mc27/labs/sum-divisors/sum-of-divisors.scmNow you should time how long it takes to find the sum of divisors of 100, 1000, 10000, 100000, and 1000000. You should do the same timing repeatedly, at least for the smaller numbers, to get some idea how precisely repeatable the timings are. To illustrate how you would do a timing, here is a sample timing of the
sum-of-divisors of 100:
(run-time sum-of-divisors 100) ;Time: .04695454545454616 ;Value: 217The time is given in seconds; e.g., in the above example, the evaluation took a little less than five hundredths of a second. The time reported will not agree well with your own impression of the time taken, because it doesn't include time the computer spends doing other things, and also because for fast evaluations (such as the above) the evaluation is repeated until at least a second has elapsed and an average time for the repetitions is reported.
What is the ratio of times from each measurement to the next? (That is: What is the ratio of times going from 100 to 1000? From 1000 to 10000? And so forth.) How does this compare with your expectation? (Note: When answering questions like these in your project write-up, be sure to back up your answers with adequate arguments. In other words, give reasons, probably in the form of big Theta arguments, which explain your expectations.)
sum-of-divisors procedure other
than finding perfect numbers is to measure the relative frequency of
abundant and deficient
numbers. As mentioned in section 3.3, very few numbers are perfect. The
remaining numbers either have a sum of divisors that is more than twice
the number, in which case they are called abundant, or less than twice
the number, in which case they are called deficient. The empirical question
we'd like to ask is, are these two kinds of numbers equally common, or
does one predominate? If so, by how much? The usual mathematical way to
formulate this is to count how many numbers less than or equal to n
are abundant and how many are deficient, and take the ratio. Then repeat
this for larger and larger values of n. If the ratio approaches
closer and closer to some limiting value as n increases, then this
limiting ratio tells us the relative frequency of abundant and deficient
numbers. For example, if the ratio approaches a limit of 1, then abundant
and deficient numbers are equally frequent. On the other hand, a limiting
value of 1/2 would mean that there are roughly twice as many deficient
numbers as abundant numbers.
Write a procedure that generates an iterative process for computing this ratio, given n. Most of the work can be done by a subsidiary procedure that keeps count of how many abundant numbers it has found and how many deficient numbers it has found as it scans the range from 1 to n. Once the entire range has been scanned, one count can be divided by the other. Test your procedure to be sure that it works.
sum-of-divisors with your procedure for computing the
ratio, and double the size of the range being tested. What is the
running time of the procedure expressed in O-notation? By
roughly what factor do you expect the number of divides?
tests (and hence time) to increase? How about if you use the
sum-of-divisors procedure from exercise 3.6 with your
ratio finding procedure? (You can use the same general style of
reasoning as on page 81 to produce determine the running time
expressed in big Theta notation.)
Now measure how long your procedure takes to find the ratio for n
equal to 200, 400, 800, 1600 and 3200, and calculate the ratio of each
consecutive pair of times. Do this with each of the two definitions for
sum-of-divisors.
How well do your measurements agree with your predictions? Do the
abundant/deficient ratios seem to approach some simple limiting value?
If so, what?