Сочетание Eigen и CppAD

Я хочу использовать механизм автоматического дифференцирования, предоставляемый
CppAD внутри линейной алгебры. Пример типа
Эйген :: Матрица< CppAD :: AD, -1, -1>. Так как CppAD :: AD является пользовательским числовым типом
NumTrait для этого типа должны быть предоставлены. CppAD обеспечивает
те, в файле cppad / пример / 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, это сработает. Однако это
не является решением, потому что продвижение типа практически используется
везде в Эйгене.

Мне кажется, что NumTraits, предоставляемые CppAD, не подходят для этого случая. Это подтверждается сообщением об ошибке:

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> > >’

Кто-нибудь может указать мне правильное направление? Возможно, что NumTrait для старых собственных версий. Я использую 3.3.2 и CppAD из
текущая мастер ветка.

4

Решение

Если вы хотите умножить 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;
5

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector