zoukankan      html  css  js  c++  java
  • 自适应Simpson积分

    自适应Simpson积分

    作用

      如标题所示,这玩意就是当你不会微积分的时候来求积分的。

      总所周知,积分的定义就是函数的某一段与坐标轴之间的面积。

      那么,自适应Simpson积分就是一种可以再某些精度下计算出较为平滑的函数的积分的比较简单优美的算法。

      (PS:这玩意的时间复杂度?大概是O(玄学)吧)

    引子

      积分的定义是面积,那么我们可以通过最基本的切割法来求出一定精度下面积。

      (ps:就是0.0000……01那样扫过去,把这个当做宽,把函数值当做高,然后乘起来当做面积)

      然而这个耗费的时间太多,而且精度也不如人意,所以就出现了Simpson积分。

    正文

      依旧是总所周知,一条二次函数曲线由三个点确定,那么也意味着,我们确定三个点可以确定一条二次函数曲线。

      还是总所周知,二次函数的积分是好求的,也就是牛顿科特斯的公式中n=2的情况。那么我们就可以通过二分取点来吧当前区间的积分拟成一个二次函数的积分。

      来写份伪代码可能会清楚一点

    double get(double l,double r){
    
    	mid=(l+r)/2;
    
    	return (横坐标为l,r,mid,纵坐标为他们在要积分的函数上的值)穿过这三个点的二次函数在l到r之间的积分。这一步具体可以表现为(r-l)(f(l)+f(r)+4*f(mid))/6(这个公式据说用导数求很方便,在这里会用就好,我也并不会证明(我太弱啦))
    
    }
    
    double Simpson(double l,double r){
    
    	double mid=(l+r)/2;
    
    	s1=get(l,mid)+get(mid,r);
    
    	s2=get(l,r);
    
    	if(abs(s1-s2)<eps(这玩意是精度误差))return s2;
    
    	return Simpson(l,mid)+Simpson(mid,r);
    
    }
    

      如代码所示,自适应Simpson积分就是不停地二分区间,然后把每一段函数看成两段二次函数,然后积分,再中间取点,若这个与继续分下去的差小于精度误差,那么这个区间再分下去也不会对答案的精度范围造成什么影响,那么就直接返回这一段区间的值。

      然而据大佬yww讲,这玩意是假的自适应Simpson积分,因为没有精度保障,他的都是把eps也二分传下去。这样做确实能有精度保障(然而在bzoj的某道题目,yww的真丶自适应积分爆炸了,假的自适应积分过了),所以我还是写假的自适应Simpson积分吧。

    某些注意事项

      有许多根本积不了分的函数也照样可以被自适应Simpson积分摁在地上日,原因很显然,就是这玩意就一逼近算法,没太多数学上的限制。当然,越平滑的函数用Simpson积分所造成的误差会越小,如果有什么七次函数八次函数什么的倒是也可以用,不过效果怎么样就不知道了。

    众星因你,皆降为尘。
  • 相关阅读:
    面向对象基本原则
    策略模式
    简单工厂模式
    高内聚、低耦合
    UML在代码中的展现
    使用commons-csv简单读写CSV文件
    java反射机制
    SrpingDruid数据源加密数据库密码
    markdown学习经验
    Vue.js学习笔记
  • 原文地址:https://www.cnblogs.com/Star-dust/p/7375853.html
Copyright © 2011-2022 走看看