c++ - 使用 Eigen 和为自动微分设计的自定义复数

标签 c++ eigen

我在特征库的混合表达式中使用自定义标量类型时遇到问题。我按照添加自定义标量类型的说明进行操作 这里https://eigen.tuxfamily.org/dox/TopicCustomizing_CustomScalar.html .尽管遵循了这些,但我无法编译我的代码。我假设我只是没有正确按照说明进行操作,所以我希望有人可以帮助告诉我我做错了什么。

具体来说,我已将我的问题归结为一个非常简单的示例。我有一个名为“cplx”的类型(您可以在这里找到它:http://mdolab.engin.umich.edu/sites/default/files/complexify.h_0.txt),我用它来进行复杂的数值微分。我正在尝试将 cplx 用作 Eigen 中的标量类型。我按照上面链接的说明生成了以下 NumTraits 结构,

template<> struct NumTraits<cplx> : NumTraits<std::complex<double>>
{
    typedef double Real;
    typedef cplx NonInteger;
    typedef cplx Nested;

    enum {
        IsComplex = 1,
        IsInteger = 0,
        IsSigned = 1,
        RequireInitialization = 1,
        ReadCost = 2 * NumTraits<double>::ReadCost,
        AddCost = 2 * NumTraits<double>::AddCost,
        MulCost = 4 * NumTraits<double>::MulCost + 2 * NumTraits<double>::AddCost
    };

};

然后我想构建以下形式的表达式:

Eigen::Matrix<cplx, 3, 10> dc;
Eigen::Matrix<double, 10, 3> dNdx;
Eigen::Matrix<cplx, 3, 3> Fc = dc * dNdx;

当我尝试编译它时,出现以下错误:

Severity    Code    Description Project File    Line    Suppression State
Error   C2672   'Eigen::internal::gebp_traits<cplx,double,false,false>::madd': no matching overloaded function found    Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  999 
Error   C2782   'void Eigen::internal::gebp_traits<cplx,double,false,false>::madd(const LhsPacketType &,const RhsPacketType &,AccPacketType &,AccPacketType &) const': template parameter 'AccPacketType' is ambiguous  Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  999 
Error   C2784   'void Eigen::internal::gebp_traits<cplx,double,false,false>::madd(const LhsPacketType &,const RhsPacketType &,AccPacketType &,AccPacketType &) const': could not deduce template argument for 'AccPacketType &' from 'double'   Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  999 
Error   C2672   'Eigen::internal::gebp_traits<cplx,double,false,false>::madd': no matching overloaded function found    Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1000    
Error   C2782   'void Eigen::internal::gebp_traits<cplx,double,false,false>::madd(const LhsPacketType &,const RhsPacketType &,AccPacketType &,AccPacketType &) const': template parameter 'AccPacketType' is ambiguous  Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1000    
Error   C2784   'void Eigen::internal::gebp_traits<cplx,double,false,false>::madd(const LhsPacketType &,const RhsPacketType &,AccPacketType &,AccPacketType &) const': could not deduce template argument for 'AccPacketType &' from 'double'   Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1000    
Error   C2672   'Eigen::internal::gebp_traits<cplx,double,false,false>::madd': no matching overloaded function found    Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1001    
Error   C2782   'void Eigen::internal::gebp_traits<cplx,double,false,false>::madd(const LhsPacketType &,const RhsPacketType &,AccPacketType &,AccPacketType &) const': template parameter 'AccPacketType' is ambiguous  Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1001    
Error   C2784   'void Eigen::internal::gebp_traits<cplx,double,false,false>::madd(const LhsPacketType &,const RhsPacketType &,AccPacketType &,AccPacketType &) const': could not deduce template argument for 'AccPacketType &' from 'double'   Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1001    
Error   C2782   'void Eigen::internal::gebp_traits<cplx,double,false,false>::madd(const LhsPacketType &,const RhsPacketType &,AccPacketType &,AccPacketType &) const': template parameter 'AccPacketType' is ambiguous  Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1002    
Error   C2672   'Eigen::internal::gebp_traits<cplx,double,false,false>::madd': no matching overloaded function found    Simulation_MechanicalTest   c:\users\nick.burgess\documents\code\toolsets\eigen\3.3.3\source\eigen\src\core\products\generalblockpanelkernel.h  1002

有没有人遇到过这个错误。我很困惑可能出了什么问题?作为尝试调试的一部分,我当然尝试过类似的表达式

Eigen::Matrix<cplx, 3, 10> dc;
Eigen::Matrix<cplx, 10, 3> dNdx;
Eigen::Matrix<cplx, 3, 3> Fc = dc * dNdx;

编译得很好。完全没有错误。因此,将 double 和 cplx 混合在一起显然是一个问题。任何帮助,将不胜感激。

最佳答案

默认情况下,Eigen 不允许在表达式中混合使用不同的标量类型(无隐式转换)。

Eigen::Matrix<float, 4,4> Af;
Eigen::Matrix<double,4,4> Ad;
// Af*Ad;  // not allowed
Af.cast<double>()*Ad; // explicitly cast Af to double

为了允许混合不同的标量类型,您可以像上面那样显式地将一种类型转换为另一种类型,或者专门化以下特征(除了 Eigen::NumTraits 之外):

namespace Eigen{
  template<typename BinOp>
  struct ScalarBinaryOpTraits<cplx,double,BinOp>
  { typedef cplx ReturnType; };
  template<typename BinOp>
  struct ScalarBinaryOpTraits<double,cplx,BinOp>
  { typedef cplx ReturnType; };
}

这还应该允许加、减和除 cplxdouble 表达式(我没有用你的代码测试这个)。

关于c++ - 使用 Eigen 和为自动微分设计的自定义复数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49456181/

相关文章:

c++ - operator[] 重载的内部类不起作用

c++ - Eigen 矩阵的静态 reshape

c++ - 检查两个正方形是否相交

c++ - 如何在 C++ 中使用 Google 的 Protocol Buffer 添加重复字段?

c++ - 在 Visual C++ 中接收关于 fgets() 的访问冲突错误

c++ - 为 std::complex 重载标准运算符<<

matrix - 非正定矩阵的 Eigen 共轭梯度

c++ - vector 元素类型的 Eigen 稀疏矩阵CoeffRef的误差

c++ - 使用RowMajor和ColMajor数据排列的矩阵行求和的奇怪性能差异

c++ - 当我的计算机中有两个 OpenCV(相同版本)时,如何选择在 CMakeLists.txt 中使用哪个 OpenCV?