2017-12-27 16 views
0

問題:Levenberg Marquardtを使用するヤコビ行列または関数ベクトルの正確なサイズはわかりません。したがって、私はコンパイル時にそれらの次元を設定する必要があります。Eigen Levenberg Marquardtで使用するEigen DesnseFunctorの入力値と値の設定方法

予想される:MyFunctorDenseのインスタンスを宣言した後。私は "InputsAtCompileTime"を自分の入力サイズに設定し、 "ValuesAtCompileTime"を自分の値のサイズに設定することができました。その後、私のヤコビアン、aFjacは、寸法にtValuesのXのtInputsを持つべきである、と私の関数ベクトル、ああ、寸法を有していなければならない。1.

を観察したX tValues: enter image description here

.hファイル

#pragma once 

#include "stdafx.h" 
#include <iostream> 

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


//Generic functor 
template <typename _Scalar, typename _Index> 
struct MySparseFunctor 
{ 
    typedef _Scalar Scalar; 
    typedef _Index Index; 
    typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1> InputType; 
    typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1> ValueType; 
    typedef Eigen::SparseMatrix<Scalar, Eigen::ColMajor, Index> 
    JacobianType; 
    typedef Eigen::SparseQR<JacobianType, Eigen::COLAMDOrdering<int> > 
    QRSolver; 
    enum { 
     InputsAtCompileTime = Eigen::Dynamic, 
     ValuesAtCompileTime = Eigen::Dynamic 
    }; 

    MySparseFunctor(int inputs, int values) : m_inputs(inputs), 
m_values(values) {} 

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

    const int m_inputs, m_values; 


}; 

template <typename _Scalar, int NX=Eigen::Dynamic, int NY=Eigen::Dynamic> 
struct MyDenseFunctor 
{ 
    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; 
    typedef Eigen::ColPivHouseholderQR<JacobianType> QRSolver; 
    const int m_inputs, m_values; 

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

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

}; 


struct MyFunctorSparse : MySparseFunctor<double, int> 
{ 
    MyFunctorSparse(void) : MySparseFunctor<double, int>(2 , 2) {} 

    int operator()(const Eigen::VectorXd &aX, //Input 
       Eigen::VectorXd &aF) const; //Output 
    int df(const InputType &aF, JacobianType& aFjac); 
}; 


struct MyFunctorDense : MyDenseFunctor<double> 
{ 
    MyFunctorDense(void) : MyDenseFunctor<double>(Eigen::Dynamic , 
Eigen::Dynamic) {} 

    int operator()(const InputType &aX, //Input 
       ValueType &aF) const; //Output 

    int df(const InputType &aX, JacobianType& aFjac); 
}; 

.cppファイル の#pragma一度 の#include "stdafx.hを" #I "Main.h"

int MyFunctorSparse::operator()(const Eigen::VectorXd &aX,  //Input 
          Eigen::VectorXd &aF) const  //Output 
{ 
     //F = aX0^2 + aX1^2 
    aF(0) = aX(0)*aX(0) + aX(1)*aX(1); 
    aF(1) = 0; 

    return 0; 
} 

int MyFunctorDense::operator()(const InputType &aX,  //Input 
          ValueType &aF) const  //Output 
{ 
//F = aX0^2 + aX1^2 
for (int i = 0; i < aF.size(); i++) 
{ 
    aF(i) = i*aX(0)*aX(0) + i*(aX(1)-1)*(aX(1)-1); 
} 


    return 0; 
} 


int MyFunctorSparse::df(const InputType &aX, JacobianType& aFjac) 
{ 
    aFjac.coeffRef(0, 0) = 2*aX(0); 
    aFjac.coeffRef(0, 1) = 2*aX(1); 
    aFjac.coeffRef(1, 0) = 0.0; 
    aFjac.coeffRef(1, 1) = 0.0; 

    return 0; 
} 

int MyFunctorDense::df(const InputType &aX, JacobianType& aFjac) 
{ 
    for(int i = 0; i< aFjac.size(); i++) 
    { 
    aFjac(i, 0) = 2*i*aX(0); 
    aFjac(i, 1) = 2*i*(aX(1)-1); 
    } 
    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    int input; 
    std::cout << "Enter 1 to run LM with DenseFunctor, Enter 2 to run LM with 
SparseFunctor: " << std::endl; 
std::cin >> input; 

    Eigen::VectorXd tX(2); 
    tX(0) = 10; 
    tX(1) = 0.5; 
    int tInputs = tX.rows(); 
    int tValues = 60928; 

    std::cout << "tX: " << tX << std::endl; 

    if (input == 1) 
    { 
    MyFunctorDense myDenseFunctor; 
    tInputs = myDenseFunctor.inputs(); 
    tValues = myDenseFunctor.values(); 

    std::cout << "tInputs : " << tInputs << std::endl; 
    std::cout << "tValues : " << tValues << std::endl; 

    Eigen::LevenbergMarquardt<MyFunctorDense> lm(myDenseFunctor); 
    lm.setMaxfev(30); 
    lm.setXtol(1e-5); 
    lm.minimize(tX); 
    } 

    if (input == 2) 
    { 
    MyFunctorSparse myFunctorSparse; 
    //Eigen::NumericalDiff<MyFunctor> numDiff(myFunctor); 
    //Eigen::LevenbergMarquardt<Eigen::NumericalDiff<MyFunctor>,double> 
    lm(numDiff); 

    Eigen::LevenbergMarquardt<MyFunctorSparse> lm(myFunctorSparse); 
    lm.setMaxfev(2000); 
    lm.setXtol(1e-10); 

    lm.minimize(tX); 
    } 

    std::cout << "tX minimzed: " << tX << std::endl; 

    return 0; 
} 

答えて

0

ソリューションをnclude:私は私の問題を考え出しました。私が交換さ:

const int m_inputs, m_values; 

int m_inputs, m_values; 

で "の.h" ファイルで、これは変更可能な構造体MyFunctorDenseのメンバ変数になります。だから、その行

std::cout << "tX: " << tX << std::endl; 

以下 ".cppファイル" に私が追加:

Eigen::VectorXd tF(60928); 

を、これは寸法60928x1のテスト機能ベクトルであるため。したがって、任意のnx1次元に入れることができます。

MyFunctorDense myDenseFunctor; 

私が追加:

enter image description here

myDenseFunctor.m_inputs = tX.rows(); 
    myDenseFunctor.m_values = tF.rows(); 

は今、私は結果を得るそして、線の下の

関連する問題