Search code examples
clojureclojure-contrib

Writing the Lp norm function


I'm attempting to write the Lp norm function as to generalize the standard L2 norm (Euclidean distance) used. Here is what I have come up with so far, given how I had written the L2 norm:

(defn foo [a b p]
     (reduce + (map (comp (map #(power a %) p) -) a b)))

However I am getting the error ClassCastException whenever I try to implement this function. Part of the interim code is from a previously asked question Raising elements in a vector to a power where the following code was provided:

(defn compute [exp numbers]
     (map #(power exp %) numbers))

Solution

  • Consider factoring your code.

    First define the p-norm

    (defn p-norm [p x] 
       (if (= p :infinity) 
         (apply max (for [xi x] (Math/abs xi)))
         (Math/pow 
           (reduce + (for [xi x] (Math/pow xi p))) 
           (/ 1 p))))
    

    And then use the p-norm to define your p-metric

    (defn p-metric [p x y] 
      (p-norm p (map - x y)))
    

    Example

    (p-metric 2 [0 0] [3 4])
    ;=> 5.0
    
    (p-metric :infinity [0 0] [3 4])
    ;=> 4