在 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 是完整的错误信息。请注意,如果我将 m1
和 m2
定义为具有固定大小,它可以正常工作。
我正在使用 Eigen3.3.1
。它在 Mac 运行 OSX-10.12 上与 Apple 的 clang-800.0.42.1
.
进行了测试
这是因为一般的矩阵-矩阵乘积通过积极的手动向量化、流水线、多级缓存等进行了高度优化。这部分不支持混合浮点数和双精度数。您可以使用 m1.lazyProduct(m2)
绕过这个高度优化的实现,它对应于用于小型固定大小矩阵的实现,但这样做只有缺点:ALU 不支持混合浮点数和双精度数,因此浮点值必须无论如何被提升为 double ,你将失去矢量化。最好将 float 显式转换为 double:
m1.cast<double>() * m2
#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 是完整的错误信息。请注意,如果我将 m1
和 m2
定义为具有固定大小,它可以正常工作。
我正在使用 Eigen3.3.1
。它在 Mac 运行 OSX-10.12 上与 Apple 的 clang-800.0.42.1
.
这是因为一般的矩阵-矩阵乘积通过积极的手动向量化、流水线、多级缓存等进行了高度优化。这部分不支持混合浮点数和双精度数。您可以使用 m1.lazyProduct(m2)
绕过这个高度优化的实现,它对应于用于小型固定大小矩阵的实现,但这样做只有缺点:ALU 不支持混合浮点数和双精度数,因此浮点值必须无论如何被提升为 double ,你将失去矢量化。最好将 float 显式转换为 double:
m1.cast<double>() * m2