将成员函数作为参数传递给优化器(将成员函数传递给函数)
Passing member functions as arguments to optimizer (passing member functions to a function)
我正在尝试使用 dlib 来最小化一个函数,我可以在其中使用 find_min.
计算函数及其在给定参数值下的梯度
由于函数根据输入而变化,我定义了一个 class,其中输入作为 class 的成员,以及两个 public 函数,用于计算函数及其梯度目前对解决方案的猜测:
#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);
但是,我在尝试从 Link
提供非静态成员函数 linear.likelihood
和 linear.gradient
时遇到编译器错误:'reference to non-static member function must be called'.
我以前在仅使用可能性时通过重载 operator()
来实现此功能,但不能使用两个函数(可能性和梯度)来实现。将它们转换为函数指针会产生相同的错误。
搜索其他答案时,我发现尝试将非静态成员函数作为参数传递时会出现类似问题,但无法让它们在这里工作。是否有使用模板参数的标准解决方案我应该用来解决这个问题?
还是我完全以错误的方式解决了这个问题,我不应该像这样使用 class?
dlib::find_min()
的参数必须是可以用 function-call operator()
调用的对象。 linear.likelihood()
调用似然函数和 returns 结果,但 linear.likelihood
本身不是 well-formed C++。
一个简单的解决方案是使用 lambda expressions 并通过引用捕获对象 linear
。 lambda 表达式是一个可调用的临时对象。
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);
我正在尝试使用 dlib 来最小化一个函数,我可以在其中使用 find_min.
计算函数及其在给定参数值下的梯度由于函数根据输入而变化,我定义了一个 class,其中输入作为 class 的成员,以及两个 public 函数,用于计算函数及其梯度目前对解决方案的猜测:
#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);
但是,我在尝试从 Link
提供非静态成员函数 linear.likelihood
和 linear.gradient
时遇到编译器错误:'reference to non-static member function must be called'.
我以前在仅使用可能性时通过重载 operator()
来实现此功能,但不能使用两个函数(可能性和梯度)来实现。将它们转换为函数指针会产生相同的错误。
搜索其他答案时,我发现尝试将非静态成员函数作为参数传递时会出现类似问题,但无法让它们在这里工作。是否有使用模板参数的标准解决方案我应该用来解决这个问题?
还是我完全以错误的方式解决了这个问题,我不应该像这样使用 class?
dlib::find_min()
的参数必须是可以用 function-call operator()
调用的对象。 linear.likelihood()
调用似然函数和 returns 结果,但 linear.likelihood
本身不是 well-formed C++。
一个简单的解决方案是使用 lambda expressions 并通过引用捕获对象 linear
。 lambda 表达式是一个可调用的临时对象。
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);