How to use the Eigen unsupported levenberg marquardt implementation?

后端 未结 4 480
说谎
说谎 2020-12-24 04:29

I\'m trying to minimize a following sample function:

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

A normal way to minim

4条回答
  •  轮回少年
    2020-12-24 04:56

    So I believe I've found the answers.

    1) The function is able to work as a function vector and as a function scalar.
    If there are m solveable parameters, a Jacobian matrix of m x m needs to be created or numerically calculated. In order to do a Matrix-Vector multiplication J(x[m]).transpose*f(x[m]) the function vector f(x) should have m items. This can be the m different functions, but we can also give f1 the complete function and make the other items 0.

    2) The parameters can be set and read using lm.parameters.maxfev = 2000;

    Both answers have been tested in the following example code:

    #include 
    #include 
    
    #include 
    #include 
    
    // Generic functor
    template
    struct Functor
    {
    typedef _Scalar Scalar;
    enum {
        InputsAtCompileTime = NX,
        ValuesAtCompileTime = NY
    };
    typedef Eigen::Matrix InputType;
    typedef Eigen::Matrix ValueType;
    typedef Eigen::Matrix 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
    {
    my_functor(void): Functor(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 numDiff(functor);
    Eigen::LevenbergMarquardt,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;
    }
    

提交回复
热议问题