a mathematical vector is a compound mathematical datum that keeps track of many things -- posn for many different dimensions, not just 2: space, time, temperature, ... one of our colleagues works with 20-dim spaces
( a1 ... aN )they are called N-tuples
[okay, this is not the most general def but it does for here]
there are two key operations on vectors in mathematics:
V1 + V2 :: addition of two vectors s * V :: multiplication of a vector with a scalar
in our simple example, vector addition means pointwise addition of two N-tuples and the multiplication of the scalar with every item in the vector
(a1 ... aN) + (b1 ... bN) = (a1+b1 ... aN + bN) s * (a1 ... aN) = (s * a1... a * aN)
build-vector : N (N -> X) -> (vector X) vector-ref : (vector X) N -> X
Task: define scalar* and vector+
;; scalar* : num (vector num) -> (vector num) ;; Purpose: scalar multipl for vectors (define (scalar* s vec) (build-vector (vector-length vec) (lambda (i) (* s (vector-ref vec i))))) ;; vector+ : (vector num) (vector num) -> (vector num) ;; Purpose: vector addition (pointwise) (define (vector+ vec1 vec2) (build-vector (vector-length vec1) (lambda (i) (+ (vector-ref vec1 i) (vector-ref vec2 i)))))
Now define scalar-product:
;; scalar-product : (vector num) (vector num) -> num ;; Purpose: scalar product for vectors ;; Example: (a1 .. aN> sp*= a1 * b1 + ... + aN * bN (define (scalar-product vec1 vec2) (foldl + 0 (build-list (vector-length vec1) (lambda (i) (* (vector-length vec1) (vector-length vec2)))))) ;; norm : (vector num) -> num ;; Purpose: compute the size (length) of a vector (define (norm vec) (sqrt (scalar-product vec vec)))
(define build-vector build-list)
(define vector-length length)
;; list-ref : (listof X) N -> X
;; Purpose: determine the a-nn-th item on a-list, start counting with 0
(define (list-ref a-list a-nn)
(cond
((and (cons? a-list) (= a-nn 0)) (first a-list))
((and (empty? a-list) (= a-nn 0)) (error ...))
((and (empty? a-list) (> a-nn 0)) (error ...))
(else (list-ref (rest a-list) (sub1 a-nn)))))
(define vector-ref list-ref)
No. Access to items is constant time:
| list | vector | structures |
|---|---|---|
| build-list : N (N -> X) -> (listof X) | build-vector : N (N -> X) -> (listof X) | (define-structure foo (ab cd ef)) |
| ... creates arbitrarily large values | ... creates arbitrarily large values | ... creates values from three components |
Access: (list-ref (list 'a 'b 'c) 2) |
Access: (vector-ref (list 'a 'b 'c) 2) |
Access: (foo-ef (make-foo 2 3 4)) |
| ... requires a-nn recursions | ... is instantaneous | ... is instantaneous |
In short, a vector combines the properties of a list (combines
arbitrarily many values into one) and a structure (gives instantaneous
access to the constituent values)
if a program potentially inspects "all" constituents, use list
if a program inspects individual constituents at "random", use vector
Example: the elevator program (picture) -- hardware needs to record the status of floors and the controller needs to sweep over it to find the proper one
vector-set! : (vector X) N X -> void (vector-set! status n PRESSED)Once it is served, the elevator should record that too:
(vector-set! status n SERVED)
Here are the basic sketches on our canvas:
;; FLOORS : num
(define FLOORS 10)
;; status : (vec boolean)
(define status (build-vector FLOORS (lambda (floor) #f)))
;; controller : num { 'up 'down } -> num
(define (controller cf dir)
(cond
((eq? dir 'up) (up-controller cf))
((eq? dir 'down) (down-controller cf))))
-------------------------------------------------------------------------
cf
-------------------------------------------------------------------------
upwards: find #t, starting from | ==>
downwards: find #f, starting from <==|
(define (up-controller cf)
(local ((define upwards-demand (find-true-up cf)))
(cond
(upwards-demand upwards-demand)
((find-true-down cf) (find-true-down cf))
(else cf))))
(define (down-controller cf)
(local ((define downwards-demand (find-true-down cf)))
(cond
(downwards-demand downwards-demand)
((find-true-up cf) (find-true-up cf))
(else cf))))
If something is arbitrarily large, we need an inductive data
definition. What is inductive about (build-vector n 'x) ?
The natural number! We need to work with variations on natural numbers!
;; find-true-up : N -> N or #f
;; Purpose : determine the first index i:
;; FLOORS > i >= cf where status is #t
;; otherwise produce #f
(define (find-true-up cf)
(cond
((= cf FLOORS) #f)
(else (cond
((vector-ref status cf) cf)
(else (find-true-up (add1 cf)))))))
|
;; find-true-up : N -> N or #f
;; Purpose : determine the first index i:
;; cf > i >= 0 where status is #t
;; otherwise produce #f
(define (find-true-down cf)
(cond
((= cf 0) #f)
(else
(local ((define new (sub1 cf)))
(cond
((vector-ref status new) new)
(else (find-true-down new)))))))
|
#| Tests: |# ;; press button on 0th floor (vector-set! status 0 #t) (= (controller 3 'up) 0) (= (controller 3 'down) 0) ;; press button on 6th floor (vector-set! status 6 #t) (= (controller 3 'up) 6) (= (controller 3 'down) 0)
| Matthias Felleisen | This page was generated on Mon Apr 19 09:00:37 CDT 1999. |