c++ - c++ 中的 fsolve &fzero 与 GSL 根查找

标签 c++ matlab gsl

我在 Matlab 中有一个原型(prototype)代码,它在一些计算中使用了 fsolve 和 fzero。 在 C++ 中,我正在使用 GSL 并试图找到 f(x)=0 的值 x;

以我为例, 在 Matlab 中我这样做:

functionSolver= @(x) myFunction(x);
XSol = fsolve(functionSolver,0);

这一个清楚地解决了 Matlab 函数:

function F = myFunction(x)
%% do something with x
F = x;
end

那么在 C++ 中,我将 myFunction 作为;

double myClass::myFunction(double x){
//do something with x
return x;
}

在 GSL 文档中,它讲述了根查找示例,但需要一些帮助。 https://www.gnu.org/software/gsl/manual/html_node/Root-Finding-Examples.html#Root-Finding-Examples

必须有一些清晰的方法来找到给定函数的 0 个根。即使您能给我提供简单的示例,我也会很高兴!

一切顺利。

最佳答案

不能将类成员函数转换为gsl_function without a wrapper .您必须使用全局函数。在这种情况下,the GSL documentation 上显示的第二个示例如果您不能提供函数一阶导数(否则请检查第一个示例),您链接的是使用该库的标准方法。没有太多的简化。

但是,如果您愿意使用包装器,有很多方法可以简化您的生活。例如,您可以使用包装器 to enable c++11 features like lambdas! .一般来说,我不建议任何人在没有仔细检查代码的情况下使用 GSL 的第三方包装器。您应该首先学习标准方法。

另一个例子:我开发了一个小型包装器来简化 GSL 1D Root Finder API。您可以在此 link 中找到源代码和一个很好的示例.我不是说你应该使用我的 wrapper 。假以时日,您可能会开发自己的!

更新 1:还有 O2Scl这是我所知道的最发达的 gsl C++ 包装器。它似乎有一个非常好的 API。再次声明:您应该非常小心地使用 wrapper。

更新 2:回答评论中提出的问题:您还可以创建一个全局函数并将其用作包装器。示例:

double myFunction(double x, void* ptr) {
    myClass* ptr2 = static_cast<myClass*>(ptr);
    return ptr2->myFunction(x);
}

在更复杂的情况下我不喜欢这个解决方案(但这里非常好并且可能是更简单的选项)因为如果你想发送更多参数(例如:你需要 2 个参数:类本身和一个额外的数字 - 在这种情况下,您需要创建一个额外的结构来容纳两者!)。使用我链接的包装器,您可以使用 lambda 轻松地发送许多参数!示例

double a = 1;
myClass m1 ....
gsl_function_pp Fp( [&](double x){return a * m1.myFunction(x);} ); 
gsl_function *F = static_cast<gsl_function*>(&Fp); 

只是为了完成,这是包装代码

class gsl_function_pp : public gsl_function
{
   public:
   gsl_function_pp(std::function<double(double)> const& func) : _func(func){
   function=&gsl_function_pp::invoke;
   params=this;
   }     
   private:
   std::function<double(double)> _func;
   static double invoke(double x, void *params) {
   return static_cast<gsl_function_pp*>(params)->_func(x);
   }
};

关于c++ - c++ 中的 fsolve &fzero 与 GSL 根查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23471673/

相关文章:

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

c++ - 出现 BK4503 小错误后,Visual Studio 2013 突然编译真的很慢

c++ - 如何将字符串转换为long long

c++ - x64 上的 WMI 链接器错误

MATLAB 帮助/文档显示不正确

matlab - 为什么分解单应矩阵需要相机内参?

C++:ifstream 作为参数

ruby - 我可以在 Ruby 中加载 MATLAB mat 文件吗?

c++ - 是否隐藏了 void* 参数的名称?

c++ - 条件运算符(<、>)在 gsl 插值函数中不起作用