2016-09-11 50 views
1

我一直在使用Eigen的AutoDiffScalar,並取得了很大的成功,現在希望轉到AutoDiffJacobian而不是自己做這個。因此,在研究了AutoDiffJacobian.h之後,我創建了一個學習示例,但出現了一些問題。Eigen的AutoDiffJacobian,需要一些幫助才能獲得學習示例

函子:

template <typename Scalar> 
struct adFunctor 
{ 
    typedef Eigen::Matrix<Scalar, 3, 1> InputType; 
    typedef Eigen::Matrix<Scalar, 2, 1> ValueType; 
    typedef Eigen::Matrix<Scalar, 
         ValueType::RowsAtCompileTime, 
         InputType::RowsAtCompileTime> JacobianType; 

    enum { 
    InputsAtCompileTime = InputType::RowsAtCompileTime, 
    ValuesAtCompileTime = ValueType::RowsAtCompileTime 
    }; 

    adFunctor() {} 

    size_t inputs() const { return InputsAtCompileTime; } 

    void operator() (const InputType &input, 
        ValueType *output) const 
    { 
    Scalar s1 = Scalar(0), s2 = Scalar(0); 

    /* Some operations to test the AD. */ 
    for (int i = 0; i < 3; i++) 
    { 
     s1 += log(input(i)); 
     s2 += sqrt(input(i)); 
    } 

    (*output)(0) = s1; 
    (*output)(1) = s2; 
    } 
}; 

用法:

Eigen::Matrix<double, 3, 1> in; 
in << 1,2,3; 
Eigen::Matrix<double, 2, 1> out; 
Eigen::AutoDiffJacobian< adFunctor<double> > adjac; 
adjac(in, &out); 

是從該接收的錯誤原樣如下:

/usr/include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h: In instantiation of ‘void Eigen::AutoDiffJacobian<Functor>::operator()(const InputType&, Eigen::AutoDiffJacobian<Functor>::ValueType*, Eigen::AutoDiffJacobian<Functor>::JacobianType*) const [with Functor = adFunctor<double>; Eigen::AutoDiffJacobian<Functor>::InputType = Eigen::Matrix<double, 3, 1>; Eigen::AutoDiffJacobian<Functor>::ValueType = Eigen::Matrix<double, 2, 1>; Eigen::AutoDiffJacobian<Functor>::JacobianType = Eigen::Matrix<double, 2, 3, 0, 2, 3>]’: 
/home/emifre/Git/autodiff-test/src/autodiff_test.cpp:55:17: required from here 
/usr/include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h:69:24: error: no matching function for call to ‘Eigen::AutoDiffJacobian<adFunctor<double> >::operator()(Eigen::AutoDiffJacobian<adFunctor<double> >::ActiveInput&, Eigen::AutoDiffJacobian<adFunctor<double> >::ActiveValue*) const’ 
    Functor::operator()(ax, &av); 
    ~~~~~~~~~~~~~~~~~~~^~~~~~~~~ 
/home/emifre/Git/autodiff-test/src/autodiff_test.cpp:27:8: note: candidate: void adFunctor<Scalar>::operator()(const InputType&, adFunctor<Scalar>::ValueType*) const [with Scalar = double; adFunctor<Scalar>::InputType = Eigen::Matrix<double, 3, 1>; adFunctor<Scalar>::ValueType = Eigen::Matrix<double, 2, 1>] 
    void operator() (const InputType &input, 
     ^~~~~~~~ 
/home/emifre/Git/autodiff-test/src/autodiff_test.cpp:27:8: note: no known conversion for argument 2 from ‘Eigen::AutoDiffJacobian<adFunctor<double> >::ActiveValue* {aka Eigen::Matrix<Eigen::AutoDiffScalar<Eigen::Matrix<double, 3, 1> >, 2, 1, 0, 2, 1>*}’ to ‘adFunctor<double>::ValueType* {aka Eigen::Matrix<double, 2, 1>*}’ 

從這個錯誤似乎我有點不第二次調用函數AutoDiffJacobian.h中有正確的函數類型,但第一次調用 有用。 我希望這裏有人有一個想法,爲什麼可以幫助,也許我剛剛誤解了用法。

編輯:可編譯的示例,說明此問題:

#include <Eigen/Dense> 
#include <unsupported/Eigen/AutoDiff> 

/* 
* Testing differentiation that will produce a Jacobian, using functors and the 
* AutoDiffJacobian helper. 
*/ 

template <typename Scalar> 
struct adFunctor 
{ 
    typedef Eigen::Matrix<Scalar, 3, 1> InputType; 
    typedef Eigen::Matrix<Scalar, 2, 1> ValueType; 
    typedef Eigen::Matrix<Scalar, 
         ValueType::RowsAtCompileTime, 
         InputType::RowsAtCompileTime> JacobianType; 

    enum { 
    InputsAtCompileTime = InputType::RowsAtCompileTime, 
    ValuesAtCompileTime = ValueType::RowsAtCompileTime 
    }; 

    adFunctor() {} 

    size_t inputs() const { return InputsAtCompileTime; } 

    void operator() (const InputType &input, 
        ValueType *output) const 
    { 
    Scalar s1 = Scalar(0), s2 = Scalar(0); 

    /* Some operations to test the AD. */ 
    for (int i = 0; i < 3; i++) 
    { 
     s1 += log(input(i)); 
     s2 += sqrt(input(i)); 
    } 

    (*output)(0) = s1; 
    (*output)(1) = s2; 
    } 
}; 



int main(int argc, char *argv[]) 
{ 
    Eigen::Matrix<double, 3, 1> in; 
    in << 1,2,3; 
    Eigen::Matrix<double, 2, 1> out; 
    Eigen::AutoDiffJacobian< adFunctor<double> > adjac; 
    adjac(in, &out); 

    return 0; 
} 
+0

解決編譯錯誤一個接一個,這些都很清楚,不要問在這裏爲你做這件事。請至少張貼[MCVE]來重現問題。 –

+0

我已經添加了一個完整的例子。 – Korken

+0

我能解決第一個問題,我的Google-fu不在首位。但仍然有一個錯誤隱藏了我,第二次調用函數AutoDiffJacobian說函子的類型不匹配,但第一次調用沒有問題。必須有我缺少的使用模式,但我無法弄清楚什麼。 – Korken

回答

1

歐凱,大量的測試後,我得到它的工作。 這只是我誤解了編譯器的錯誤,直接說出來,我錯過了操作符本身的模板。

它只需要改爲:

template <typename T1, typename T2> 
void operator() (const T1 &input, T2 *output) const 

現在它就像一種享受!我希望比我更多的人使用這個。