Search code examples
vectorschemelispracketnormalization

What is wrong with my Scheme using vector-set implementation?


I was wondering what I am doing wrong here with vector-set

(define foo0
  (lambda (vec)
    (let* ((newvec (vector vec))
           (l      (vector-length vec))
           (norm   (norm0 vec)))
      (do ((i 0(+ i 1)))
        ((= i l))
        (vector-set*! newvec  i (/(vector-ref vec i) norm))) newvec)))

I am trying to set each element of the vector to be divided by norm (an integer from another predicate).

The error I keep getting is

  vector-set!: index is out of range
  index: 1
  valid range: [0, 0]
  vector: '#(3/4)

So I am finding the first solution, however, the newvec gets reset to size 1, so the index goes out of range.


Solution

  • vector makes a mutable vector with the elements given as arguments, thus:

    (vector 4)      ; a vector of one element
    (vector 1 2 3)  ; a vector of 3 elements
    

    SO lets say you need a 20 element vector that you are going to mutate and work with. Using vector is out of the question since then you would have to have 20 dummy arguments. Instead you use make-vector It takes two arguments, the size and an optional initial value for all the elements:

    (make-vector 20 0)
    ; ==> #(0 0 ... 0), a vector of 20 elements, all 0
    

    Now with the knowledge that you can get the length of the passed vector with vector-length you can pass that to make-vector to make a same size vector that you can copy values to to make a shallow copy. However you can do it much easier by using vector-copy