我编写了一个测试程序来查看 BrentSolver class通过Apache Commons Math library .
import java.util.TreeSet;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.solvers.*;
public class TestBrent {
public static void main(String[] args) {
BrentSolver test2 = new BrentSolver(1E-10);
UnivariateFunction func = (double x) -> Math.sin(x);
TreeSet<Double> set = new TreeSet<>();
for (int i = 1; i <= 500; i++) {
set.add(test2.solve(1000, func, i, i+1));
}
for (Double s : set) {
if(s > 0)
System.out.println(s);
}
}
}
运行程序时,返回以下错误
Exception in thread "main" org.apache.commons.math3.exception.NoBracketingException: function values at endpoints do not have different signs, endpoints: [1, 2], values: [0.841, 0.909]
at org.apache.commons.math3.analysis.solvers.BrentSolver.doSolve(BrentSolver.java:133)
at org.apache.commons.math3.analysis.solvers.BaseAbstractUnivariateSolver.solve(BaseAbstractUnivariateSolver.java:199)
at org.apache.commons.math3.analysis.solvers.BaseAbstractUnivariateSolver.solve(BaseAbstractUnivariateSolver.java:204)
at TestBrent.main(TestBrent.java:12)
Java Result: 1
删除 if 语句可以让程序找到根。
import java.util.TreeSet;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.solvers.*;
public class TestBrent {
public static void main(String[] args) {
BrentSolver test2 = new BrentSolver(1E-10);
UnivariateFunction func = (double x) -> Math.sin(x);
System.out.println(test2.solve(1000, func, 1, 4));
}
}
这是 Apache Commons Math 库中的错误吗?所有求根算法(牛顿法之外)似乎都有相同的错误。
最佳答案
不,这不是错误。该错误告诉您,您的函数(在本例中为 sin(x)
)在 x==1
处计算的符号与在 x= 处计算的符号相同=2
。这表明您传递给它的间隔内部没有根。为了可靠地工作,求解器需要传递一个包含一个根的区间。对此的粗略检查是区间界限的函数符号不同(当然这并不排除包含多个根的区间......)。请参阅the docs ,其中说:
A solver may require that the interval brackets a single zero root.
在第一个示例中,for
循环将向求解器传递不同的间隔([1,2]
,[2,3]
等等)。有些会 Root ,有些不会。不幸的是,for
循环永远不会超过第一次迭代,因为 1
和 2
之间没有根。
在第二个示例中,您向求解器传递间隔[1,4]
。当然,sin(x)
确实在 x=PI
处的这些点之间有根。
引起错误的是问题的条件,而不是库中的错误。
<小时/>如果您想使用第一个公式 - 您可以围绕该线
set.add(test2.solve(1000, func, i, i+1));
使用 try...catch
循环,例如:
try {
set.add(test2.solve(1000, func, i, i+1));
}
catch (NoBracketingException e) {
System.err.println("Oops - error. Likely cause: No root in interval ["+i+","+(i+1)+"]");
System.err.println(e.message());
}
关于Java- Commons.Math BrentSolver 返回 NoBracketingException。这是一个错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32504227/