@comment(Hey, EMACS, this is -*- SCRIBE -*- input)
@device(dover)
@make(6001)

@modify(excounter, numbered [Exercise @1], referenced [@1])

@PageHeading(left "6.001 -- Spring Semester 1986",
             center "@Value(Page)",
             right "Problem set 2")

@begin(center)
MASSACHUSETTS INSTITUTE OF TECHNOLOGY
Department of Electrical Engineering and Computer Science
6.001 Structure and Interpretation of Computer Programs
Spring Semester, 1986

Problem Set 2
@end(center)
@blankspace(0.25 in)

@begin(flushleft)
Issued: Tuesday, 11 February 1986

Due:
@begin(itemize)
Wednesday, 19 February 1986
for recitations meeting at 9:00, 10:00, and 11:00

Friday, 21 February 1986
for recitations meeting at 12:00, 1:00, and 2:00
@end(itemize)

Reading: From text, Chapter 1, sections 1.2 and 1.3.  
(This completes chapter 1.)
@end(flushleft)

Problem sets should always be handed in at recitation.  Late work will
not be accepted.  As explained in the Course Organization handout, we
are staggering the due-dates for problem sets, so as to
minimize crowding in the lab.  The Wednesday/Friday due dates will be
reversed during the second half of the semester to assure equitable
treatment of students in both morning and afternoon recitations.
Specific due dates will be announced as each problem set is handed
out.

@section(Homework exercises)

Write up and turn in the following exercises from the text:
@begin(itemize)

Exercise 1.11: Iterative exponentiation

Exercise 1.21: Meet Louis Reasoner.  Note, you need not do 1.19.

Exercise 1.23: Simpson's rule

Exercise 1.24: Iteration
@end(itemize)

Also do the following exercise:
@begin(itemize)
For each of the following expressions, what must @a[f]
be in order for the evaluation of the expression to not cause an
error?  For each expression, give a definition of @a[f] such that
evaluating the expression will not cause an error, and say what the
expression's value will be, given your definition.
@begin(example)
f

(f)

(f 3)

((f))

(((f)) 3)
@end(example)

@end(itemize)

@section(Programming Assignment:)

Hand in your work on all labelled problems.

@subsection(Pascal's Triangle)

Imagine that we have a triangular maze, with paths connecting an
entrance at the top to a set of bins at the bottom as in the diagram
below.  Eventually the path ends up in one of the bins at the
bottom of the lattice.  (Perhaps you have seen a demonstration of such
a maze in an exhibit on probability.)  We illustrate one
typical path on the diagram by labelling it with "*".

@begin(example)
level

0     *
      |*  
      | * 
      |  *
1     |   *
      |\  *\
      | \ * \
      |  \*  \
2     |   *   |
      |\  |*  |\
      | \ | * | \
      |  \|  *|  \
3     |   |   *   |
      |\  |\  *\  |\ 
      | \ | \ * \ | \
      |  \|  \*  \|  \
4     |   |   *   |   |
      |\  |\  *\  |\  |\  
      | \ | \ * \ | \ | \ 
      |  \|  \*  \|  \|  \      
5     |   |   *   |   |   |
      |\  |\  |*  |\  |\  |\  
      | \ | \ | * | \ | \ | \ 
      |  \|  \|  *|  \|  \|  \
6     |   |   |   *   |   |   \
    |   |   |   | * |   |   |   |
    -----------------------------
bin = 0   1   2   3   4   5   6 
@end(example)There are two ways to get to level 1.  There are 4 ways to get to
level 2  (1 way to get to level 2 bin 0, 2 ways to get to level 2 bin
1, and 1 way to get to level 2 bin 2).

@b[Problem 1:]
In general, how many ways are there to get to the n-th
level of the maze?  (This answer is easy.  Work it out before even
thinking about going to lab.)

It is a more complicated problem to determine how many different paths
there are from the vertex to a particular bin at the bottom of the
maze.

We observe that if we are at level zero we can get into the maze only
at bin zero.  If we are not at level zero there are only 2 ways to get
to bin k at level n -- we must come from either bin k of level n-1 or
bin k-1 at level n-1.  Thus the number of paths to bin k at level n
must be the sum of the number of paths to the contributing bins.  We
can formalize this description as a Scheme program as follows:

@begin(example)
(define (n-paths level bin)
  (if (= level 0)
      (if (= bin 0) 1 0)
      (+ (n-paths (- level 1) (- bin 1))
	 (n-paths (- level 1) bin))))
@end(example)

Compute, by hand, the table of values of @a[(n-paths n k)] for
n, k = 0, 1, 2, 3, 4, 5.  This takes very little work 
(than 5 minutes!) if you organize it carefully.  Start with small
values and you will soon see the pattern.  Check your answer
on a Chipmunk if you like.

You have probably noticed that the numbers you computed in the
previous exercise are the binomial coefficients (Pascal's triangle).
These numbers represent the number of combinations of n objects taken
k at a time, ignoring order.
@begin(example)
                       (n-paths n k) = C(n, k)
@end(example)
Our algorithm for computing these numbers is one of the worst that a
sensible person might devise.


@b[Problem 2:] 
In general, how many calls to @a[n-paths] are required to
compute the value of @a[(n-paths n k)] using the algorithm indicated
above?  The answer is a simple function of n (independent of k).

An alternative (and far better way) to compute binomial coefficients
is to use the formula:
@begin(example)
		       C(n, k) = n!/(k! (n-k)!)
@end(example)
Unfortunately, factorials become very large very fast, and arithmetic
with large numbers is expensive.  Also, computing C(n, k) in this way
requires a number of redundant multiplications (because some of the
multiplications in the computation of n! are just to be undone by the
division by either k! or (n-k)!).

@b[Problem 3:]
Write a short, elegant program for @a[(n-paths level bin)],
that avoids the redundant multiplications indicated above.  Hand in
this program, along with examples of its use, 
showing that it works for n up to 6.  Give an estimate
of the order of growth of time and space used by your program.

@subsection(Smoothing)

When random errors occur in measurements it is common to average
data to reduce their effect.  The following exercises are concerned 
with a form of averaging called smoothing.  Consider measurements 
of the height of a ball thrown upwards with velocity V at
time -T (with T chosen such that the ball reaches its maximum height
(0) at time t=0.  The true position of the ball is y(t)=Vt-gt@+[2]/2,
the measured position m(t)=y(t)+e(t), where e(t) is the measurement
error.

@b[Problem 4:]
Construct a procedure @a[true-pos] with arguments V G and t that 
computes the true height of the ball at time t.

To reduce the effect of measurement errors, we might attempt to smooth
the data by averaging adjacent values: S[m(t)] = (m(t+h)+m(t-h))/2,
where h is a small time increment.

We can express the idea of smoothing as a procedure (analogous to
the @a[deriv] procedure discussed on p. 68 of the text) as follows:
@begin(example)
(define (smooth f h)
  (lambda (x)
    (average (f (+ x h))
	     (f (- x h)))))

(define (average x y)
  (/ (+ x y) 2))
@end(example)

@b[Problem 5:]
Even in the absence of random error (e(t)=0) S[m(t)] differs from
the true position, y(t).  We call this difference the systematic error
introduced by smoothing.  Determine how the systematic error depends
on h.  You are to develop an expression for the systematic error in
the measurement of y(t) as a function of h.

@b[Problem 6:]
Verify, by numerical experiment, that the systematic error
introduced by applying @a[smooth] to @a[true-pos] has the 
dependence on h that you determined above.

When the random error term is non-zero, S[m(t)] differs from y(t) by
the sum of the systematic error determined above and a term equal to
(e(t-h)+e(t+h))/2.  In many cases this is smaller than e(t).  For
example, when e(t-h), e(t), and e(t+h) are roughly of the same size,
(e(t-h)+e(t+h))/2 is of the same size when e(t-h) and e(t+h) are of
the same sign, but smaller when they differ in sign. In most practical
situations, h is chosen by compromise since reducing the size of h 
decreases the systematic error, but also reduces the likelihood that 
the contributions of e(t-h) and e(t+h) to S[m(t)] will cancel out.

When the random error of measurement is large it is often advantageous
to repeat the smoothing operation a number of times, though this will
increase the systematic error.  So, for example, @a[(smooth (smooth m h)
h)] may be less noisy than @a[(smooth m h)] which may be less noisy than m.

One useful abstraction for repeatedly applying a procedure is the
@a[repeated] procedure, defined below:
@begin(example)
(define (repeated f n)
  (if (= n 0)
      identity
      (compose f (repeated f (- n 1)))))

(define (identity x) x)

(define (compose f g)
  (lambda (x) (f (g x))))
@end(example)

For example, using this procedure, one can write:

@begin(example)
==> ((repeated square 3) 5)
390625
@end(example)

@b[Problem 7:]
Define and test a procedure, @a[nth-smooth], of three arguments, @a[n] --
the number of times to apply the smoothing procedure, @a[f] -- the
function to smooth, and @a[h] -- the smoothing interval.  @a[nth-smooth] must
return the smoothed procedure.  For example, @a[(nth-smooth 2 m h)] should
return a procedure equivalent to @a[(smooth (smooth m h) h)].  You should
be sure to work this out carefully before testing it on a Chipmunk.
The required procedure is not long, but some thought is required to 
get it right.

@begin(comment)
   ***** Answer
   (define (nth-smooth n f h)
     ((repeated (lambda (g) (smooth g h)) n) f))
@end(comment)

@a[((smooth f h) t)] is equivalent to the
algebraic expression (f(t-h)+f(t+h))/2.  Write algebraic expressions
equivalent to @a[((smooth (smooth f h) h) t)] and to @a[((smooth (smooth
(smooth f h) h) h) t)].  You should see that the coefficients of f in
these expressions are closely related to the numbers in Pascal's
triangle, discussed above.

@b[Problem 8:]
How many times must @a[f], the procedure that implements the function
being smoothed, be applied when evaluating @a[(nth-smooth n f h)]?


@b[Problem 9:]
Write a different implementation of @a[nth-smooth] 
that applies the procedure that
implements the function being smoothed only n+1 times 
when evaluating @a[(nth-smooth n f h)]?
Make use of your work in Problem 3, above. 
