使用 Math.Commons 库的 Newton-Raphson 方法
Newton-Raphson method using the Math.Commons library
我制作了一个测试程序来试用 NewtonRaphsonSolver class through the Apache Commons Math 库。牛顿法用于求给定函数的根。
我写的测试程序引用了cos(x)函数(我有一个比较难分析的函数,先看cos(x)函数)
测试程序的代码是
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
import org.apache.commons.math3.analysis.solvers.*;
import org.apache.commons.math3.exception.DimensionMismatchException;
public class Test3 {
public static void main(String args[]) {
NewtonRaphsonSolver test = new NewtonRaphsonSolver();
UnivariateDifferentiableFunction f = new UnivariateDifferentiableFunction() {
public double value(double x) {
return Math.cos(x);
}
@Override
public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
return t.cos();
}
};
for (int i = 1; i <= 500; i++) {
System.out.println(test.solve(1000, f, i, i+0.1));
}
}
}
不确定我是否需要引用 Math.cos(x) 和 t.cos() 两次
public double value(double x) {
return Math.cos(x);
}
@Override
public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
return t.cos();
}
牛顿法找到所有的零点并将它们显示给用户。
1.5707963267948966
1.5707963267948966
-7.853981633974483
4.71238898038469
4.71238898038469
1.5707963267948966
7.853981633974483
7.853981633974483
10.995574287564276
10.995574287564276
10.995574287564276
10.995574287564276
14.137166941154069
14.137166941154069
14.137166941154069
127.23450247038663
17.278759594743864
17.278759594743864
23.56194490192345
20.420352248333657
20.420352248333657
39.269908169872416
23.56194490192345
23.56194490192345
14.137166941154069
26.703537555513243
26.703537555513243
23.56194490192345
29.845130209103036
29.845130209103036
26.703537555513243
32.98672286269283
32.98672286269283
32.98672286269283
36.12831551628262
36.12831551628262
36.12831551628262
23.56194490192345
39.269908169872416
39.269908169872416
45.553093477052
42.411500823462205
42.411500823462205
有什么方法可以防止打印出重复的零吗?例如,上面的输出将显示为
1.5707963267948966
4.71238898038469
7.853981633974483
10.995574287564276
14.137166941154069
17.278759594743864
20.420352248333657
23.56194490192345
26.703537555513243
29.845130209103036
32.98672286269283
36.12831551628262
39.269908169872416
42.411500823462205
45.553093477052
可以在 for 循环内或通过只打印出不重复的值的数组来完成吗?
第一个问题是,什么是相同的零。我会做一个 class:
class SolutionForZero{
public final double value;
final int hash;
static double tolerance = 1e-6;
public SolutionForZero(double value){
this.value = value;
hash = 1;
}
public boolean equals(Object other){
if( other instanceof SolutionForZero ){
double v = value - other.value;
return (v < 0) ? (-v > tolerance) : (v > tolerance);
}
return false;
}
public int hashCode(){
return hash;
}
}
这 class 将比较双打。要使用这个 class:
Set<SolutionForZero> resultSet = new HashSet<>();
for(double d: yourAnswers){
if(resultSet.add(new SolutionForZero(d))){
System.out.println("'unique' zero at: " + d);
};
}
现在您的结果集将只包含至少相距公差的值。
哈希码有点棘手。只要公差小于 1.0,我提供的方法就会起作用。我将不胜感激。
import java.util.TreeSet;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
import org.apache.commons.math3.analysis.solvers.*;
import org.apache.commons.math3.exception.DimensionMismatchException;
public class Test5 {
public static void main(String args[]) {
NewtonRaphsonSolver test = new NewtonRaphsonSolver(1E-10);
UnivariateDifferentiableFunction f = new UnivariateDifferentiableFunction() {
public double value(double x) {
return Math.sin(x);
}
public DerivativeStructure value(DerivativeStructure t) throws
DimensionMismatchException {
return t.sin();
}
};
double EPSILON = 1e-6;
TreeSet<Double> set = new TreeSet<>();
for (int i = 1; i <= 5000; i++) {
set.add(test.solve(1000, f, i, i + EPSILON));
}
for (Double s : set) {
if (s > 0) {
System.out.println(s);
}
}
}
}
我制作了一个测试程序来试用 NewtonRaphsonSolver class through the Apache Commons Math 库。牛顿法用于求给定函数的根。
我写的测试程序引用了cos(x)函数(我有一个比较难分析的函数,先看cos(x)函数)
测试程序的代码是
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
import org.apache.commons.math3.analysis.solvers.*;
import org.apache.commons.math3.exception.DimensionMismatchException;
public class Test3 {
public static void main(String args[]) {
NewtonRaphsonSolver test = new NewtonRaphsonSolver();
UnivariateDifferentiableFunction f = new UnivariateDifferentiableFunction() {
public double value(double x) {
return Math.cos(x);
}
@Override
public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
return t.cos();
}
};
for (int i = 1; i <= 500; i++) {
System.out.println(test.solve(1000, f, i, i+0.1));
}
}
}
不确定我是否需要引用 Math.cos(x) 和 t.cos() 两次
public double value(double x) {
return Math.cos(x);
}
@Override
public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
return t.cos();
}
牛顿法找到所有的零点并将它们显示给用户。
1.5707963267948966
1.5707963267948966
-7.853981633974483
4.71238898038469
4.71238898038469
1.5707963267948966
7.853981633974483
7.853981633974483
10.995574287564276
10.995574287564276
10.995574287564276
10.995574287564276
14.137166941154069
14.137166941154069
14.137166941154069
127.23450247038663
17.278759594743864
17.278759594743864
23.56194490192345
20.420352248333657
20.420352248333657
39.269908169872416
23.56194490192345
23.56194490192345
14.137166941154069
26.703537555513243
26.703537555513243
23.56194490192345
29.845130209103036
29.845130209103036
26.703537555513243
32.98672286269283
32.98672286269283
32.98672286269283
36.12831551628262
36.12831551628262
36.12831551628262
23.56194490192345
39.269908169872416
39.269908169872416
45.553093477052
42.411500823462205
42.411500823462205
有什么方法可以防止打印出重复的零吗?例如,上面的输出将显示为
1.5707963267948966
4.71238898038469
7.853981633974483
10.995574287564276
14.137166941154069
17.278759594743864
20.420352248333657
23.56194490192345
26.703537555513243
29.845130209103036
32.98672286269283
36.12831551628262
39.269908169872416
42.411500823462205
45.553093477052
可以在 for 循环内或通过只打印出不重复的值的数组来完成吗?
第一个问题是,什么是相同的零。我会做一个 class:
class SolutionForZero{
public final double value;
final int hash;
static double tolerance = 1e-6;
public SolutionForZero(double value){
this.value = value;
hash = 1;
}
public boolean equals(Object other){
if( other instanceof SolutionForZero ){
double v = value - other.value;
return (v < 0) ? (-v > tolerance) : (v > tolerance);
}
return false;
}
public int hashCode(){
return hash;
}
}
这 class 将比较双打。要使用这个 class:
Set<SolutionForZero> resultSet = new HashSet<>();
for(double d: yourAnswers){
if(resultSet.add(new SolutionForZero(d))){
System.out.println("'unique' zero at: " + d);
};
}
现在您的结果集将只包含至少相距公差的值。
哈希码有点棘手。只要公差小于 1.0,我提供的方法就会起作用。我将不胜感激。
import java.util.TreeSet;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
import org.apache.commons.math3.analysis.solvers.*;
import org.apache.commons.math3.exception.DimensionMismatchException;
public class Test5 {
public static void main(String args[]) {
NewtonRaphsonSolver test = new NewtonRaphsonSolver(1E-10);
UnivariateDifferentiableFunction f = new UnivariateDifferentiableFunction() {
public double value(double x) {
return Math.sin(x);
}
public DerivativeStructure value(DerivativeStructure t) throws
DimensionMismatchException {
return t.sin();
}
};
double EPSILON = 1e-6;
TreeSet<Double> set = new TreeSet<>();
for (int i = 1; i <= 5000; i++) {
set.add(test.solve(1000, f, i, i + EPSILON));
}
for (Double s : set) {
if (s > 0) {
System.out.println(s);
}
}
}
}