(ns sekai.math.vectors)

(defn vecn->m "Convert a vector to an m-element vector." [m v]
  (vec (take m (into v (repeat (- m (count v)) 0)))))

(defn components [vecs]
  (vec (map (fn [idx] (map #(nth % idx) vecs))
            (range (count (first vecs))))))

(defn comp-reduce [op vecs]
  (vec (map #(reduce op %) (components vecs))))

(defn manip-scalar
  "Manipulate Vectors by Scalar and Operation."
  [op s vecs]
  (map #(op % (repeat (count %) s)) vecs))

(defn dist "Distance between two Vectors."
  [v1 v2]
  (reduce + (map #(abs (- %1 %2)) v1 v2)))

(defn add "Add Vectors." [& vecs] (comp-reduce + vecs))
(defn sub "Subtract Vectors." [& vecs] (comp-reduce - vecs))
(defn mult "Multiply Vectors." [& vecs] (comp-reduce * vecs))
(defn div "Divide Vectors." [& vecs] (comp-reduce / vecs))

(defn mult-s "Multiply Vectors by Scalar"
  [s & vecs] (manip-scalar mult s vecs))

(defn div-s "Divide Vectors by Scalar"
  [s & vecs] (manip-scalar div s vecs))

(defn dot "Dot Product" [& vecs] (reduce + (apply mult vecs)))
