c++ - 特征模板不适用于固定大小的矩阵
问题描述
我编写了以下模板来检查三角形是否退化:
template<typename Derived>
bool nondegenerate(const Eigen::PlainObjectBase<Derived>& triangle) {
typedef typename Derived::Scalar scalarType;
if (triangle.cols() == 2) {
Eigen::Matrix<scalarType, 1, 2> v1 = triangle.row(1) - triangle.row(0);
Eigen::Matrix<scalarType, 1, 2> v2 = triangle.row(2) - triangle.row(0);
return v1(0)*v2(1) - v1(1)*v2(0);
} else if (triangle.cols() == 3) {
Eigen::Matrix<scalarType, 1, 3> v1 = triangle.row(1) - triangle.row(0);
Eigen::Matrix<scalarType, 1, 3> v2 = triangle.row(2) - triangle.row(0);
return v1.cross(v2).norm();
} else {
std::cerr << "Undefined input." << std::endl;
return false;
}
}
如果我nondegenerate
用类型的矩阵调用,上面的代码可以正常工作Eigen::MatrixXi
:
Eigen::MatrixXi triangle;
triangle.resize(3,2);
triangle << 1,2,3,4,5,6;
nondegenerate(triangle);
但是,如果我用固定大小的矩阵替换上述动态大小矩阵:
Eigen::Matrix<int, 3, 2> triangle;
triangle << 1,2,3,4,5,6;
nondegenerate(triangle);
它报告编译错误:
/usr/local/include/eigen3/Eigen/src/Core/AssignEvaluator.h:833:3: error: static_assert 由于要求失败'(int(Eigen::internal::size_of_xpr_at_compile_time<Eigen::Matrix<int, 1 , 3, 1, 1, 3> >::ret) == 0 && int(Eigen::internal::size_of_xpr_at_compile_time<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen:: Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, 假> > >::ret) == 0) || ((int(Matrix<int, 1, 3, 1, 1, 3>::RowsAtCompileTime) == Eigen::Dynamic || int(CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen: :Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >::RowsAtCompileTime) == Eigen::Dynamic || int(Matrix<int, 1, 3, 1, 1, 3>::RowsAtCompileTime) == int(CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix <int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >::RowsAtCompileTime)) && (int(Matrix<int, 1, 3, 1, 1, 3>::ColsAtCompileTime) == Eigen::Dynamic || int(CwiseBinaryOp<Eigen::internal::scalar_difference_op< int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int , 3, 2, 0, 3, 2>, 1, 2, false> >::ColsAtCompileTime) == Eigen::Dynamic || int(Matrix<int, 1, 3, 1, 1, 3>::
^~~~~~~~~~~~~~~~~~~~~~ /usr/local/include/eigen3/Eigen/src/Core/util/StaticAssert.h:33:40: 注意: 展开从宏 'EIGEN_STATIC_ASSERT' #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG); ^ ~ /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:732:17:注意:在函数模板特化'Eigen::internal::call_assignment_no_alias<Eigen::Matrix<int, 1 , 3, 1, 1, 3>, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >, Eigen::internal::assign_op <int, int> >' 在这里请求 internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op< 标量,类型名 OtherDer... ^ /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:537:7: 注意:在函数模板特化 'Eigen::PlainObjectBase<Eigen::Matrix< 的实例化中int, 1, 3, 1, 1, 3> >::_set_noalias<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3 , 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> > > ' 在这里请求 _set_noalias(other); ^ /usr/local/include/eigen3/Eigen/src/Core/Matrix.h:377:9: 注意:在函数模板特化的实例化中'Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1 , 1, 3> >::PlainObjectBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen:: Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> > >' 在此处请求:Base(other.derived()) ^ testEigenIgl.cpp:1052:42: 注意:在函数模板特化 'Eigen::Matrix<int, 1, 3, 1, 1, 3>::Matrix<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> > >' 在这里请求特征: :Matrix<scalarType, 1, 3> v1 = triangle.row(1) - triangle.row(0); ^ testEigenIgl.cpp:1082:7: 注意:在函数模板特化 'nondegenerate<Eigen::Matrix<int, 3, 2, 0, 3, 2> 的实例化中
如何修复模板以同时接受动态和固定大小的矩阵?
谢谢!
解决方案
您遇到的问题是您的第一个分支的两个分支if
都必须有效,并且在固定大小矩阵的情况下,至少一个分支不是,因为您为算术结果指定了确切的尺寸。
template<typename Derived>
bool nondegenerate(const Eigen::PlainObjectBase<Derived>& triangle) {
typedef typename Derived::Scalar scalarType;
if (triangle.cols() == 2) {
auto v1 = triangle.row(1) - triangle.row(0);
auto v2 = triangle.row(2) - triangle.row(0);
return v1(0)*v2(1) - v1(1)*v2(0);
} else if (triangle.cols() == 3) {
auto v1 = triangle.row(1) - triangle.row(0);
auto v2 = triangle.row(2) - triangle.row(0);
return v1.cross(v2).norm();
} else {
std::cerr << "Undefined input." << std::endl;
return false;
}
}
另外:有一些通用公式可以找到任何大小的方阵的行列式,为什么不使用其中一种方法呢?
推荐阅读
- scala - 使用 <:< 的 Nothing 的隐式解析失败
- python - 用 Sympy 求解线性方程组
- r - 如何从 R 中的字符串中提取文本的特定部分?
- python - Pandas:计算当天持续时间总和超过30分钟的天数
- sql-server - 使用 OPEN XML 从数据存储中提取信息
- angular - 我在我的 Angular 应用程序中使用 ngb Pagination,但它无法正常工作
- oracle-apex - 将 2 页合并为一页
- python - SQLite 布尔列,其中只有一个条目可以为真
- graphql - 参数化查询 qraphQL
- javascript - 未捕获的 TypeError:无法读取 null 错误 javascript 的属性“样式”