Clojure:调用超类方法
Clojure : call a superclass method
我有一个很大的问题,我无法解决,我真的没有找到错误。
我想使用这个功能:
Apache 的示例测试代码是:
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 告诉我 "No matching method found : optimize for class ....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))))
好的,让我们创建一个正确的答案。从 Clojure 调用 Java 方法时,查找方法的实际签名很重要。仅从 Java 示例代码复制可能并不总是有效。这主要是由于 vargars。 Java Clojure 中的互操作需要程序员在涉及可变参数时做一些额外的工作。
您尝试调用的 optimize
方法的签名是:
public UnivariatePointValuePair optimize(OptimizationData... optData)
throws TooManyEvaluationsException
注意 ...
,这意味着该方法采用 0 个或多个 OptimizationData
类型的参数。在Java中,只要foo、bar、baz的类实现了OptimizationData
接口,就可以像optimize(foo, bar, baz)
一样调用该方法。
然而,这种对可变参数的处理主要是由于 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
函数,我们只需要那个值。
我有一个很大的问题,我无法解决,我真的没有找到错误。
我想使用这个功能:
Apache 的示例测试代码是:
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 告诉我 "No matching method found : optimize for class ....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))))
好的,让我们创建一个正确的答案。从 Clojure 调用 Java 方法时,查找方法的实际签名很重要。仅从 Java 示例代码复制可能并不总是有效。这主要是由于 vargars。 Java Clojure 中的互操作需要程序员在涉及可变参数时做一些额外的工作。
您尝试调用的 optimize
方法的签名是:
public UnivariatePointValuePair optimize(OptimizationData... optData)
throws TooManyEvaluationsException
注意 ...
,这意味着该方法采用 0 个或多个 OptimizationData
类型的参数。在Java中,只要foo、bar、baz的类实现了OptimizationData
接口,就可以像optimize(foo, bar, baz)
一样调用该方法。
然而,这种对可变参数的处理主要是由于 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
函数,我们只需要那个值。