2017-07-20 6 views
3

私は、固有線形代数の中で CppADが提供する自動微分機構を使いたいです。例のタイプは、 Eigen :: Matrix < CppAD :: AD、-1、-1>です。 CppAD :: ADはカスタム数値タイプ であるため、このタイプのNumTraitを提供する必要があります。 CppADはcppad/example/cppad_eigen.hppのファイルを に提供します。固有とCppADの結合

#include <cppad/cppad.hpp> 
#include <cppad/example/cppad_eigen.hpp> 

int main() { 
    typedef double Scalar; 
    typedef CppAD::AD<Scalar> AD; 

    // independent variable vector 
    Eigen::Matrix<AD,Eigen::Dynamic,1> x(4); 
    CppAD::Independent(x); 

    // dependent variable vector 
    Eigen::Matrix<AD,Eigen::Dynamic,1> y(4); 

    Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> m(4,4); 
    m.setIdentity(); 

    y = 1. * x; 
    // THIS DOES NOT WORK 
    // y = m * x; 

    CppAD::ADFun<Scalar> fun(x, y); 
} 

とすぐにいくつかのより複雑な表現が使用されているように、例えば:これは、最小限の例のコンパイル次 を作ります が

y = m * x; 

コードがコンパイルに失敗言及:

PATH/Eigen/latest/include/Eigen/src/Core/Product.h:29:116: error: 
     no type named 'ReturnType' in 'Eigen::ScalarBinaryOpTraits<double, CppAD::AD<double>, 
     Eigen::internal::scalar_product_op<double, CppAD::AD<double> > >' 
    ...typename ScalarBinaryOpTraits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType... 

私は手動でADに二重のマトリックスをキャストした場合、それが動作します。ただし、 は解決策ではありません。タイププロモーションはEigenのどこでも事実上 です。

CppADによって提供されたNumTraitsがこの場合十分でないかのように見えます。これは、フォローのエラーメッセージによってサポートされています。

PATH/Eigen/src/Core/functors/Binary 
Functors.h:78:92: error: no type named ‘ReturnType’ in ‘struct Eigen::ScalarBinaryOpTraits<dou 
ble, CppAD::AD<double>, Eigen::internal::scalar_product_op<double, CppAD::AD<double> > >’ 

誰もが正しい方向に私を指すことができます:

PATH/Eigen/latest/include/Eigen/src/Core/Product.h:155:5: error: 
     no type named 'CoeffReturnType' in 
     'Eigen::internal::dense_product_base<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 
     Eigen::Matrix<CppAD::AD<double>, -1, 1, 0, -1, 1>, 0, 7>' 
    EIGEN_DENSE_PUBLIC_INTERFACE(Derived) 
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

他の使用例のようなメッセージがエラーにつながりますか? NumTraitは古いEigen Versions用である可能性があります。私は現在のマスターブランチの から3.3.2とCppADを使用しています。

+0

は、なぜあなたは 'M'はタイプ '固有::マトリックス '? – Alex

答えて

3

あなたはMatrix<double, ...>Matrix<CppAD::AD<double>, ...>を掛けたい場合にも対応するScalarBinaryOpTraitsを特化する必要があります。

namespace Eigen { 
template<typename X, typename BinOp> 
struct ScalarBinaryOpTraits<CppAD::AD<X>,X,BinOp> 
{ 
    typedef CppAD::AD<X> ReturnType; 
}; 

template<typename X, typename BinOp> 
struct ScalarBinaryOpTraits<X,CppAD::AD<X>,BinOp> 
{ 
    typedef CppAD::AD<X> ReturnType; 
}; 
} // namespace Eigen 

これはCppAD::AD<X>() * X()が実装されている必要があります。

はまた、あなたの行列mADにキャストする必要があります。

// should work: 
y = m.cast<CppAD::AD<double> >() * x; 
関連する問題