In the last chapter when we computed the magnitude of a we squared each element of the vector before adding. Now consider an operation called normalization. Normalizing a vector produces a new vector which points in the same direction, but with a magnitude (length) of 1. Mathematicians refer to vectors of length one as unit vectors. Normalizing is an operation often used in writing low-level computer graphics programs. To normalize a vector we simply divide each element of the vector by the magnitude.
Scheme has a handy function called map which takes a function and a list, invokes the function on each element of the list, and returns the list of results. Some examples:
> (map car '((a b) (c d) (e f))) (a c e) > (map ((curry +) 2) '(1 5 2 4 3)) (3 7 4 6 5) > (define vec '(10 11 4 8)) > (map add1 vec) (11 12 5 9) > (map (lambda (x) (* x 2)) vec) (20 22 8 16)
(map (lambda (f) ((compose ((curry *) 2) f) 3)) (cons add1 (cons sub1 (cons (lambda (z) (* z 3)) ()))))
Now, we can use map to normalize the vector (10.5 10.1 3.5 2.0).
> (define vec '(10.5 10.1 3.5 2.0)) > (define the-mag (apply mag vec)) > (map (lambda (item) (/ item the-mag)) vec) (0.6946030627129489 0.6681419936572175 0.23153435423764962 0.13230534527865692) >
To accomplish this without using map, we would use the normal flat-recursion technique:
(define the-mag ...) (define normalize-v (lambda (v) (if (null? v) '() (cons (/ (car v) the-mag) (normalize (cdr v))))))
Define a procedure norm which takes a list of reals as its
argument and returns a normalized list. Recall normalizing is done by
dividing each element of the list by the magnitude. Use mag from Exercise 2 to compute the magnitude and map to perform the
normalizing.
> (and-map atom? '(a b c () g)) #t > (and-map pair? '((a b) 2 (g h) 4 5)) #f