C++:OpenMP+ Boost Odeint与OpenMP+ GSL集成

发布于 2025-02-02 12:11:34 字数 5131 浏览 3 评论 0 原文

我的目标是平行一个一维积分。我已经环顾四周,我会说我可以通过两种方式做到这一点:i)用 OpenMP 使用 odeint boost library> library integrate_adapative function (see https://www.boost.org/doc/libs/1_56_0/libs/numeric/numeric/odeint/doc/doc/doc/doc/html/boost_numeric_ode_odeirt/parallection/parallectal/parallelal _computation_with_with_with_with_with_open_open_openmp_and_and_mmpi.mmpi.mmpi.mmpi.htl 使用使用 GSL Monte Carlo集成(如下所示:内部编译器误差在OpenMP并行区域中具有嵌套功能)。

我的问题是,我无法真正理解他们在我提供的两个链接中所做的一切。 我想知道有人是否有经验,并可能指出我如何在案件中实施这两种方法。是 openMP 带有 boost 更快还是 gsl OpenMP 实现?

pdffunction 表示积分函数中使用的概率密度函数。 pdffunction 等效于

7BT%7D%7b%5CTAU%7D% 5DCO i代码:

double PDFfunction(double invL, int t, double invtau, double x0, double x, int n) {

const double c =  M_PI * (M_PI/4) * ((2 * t) * invtau);

double res = 0;

for(int i = 1; i <= n; ++n){

  res += exp(-1 * (i * i) * c) * cos((i * M_PI * x) * invL) * cos((i * M_PI * x0) * invL);

}

return invL + ((2 * invL) * res);
}

Composite_at_t 是一个功能,它使用 pdffunction 来计算 pba pbb composite_at_t 等于” src =“ https://chart.googleapis.com/chart?cht=tx&; chl = p =(x,图表?

”

double Composite_at_t(double t, double B, double x0, double xt_pos, double y0, double yt_pos, double invLtot, double invtau, int n_lim) {

double pbA = PDFfunction(invLtot, t, invtau, x0, xt_pos, n_lim);
double pbB = PDFfunction(invLtot, t, invtau, y0, yt_pos, n_lim);
double b1 = 2 * (2 * t) * exp(-2 * t * B);
return pbA * pbB * b1;
}

composite_at_t_tclass 是一个func类,它计算了一个超过variable 的第一个积分t

class Composite_at_tCLASS: public Func{
private:
    double B;
    double x0;
    double xt_pos;
    double y0;
    double yt_pos;
    double invLtot;
    double invtau;
    int n_lim;
public:
    Composite_at_tCLASS(double B_, double x0_, double xt_pos_, double y0_, double yt_pos_, double invLtot_, double invtau_, int n_lim_) : B(B_), x0(x0_), xt_pos(xt_pos_), y0(y0_), yt_pos(yt_pos_), invLtot(invLtot_), invtau(invtau_), n_lim(n_lim_) {}
    double operator()(const double& t) const{
        return Composite_at_t(t, B, x0, xt_pos, y0, yt_pos, invLtot, invtau, n_lim);
    }
};

Integrate_compositeclass 是使用类 Composite_at_tclass 并通过 t 执行积分的实际功能, > time_lim 。

double integrate_CompositeCLASS(double B, double x0, double xt_pos, double y0, double yt_pos, double invLtot, double invtau, int n_lim, double time_lim){

    Composite_at_tCLASS f(B, x0, xt_pos, y0, yt_pos, invLtot, invtau, n_lim);
    double err_est;
    int err_code;
    double res = integrate(f, 0, time_lim, err_est, err_code);
    return res;
}

对于使用GSL库的数值集成,我将使用以下代码:

struct my_f_params { double B; double x0; double xt_pos; double y0; double yt_pos; double invtau; int n_lim; double invLtot;};

double g(double *k, size_t dim, void *p){
  struct my_f_params * fp = (struct my_f_params *)p;
  return Composite_at_t(k[0],fp->B, fp->x0, fp->xt_pos, fp->y0, fp->yt_pos, fp->invLtot, fp->invtau, fp->n_lim);
}

这是执行GSL积分的实际对象:

double integrate_integral(const double& invtau, const int& n_lim, const double& invLtot,
  const double& x0, const double& xt_pos, const double& y0, const double& yt_pos, const double& time_lim){

double res, err;

double xl[1] = {0};
double xu[1] = {time_lim};
const gsl_rng_type *T;
gsl_rng *r;

gsl_monte_function G;
struct my_f_params params = { B, x0, xt_pos, y0, yt_pos, invtau, n_lim, invLtot};

G.f = &g;
G.dim = 1;
G.params = &params;

size_t calls = 10000;

gsl_rng_env_setup ();

T = gsl_rng_default;
r = gsl_rng_alloc (T);


  gsl_monte_vegas_state *s = gsl_monte_vegas_alloc (1);
  gsl_monte_vegas_integrate (&G, xl, xu, 1, 10000, r, s,
                             &res, &err);

  do
        {
          gsl_monte_vegas_integrate (&G, xl, xu, 1, calls/5, r, s,
                                     &res, &err);
        }
      while (fabs (gsl_monte_vegas_chisq (s) - 1.0) > 0.5);

      gsl_monte_vegas_free (s);
      gsl_rng_free (r);


return res;
}

My objective is to parallelise a one-dimensional integral. I have looked around, and I would say that I could do that in two ways: i) implementing OpenMP with ODEINT, boost library integrate_adapative function (see https://www.boost.org/doc/libs/1_56_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/tutorial/parallel_computation_with_openmp_and_mpi.html).; ii) implementing OpenMP with GSL monte carlo integration (as in here: Internal compiler error with nested functions in OpenMP parallel regions).

My problem is that I cannot really understand what they did in both links I provided.
I was wondering whether someone has experience with that, and may point out how I could implement both approaches on my case. Is it OpenMP with boost faster or GSL and OpenMP implementation?

PDFfunction represents the probability density function that is used within the integrand function. PDFfunction is equivalent to , and in LateX is expressed as:

And this is how I code it:

double PDFfunction(double invL, int t, double invtau, double x0, double x, int n) {

const double c =  M_PI * (M_PI/4) * ((2 * t) * invtau);

double res = 0;

for(int i = 1; i <= n; ++n){

  res += exp(-1 * (i * i) * c) * cos((i * M_PI * x) * invL) * cos((i * M_PI * x0) * invL);

}

return invL + ((2 * invL) * res);
}

Composite_at_t is a function that makes use of the PDFfunction to compute pbA and pbB. Composite_at_t is equivalent to , where ) and ).

double Composite_at_t(double t, double B, double x0, double xt_pos, double y0, double yt_pos, double invLtot, double invtau, int n_lim) {

double pbA = PDFfunction(invLtot, t, invtau, x0, xt_pos, n_lim);
double pbB = PDFfunction(invLtot, t, invtau, y0, yt_pos, n_lim);
double b1 = 2 * (2 * t) * exp(-2 * t * B);
return pbA * pbB * b1;
}

Composite_at_tCLASS is a Func class which computes a first integral over variable t.

class Composite_at_tCLASS: public Func{
private:
    double B;
    double x0;
    double xt_pos;
    double y0;
    double yt_pos;
    double invLtot;
    double invtau;
    int n_lim;
public:
    Composite_at_tCLASS(double B_, double x0_, double xt_pos_, double y0_, double yt_pos_, double invLtot_, double invtau_, int n_lim_) : B(B_), x0(x0_), xt_pos(xt_pos_), y0(y0_), yt_pos(yt_pos_), invLtot(invLtot_), invtau(invtau_), n_lim(n_lim_) {}
    double operator()(const double& t) const{
        return Composite_at_t(t, B, x0, xt_pos, y0, yt_pos, invLtot, invtau, n_lim);
    }
};

integrate_CompositeCLASS is the actual function that uses the class Composite_at_tCLASS and perform the integral over t, between 0 and time_lim.

double integrate_CompositeCLASS(double B, double x0, double xt_pos, double y0, double yt_pos, double invLtot, double invtau, int n_lim, double time_lim){

    Composite_at_tCLASS f(B, x0, xt_pos, y0, yt_pos, invLtot, invtau, n_lim);
    double err_est;
    int err_code;
    double res = integrate(f, 0, time_lim, err_est, err_code);
    return res;
}

For the numerical integration using the GSL library I would use the following code:

struct my_f_params { double B; double x0; double xt_pos; double y0; double yt_pos; double invtau; int n_lim; double invLtot;};

double g(double *k, size_t dim, void *p){
  struct my_f_params * fp = (struct my_f_params *)p;
  return Composite_at_t(k[0],fp->B, fp->x0, fp->xt_pos, fp->y0, fp->yt_pos, fp->invLtot, fp->invtau, fp->n_lim);
}

And this is the actual object that perform the GSL integral:

double integrate_integral(const double& invtau, const int& n_lim, const double& invLtot,
  const double& x0, const double& xt_pos, const double& y0, const double& yt_pos, const double& time_lim){

double res, err;

double xl[1] = {0};
double xu[1] = {time_lim};
const gsl_rng_type *T;
gsl_rng *r;

gsl_monte_function G;
struct my_f_params params = { B, x0, xt_pos, y0, yt_pos, invtau, n_lim, invLtot};

G.f = &g;
G.dim = 1;
G.params = ¶ms;

size_t calls = 10000;

gsl_rng_env_setup ();

T = gsl_rng_default;
r = gsl_rng_alloc (T);


  gsl_monte_vegas_state *s = gsl_monte_vegas_alloc (1);
  gsl_monte_vegas_integrate (&G, xl, xu, 1, 10000, r, s,
                             &res, &err);

  do
        {
          gsl_monte_vegas_integrate (&G, xl, xu, 1, calls/5, r, s,
                                     &res, &err);
        }
      while (fabs (gsl_monte_vegas_chisq (s) - 1.0) > 0.5);

      gsl_monte_vegas_free (s);
      gsl_rng_free (r);


return res;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文