https://baike.baidu.com/item/%E8%BE%9B%E6%99%AE%E6%A3%AE%E7%A7%AF%E5%88%86%E6%B3%95/23337870 1.定积分:
定积分的定义:
此时f(x)在[a,b]上可积
定积分是积分的一种,是函数f(x)在区间[a,b]上积分和的极限。
而java就定积分,则需要用另一种办法,是用辛普森法则:辛普森法则的基本思想是利用函数在某区间内的奇次幂的积分性质,即在一个奇数个点的区间上,函数的积分可以表示为这些点上的函数值的线性组合。对于一个给定的区间[a, b],辛普森法则将其分成n个等宽的小区间,每个小区间的宽度为h = (b - a) / (n - 1),其中n是子区间的数量。
公式如下:
对于奇数个子区间:
对于偶数个子区间(n为偶数):
用以上法则可以轻而易举的算出定积分,直接上代码
/**
* @param upper 积分上限
* @param lower 积分下限
* @param n 划分积分区间的数量
* @param df 用于计算被积函数的函数接口
* @return 数值积分的结果
*
* 辛普森法则来进行数值积分计算。
* */
public double simpsonRule(double upper, double lower, int n, Function df){
double result = 0;
double unit = (upper - lower) / n; // f(a) - f(b) / n 计算每一个小区间的宽度
double factor = unit / 3;
double x[] = new double[n+1];
for (int i = 0; i < x.length; i++) {
x[i] = lower + unit * i;
}
for (int i = 0;i < x.length;i++){
if(i==0 || i == x.length -1){
result += (double)df.apply(x[i]);
}else if(i % 2 == 0){
result += 2.0 * (double)df.apply(x[i]);
}else {
result += 4.0 * (double)df.apply(x[i]);
}
}
result *= factor;
return result;
}
/** * 计算标准正态分布在负无穷到 realUpper 的积分值,使用辛普森法则进行数值积分
* @param realUpper 实际积分上限
* @return 积分值
*/
public double stdGaussValue(double realUpper){
Integration integration = new Integration(); // 创建积分类实例
double upper = 1.0; // 积分上限
double lower = 2.0; // 积分下限
int n = 200; // 把积分区间划分成200个小区间
if (realUpper > 5.0){ // 如果实际积分上限大于5,返回1
return 1.0;
}
double result = integration.simpsonRule(upper, lower, n, (Function<Double, Double>) x -> {
// 定义被积函数
if (x == 0) { // 如果 x = 0,返回0
return 0.0;
}
double t = realUpper - (1 - x) / x; // 计算被积函数中的 t 值
return Math.pow(Math.E, -0.5 * t * t) / (x * x); // 返回被积函数的值
});
result /= Math.pow(2 *Math.PI,0.5); // 对积分结果进行修正
result = new BigDecimal(result).setScale(6, RoundingMode.HALF_UP).doubleValue(); // 进行四舍五入计算,只保留6位小数,使用 doubleValue() 转为 double 类型
return result; // 返回积分结果
}
public class IntegrationTest {
public static void main(String[] args) {
Integration test = new Integration();
double result = test.stdGaussValue(4.42);
System.out.println(result);
}
}
测试函数,以下测试函数都是在书上可以找到,注释跟第二块代码块一样
public static void main3(String[] args) {
Integration integration = new Integration();
double upper = 1.0;
double lower = 0.0;
int n = 50;
double realUpper = 0.39;
double result =
integration.simpsonRule(upper, lower, n, new Function() {
@Override
public double fun(double x) {
if(x==0) {
return 0;
}
double t = realUpper-(1-x)/x;
return Math.pow(Math.E, -0.5*t*t) / (x*x);
}
});
result /= Math.pow(2*Math.PI, 0.5);
result = new BigDecimal(result).
setScale(4, RoundingMode.HALF_UP).doubleValue();
System.out.println(result);
}
public static void main2(String[] args) {
Integration integration = new Integration();
double upper = 1.0;
double lower = 0.0;
int n = 10;
double result =
integration.simpsonRule(upper, lower, n, new Function() {
@Override
public double fun(double x) {
return Math.pow(Math.E, -x*x/2);
}
});
result /= Math.pow(2*Math.PI, 0.5);
System.out.println(result);
BigDecimal decimal = new BigDecimal(result).setScale(4, RoundingMode.HALF_UP);
result = Double.valueOf(decimal.toString());
System.out.println(result);
}
public static void main1(String[] args) {
Integration integration = new Integration();
double upper = 1.0;
double lower = 0;
int n = 10;
double result =
integration.simpsonRule(upper, lower, n, new Function() {
@Override
public double fun(double x) {
return 4 / (1+Math.pow(x,2.0));
}
});
System.out.println(result);
}
测试:
1.定积分表达式:
2.求无穷限积分是基于定积分的(本文以求标准正态分布下限反常积分为例)
2)标准正态分布的无穷下限反常积分可转化为:
推广形式: