Apache.Commons.Math3里面的数值积分支持类采用的是“逼近法”,即,先对大区间做一次积分,再对小区间做一次积分,若两次积分结果的差值小于某一设定的误差值,则认为积分完成。否则,将区间再次细分,对细分后的区间进行积分,与前一次积分相比较,如此反复迭代,直至最近的两次积分差值足够小。这样的结果,有可能会导致无法收敛。
为了使用org.apache.commons.math3.analysis.integration包中的积分器类,需要先实现UnivariateFunction接口(本文以MyFunction为例),实现其value方法。然后创建指定的积分器对象,本文以SimpsonIntegrator为例,最后调用其integrate(…)方法即可算出MyFunction的积分。
调用integrate(…)方法时需要提供4个参数:
	第1个是最大逼近次数,要适当大一些,否则可能会无法收敛;
	第2个是MyFunction类的实例;
	第3个是积分区间下限;
	第4个是积分区间上限。
SimpsonIntegrator在第一次迭代时一定是分别以积分下限和积分上限作为x调用连词MyFunction.value(…)方法,下一次则会将区间分成2份(除上下限x值之外,还有一个中间x值),再下一次则是分成4份……
以下是使用辛普森积分类的例子:
| 
 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
 
								13
 
								14
 
								15
 
								16
 
								17
 
								18
 
								19
 
								20
 
								21
 
								22
 
								23
 
								24
 
								25
 
								26
 
								27
 
								28
 
								29
 
								30
 
								31
 
								32
 
								33
 
								34
 
								35
 
								36
 
								37
 
								38
 
								39
 
								40
 
								41
 
								42
 
								43
 
								44
 
								45
 
								46
 
								47
 
								48
 
								49
 
								50
 
								51
 
								52
 
								53
 
								54
 
								55
 
								56
 
								57
 
								58
 
								59
 
								60
 
								61
 
								62
 
								63
 
								64
 
								65
 
								66
 
								67
 
								68
 
								69
 
								70
 
								71
 
								72
 
								73
 
								74
 
								75
 
								76
 
								77
 
								78
 
								79
 
								80
 
								81
 
								82
 
								83
 
								84
 
								85
 
								86
 
								87
 
								88
 
								89
 
								90
 
								91
 
								92
 
								93
 
								94
 
								95
 
								96
 
								97
 
								98
 
								99
 
								100
 
								101
 
								102
 
								103
 
								104
 
								105
 
								106
 
								107
 
								108
 
								109
 
								110
 
								111
 
								112
 
								113
						  | 
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.integration.SimpsonIntegrator;
import org.apache.commons.math3.analysis.integration.UnivariateIntegrator;
interface TestCase 
{
public Object run(List<Object> params) throws Exception;
public List<Object> getParams();
public void printResult(Object result) throws Exception;
}
public class TimeCostCalculator 
{
public TimeCostCalculator() 
{
}
/** 
* 计算指定对象的运行时间开销。 
* 
* @param testCase 指定被测对象。 
* @return 返回sub.run的时间开销,单位为s。 
* @throws Exception 
*/
private double calcTimeCost(TestCase testCase) throws Exception 
{
List<Object> params = testCase.getParams();
long startTime = System.nanoTime();
Object result = testCase.run(params);
long stopTime = System.nanoTime();
testCase.printResult(result);
double timeCost = (stopTime - startTime) * 1.0e-9;
return timeCost;
}
public void runTest(TestCase testCase) throws Exception 
{
double timeCost = calcTimeCost(testCase);
System.out.println("时间开销:: " + timeCost + "s");
System.out.println("-------------------------------------------------------------------------------");
}
public static void main(String[] args) throws Exception 
{
TimeCostCalculator tcc = new TimeCostCalculator();
tcc.runTest(new CalcSimpsonIntegrator());
}
}
/** 
* 使用辛普森法求解数值积分。Apache.Common.Math3中所用的辛普森法是采用逼近法,即先对整个积分区间用矩形积分,然后将区间分解为4份,再次积分,比较两次积分的差值,若想对误差大于某个预订数值, 
* 则认为还需要继续细分区间,因此会将区间以2倍再次细分后求积分,并将结果与前一次积分的结果比较,直至差值小于指定的误差,就停止。 
* @author kingfox 
* 
*/
class CalcSimpsonIntegrator implements TestCase 
{
public CalcSimpsonIntegrator() 
{
System.out.print("本算例用于测试使用辛普森法计算积分。正在初始化计算数据 ... ...");
inputData = new double[arrayLength];
for (int index = 0; index < inputData.length; index++) // 鏂滃潯鍑芥暟 
{
inputData[index] = Math.sin(2 * Math.PI * index * MyFunction.factor * 4);
}
func = new MyFunction();
integrator = new SimpsonIntegrator();
System.out.println("初始化完成!");
}
@Override
public Object run(List<Object> params) throws Exception 
{
double result = ((SimpsonIntegrator)(params.get(1))).integrate(steps, (UnivariateFunction)(params.get(0)), lower, upper);
return result;
}
/** 
* 获取运行参数 
* @return List对象,第一个元素是求积函数,第二个参数是积分器。 
*/
@Override
public List<Object> getParams() 
{
List<Object> params = new ArrayList<Object>();
params.add(func);
params.add(integrator);
return params;
}
@Override
public void printResult(Object result) throws Exception 
{
System.out.println(">>> integration value: " + result);
}
UnivariateFunction func = null;
UnivariateIntegrator integrator = null;
class MyFunction implements UnivariateFunction 
{
@Override
public double value(double x) 
{
// double y = x * factor; // 1. 
// double y = 4.0 * x * x * x - 3.0 * x * x + 2.0 * x - 1.0; // 2. 
// double y = -1.0 * Math.sin(x) + 2.0 * Math.cos(x) - 3.0; // 3. 
double y = inputData[(int)(x / factor)];
// 4. 
// System.out.println(x + ", " + y); 
return y;
}
private static final double factor = 0.0001;
}
private double[] inputData = null;
private static final int arrayLength = 5000;
private static final double lower = 0.0;
// private static final double upper = 2.0 * Math.PI; // 3. 
private static final double upper = (arrayLength - 1) * MyFunction.factor;
// 1. 2. 4. 
private static final int steps = 1000000;
}
 | 
上述代码中,注释为1. 2. 3.的可以正常计算出结果,但注释为4.的就无法收敛。
基于org.apache.commons.math3.analysis.integration.UnivariateIntegrator的积分器的另一个局限性在于必须编写一个继承于UnivariateFunction的函数类,实现其value方法(根据输入的x值计算出y值),这种做法有利于可用解析式表达的情况,不利于对存放于外存的大量数据做积分处理。
总结
以上就是本文关于Apache Commons Math3学习之数值积分实例代码的全部内容,希望对大家有所帮助。有什么问题可以随时留言,小编会及时回复大家的。希望大家能够喜欢,希望对本站多多支持!
原文链接:http://blog.csdn.net/kingfox/article/details/44153331
相关文章
- 个人服务器网站搭建:如何选择合适的服务器提供商? 2025-06-10
 - ASP.NET自助建站系统中如何实现多语言支持? 2025-06-10
 - 64M VPS建站:如何选择最适合的网站建设平台? 2025-06-10
 - ASP.NET本地开发时常见的配置错误及解决方法? 2025-06-10
 - ASP.NET自助建站系统的数据库备份与恢复操作指南 2025-06-10
 
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
 - 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
 - 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
 - 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
 - 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
 
快网idc优惠网
QQ交流群
- 
            2025-05-27 27
 - 
            2025-05-25 52
 - 
            2025-05-25 73
 - 
            
Windows 8系统怎么升级成Windows 11系统,Windows 8升级Windows 11系统操作步骤
2025-05-27 101 - 
            2025-06-04 59
 
        
    		
            	
        
        
        