我们知道,微积分的求值是比较复杂的。一般来说,求积分有定积分和不定积分之分。不定积分需要求出具体的表达式,但被积函数非常复杂时,求解非常费劲,非常可能找不到原函数。而定积分给定了区间范围,可以利用数值方法,利用微分的本质原理来进行积分数值计算。当前,微积分的数值计算方法很多,比如常见的有如下算法:梯形规则,辛普森规则和龙贝格规则。
1 Simpson's Rule原理
下面我们介绍一下辛普森规则如何求数值积分,积分的数值本质上就是被积函数f(x)下的面积,定积分f(x) 在[a,b]上的数值就是被积函数f(x)在x轴a和b围起来的面积。当按照x轴方向,分成非常多的份,每一个份∇x就是非常小的微分单位,比如0.00001,这样曲线的面积,就可以近似看成是梯形或者方形和三角形的和等。下面给出辛普森规则的推导公式:
此公式也有其他的表现形式,但是基本原理相同。它也称作Simpson’s 1/3 rule 。公式来自: http://www.numericmethod.com/About-numerical-methods/numerical-integration/simpson-s-rule
2 F#Simpson's Rule实现
结合如上的算法公式,用F#语言可实现数值积分的计算,代码如下:
moduleNumMethodletrecNIntfab=letnumSteps=1000000leth=double(b-a) / (double(numSteps)) letmutablevalueEven=double(0.) letmutablevalueOdd=double(0.) fori=0tonumStepsdoifi%2<>0thenvalueOdd<-valueOdd+f( a+h*double(i)) elsevalueEven<-valueEven+f(a+h*double(i)) (f(a)+f(b)+4.0*valueOdd+2.0*valueEven)*(h/3.0)
这里的微分步长numSteps可以根据需要进行调整,理论上,越大应该精确度越高,但是性能越差。算法的本质就是在区间[a,b]上去划分成N个小区域,然后计算每个小区域的面积,而小区域的面积的一边虽然是曲线f(x),但由于间距很小,可用直线近似替代。最后将每个小区域的面积相加即可完成数值积分的近似计算。
3 测试
下面给定一些函数来进行定积分数值的计算测试,代码如下:
lettest=letf1x=2.+cos(2.*sqrt(x)) letz=NIntf10.12.0printfn"%f"z//3.169783 //3.1697776595193/////////////////////////letf2x=2.*xletz=NIntf21.2.0printfn"%f"z//3.000004 // 3
由测试可知,在一定的精确度下,数值积分的结果与实际的积分结果还是比较接近的。