Передача функций-членов в качестве аргументов оптимизатору (передача функций-членов в функцию) - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь использовать dlib, чтобы минимизировать функцию, где я могу вычислить функцию и ее градиент при заданном значении параметра, используя find_min .

Поскольку функция изменяется в зависимости от вводаЯ определил класс с входными данными как члены класса и две открытые функции, которые вычисляют функцию и ее градиент при текущем предположении решения:

#include <dlib/matrix.h>
typedef dlib::matrix<double,0,1> column_vector;
class Link
{
   public:
      // Initialisation
      Link(const column_vector& predictors, const column_vector& responses)
         : _predictors(predictors), _responses(responses)
      {
      }

      // Likelihood and first derivative
      double likelihood(const column_vector& b) const;
      column_vector gradient(const column_vector& b) const;

   protected:
      column_vector _predictors;
      column_vector _responses;
};

(без кода для вычисления этихфункции для простоты).

Затем я выполняю цикл предикторов и ответов, минимизируя каждый случай:

column_vector starting_point(2);
Link linear(x, y);

dlib::find_min(dlib::bfgs_search_strategy(),
               dlib::objective_delta_stop_strategy(1e-7),
               linear.likelihood,
               linear.gradient,
               starting_point);

Однако я получаю ошибку компилятора при попытке предоставить нестатическийфункции-члены linear.likelihood и linear.gradient из Link: 'ссылка на нестатическую функцию-член должна быть вызвана'.

Ранее я заставлял это работать, перегружая operator() при использовании тольковероятность, но не может сделать это с двумя функциями (вероятность и градиент).Превращение их в указатели на функции приводит к той же ошибке.

При поиске других ответов я обнаружил похожие проблемы при попытке передать нестатические функции-члены в качестве аргументов, но не смог заставить их работать здесь.Есть ли стандартное решение, использующее аргументы шаблона, которые я должен использовать, чтобы исправить это?

Или я решаю эту проблему совершенно неправильно, и я не должен использовать такой класс?

1 Ответ

1 голос
/ 10 мая 2019

Аргументы dlib::find_min() должны быть объектами, которые могут быть вызваны вызовом функции operator().linear.likelihood() вызывает функцию правдоподобия и возвращает результат, но linear.likelihood сам по себе не является правильно сформированным C ++.

Простым решением является использование лямбда-выражений и захват объекта linear по ссылке.Лямбда-выражение - это временный объект, который можно вызвать.

dlib::find_min(dlib::bfgs_search_strategy(),
               dlib::objective_delta_stop_strategy(1e-7),
               [&linear](const column_vector& a) {
                   return linear.likelihood(a);
               },
               [&linear](const column_vector& b) {
                   return linear.gradient(b);
               },
               starting_point);
...