CS 2135: Lab 2


Lab Motivation and Goals

This lab is designed to help you practice

Exercises: Implementing Derivatives

Consider calculus. Assume we've defined a function f(x)=x^2 (x squared). What is d/dx f?

d/dx f = 2*x, which is a function.

So, what does d/dx do? It takes a function and returns a function (the derivative). That sounds like something we can write a contract for ...

          d/dx : (num -> num) -> (num -> num)  

In this series of exercises, you will implement the derivative function in Scheme.

How can we calcuate the derivative of a function? Given a function f, an argument x to f, and some small epsilon e (representing delta-x), we can compute the derivative of f(x) using the formula:

                       f(x+e) - f(x)
            lim        -------------
            e->0             e
So, we can compute the derivative of square with the formula
                       square(x+e) - square(x)
            lim        -----------------------
            e->0                 e

Let's implement derivatives!

  1. Define a global constant EPSILON to have some small value (say .01) using the following Scheme expression:

             (define EPSILON 0.01)

    [Note that you can use define in this way to define any constant, including examples constructed from data defintions.]

  2. Write a function d/dx-square that consumes a number (the argument to square, "x" in the above formula) and returns the value (number) of the derivative of square at the input with respect to EPSILON.

         ;; d/dx-square : num -> num 

  3. Generalize d/dx-square to work over any function from number to number (ie, abstract out square). Call the new function d/dx-at-x.

         ;; d/dx-at-x : (num -> num) num -> num 

  4. Redefine d/dx-square in terms of d/dx-at-x.

  5. d/dx-at-x doesn't have the same contract as d/dx does in calculus though, because d/dx returns a function on x. Our version takes x as an argument and returns the value of the derivative at x.

    Write a function d/dx that consumes a function from number to number and returns a the derivative (a function from number to number)

         ;; d/dx : (num -> num) -> (num -> num) 

    Note Don't start this problem from scratch. Start with your d/dx-at-x definition and figure out how to transform it to satisfy the contract for d/dx

  6. Redefine d/dx-square in terms of d/dx.

  7. Using d/dx-square, compute the derivative of square at different values of EPSILON. As EPSILON gets smaller, the derivative should produce values closer to 2*x.

  8. Using d/dx, define a function d/dx-cube that computes the derivative of cube. Try to do this without naming the cube function explicitly (ie, you shouldn't have (define (cube n) ...) in your code.

  9. When studying formulas involving limits (such as derivative), students often find it useful to watch how the value of the formula changes as the limit is reached. For d/dx, we'd like to see how the value gets closer to the closed-form derivative as EPSILON approaches zero.

    Write a program limit-values that consumes a limiting function (of one argument -- the one that approaches zero) and a smallest limit value (smaller than 1) and returns a list of values of the function at successively smaller values of EPSILON (starting with EPSILON=1).

         ;; limit-values : (num -> num) num -> list[num] 

    All of our programs derive from data definitions, so write down the data definitions that would drive this program.

    And, make sure your program will terminate.

    Test your program by checking that the derivative of square approaches 2*x.