16

次のサンプル関数を最小化しようとしています:

F(x) = f[0]^2(x[0],...,x[n-1]) + ... + f[m-1]^2(x[0],...,x[n-1])

このような関数を最小化する通常の方法は、Levenberg-Marquardt アルゴリズムです。この最小化を C++ で実行したいと考えており、Eigen を使用していくつかの初期テストを行ったところ、予想される解決策が得られました。

私の質問は次のとおりです。私は ie を使用して python で最適化することに慣れていscipy.optimize.fmin_powellます。ここで、入力関数のパラメーターは(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, direc=None)です。を定義しfunc(x0)x0ベクトルを指定して最適化を開始できます。必要に応じて、最適化パラメーターを変更できます。

現在、Eigen Lev-Marq アルゴリズムは別の方法で動作します。関数ベクトルを定義する必要があります (なぜですか?) さらに、最適化パラメーターを設定できません。によると:
http://eigen.tuxfamily.org/dox/unsupported/classEigen_1_1LevenbergMarquardt.htmlおよびその他のセット関数
を使用できるはずです。setEpsilon()

しかし、次のコードがある場合:

my_functor functor;
Eigen::NumericalDiff<my_functor> numDiff(functor);
Eigen::LevenbergMarquardt<Eigen::NumericalDiff<my_functor>,double> lm(numDiff);
lm.setEpsilon(); //doesn't exist!

だから私は2つの質問があります:

  1. 関数ベクトルが必要な理由と、関数スカラーでは不十分な理由は何ですか?
    私が答えを探した参考文献:
    http://www.ultimatepp.org/reference$Eigen_demo$en-us.html
    http://www.alglib.net/optimization/levenbergmarquardt.php

  2. set 関数を使用して最適化パラメーターを設定するにはどうすればよいですか?

4

4 に答える 4

24

だから私は答えを見つけたと信じています。

1) 関数は、関数ベクトルおよび関数スカラーとして機能します。
解けるパラメータがある場合はm、mxm のヤコビ行列を作成するか、数値的に計算する必要があります。行列とベクトルの乗算を行うにはJ(x[m]).transpose*f(x[m])、関数ベクトルにアイテムf(x)が必要です。mこれはさまざまな機能である可能性がありますが、完全な機能をm与えて他の項目を作成することもできます。f10

2) パラメータは、lm.parameters.maxfev = 2000;

両方の回答は、次のサンプル コードでテストされています。

#include <iostream>
#include <Eigen/Dense>

#include <unsupported/Eigen/NonLinearOptimization>
#include <unsupported/Eigen/NumericalDiff>

// Generic functor
template<typename _Scalar, int NX = Eigen::Dynamic, int NY = Eigen::Dynamic>
struct Functor
{
typedef _Scalar Scalar;
enum {
    InputsAtCompileTime = NX,
    ValuesAtCompileTime = NY
};
typedef Eigen::Matrix<Scalar,InputsAtCompileTime,1> InputType;
typedef Eigen::Matrix<Scalar,ValuesAtCompileTime,1> ValueType;
typedef Eigen::Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;

int m_inputs, m_values;

Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}

int inputs() const { return m_inputs; }
int values() const { return m_values; }

};

struct my_functor : Functor<double>
{
my_functor(void): Functor<double>(2,2) {}
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
{
    // Implement y = 10*(x0+3)^2 + (x1-5)^2
    fvec(0) = 10.0*pow(x(0)+3.0,2) +  pow(x(1)-5.0,2);
    fvec(1) = 0;

    return 0;
}
};


int main(int argc, char *argv[])
{
Eigen::VectorXd x(2);
x(0) = 2.0;
x(1) = 3.0;
std::cout << "x: " << x << std::endl;

my_functor functor;
Eigen::NumericalDiff<my_functor> numDiff(functor);
Eigen::LevenbergMarquardt<Eigen::NumericalDiff<my_functor>,double> lm(numDiff);
lm.parameters.maxfev = 2000;
lm.parameters.xtol = 1.0e-10;
std::cout << lm.parameters.maxfev << std::endl;

int ret = lm.minimize(x);
std::cout << lm.iter << std::endl;
std::cout << ret << std::endl;

std::cout << "x that minimizes the function: " << x << std::endl;

std::cout << "press [ENTER] to continue " << std::endl;
std::cin.get();
return 0;
}
于 2013-08-30T15:15:40.517 に答える