基于DeNASBASE的模板函数的C++特征块运算

基于DeNASBASE的模板函数的C++特征块运算,c++,eigen,C++,Eigen,这很有效 Vector2d a(1,2); VectorXd cc(10); cc << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9; VectorXd rr(10); rr << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9; int R(10); Vector2d G(Vector2d::Zero()); G.noalias() -= cc.segment(4, 2) + (rr.segment(1,

这很有效

Vector2d a(1,2);
VectorXd cc(10);
cc << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
VectorXd rr(10);
rr << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
int R(10);
Vector2d G(Vector2d::Zero());


G.noalias() -= cc.segment(4, 2) + 
               (rr.segment(1, 2) - R*Vector2d::Ones()).cwiseQuotient(a); // OK here
但是当rr.segment1,2作为参数传递给函数时,最后一行中的运算符不会编译。此代码中出现了问题

template <typename DerivedA, typename DerivedB, typename DerivedC>
void testFunc(MatrixBase<DerivedA>& G, const DenseBase<DerivedB>& c, const DenseBase<DerivedC>& r)
{  
   Vector2d a(1,2);
   int R(10);
   G.noalias() -= c + (r - R*Vector2d::Ones()).cwiseQuotient(a);
};

VectorXd cc(10);
cc << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
VectorXd rr(10);
rr << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
Vector2d G(Vector2d::Zero());
testFunc(G, cc.segment(4, 2), rr.segment(1, 2)); // ERROR : no match for 'operator-'

我知道问题在于,在testFunc中,cc.segment被视为一个通用的DenseBase对象,虽然它是为特定的class.block实现的,但没有为其实现运算符-。

您可以通过编写c.derived和r.derived来告诉Eigen使用DenseBase类封装的实际类型

无关:不写R*Vector2d::Ones,而是写Vector2d::ConstantR,如果整个表达式是元素操作,那么无论如何都应该在数组域中工作:

template <typename DerivedA, typename DerivedB, typename DerivedC>
void testFunc(MatrixBase<DerivedA>& G, const DenseBase<DerivedB>& c, const DenseBase<DerivedC>& r)
{
   Array2d a(1,2);
   int R(10);
   G.array() -= c.derived().array() + (r.derived().array() - R)/a;
}
如果传递的是ArrayBase而不是MatrixBase或DenseBase,则可以省略所有.derived和.array


此外,只有当涉及矩阵乘积时,.noalias才是必需的。

testFunc实现在矩阵表达式上工作,因此它应该采用MatrixBase参数,即添加向量2D是一种矩阵操作。你为什么要用DenseBase?因为我把.block作为参数传递。矩阵表达式的块仍然是矩阵表达式,因此应该匹配MatrixBase。。。也就是说,在你的代码中用MatrixBase替换DenseBase对我来说很好。此外,请注意,使用建议的派生方法就像说谎:函数要求DenseBase,内部希望对矩阵进行操作……谢谢你的评论。我明白你的意思。。。使用ArrayBase而不是MatrixBase来避免.array everywhere无法编译,但实际上,使用MatrixBase和.array而不是DenseBase和.derived.array将是最好的解决方案:您应该早点建议;