Search code examples
c++boostarguments

How to pass some constants in Boosts's brent_find_minima()?


How can I pass some constants in boost::math::tools::brent_find_minima() from main()?

struct func
{
  template <class T>
  T operator()(T const& x)
  { //
      T Wnew = 20.0/9.0*720.0; // Goal is to pass it through main()
      T W = 2500;  // Goal is to pass it through main()
      return abs(Wnew/2/x - atan(W/2/x));
  }
};

int main(int argc, char **argv)
{
    // How can I pass Wnew and W values while calling boost::math::tools::brent_find_minima() from main()
    std::pair<double, double> r = boost::math::tools::brent_find_minima(func(), 1.0, 2000.0, std::numeric_limits<double>::digits);
    std::cout.precision(std::numeric_limits<double>::digits10);
    std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
}

Solution

  • I suppose what you want is to create different instances of func with different values for W and Wnew. You are almost there, just give your func some state:

    struct func
    {
      double Wnew;
      double W;
      func(double Wnew, double W) : Wnew(Wnew),W(W) {}
    
      double operator()(double const& x)
      { 
          return abs(Wnew/2/x - atan(W/2/x));
      }
    };
    

    And then create an instance like this:

    double Wnew = 1.0;
    double W = 2.0;
    auto r = boost::math::tools::brent_find_minima(func(Wnew,W), 1.0, 2000.0, std::numeric_limits<double>::digits);
                                                      // ^^
    

    I was a bit puzzled by your operator() being a template and changed that. If you had good reasons for it, simply make it a template again.

    PS: Since C++11, there are lambda expressions that allow a much terser syntax for functors.