积分冻结 java 实现 java定积分_开发语言

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.定积分:
定积分的定义:

 

积分冻结 java 实现 java定积分_开发语言_02

 此时f(x)在[a,b]上可积

定积分是积分的一种,是函数f(x)在区间[a,b]上积分和的极限

而java就定积分,则需要用另一种办法,是用辛普森法则:辛普森法则的基本思想是利用函数在某区间内的奇次幂的积分性质,即在一个奇数个点的区间上,函数的积分可以表示为这些点上的函数值的线性组合。对于一个给定的区间[a, b],辛普森法则将其分成n个等宽的小区间,每个小区间的宽度为h = (b - a) / (n - 1),其中n是子区间的数量。

公式如下:

对于奇数个子区间:

积分冻结 java 实现 java定积分_算法_03

对于偶数个子区间(n为偶数):

积分冻结 java 实现 java定积分_java_04

用以上法则可以轻而易举的算出定积分,直接上代码

/**
     * @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.定积分表达式:

积分冻结 java 实现 java定积分_算法_05

2.求无穷限积分是基于定积分的(本文以求标准正态分布下限反常积分为例)

积分冻结 java 实现 java定积分_积分冻结 java 实现_06

2)标准正态分布的无穷下限反常积分可转化为:

积分冻结 java 实现 java定积分_积分冻结 java 实现_07

推广形式:

积分冻结 java 实现 java定积分_开发语言_08