使用在结构中定义的GSL功能(Using GSL functions defined in a st

2019-10-18 17:30发布

我想要写一个包含所有功能(包括GSL函数)和参数求解ODE系统的结构。 从主要功能,我只是想调用的结构定义的更新功能通过一个时间步推进系统。 当我尝试这个但是,我得到的错误:

Line 27, ERROR:  cannot convert ‘ODE::funcS’ from type ‘int (ODE::)(double, const double*, double*, void*)’ to type ‘int (*)(double, const double*, double*, void*)’ Below is a minimal code. \

这里是我的代码最低版本:

#include <iostream>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv.h>

struct ODE
{
    void update(double dt)
    {
        // code to advance ODE solution by one time-step dt
    }

    int
    funcS (double t, const double y[], double f[],
          void *params)
    {
        return GSL_SUCCESS;
    }

    double mu = 10;

    gsl_odeiv_system sysS;

    void
    initializeSys()
    {
        sysS.function = funcS; //Line 27
    }
};

int
func (double t, const double y[], double f[],
          void *params)
{
    return GSL_SUCCESS;
}

int main()
{
    // GIVES ERROR
    ODE mySys;
    mySys.update(0.01);


    // WORKS
    double mu = 10;
    gsl_odeiv_system sys;
    sys.function = func;

    return 0;
}

Answer 1:

你并不需要直接使用静电功能。 相反,你可以写一个非常普遍的包装。

我相信这是一个重复的问题 。 我的回答对我只是链接的问题是根据给出的包装这里 。 不过,我概括它使用模板来避免的std ::功能的性能损失 ,由于该标准::函数持有仿函数的堆分配(原答案只发出警告是通过参与多个间接导致的罚款读者的std ::功能实现,这是相比于引起堆分配问题)可忽略不计。

编辑1:这个问题也是讨论这里

编辑2(回答我回答你第一个评论提出了一个问题)。 首先需要注意的是,你必须确保任何std::function持有GSL完成计算之前不会被删除。 此外,@Managu指出,包装本身必须不超出范围,而GSL的作品。 这不是很难执行,如果你仔细地编写代码。 不好的代码示例:

 // BAD PROGRAM - EXAMPLE OF WHAT YOU MUST NOT DO. DO NOT COPY THIS CODE
 // HERE THE WRAPPER GETS PREMATURELY OUT OF SCOPE => CRASH
 gsl_function *F 
 auto ptr = [](double x)->double{return 2*x;};
 std::function<double(double)> FF1(std::cref(ptr))

 {      
   gsl_function_pp Fp(FF1);
   F = static_cast<gsl_function*>(&Fp);  
 }
 (...)
 // CALL GSL


文章来源: Using GSL functions defined in a structure
标签: c++ gsl