Apache Commons Math3学习之数值积分实例代码

2025-05-29 0 92

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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Apache Commons Math3学习之数值积分实例代码 https://www.kuaiidc.com/114581.html

相关文章

发表评论
暂无评论