【问题标题】:A numerical library which uses a paralleled algorithm to do one dimensional integration?使用并行算法进行一维积分的数值库?
【发布时间】:2014-07-06 18:06:06
【问题描述】:

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

谢谢!

【问题讨论】:

    标签: numerical numerical-integration


    【解决方案1】:

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

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

    这里的函数“f”计算向量x[]给出的nx横坐标处的被积函数。这就是并行化出现的地方,因为您可以使用parallel_for(例如在openmp 中实现)同时在这些点上评估f。集成器本身是单线程的。

    Nag 是一个非常昂贵的库,但是如果您自己使用例如numerical recipes 编写积分器,则使用 NAG 的想法修改串行实现以创建并行自适应积分器并不困难。

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

    在每一步,梯形规则都可以使用以下通用实现来计算

    double trapezoidal( double (*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;
    }
    

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

    【讨论】:

    • 感谢您的解决方案!是的,这正是我需要的。将被积函数的参数向量化也是一个好主意,我相信修改数值配方或GSL的版本应该不是一件难事。
    【解决方案2】:

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

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

    【讨论】:

    • 在某些情况下,不可能同时评估多个集成。例如,如果您正在运行马尔可夫链,则在完成此步骤之前,您将不知道下一步要评估什么。如果一个步骤包括数值积分,则除非您对积分算法本身进行并行化,否则您无法并行化它。
    • @xuhdev:您可以在连续评估马尔可夫链的同时并行化每个步骤中的积分。
    • 如果每个步骤只有一个集成怎么办?此外,即使您要在一个步骤中完成多个集成(N 个集成),您也无法使用第 (N+1) 个处理器。
    • @xuhdev:您可以将积分范围平均划分为 N+1 个区间,在不同的线程上对它们中的每一个进行积分(如果在一个线程上的整个范围),并在它们全部完成后将它们加在一起,然后再进行下一步。
    • 分割区间是否会显着增加全局自适应方法的积分时间?
    猜你喜欢
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    相关资源
    最近更新 更多