有没有这样做的方法?我有一个需要曲线下面积的应用程序,并且我得到了公式,所以如果我可以手头进行集成,我应该能够以编程方式进行吗?我找不到我所指的方法的名称,但这张图片展示了它: http: //www.mathwords.com/a/a_assets/area%20under%20curve%20ex1work.gif
编辑:回复大家,我已经实现了矩形、梯形和辛普森规则。但是,它们需要 10k+ 条才能准确,我是否应该无法以编程方式找到功能的集成版本?如果没有,那肯定有一个该死的充分理由。
有没有这样做的方法?我有一个需要曲线下面积的应用程序,并且我得到了公式,所以如果我可以手头进行集成,我应该能够以编程方式进行吗?我找不到我所指的方法的名称,但这张图片展示了它: http: //www.mathwords.com/a/a_assets/area%20under%20curve%20ex1work.gif
编辑:回复大家,我已经实现了矩形、梯形和辛普森规则。但是,它们需要 10k+ 条才能准确,我是否应该无法以编程方式找到功能的集成版本?如果没有,那肯定有一个该死的充分理由。
数值积分
有多种方法,可以使用。有关描述,请查看数值食谱:科学计算的艺术。
对于 Java,有 Apace Commons 库,可以使用。积分例程在数值分析部分。
符号集成
查看jScience。函数模块“为相当简单的符号数学分析提供支持(求解代数方程、积分、微分、计算表达式等)”。
如果给定函数类型,则在特定情况下集成速度可能比使用某些标准库时更快。
我建议使用辛普森规则或梯形规则,因为集成每种类型的图可能过于复杂。
这是一个简单但有效的方法:
public static double area(DoubleFunction<Double> f, double start, double end, int intervals) {
double deltaX = (end - start)/intervals;
double area = 0.0;
double effectiveStart = start + (deltaX / 2);
for (int i=0; i<intervals; ++i) {
area += f.apply(effectiveStart + (i * deltaX));
}
return deltaX * area;
}
这是使用中点规则的黎曼和,它是梯形规则的变体,除了计算梯形的面积之外,我在区间中间使用 f(x) 的矩形。这更快并给出更好的结果。这就是为什么我的 x 的有效起始值位于第一个间隔的中间。通过循环一个整数,我避免了任何舍入问题。
我还通过等到循环结束再乘以来提高性能deltaX
。我可以这样写循环:
for (int i=0; i<intervals; ++i) {
area += deltaX * f.apply(effectiveStart + (i * deltaX)); // this is x * y for each rectangle
}
但是deltaX
是恒定的,因此等待循环完成会更快。
最流行的数值积分形式之一是 Runge-Kutta order 4 (RK4) 技术。它的实现如下:
double dx, //step size
y ; //initial value
for(i=0;i<number_of_iterations;i++){
double k1=f(y);
double k2=f(y+dx/2*k1);
double k3=f(y+dx/2*k2);
double k4=f(y+dx*k3);
y+= dx/6*(k1+2*k2+2*k3+k4);
}
并且会比矩形、梯形和辛普森规则收敛得更快。它是物理模拟中最常用的集成技术之一。