一个使用并行算法进行一维积分的数值库?

时间:2014-05-18 20:35:16

标签: numerical numerical-integration

是否有可以使用并行算法进行一维积分的数值库(全局自适应方法)?我的代码的基础结构决定我不能并行进行多个数值集成,但我必须使用并行算法来加速。

谢谢!

2 个答案:

答案 0 :(得分:1)

Nag C数值库确实具有自适应正交的并行版本(链接here)。他们的诀窍是向用户请求以下功能

void (*f)(const double x[], Integer nx, double fv[], Integer *iflag, Nag_Comm *comm)

此处函数“f”评估向量nx给出的x[]个缩写点处的被积函数。这就是并行化的用武之地,因为您可以使用parallel_for(例如在openmp中实现)来同时评估这些点的f。集成商本身是单线程的。

Nag是一个非常昂贵的库,但如果您自己使用numerical recipes编写集成器代码,则使用NAG构思修改串行实现来创建并行自适应积分器并不困难。

我无法复制数字食谱书,以显示由于许可限制而需要进行修改的地方。因此,让我们采用trapezoidal rule的最简单示例,其中实现非常简单且众所周知。使用梯形法则创建自适应方法的最简单方法是计算点网格处的积分,然后将精确点数加倍并比较结果。如果结果变化小于要求的精度,那么就会收敛。

在每个步骤中,可以使用以下通用实现来计算梯形规则

double trapezoidal( void (*f)(double x), double a, double b, int n)
{
  double h = (b - a)/n;
  double s = 0.5 * h * (f(a) + f(b));
  for( int i = 1; i < n; ++i ) s += h * f(a + i*h);
  return s;
}

现在,您可以进行以下更改以实施NAG构思

double trapezoidal( void (*f)( double x[], int nx, double fv[] ), double a, double b, int n)
{
  double h = (b - a)/n;
  double x[n+1];
  double fv[n+1];
  for( int i = 0; i < n; ++i ) x[i+1] = (a + i * h);
  x[n] = b;

  f(x, n, fv); // inside f, use parallel_for to evaluate the integrand at x[i], i=0..n

  double s = 0.5 * h * ( fv[0] + fv[n] );
  for( int i = 1; i < n; ++i ) s += h * fv[i];
  return s;
}

但是,如果被积函数的计算成本非常高,则此过程只会加快代码的速度。否则,您应该在更高的循环而不是积分器内并行化代码。

答案 1 :(得分:0)

为什么不简单地围绕单线程算法实现一个包装器,该算法将边界细分的积分分派到不同的线程,然后在最后将它们一起添加? e.g。

thread 0: i0 = integral(x0, (x0+x1)/2)
thread 1: i1 = integral((x0+x1)/2, x1)

i = i0 + i1