结合 Eigen 和 CppAD
Combining Eigen and CppAD
我想使用由
本征线性代数中的 CppAD。一个示例类型是
Eigen::Matrix。因为 CppAD::AD 是自定义数字类型
必须提供此类型的 NumTraits。 CppAD 提供
文件 cppad/example/cppad_eigen.hpp 中的那些。这使得
以下最小示例编译:
#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/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)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
其他用例会导致错误消息,例如:
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> > >’
任何人都可以指出我正确的方向吗? NumTraits 可能适用于旧的 Eigen 版本。我使用的是 3.3.2 和 CppAD
当前主分支。
如果你想将 Matrix<CppAD::AD<double>, ...>
乘以 Matrix<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()
。
或者,您需要将矩阵 m
转换为 AD
:
// should work:
y = m.cast<CppAD::AD<double> >() * x;
我想使用由
本征线性代数中的 CppAD。一个示例类型是
Eigen::Matrix
#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/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)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
其他用例会导致错误消息,例如:
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> > >’
任何人都可以指出我正确的方向吗? NumTraits 可能适用于旧的 Eigen 版本。我使用的是 3.3.2 和 CppAD 当前主分支。
如果你想将 Matrix<CppAD::AD<double>, ...>
乘以 Matrix<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()
。
或者,您需要将矩阵 m
转换为 AD
:
// should work:
y = m.cast<CppAD::AD<double> >() * x;