Fundamentals of Computer Science I: Media Computing (CS151.02 2007F)

Vectors


Summary: In this laboratory, you will explore various aspects of the Vector data type that Scheme provides as an alternative to lists.

Exercises

Exercise 1: Create a Simple Vector

a. In the interaction window, type in a vector literal that denotes a vector containing just the two elements 3.14159 and 2.71828. How does DrFu display the value of this vector?

b. Create a vector that contains the same two values by using the vector procedure.

c. Create a vector that contains the same two values by using the make-vector and vector-set! procedures.

Exercise 2: Modifying Lists and Vectors

Consider the following code. (That is, read it, don't enter it.)

> (define aardvark (list 1 2 3 4))
> (define baboon aardvark)
> (define aardvark (cons 5 (cdr aardvark)))
> (define chinchilla (vector 1 2 3 4))
> (define dingo chinchilla)
> (vector-set! chinchilla 0 5)

a. What do you expect the output of the following commands to be?

> (list-ref aardvark 0)
_____
> (list-ref baboon 0)
_____

b. Verify your answer experimentally. (That is, you can type in the commands now.)

c. What do your results suggest about Scheme?

d. What do you expect the output of the following commands to be? (That is, think about the answer; don't just type it in.)

> (vector-ref chinchilla 0)
_____
> (vector-ref dingo 0)
_____

e. Verify your answer experimentally. (You can type the commands now.)

f. What do your results suggest about Scheme?

Exercise 3: Summing Vectors

Write a procedure, (vector-sum numbers), which takes one argument, a vector of numbers, and returns the sum of the elements of that vector.

You can use vector->list from the reading as a pattern for vector-sum; only a few judicious changes are needed. However, you should not use vector->list as a helper.

;;; Procedure:
;;;   vector->list
;;; Parameters:
;;;   vec, a vector
;;; Purpose:
;;;   Builds a list that contains the elements of vec in the same order.
;;; Produces:
;;;   lst, a new list.
;;; Preconditions:
;;;   [None]
;;; Postconditions:
;;;   The element at position i of lst is the element at position
;;;     i of vec for all reasonable i.
;;;   Does not change vec.
(define vector->list
  (lambda (vec)
    (vector->list-kernel vec 0 (vector-length vec))))

;;; Procedure:
;;;   vector->list-kernel
;;; Parameters:
;;;   vec, a vector
;;;   start, an integer
;;;   finish, an integer
;;; Purpose:
;;;   Builds a list that contains elements start ... finish-1 of vec
;;; Produces:
;;;   lst, a new list.
;;; Preconditions:
;;;   start >= 0
;;;   finish >= start
;;;   finish <= length of vec
;;; Postconditions:
;;;   The element at position i of lst is the element at position
;;;     i+start of vec for all reasonable i.
;;;   Does not change vec.
(define vector->list-kernel
  (lambda (vec start finish)
    ; We stop at the finish.
    (if (= start finish)
        ; There are no more elements to put into a list, so use
        ; the empty list.
        null
        ; Otherwise, add the element at position start to a list of
        ; the remaining elements.
        (cons (vector-ref vec start)
              (vector->list-kernel vec (+ 1 start) finish)))))

Exercise 4: Filling Vectors

In the reading on vectors, we saw that it was possible to implement list->vector and vector->list by using more primitive operations (particularly vector-set! and vector-length).

Here's the definition of list->vector and its kernel.

;;; Procedure:
;;;   list->vector
;;; Parameters:
;;;   lst, a list.
;;; Purpose:
;;;   Convert the list to a vector.
;;; Produces:
;;;   vec, a vector
;;; Preconditions:
;;;   lst is a list
;;; Postconditions:
;;;   vec is a vector.
;;;   The length of vec equals the length of lst.
;;;   The ith element of vec equals the ith element of lst for
;;;     all "reasonable" i.
(define list->vector
  (lambda (lst)
    (list->vector-kernel! lst ; Copy the whole list
                          0   ; Starting at position 0
                          (make-vector (length lst) null)
                              ; Into a new vector of the appropriate length
                          )))

;;; Procedure:
;;;   list->vector-kernel!
;;; Parameters:
;;;   lst, a list to copy
;;;   pos, a position in the vector
;;;   vec, a vector
;;; Purpose
;;;   Copy values from lst into positions pos, pos+1, ...
;;; Produces:
;;;   vec, the same vector but with different contents.
;;; Preconditions:
;;;   The length of vec = pos + the length of list. [Unverified]
;;;   pos >= 0. [Unverified]
;;; Postconditions:
;;;   Element pos of vec now contains element 0 of list.
;;;   Element pos+1 of vec now contains element 1 of lst.
;;;   Element pos+2 of vec now contains element 2 of lst.
;;;   ...
;;;   The last element of vec now contains the last element of lst.
(define list->vector-kernel!
  (lambda (lst pos vec)
    ; We don't bother to verify the preconditions because this
    ; procedure should only be called by something that has already
    ; verified the preconditions (explicitly or implicitly).

    (cond 
      ; If there's nothing left to copy, stop.
      ((null? lst) 
       vec)
      ; Otherwise, copy the initial element of the list and
      ; then copy the remaining elements
      (else
       (vector-set! vec pos (car lst))
       (list->vector-kernel! (cdr lst) (+ pos 1) vec)))))

a. The design of list->vector is a bit subtle. Explain what the kernel does. If you're not completely sure, you may want to add a call to display to the kernel, as in

     (display (list 'l2v-kernel! lst pos vec)) (newline)

b. Write your own version of vector-fill!. Remember that vector-fill! takes two parameters, a vector and a value, and puts that value in every position of the vector.

Note: You may find that you want to do two things for a particular position: fill the value at that position and recurse. Remember that when you want to sequence actions if a test succeeds, you should use a cond rather than a if.

Optional Exercises on Vectors and Palettes

It may be that vectors provide a better mechanism for storing palettes than lists. How can we tell? We can rewrite some of the procedures to check.

Write a procedure, (vpalette.index-of vpalette color), that given a vector of colors and a color as parameters, finds the index of the color in the vector closest to color.

For Those With Extra Time

Extra 1: Rotating Vectors

Write a procedure, (rotate! vec) that rotates the elements in vec. That is, rotate! puts the initial element of vec at the end, the element at position 1 in position 0, the element at position 2 in position 1, and so on and so forth.

Extra 2: Reversing Vectors

a. Write a procedure, (vector.reverse vec), that creates a new vector whose elements appear in the reverse order of the elements in vec.

b. Write a procedure, (vector.reverse! vec), that reverses vecin place”. That is, instead of producing a new vector, it rearranges the elements within vec.

Extra 3: Rotating Vectors, Revisited

Write a procedure, (rotate! vec amt), that rotates the values in vec by amt positions. That is, the first amt values in vec move to the end, the value in position amt moves to position 0, the value in position amt+1 moves to position 1, and so on and so forth.

Notes

Notes on Exercise 4: Filling Vectors

Just as in the case of list->vector, you will probably want to define a helper procedure that fills only part of the vector. Your termination condition will certainly be different and should probably involve the length of the vector.

Creative Commons License

Samuel A. Rebelsky, rebelsky@grinnell.edu

Copyright 2007 Janet Davis, Matthew Kluber, and Samuel A. Rebelsky. (Selected materials copyright by John David Stone and Henry Walker and used by permission.)

This material is based upon work partially supported by the National Science Foundation under Grant No. CCLI-0633090. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.

This work is licensed under a Creative Commons Attribution-NonCommercial 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.