使用在结构中定义的GSL函数 [英] Using GSL functions defined in a structure

查看:217
本文介绍了使用在结构中定义的GSL函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个包含所有函数(包括GSL函数)和参数的结构来解决ODE系统。从主函数,我只想调用在struct中定义的更新函数,将系统推进一个时间步长。当我尝试这个但是,我得到的错误:

I want to write a structure containing all the functions (including GSL functions) and parameters for solving an ODE system. From the main function, I only want to call an update function defined in the struct to advance the system by one time-step. When I try this however, I get the error:

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. \

这是我的代码的最小版本:

Here is a minimal version of my 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;
}


推荐答案

直接使用静态函数。而是可以写一个非常笼统的包装器。

You don't need to use static function directly. Instead you can write a very general wrapper.

我相信这是一个重复的问题。对我刚才链接的问题的我的回答是基于显示的包装器这里。但是,我使用模板来概括它,以避免 std :: function 的性能损失到堆分配std :: function保存的函数(原始答案只警告读者关于由std :: function实现中涉及的多个间接引起的惩罚,并且这与堆引起的问题相比是可以忽略的分配)。

I believe this is a duplicate question. My answer to the question I just linked is based on the wrapper presented here. However, I generalized it using templates to avoid the performance penalty of std::function due to heap allocation of the functor that std::function holds (the original answer only warns the reader about the penalty that is caused by the multiple indirection involved in std::function implementation, and this is negligible in comparison to the problem caused by heap allocation).

编辑1:此问题也在这里

编辑2(回答你在我的回答的第一个评论中提出的问题)。第一个警告是,你必须确保 std :: function 保存在GSL完成计算之前不会被删除。此外,@Managu指出,GSL工作时,包装器本身不能超出范围。如果你仔细编码,这并不难执行。错误代码示例:

EDIT 2 (to answer a question you raised in your first comment to my answer). The first caveat is that you have to make sure that whatever std::function holds is not deleted before GSL finish the calculation. Also, @Managu pointed out that the wrapper itself must not be out of scope while GSL works. This is not hard to enforce if you code carefully. Example of bad code:

 // 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

这篇关于使用在结构中定义的GSL函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆