编写Lp规范函数

时间:2014-01-17 15:45:54

标签: clojure clojure-contrib

我正在尝试编写Lp范数函数,以概括所使用的标准L2范数(欧几里德距离)。到目前为止,我已经提出了这个问题,考虑到我如何编写L2规范:

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

但是每当我尝试实现此功能时,我都会收到错误ClassCastException。部分临时代码来自之前提出的问题Raising elements in a vector to a power,其中提供了以下代码:

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

2 个答案:

答案 0 :(得分:1)

你的内心(地图):

(map #(power a %) p)

返回一个序列,你不能将它提供给(comp)。 'comp'代表'功能组合'。

在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.

开始将代码分解为更小的步骤。 (让)形式非常方便,不要害羞使用它。

答案 1 :(得分:1)

考虑将代码分解。

首先定义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))))

然后使用p-norm定义p-metric

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

实施例

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

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