0

I have a prototype code in Matlab, it's using fsolve and fzero in some calculations. In c++ I'm using GSL and trying to find the value x which is f(x)=0;

So for my example, in Matlab I do:

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

this one clearly solves the Matlab function which is:

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

So then in C++, i have myFunction as;

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

In GSL documentation it's telling about root finding example however need some help. https://www.gnu.org/software/gsl/manual/html_node/Root-Finding-Examples.html#Root-Finding-Examples

There must be some clear ways to find 0 root(s) of given function. Even if you can provide me simple example I'll be so glad!

All best.

questioner
  • 97
  • 10

1 Answers1

1

You can't cast class member functions into gsl_function without a wrapper. You must use global functions. In this case, the second example shown on the GSL documentation you linked is the standard way to use the library if you can't provide the function first derivative (otherwise check the first example). There is not much simplification left.

If you are willing to use a wrapper, however, there a many ways to simplify your life. For example, you can use a wrapper to enable c++11 features like lambdas!. In general, I don't recommend anyone to use third-party wrapper for GSL without a careful code check. You should first learn the standard way.

Another example: I developed a small wrapper that simplifies the GSL 1D Root Finder API. You can find the source code and a nice example in this link. I am NOT saying you should use my wrapper. In time, you will probably develop your own!

Update 1: There is also O2Scl which is the most developed C++ wrapper for gsl that I am aware of. It seems to have a very nice API. Again: you should use wrapper with great care.

Update 2: To answer a question raised in a comment: You can also create a global function and use it as a wrapper. Example:

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

I don't like this solution in more complicated cases (but here is perfectly fine and probably the simpler option) because it is cumbersome if you want to send more parameters (example: you need 2 parameters: the class itself and an extra number - in this case you would need to create an extra struct to hold both!). Using the wrapper I linked you can easily send many parameters using lambdas! Example

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

Just for completion, here is the wrapper code

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);
   }
};
Community
  • 1
  • 1
Vivian Miranda
  • 2,276
  • 1
  • 13
  • 26
  • thank you so much for the answer Vinicius! Good to hear about wrappers. I'll use without wrapper. Could you just clarify that standard way of using library? – questioner May 06 '14 at 07:31
  • So okay, the standard way is using gsl without a class member function right?.. Then no I have to use it one of my class function, because it should use pre-calculated global parameters. If I use gsl function then, Somehow I should pass all my parameters to that function. Here I found one of your solution http://stackoverflow.com/questions/13074756/how-to-avoid-static-member-function-when-using-gsl-with-c However this way is pushing it to work very hard. There must be other ways. Could you tell me, or link me more about wrappers? seemingly I'll be writing own wrapper functions, b need advices – questioner May 06 '14 at 12:16
  • Thank you so much Vinicius, u re the best on this topic. I understood it but just can't try it now. I'll let u know. Thanks a lot+++!!! – questioner May 07 '14 at 16:04