如何设置使用的本征DesnseFunctor输入和值大小在本征的Levenberg马夸特

问题:我并不总是知道我要上使用的Levenberg夸特的行列式或功能载体的确切大小。因此,我需要在编译时设置它们的尺寸。如何设置使用的本征DesnseFunctor输入和值大小在本征的Levenberg马夸特

预计:我宣布MyFunctorDense的一个实例后。我可以将“InputsAtCompileTime”设置为我的输入大小,并将“ValuesAtCompileTime”设置为我的值大小。然后,我的雅可比,aFjac,应该有尺寸tValues X tInputs,和我的功能载体,啊,应该有尺寸tValues X 1.

观察:

.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 nclude “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;

}

回答:

解决方案:我想通了,我的问题。我取代:

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; 

我说:

myDenseFunctor.m_inputs = tX.rows(); 

myDenseFunctor.m_values = tF.rows();

现在我得到的结果是:

以上是 如何设置使用的本征DesnseFunctor输入和值大小在本征的Levenberg马夸特 的全部内容, 来源链接: utcz.com/qa/266553.html

回到顶部