【问题标题】:Clojure : call a superclass methodClojure:调用超类方法
【发布时间】:2016-02-25 15:54:25
【问题描述】:

我有一个大问题我无法解决,我真的找不到错误。

我想使用这个功能:

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)

version 从 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))))

【问题讨论】:

  • 你试过去掉GoalType/MINIMIZE周围的括号吗?
  • 嗯.. 查看 javadoc,您可能想要(.optimize (into-array OptimizationData [optimizer maxeval of goal interval])) 之类的东西。您需要导入 org.apache.commons.math3.optim.OptimizationData 并丢失 GoalType/MINIMIZE 周围的括号
  • 天哪,非常感谢,它成功了。不知道将 Optimizationdata ... 绑定到 OptimizationData[] !祝你有美好的一天

标签: clojure clojure-java-interop


【解决方案1】:

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

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

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

注意...,这意味着该方法接受0 个或多个OptimizationData 类型的参数。在 Java 中,只要 foo、bar 和 baz 类实现了OptimizationData 接口,就可以将该方法调用为optimize(foo, bar, baz)

然而,对 vararg 的这种处理主要是由于 Java 编译器造成的。在幕后,该方法实际上需要一个 OptimizationData [] 类型的参数 - OptimizationData 的数组。 Java 编译器生成的代码将参数打包到一个数组中,程序员不必担心。

但是当从 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函数,我们只需要那个值。

【讨论】:

    猜你喜欢
    • 2011-03-28
    • 1970-01-01
    • 2012-12-30
    • 2011-10-24
    • 2014-01-15
    • 1970-01-01
    • 2018-01-22
    • 2015-04-20
    • 2012-04-18
    相关资源
    最近更新 更多