 (defn pca-project [data pcs]
   "Apply the principal component projection specified by pcs to the data"
   ; Here we map each row of data to it's projection
-  (mapv
-    ; each projection is the map of the pcs to the dot of a pc and the data-row
-    (fn [data-row] (mapv #(dot data-row %) pcs))
-    data))
+  (mmul data (transpose pcs)))
 
 

(defn xtxr [data start-vec]
  "Will need to rename this and some of the inner variables to be easier to read...
  Computes an inner step of the power-iteration process"
  (let [n-rows (count (first data))
        curr-vec (ic.core/trans (repeatv n-rows 0))]
    (loop [data data curr-vec curr-vec]
      (if-let [row (first data)]
        (recur (rest data)
               (ic.core/plus (tr/trace curr-vec)
                             (tr/trace (ic.core/mult (dot row start-vec) row))))
        curr-vec))))



(defn proj-vec [xs ys]
  "This computes the projection of ys orthogonally onto the vector spanned by xs"
  (let [coeff (/ (dot xs ys) (dot xs xs))]
    (* coeff xs)))


(defn factor-matrix [data xs]
  "As in the Gram-Shmidt process; we can 'factor out' the vector xs from all the vectors in data,
  such that there is no remaining variance in the xs direction within the data."
  (matrix (mapv #(- % (proj-vec xs %)) data)))


(defn centered-data [data]
  (- data (mean data)))


; Will eventually also want to add last-pcs
