anchor.diff:     iterations. The `iteration-limit' is the amount of times the
      algorithm may traverse the graph before giving up (if the algorithm
      does not converge)."
  -  (loop for document in (documents collection) do
  -           (setf (rank document)
  -                 (or initial-rank
  -                     (/ 1 (length (documents collection))))))
     (with-accessors ((documents documents)) collection
  -    (labels ((graph-neighbor-ids (node-id)
  +    (labels ((set-initial-rank ()
  +               "Set the initial rank of all documents to a supplied
  +                value OR 1/length of the documents."
  +               (let ((initial-rank (or initial-rank (/ 1 (length documents)))))
  +                 (mapcar (lambda (document) (setf (rank document) initial-rank)) documents)))
  +             (graph-neighbors (document)
                  "Return a list of neighbors. In a fully connected graph,
  -              all nodes are a neighbor except for the node itself."
  -               (loop for i from 0 below (length (documents collection))
  -                     when (/= i node-id)
  -                     collect i))
  -             (graph-neighbor-edge-sum (node-id)
  +                all nodes are a neighbor except for the node itself."
  +               (remove document documents))
  +             (graph-neighbor-edge-sum (document)
                  "Add up the edges of all neighbors of a given node."
  -               (loop for neighbor in (graph-neighbor-ids node-id)
  -                     sum (aref (matrix collection) node-id neighbor)))
  -             (converged-p (previous-score current-score)
  +               (reduce #'+ (mapcar #'car (similarity-vector document))))
  +             (document-similarity (document-a document-b)
  +               (car (find document-b (similarity-vector document-a) :key #'cdr)))
  +             (convergedp (previous-score current-score)
                  "Check if a delta qualifies for convergence."
  -               (if (<=  (abs (- previous-score current-score)) epsilon)
  -                   t
  -                   nil)))
  +               (<=  (abs (- previous-score current-score)) epsilon))
  +             (rank-document (document)
  +               (setf (rank document) (- 1 damping))
  +               (loop for neighbor in (graph-neighbors document)
  +                     do (setf (rank neighbor)
  +                              (/ (* damping (rank neighbor) (document-similarity document neighbor))
  +                                 (graph-neighbor-edge-sum neighbor))))))
  +      (set-initial-rank)
         (let (converged)
  -        (loop for iterations from 0 until (or converged (= iterations iteration-limit)) do
  -                 (setf converged t)
  -                 (loop for x from 0 below (length (documents collection))
  -                       do (let ((previous-rank (rank (nth x (documents collection)))))
  -                            (setf (rank (nth x documents)) (- 1 damping))
  -                            (loop for y in (graph-neighbor-ids x)
  -                                  do (setf (rank (nth x documents))
  -                                           (/ (* damping
  -                                                 (rank (nth y documents))
  -                                                 (aref (matrix collection) x y))
  -                                              (graph-neighbor-edge-sum y)))
  -                                     (unless (converged-p previous-rank
  -                                                          (rank (nth x (documents collection))))
  -                                       (setf converged nil))))))))))
  +        (loop for iteration from 0 to iteration-limit until converged
  +              do (setf converged t)
  +                 (loop for document in documents
  +                       do (let ((previous-rank (rank document)))
  +                            (rank-document document)
  +                            (unless (convergedp previous-rank (rank document))
  +                              (setf converged nil)))))))))
  
positive.code:         (/ (vector-product document-a document-b)
             (* (vector-sum-root document-a) (vector-sum-root document-b))))))
  
  (defmethod generate-document-similarity-matrix ((collection document-matrix))
    (setf (matrix collection)
          (make-array (list (length (documents collection))
                            (length (documents collection)))
                      :initial-element 0))
    (loop for x in (documents collection)
          for ix from 0 below (length (documents collection)) do
             (loop for y in (documents collection)
                   for iy from 0 below (length (documents collection)) do
                      (setf (aref (matrix collection) ix iy)
                            (cosine-similarity x y)))))
  
  (defmethod text-rank ((collection document-matrix) &key (epsilon 0.001)
                                                          (damping 0.85)
                                                          (initial-rank)
                                                          (iteration-limit 100))
    "This method is used to calculate the text rankings for a document
     collection. The `epsilon' is the maximum delta for a given node
     rank change during an iteration to be considered convergent. The
  
negative.code: 
  ;;; text-rank.lisp -- implementation of textrank algorithm
  
  (defclass document-similarity-vector (document)
    ((similarity-vector :accessor similarity-vector)))
  
  (defmethod word-count-vectorize ((document document) dictionary)
    "Transform a document into a vector using word counts."
  