在Java中计算曲线下的精确区域

时间:2012-11-12 08:00:44

标签: java math

有没有哪种方法可以做到这一点?我有一个应用程序,我需要曲线下面积,我给了公式,所以如果我可以手头进行集成,我应该能够以编程方式进行吗?我找不到我所指的方法的名称,但此图片演示了它:http://www.mathwords.com/a/a_assets/area%20under%20curve%20ex1work.gif

编辑:对每个人都回复,我已经实施了矩形,梯形和辛普森的规则。但是,它们像10k +条纹一样准确,我应该无法以编程方式找到函数的集成版本吗?如果没有,那就必须有一个血腥的理由。

7 个答案:

答案 0 :(得分:4)

数值整合
有多种方法可以使用。有关说明,请查看Numerical Recipes: The Art of Scientific Computing 对于Java,可以使用Apace Commons库。集成例程位于Numerical Analysis部分。

符号整合
查看jScienceFunctions模块"为相当简单的符号数学分析提供支持(解决代数方程,积分,区分,计算表达式等)"。
如果给出了函数类型,则可以在特定情况下比使用某些标准库时更快地集成。

答案 1 :(得分:1)

要精确计算它,您需要某种computer algebra system库来执行符号操作。这样的系统实现起来相当复杂,我不熟悉任何高质量的Java开源库。但是,假设它符合您的要求,另一种方法是使用trapezoidal rule估算曲线下面积。根据您对结果的准确程度,您可以相应地改变细分的大小。

答案 2 :(得分:0)

我建议使用Simpsons规则或梯形规则,因为整合每种类型的图形可能过于复杂。

答案 3 :(得分:0)

请参见Numerical analysis具体的数值积分。如何使用Riemann sum方法?

答案 4 :(得分:0)

您可以使用numerical integration,使用一些规则,如已经提到过的Simpsons,Trapezoidal或Monte-Carlo simulation。它使用伪随机生成器。

您可以尝试使用某些库进行符号集成,但我不确定您是否可以获得每个积分的符号表示。

答案 5 :(得分:0)

最流行的数字整合形式之一是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);
}

并且会比矩形,梯形和辛普森的规则快得多。它是物理模拟中更常用的集成技术之一。

答案 6 :(得分:0)

这是一种简单但有效的方法:

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是常量,因此等待循环完成会更快。