【发布时间】:2016-10-05 20:09:50
【问题描述】:
我正在使用 fungp(一种基因编程工具)来建模一个复杂的函数,并且遇到了 sqrt 的问题。
基本上,我必须将一个函数向量及其数量传递给 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>
我认为这是由于 fungp.util/sqrt 的定义:
(defn sqrt [x] (if (x > 0) (Math/sqrt x) 0))
我认为 0 导致无法评估,但我不确定。我已经尝试定义我自己的安全平方根版本,但语法不正确。
所以,这就是我卡住的地方。我需要一个安全的平方根版本(对于负输入返回 0)并在 fungp 表达式中正确评估。
编辑:为了完整起见,这是我尝试编写自己的平方根包装器的(许多)变体之一:
(defn sqrt-fn [x] `(if (~x > 0) (Math/sqrt ~x) 0))
输出(中间位是从函数生成的表达式):
#<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)
我不是在写表达式,所以如果有多余的括号或缺少括号,它们来自我定义 sqrt 的方式。
【问题讨论】:
-
我不认为这是从该错误中得出的正确结论。这只是意味着某些东西试图调用 0.0 就像它是一个函数一样。在 repl 中键入
(0.0)会导致相同的异常。 -
@NathanHughes 所以,我很难掌握 clojure,我肯定是错的,但我认为这是问题的原因是,如果我从函数向量中省略平方根,一切正常(除了我的函数无法准确建模),如果我使用不安全的平方根包装器,ClassCastExceptions 就会消失,但由于负数,我会得到合同异常。
-
我敢打赌,错误出在您的平方根包装器中。某处有一对额外的括号。请记住,括号在 clojure 中用于调用语义和列表文字,而不是评估分组的顺序。
-
@NathanHughes 感谢您的建议。我也觉得有额外的括号,但我不知道为什么/在哪里。我已经用关于我自己的包装器的更多信息更新了这个问题。
-
>_ x 0) (Math/sqrt x) 0)) -- 放弃你的中缀方式
标签: clojure genetic-programming