如何在clojure中定义安全的sqrt函数?

如何在clojure中定义安全的sqrt函数?,clojure,genetic-programming,Clojure,Genetic Programming,我正在使用fungp(一种遗传编程工具)对一个复杂的函数建模,并且在sqrt方面遇到了问题 基本上,我必须把一个函数向量和它们的arity传递给fungp,这样它就可以用它们组成表达式。然后将对表达式求值,并返回最佳表达式。此函数向量如下所示: (def functions '[[+ 2] [- 2] [* 2] [fungp.util/abs 1] [fungp.util/sdiv 2] [fungp.util/sin 1] [fungp.util/sqrt 1]

我正在使用fungp(一种遗传编程工具)对一个复杂的函数建模,并且在sqrt方面遇到了问题

基本上,我必须把一个函数向量和它们的arity传递给fungp,这样它就可以用它们组成表达式。然后将对表达式求值,并返回最佳表达式。此函数向量如下所示:

(def functions
  '[[+ 2]
  [- 2]
  [* 2]
  [fungp.util/abs 1]
  [fungp.util/sdiv 2]
  [fungp.util/sin 1]
  [fungp.util/sqrt 1]
  [inc 1]
  [dec 1]])
该设置给了我一百行错误,如:

#<ClassCastException java.lang.ClassCastException: java.lang.Double cannot be cast to clojure.lang.IFn>
我认为0导致评估失败,但我不确定。我试图定义自己版本的安全平方根,但语法不正确

所以,这就是我被困的地方。我需要一个安全的平方根版本(负输入返回0),并在fungp表达式中正确计算

编辑:为了完整起见,这是我为编写自己的平方根包装器而尝试的(许多)变体之一:

(defn sqrt-fn [x] `(if (~x > 0) (Math/sqrt ~x) 0))
和输出(中间位是从函数生成的表达式):

#
让[](dec(-(fungp.util/sin(tutorial.tut1/sqrt-fn 8.0))(fungp.util/sdiv(*x2.0)(dec 9.0))(fungp.util/sdiv(tutorial.tut1/sqrt-fn(*x))(((-x4.0)(+x x xЮ)))(fungp.util/sdiv(tutorial.tut1/sqrt-fn(fungp.util/sin(
+(dec x)(inc x)))(fungp.util/sdiv(*(inc(inc 1.0))(*(+x 9.0)(fungp.util/sin 9.0)))(tutorial.tut1/sqrt-fn(-(tutorial.tut1/sqrt-fn x)(fungp.util/abs 3.0())))
NullPointerException clojure.lang.Numbers.ops(Numbers.java:942)

我没有编写表达式,因此如果有额外的括号或缺少括号,则它们来自我定义sqrt的方式。

这有两个错误:

(defn sqrt-fn [x] `(if (~x > 0) (Math/sqrt ~x) 0))
首先,正如评论中所暗示的,
(x>0)
试图调用
x
(可能是一个数字)作为函数
是函数,因此它必须放在第一位,如
(>x 0)
中所示


此外,您可能不希望在此处引用它们的语法-这会妨碍对内容的评估,因此您的函数将返回一个引用的符号列表。

我认为这不是从该错误得出的正确结论。它只是意味着某些东西试图调用0.0,就像调用函数一样。在repl中键入
(0.0)
会导致相同的异常。@NathanHughes所以,我正在努力理解clojure,我肯定是错的,但我认为这是问题的原因,因为如果我从函数向量中忽略平方根,一切都正常工作(除了我的函数无法精确建模)如果我使用一个不安全的平方根包装,ClassCastException会消失,但是我会因为负数而得到契约异常。我打赌错误在你的平方根包装中。某处有一对额外的括号。请记住,Paren在clojure中用于调用语义和列表文本,而不是计算分组的顺序。@NathanHughes感谢您的建议。我还觉得有额外的括号,但我不知道为什么/在哪里。我已经用关于我自己的包装器的更多信息更新了这个问题
#<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to java.lang.Number>

(let [] (- (dec (- (- (fungp.util/sin (tutorial.tut1/sqrt-fn 8.0)) (fungp.util/sdiv (* x 2.0) (dec 9.0))) (fungp.util/sdiv (tutorial.tut1/sqrt-fn (* x x)) (- (- x 4.0) (+ x x))))) (fungp.util/sdiv (tutorial.tut1/sqrt-fn (fungp.util/sin (
+ (dec x) (inc x)))) (fungp.util/sdiv (* (inc (inc 1.0)) (* (+ x 9.0) (fungp.util/sin 9.0))) (tutorial.tut1/sqrt-fn (- (tutorial.tut1/sqrt-fn x) (fungp.util/abs 3.0)))))))

NullPointerException   clojure.lang.Numbers.ops (Numbers.java:942)
(defn sqrt-fn [x] `(if (~x > 0) (Math/sqrt ~x) 0))