Clojure:调用超类方法

约瑟夫·尤林

我有一个无法解决的大问题,我真的没有发现错误。

我想使用这个功能:

http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/optim/univariate/BrentOptimizer.html

来自Apache的示例测试代码是:

(来源:https : //github.com/apache/commons-math/blob/3.6-release/src/test/java/org/apache/commons/math3/optim/univariate/BrentOptimizerTest.java

public void testSinMin() {
    UnivariateFunction f = new Sin();
    UnivariateOptimizer optimizer = new BrentOptimizer(1e-10, 1e-14);
    Assert.assertEquals(3 * Math.PI / 2, optimizer.optimize(new MaxEval(200),
                                                            new UnivariateObjectiveFunction(f),
                                                            GoalType.MINIMIZE,
                                                            new SearchInterval(4, 5)).getPoint(), 1e-8);

所以我试图用Clojure和另一个函数来复制代码:

(defn atomic-apache-peak-value [x]
  (let [lamb ((x :parameters) 0)
        x0 ((x :parameters) 1)
        f (D2Sigmoid. lamb x0)
        optimizer (BrentOptimizer. 0.0001 0.0001)
        maxeval (MaxEval. 1000)
        of (UnivariateObjectiveFunction. f)
        goal (GoalType/MINIMIZE)
        interval (SearchInterval. x0 (* 2 x0))]
    (-> (.optimize optimizer maxeval of goal interval)
        (.getPoint))))

Clojure告诉我“未找到匹配方法:针对类.... BrentOptimizer优化”

我试图在let中一一计算出代码行,并且行之有效,所以问题是最优化的。

该方法在超类上实现,或者我将其导入

[org.apache.commons.math3.optim.univariate UnivariateOptimizer BrentOptimizer UnivariateObjectiveFunction SearchInterval]
[org.apache.commons.math3.optim BaseOptimizer MaxEval]

它不会改变任何东西。

您是否认为我有语法问题,错误或执行方法错误?

谢谢

编辑 :

忘了说了

(.optimize optimizer)

版本从Apache引发异常,但被发现。因此,我认为Clojure无法找到源代码。也许有语法问题?

还尝试了没有括号的Goaltype / MINIMIZE

编辑2:

最终工作代码

(defn atomic-apache-peak-value [x]
  (let [lamb ((x :parameters) 0)
        x0 ((x :parameters) 1)
        f (D2Sigmoid. lamb x0)
        optimizer (BrentOptimizer. 0.0001 0.0001)
        maxeval (MaxEval. 1000)
        of (UnivariateObjectiveFunction. f)
        goal GoalType/MINIMIZE
        interval (SearchInterval. x0 (* 2 x0))]
    (-> (.optimize optimizer (into-array OptimizationData [maxeval of goal interval]))
        (.getPoint))))
ez121sl

好的,让我们创建一个正确的答案。从Clojure调用Java方法时,重要的是查找该方法的实际签名。仅从Java示例代码复制可能并不总是有效。那主要是由于vargars。Clojure中的Java互操作要求程序员在涉及varargs时做一些额外的工作。

optimize您尝试调用方法的签名为:

public UnivariatePointValuePair optimize(OptimizationData... optData)
                              throws TooManyEvaluationsException

注意...,这表示该方法接受0个或多个type类型的参数OptimizationData在Java中,optimize(foo, bar, baz)只要foo,bar和baz类实现该OptimizationData接口就可以调用此方法

但是,对vararg的这种处理主要归因于Java编译器。在幕后,该方法实际上期望使用类型为OptimizationData []-的单个参数OptimizationDataJava编译器生成将参数打包到数组中的代码,程序员不必担心它。

但是,当从Clojure调用此类方法时,程序员必须创建数组。好像该方法的签名在Clojure编译器中显示为optimize(OptimizationData[] optData)

在Clojure中创建数组不需要很多。一种方法是使用该into-array功能。下面显示了必要的点点滴滴:

(import '(org.apache.commons.math3.optim OptimizationData))

(.optimize  (into-array OptimizationData [optimizer maxeval of goal interval]))

同样,也不需要在括号中加上GoalType/MINIMIZE括号表示一个列表,列表在Clojure中作为函数调用进行评估。在这里我们不需要调用GoalType/MINIMIZE函数,我们只需要那个值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章