我想使用Eigenfadbad进行自动区分。

当我将两个 vector 相乘时

#include <iostream>
#include <fadiff.h>
#include <Eigen/Core>

int main(int argc, char *argv[])
{
    using Scalar = fadbad::F<double>;
    using VectorXs = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;

    VectorXs a(2);
    VectorXs b(2);

    Scalar c = a.transpose() * b;

    std::cout << c.x() << std::endl;
}

我收到以下错误消息(ninja-build,gcc-7.1):
[1/2] Building CXX object CMakeFiles/example.dir/src/main.cc.o
FAILED: CMakeFiles/example.dir/src/main.cc.o
/usr/bin/c++   -I/home/username/include/boost-1.64.0 -I/home/username/include/eigen-3.3.4 -I/home/username/include/fadbad-2.1 -I/home/username/include/termcolor-6267b85 -g -MD -MT CMakeFiles/example.dir/src/main.cc.o -MF CMakeFiles/example.dir/src/main.cc.o.d -o CMakeFiles/example.dir/src/main.cc.o -c ../src/main.cc
../src/main.cc: In function ‘int main(int, char**)’:
../src/main.cc:13:30: error: ambiguous overload for ‘operator*’ (operand types are ‘Eigen::Transpose<Eigen::Matrix<fadbad::F<double>, -1, 1> >’ and ‘VectorXs {aka Eigen::Matrix<fadbad::F<double>, -1, 1>}’)
     Scalar c = a.transpose() * b;
                ~~~~~~~~~~~~~~^~~
In file included from /home/username/include/eigen-3.3.4/Eigen/Core:72:0,
                 from ../src/main.cc:3:
/home/username/include/eigen-3.3.4/Eigen/src/Core/../plugins/CommonCwiseBinaryOps.h:50:29: note: candidate: typename Eigen::internal::enable_if<true, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<typename Eigen::internal::traits<T>::Scalar, typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::scalar_product_op<typename Eigen::internal::traits<T>::Scalar, T> > >::value>::type>, const Derived, const typename Eigen::internal::plain_constant_type<Derived, typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::scalar_product_op<typename Eigen::internal::traits<T>::Scalar, T> > >::value>::type>::type> >::type Eigen::MatrixBase<Derived>::operator*(const T&) const [with T = Eigen::Matrix<fadbad::F<double>, -1, 1>; Derived = Eigen::Transpose<Eigen::Matrix<fadbad::F<double>, -1, 1> >; typename Eigen::internal::enable_if<true,const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<typename Eigen::internal::traits<T>::Scalar, typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::scalar_product_op<typename Eigen::internal::traits<T>::Scalar, T> > >::value>::type>, const Derived, const typenameEigen::internal::plain_constant_type<Derived, typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::scalar_product_op<typename Eigen::internal::traits<T>::Scalar, T> > >::value>::type>::type> >::type = const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<fadbad::F<double>, fadbad::F<double> >, const Eigen::Transpose<Eigen::Matrix<fadbad::F<double>, -1, 1> >, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<fadbad::F<double> >, const Eigen::Matrix<fadbad::F<double>, 1, -1, 1, 1, -1> > >]
 EIGEN_MAKE_SCALAR_BINARY_OP(operator*,product)
                             ^
/home/username/include/eigen-3.3.4/Eigen/src/Core/util/Macros.h:941:4: note: in definition of macro ‘EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT’
   (METHOD)(const T& scalar) const { \
    ^~~~~~
/home/username/include/eigen-3.3.4/Eigen/src/Core/../plugins/CommonCwiseBinaryOps.h:50:1: note: in expansion of macro ‘EIGEN_MAKE_SCALAR_BINARY_OP’
 EIGEN_MAKE_SCALAR_BINARY_OP(operator*,product)
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/username/include/eigen-3.3.4/Eigen/Core:462:0,
                 from ../src/main.cc:3:
/home/username/include/eigen-3.3.4/Eigen/src/Core/GeneralProduct.h:387:1: note: candidate: const Eigen::Product<Derived, OtherDerived> Eigen::MatrixBase<Derived>::operator*(const Eigen::MatrixBase<OtherDerived>&) const [with OtherDerived = Eigen::Matrix<fadbad::F<double>, -1, 1>; Derived = Eigen::Transpose<Eigen::Matrix<fadbad::F<double>, -1, 1> >]
 MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
 ^~~~~~~~~~~~~~~~~~~
In file included from /home/username/include/eigen-3.3.4/Eigen/Core:72:0,
                 from ../src/main.cc:3:
/home/username/include/eigen-3.3.4/Eigen/src/Core/../plugins/CommonCwiseBinaryOps.h:50:29: note: candidate: typename Eigen::internal::enable_if<true, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<T, typename Eigen::internal::traits<T>::Scalar, Eigen::internal::scalar_product_op<T, typename Eigen::internal::traits<T>::Scalar> > >::value>::type, typename Eigen::internal::traits<T>::Scalar>, const typename Eigen::internal::plain_constant_type<Derived, typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<T, typename Eigen::internal::traits<T>::Scalar, Eigen::internal::scalar_product_op<T, typename Eigen::internal::traits<T>::Scalar> > >::value>::type>::type, const Derived> >::type Eigen::operator*(const T&, const StorageBaseType&) [with T = Eigen::Transpose<Eigen::Matrix<fadbad::F<double>, -1, 1> >; Derived = Eigen::Matrix<fadbad::F<double>, -1, 1>; typename Eigen::internal::enable_if<true, const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<T, typename Eigen::internal::traits<T>::Scalar, Eigen::internal::scalar_product_op<T, typename Eigen::internal::traits<T>::Scalar> > >::value>::type, typename Eigen::internal::traits<T>::Scalar>, const typename Eigen::internal::plain_constant_type<Derived, typename Eigen::internal::promote_scalar_arg<typename Eigen::internal::traits<T>::Scalar, T, Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<T, typename Eigen::internal::traits<T>::Scalar, Eigen::internal::scalar_product_op<T, typename Eigen::internal::traits<T>::Scalar> > >::value>::type>::type, const Derived> >::type = const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<fadbad::F<double>, fadbad::F<double> >, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<fadbad::F<double> >, const Eigen::Matrix<fadbad::F<double>, -1, 1> >, const Eigen::Matrix<fadbad::F<double>, -1, 1> >; Eigen::MatrixBase<Derived>::StorageBaseType = Eigen::MatrixBase<Eigen::Matrix<fadbad::F<double>, -1, 1> >]
 EIGEN_MAKE_SCALAR_BINARY_OP(operator*,product)
                             ^
/home/username/include/eigen-3.3.4/Eigen/src/Core/util/Macros.h:950:4: note: in definition of macro ‘EIGEN_MAKE_SCALAR_BINARY_OP_ONTHELEFT’
   (METHOD)(const T& scalar, const StorageBaseType& matrix) { \
    ^~~~~~
/home/username/include/eigen-3.3.4/Eigen/src/Core/../plugins/CommonCwiseBinaryOps.h:50:1: note: in expansion of macro ‘EIGEN_MAKE_SCALAR_BINARY_OP’
 EIGEN_MAKE_SCALAR_BINARY_OP(operator*,product)
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
ninja: build stopped: subcommand failed.
                ~~^~~

当我使用double作为标量类型时,它将编译并运行而没有错误。

我怎么解决这个问题?

最佳答案

这是一个常见的问题,我想问题是fadbad公开了一个通用的隐式构造函数,使其好像可以从所有内容中进行转换一样。因此,更准确地说,std::is_convertible<X, fadbad>对任何类型的X(包括Eigen::Matrix< fadbad >)都返回true。因此,在a * b中,因素之一可以解释为兼容标量。

这必须在fadbad中修复,例如使用SFINAE来仅对有效类型启用通用ctor。

关于c++ - Gadbad的特征向量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45675024/

10-09 19:55