Question

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))
Was it helpful?

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

OTHER TIPS

Your inner (map):

(map #(power a %) p)

Returns a sequence and you can't feed that to (comp). 'comp' is for 'Function Composition'.

In the REPL:

(doc comp)
clojure.core/comp
([] [f] [f g] [f g h] [f1 f2 f3 & fs])
  Takes a set of functions and returns a fn that is the composition
  of those fns.  The returned fn takes a variable number of args,
  applies the rightmost of fns to the args, the next
  fn (right-to-left) to the result, etc.

Start breaking your code into smaller steps. (let) form is quite handy, don't be shy to use it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top