在特征中混合标量类型

时间:2017-01-05 20:39:57

标签: eigen eigen3

#include <iostream>

#include <Eigen/Core>

namespace Eigen {

// float op double -> double
template <typename BinaryOp>
struct ScalarBinaryOpTraits<float, double, BinaryOp> {
  enum { Defined = 1 };
  typedef double ReturnType;
};

// double op float -> double
template <typename BinaryOp>
struct ScalarBinaryOpTraits<double, float, BinaryOp> {
  enum { Defined = 1 };
  typedef double ReturnType;
};

}

int main() {
    Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> m1(2, 2);
    m1 << 1, 2, 3, 4;

    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> m2(2, 2);
    m2 << 1, 2, 3, 4;

    std::cerr << m1 * m2 <<std::endl;  // <- boom!!
}

我想知道为什么上面的代码无法编译。 Here是完整的错误消息。请注意,如果我将m1m2定义为固定大小,则可以正常使用。

我正在使用Eigen3.3.1。它在运行OSX-10.12的Mac上使用Apple的clang-800.0.42.1进行了测试。

1 个答案:

答案 0 :(得分:2)

这是因为一般矩阵矩阵产品通过积极的手动矢量化,流水线操作,多级缓存等进行了高度优化。这部分不支持混合浮点和双精度。您可以使用m1.lazyProduct(m2)来绕过这个经过大量优化的实现,该实现与用于小型固定大小矩阵的实现相对应,但这样做的唯一缺点是:ALU不支持混合float和double,因此float值必须无论如何,要提升到双倍,你将失去矢量化。最好将浮动显式加倍:

m1.cast<double>() * m2