gpt4 book ai didi

c++ - 在共享库的类中调用 GSL 函数

转载 作者:行者123 更新时间:2023-11-30 02:51:49 27 4
gpt4 key购买 nike

我正在尝试使用 C++ 实现费米气体工具的共享库。我正在使用 GSL 库以数字方式求解函数,并且我的代码在作为脚本运行时没有问题地运行,但是在尝试将其转换为共享库和类时我遇到了问题。

我见过类似的问题: Q1 Q2 Q3

我是 C++ 编程的新手,似乎无法针对我的问题调整不同的答案。可能是因为我不太明白答案。

我的代码是:

/* Define structure for the GSL-function: chempot_integrand */
struct chempot_integrand_params { double mu; double T; };

double
ChemicalPotential::chempot_integrand (double x, void * params){
/* Computes the integrand for the integral used to obtain the chemical potential.
*
* This is a GSL-function, which are integrated using gsl_integration_qag.
*/

// Get input parameters.
struct chempot_integrand_params * p = (struct chempot_integrand_params *) params;
double mu = p->mu;
double T = p->T;

// Initiate output parameters for GSL-function.
gsl_sf_result_e10 result;
int status = gsl_sf_exp_e10_e( ( gsl_pow_2(x) - mu ) / T , &result );

if (status != GSL_SUCCESS){
printf ("Fault in calculating exponential function.");
}

// Return (double) integrand.
return (gsl_pow_2(x) / ( 1 + result.val * gsl_sf_pow_int(10,result.e10) ));
}

/* Define structure for the GSL-function: chempot_integration */
struct chempot_integral_params { double T; };

double
ChemicalPotential::chempot_integration (double mu, double T){
/* Computes the integral used to obtain the chemical potential using the integrand: chempot_integrand.
*/

// Set input parameters for the integrand: chempot_integrand.
struct chempot_integrand_params params_integrand = { mu, T };

// Initiate the numerical integration.
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000); // Allocate memory for the numerical integration. Can be made larger if neccessary, REMEMBER to change it in the function call: gsl_integration_qag as well.
double result, error;
gsl_function F;
F.function = &ChemicalPotential::chempot_integrand;
F.params = &params_integrand;

// Upper limit for integration
double TOL = 1e-9;
double upp_lim = - T * gsl_sf_log(TOL) + 10;

gsl_integration_qag (&F, 0, upp_lim, 1e-12, 1e-12, 1000, 6, w, &result, &error);

// Free memory used for the integration.
gsl_integration_workspace_free (w);

return result;
}

编译时出现错误

error: cannot convert ‘double (Fermi_Gas::ChemicalPotential::*)(double, void*)’ to ‘double (*)(double, void*)’ 

排队

F.function = &ChemicalPotential::chempot_integrand;

最佳答案

确实有趣的是人们一遍又一遍地问这个问题。原因之一可能是所提出的解决方案不容易理解。我个人在理解和实现它们时遇到了问题。 (如您所料,这些解决方案对我来说并不是开箱即用的。)

tlamadon的帮助下我刚刚想出了一个可能在这里也有帮助的解决方案。让我们看看你们的想法。

因此,回顾一下,问题是您有一个包含成员函数的类,您希望在该类上使用 GSL 库中的内容进行操作。如果 GSL 接口(interface)需要一个

gsl_function F;

see here for a definition.

所以这是示例类:

class MyClass {

private:
gsl_f_pars *p; // not necessary to have as member

public:
double obj(double x, void * pars); // objective fun
double GetSolution( void );
void setPars( gsl_f_pars * xp ) { p = xp; };
double getC( void ) ; // helper fun

};

这个练习的目标是能够

  1. 启动MyClass测试,
  2. 为其提供参数结构(或编写相应的构造函数),以及
  3. 对其调用 test.GetSolution(),它应该返回 GSL 函数的用途(obj 的最小值、根、积分或其​​他)

现在的诀窍是在参数 struct gsl_f_pars 中放置一个元素,是指向 MyClass 的指针。这是结构:

struct gsl_f_pars {
double a;
double b;
double c;
MyClass * pt_MyClass;
};

最后一部分是提供一个将在 MyClass::GetSolution() 中调用的包装器(包装器是成员函数 MyClass::obj,我们不能只在类中用 &obj 指向它)。此包装器将采用参数结构、取消引用 pt_MyClass 并评估 pt_MyClass 的成员 obj:

// Wrapper that points to member function
// Trick: MyClass is an element of the gsl_f_pars struct
// so we can tease the value of the objective function out
// of there.
double gslClassWrapper(double x, void * pp) {
gsl_f_pars *p = (gsl_f_pars *)pp;
return p->pt_MyClass->obj(x,p);
}

完整的示例有点太长,无法在这里发布,所以我提出了一个要点。这是一个header file和一个 cpp file ,它应该在任何有 GSL 的地方工作。编译运行

g++ MyClass.cpp -lgsl -o test
./test

关于c++ - 在共享库的类中调用 GSL 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19450198/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com