Как передать некоторые константы в brent_find_minima () Boosts? - PullRequest
1 голос
/ 30 января 2020

Как я могу передать некоторые константы в boost :: math :: tools :: brent_find_minima () из 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;
}

Ответы [ 2 ]

2 голосов
/ 30 января 2020

Полагаю, вам нужно создать разные экземпляры func с разными значениями W и Wnew. Вы почти у цели, просто задайте своему func какое-то состояние:

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));
  }
};

И затем создайте такой пример:

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);
                                                  // ^^

Я был немного озадачен вашим operator() будучи шаблоном и изменил это. Если у вас были веские причины для этого, просто сделайте его снова шаблоном.

PS: Начиная с C ++ 11, существуют лямбда-выражения , которые допускают гораздо более краткий синтаксис для функторов.

1 голос
/ 03 февраля 2020

Мне больше всего нравится лямбда-подход:

#include <cmath>
#include <iostream>
#include <boost/math/tools/minima.hpp>

int main(int argc, char **argv)
{
    double W = 2500;
    double Wnew = 20.0/9.0*720.0;
    if (argc == 3) {
        double W = std::stod(argv[1]);
        double Wnew = std::stod(argv[2]);
    }

    auto f = [&W, &Wnew](double x)->double {
        return std::abs(Wnew/2/x - atan(W/2/x));
    };

    std::pair<double, double> r = boost::math::tools::brent_find_minima(f, 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;
}

Документация для brent_find_minima была написана до C ++ 11 и использует то, что сейчас следует рассматривать как чрезмерно подробный синтаксис. Во всех примерах документации по C ++ 11 boost.math (например, квадратурные процедуры) используются лямбды-выражения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...