在 Eigen 中混合标量类型

Mixing Scalar Types in Eigen

#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。它在 Mac 运行 OSX-10.12 上与 Apple 的 clang-800.0.42.1.

进行了测试

这是因为一般的矩阵-矩阵乘积通过积极的手动向量化、流水线、多级缓存等进行了高度优化。这部分不支持混合浮点数和双精度数。您可以使用 m1.lazyProduct(m2) 绕过这个高度优化的实现,它对应于用于小型固定大小矩阵的实现,但这样做只有缺点:ALU 不支持混合浮点数和双精度数,因此浮点值必须无论如何被提升为 double ,你将失去矢量化。最好将 float 显式转换为 double:

m1.cast<double>() * m2