Exercise 1.44 introduces the idea of smoothing a function, a concept from signal processing. The smoothed version of a function f is the function whose value at x is the average of f(x), f(x + dx), and f(x - dx), where dx is some small value.
We're to write a procedure
smooth
that takes as its input a procedure that computes f(x) and returns a procedure that computes the smoothed f. Since it is sometimes valuable to repeatedly smooth a function, we also need to show how to generate an n-fold smoothed function using smooth
and the repeated
procedure from exercise 1.43. The exercise doesn't specify a value for dx, so we'll pass that in as a parameter to smooth
.The
smooth
procedure is fairy straightforward to implement, but a little bit complicated to test. Here is the implementation:(define (smooth f dx)
(lambda (x)
(/ (+ (f x)
(f (+ x dx))
(f (- x dx)))
3)))
But what should we use for test data? It would be nice to have some independent data to use to verify that the function works, but we don't have any. We can create some using a spreadsheet though (click the image to enlarge).
You can see from the image the affects of smoothing on the sine wave function. It's already a smooth function, so instead of the intended affect of smoothing out noise, we've just damped the function. Still, this gives us data to test with. Here's the output of our smooth function at 90 and 180 degrees.
> (sin (/ pi 2))
1.0
> ((smooth sin 0.7) (/ pi 2))
0.8432281248563256
> (sin pi)
1.2246467991473532e-016
> ((smooth sin 0.7) pi)
7.401486830834377e-017
To complete the exercise we need to write an n-fold smooth function using the
repeated
function.(define (n-fold-smooth f dx n)
(repeated (smooth f dx) n))
Repeatedly smoothing the sine function in this way should have the affect of simply damping the function even more.
> ((n-fold-smooth sin 0.7 2) (/ pi 2))
0.6297176112540723
> ((n-fold-smooth sin 0.7 3) (/ pi 2))
0.49659100370209336
> ((n-fold-smooth sin 0.7 4) (/ pi 2))
0.4017400886852076
Related:
For links to all of the SICP lecture notes and exercises that I've done so far, see The SICP Challenge.
6 comments:
(define (impulse-maker a y)
(lambda (x)
(if (= x a)
y
0)))
(define my-impulse-function
(impulse-maker 0 6))
Compare:
> ((n-fold-smooth my-impulse-function 0.00001 3) 0)
2
> (+ 0.0 ((smooth (smooth (smooth my-impulse-function 0.00001) 0.00001) 0.00001) 0))
1.5555555555555556
Hey Bill, there's a mistake in your n-fold-smooth procedure, just like dmi3s said.
The corrected version is:
(define (n-fold-smooth f n)
((repeated smooth n) f))
(define dx 0.00001)
(define (smooth f)
(lambda (x) (/ (+ (f (- x dx))
(f x)
(f (+ x dx)))
3.0)))
I defined dx outside the function as the authors of SICP had done this in section 1.3.4 for the deriv procedure used in Newton's method.
You can check that this version of n-fold-smooth gives the correct result by using the procedures given by dmi3s.
You were applying the smoothed function to itself instead of applying smooth to the smoothed function. i.e. You were doing ((smooth f)^n) instead of ((smooth)^n f).
Applying smooth to sin results in [(2 cos dx + 1) / 3] sin x.
This confirms that smooth merely scales sin but doesn't change its shape.
Note that for small dx, the above formula can be approximated by (1 - dx² / 3) sin x.
Applying n-fold-smooth to sin results in
[(2 cos dx + 1)^n / 3^n] sin x.
This confirms that n-fold-smooth merely scales sin but doesn't change its shape.
Note that for small dx, the above formula can be approximated by [1 - dx^(2n) / 3^n] sin x.
Correction to my last comment…
The approximation formula I gave previously is incorrect, it should have been
(1 - n dx² / 3) sin x.
Post a Comment