让微积分穿梭于工作与学习之间(9):自己捣鼓定积分的近似值计算,碰到了不会解决的问题
运用牛顿——莱布尼茨公式,可以把定积分的计算转化到原函数的差值当中。也就是说,只要被积函数的原函数能被求出来,并且是一个初等数学函数,那么定积分的计算就会变得相当简单。
然而,这个只要有时不一定能做到。不过我仍然相信,求不出原函数的初等函数,除了几个特定的个案或者无太大实际意义的复杂函数以外,大部分还是能算得出原函数的。
爱钻牛角尖的我,当年就把焦点落在了正态分布的函数中。我们之前高考,和英语四六级都用过标准分。它是根据正态分布的客观规律,按名次分布到正态曲线上从而算出一个所谓的标准分。
在上大学之前,由于大多数同学没学过高等数学,所以名次和标准分的对应关系都直接写到一个表格上供大家查阅。
而在我学习了一元函数微积分之后,我就开始尝试自己写代码去算那些无法用初等函数来算的定积分。
前面说过,定积分的定义是分割+近似求和+取极限。对于不复杂的函数,选取合适的分割方式,有希望以通项公式的形式表示近似求和的结果,然后算得极限值。比如连载5中的1/x定积分。但大多数函数都很难这样子做,所以我就拿了最简单粗暴的方式,不管三七二十一,直接按x等分,然后在代码中来一个for循环完事。
我们用的教材很坑,连定积分的近似计算都懒得一提,所以我除了用矩形条面积相加就没别的方法了,后面觉得矩形精度太低而改成直角梯形。而别的教材则在这个地方有所提及,并给出了抛物线法,即用抛物线弧模拟函数曲线进行计算。
我一开始是不知道的,所以只会用矩形和梯形,然后遇到的问题可想而知。就是精确度很低,所以我只能尝试增加分割的份数来去逼近,但仍跟正态分布积分表给出的结果之间存在较大误差。更坑的是,有的区间只需要分割很少的份数就能获得一个很精确的结果,而有的区间分割到1000份都未必能达到精确度的要求。性能被浪费了,但问题却还得不到解决。
正态分布函数的曲线大概是长这个样子的:
求不同区间的定积分(面积),哪怕长度相等,分割的份数要求都差别较大。比如下图的蓝色部分,我分3份就基本上能算出跟准确值比较接近的结果了。但是红色部分,拆成6份的误差都还是比蓝色部分要大得多。
其实这个玩意儿是要做误差估计,但那时候我是没懂这些东西的。而解决这一问题的方法,已经被汇总到一个叫数值积分的学科里面。要把它玩转还真的不容易。
当然了,后面看了别的教材,知道了抛物线法之后,就发现还是能凑合着用了。教材上给出的用1/(1+x^4)求pi的近似值的例子,抛物线法只要分割10份,就能精确到小数点第6位,对于实际开发来讲,大多数情况下已经够用。
就这样,我开始发现自己还真牛逼不到哪里去,就这种事情都已经无法驾驭了,更难的怎么办?
不过我还是觉得,实际中无法求出原函数的初等数学函数为数不多。把原函数求出来,就不用面对这样的问题了。
然而,无法求出原函数的初等数学函数很多很多。但是那时候自己的见识还是过于浅薄,所以就有一段时间没去深入了。在这个探索过程中,我了解到了Mathemetica(跟著名的Matlab是相似的软件),用那个求定积分近似值非常方便。美中不足的地方是我没办法了解到底层,无法用高级编程语言将其实现。
再到后面,工作中真的用到了(虽然不是我,是一个网友),我当时还自以为牛逼地去给他研究,结果以失败告终。下一篇,我会把这个事情分享给大家!