C++ 编写新的本征表达式

C++ 编写新的本征表达式,c++,eigen,eigen3,C++,Eigen,Eigen3,我正试图根据最新的文档编写新的特征表达式。基本上,我想要的是重塑功能的一部分,这在Eigen中仍然不存在。所以chop_expr(这里的特征向量表达式)应该将输入向量重塑为n倍矩阵 不幸的是,我所实现的不适用于在堆上分配的表达式,例如下面的代码不起作用,但在将MAXV更改为10之后,一切都变得完美了 另一个问题是关于 enum {Flags = EvalBeforeNestingBit} 我发现我需要它,否则,当我切掉矩阵乘法时,Eigen不会创建临时表达式,但我猜这样我也会强制切掉expr为

我正试图根据最新的文档编写新的特征表达式。基本上,我想要的是重塑功能的一部分,这在Eigen中仍然不存在。所以chop_expr(这里的特征向量表达式)应该将输入向量重塑为n倍矩阵

不幸的是,我所实现的不适用于在堆上分配的表达式,例如下面的代码不起作用,但在将MAXV更改为10之后,一切都变得完美了

另一个问题是关于

enum {Flags = EvalBeforeNestingBit}
我发现我需要它,否则,当我切掉矩阵乘法时,Eigen不会创建临时表达式,但我猜这样我也会强制切掉expr为任何其他表达式创建临时表达式。所以问题是我应该如何正确地做到这一点

namespace Eigen {

template <int chunk, typename Derived> struct ChoppedExpression;

namespace internal {

template <int chunk, typename Derived>
struct traits<ChoppedExpression<chunk, Derived>> : traits<Derived> {
  enum {Flags = EvalBeforeNestingBit};
  enum {IsRowMajor = 0};

  enum {   RowsAtCompileTime = chunk};
  enum {MaxRowsAtCompileTime = chunk};

  enum {ColsAtCompileTime = (Derived::RowsAtCompileTime == Eigen::Dynamic 
      ? Eigen::Dynamic : Derived::RowsAtCompileTime / chunk)};

  enum {MaxColsAtCompileTime = (Derived::MaxRowsAtCompileTime == Eigen::Dynamic
      ? Eigen::Dynamic : (Derived::MaxRowsAtCompileTime + chunk - 1) / chunk)};
};

}  // namespace internal

template <int chunk, class Derived> struct ChoppedExpression
  : public MatrixBase<ChoppedExpression<chunk, Derived>> {

   ChoppedExpression(const Derived& arg) : m_arg(arg) {
   EIGEN_STATIC_ASSERT(Derived::ColsAtCompileTime == 1,
       YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX);

   EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime % chunk == 0
        || Derived::RowsAtCompileTime == Eigen::Dynamic,
       VECTOR_SHOULD_HAVE_INTEGER_NUMBER_OF_CHUNKS_FOR_CHOPPING);
  }

  typedef Index Index;

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return chunk; }
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_arg.size() / chunk; }

  typedef typename internal::ref_selector<ChoppedExpression>::type Nested;
  typedef typename internal::ref_selector<Derived>::type DerivedTypeNested;

  DerivedTypeNested m_arg;
};

namespace internal {

template<int chunk, typename Derived>
struct evaluator<ChoppedExpression<chunk, Derived>>
  : public evaluator_base<ChoppedExpression<chunk, Derived>> {

  typedef ChoppedExpression<chunk, Derived> XprType;
  typedef typename nested_eval<Derived, XprType::ColsAtCompileTime>::type DerivedNested;
  typedef typename remove_all<DerivedNested>::type DerivedNestedCleaned;
  typedef typename XprType::CoeffReturnType CoeffReturnType;

  enum {
    CoeffReadCost = evaluator<DerivedNestedCleaned>::CoeffReadCost,
    Flags = traits<XprType>::Flags, IsRowMajor = 0
  };

  evaluator(const XprType& xpr) : m_argImpl(xpr.m_arg) {}

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
    { return m_argImpl.coeff(col * chunk + row); }

  evaluator<DerivedNestedCleaned> m_argImpl;
};

}  // namespace internal
}  // namespace Eigen

template<int chunk, typename Derived> EIGEN_ALWAYS_INLINE
EIGEN_DEVICE_FUNC static Eigen::ChoppedExpression<chunk, Derived>
chop_expr(const Eigen::MatrixBase<Derived> &expr)
  { return Eigen::ChoppedExpression<chunk, Derived>(expr.derived()); }


#define MAXV -1

Eigen::Matrix<double, -1, 1, 0, std::max(3*MAXV, -1)> _blendshapes(2, 1);

int main() {
  for (int i = 0; i < 2; ++i) _blendshapes[i] = double(i + 10);

  std::cout << chop_expr<2>(_blendshapes + Eigen::Matrix<double, 2, 1>(1, 1)) << std::endl;
}
名称空间特征{
模板结构斩波表达式;
命名空间内部{
模板
结构特征:特征{
枚举{Flags=evalbeforenstingbit};
枚举{IsRowMajor=0};
枚举{RowsAtCompileTime=chunk};
枚举{MaxRowsAtCompileTime=chunk};
枚举{ColsAtCompileTime=(派生::行SATCompileTime==特征::动态
?特征::动态:派生::rowstatcompiletime/chunk)};
枚举{MaxColsAtCompileTime=(派生::MaxRowsAtCompileTime==特征::动态
?特征::动态:(派生::MaxRowsAtCompileTime+chunk-1)/chunk)};
};
}//命名空间内部
模板结构ChoppedExpression
:公共矩阵库{
斩波表达式(常量派生和arg):m_arg(arg){
特征值静态断言(派生::ColsAtCompileTime==1,
您尝试调用矩阵上的向量方法);
特征值\u静态\u断言(派生::RowsAtCompileTime%chunk==0
||派生::RowsAtCompileTime==特征::动态,
向量_应_具有_整数_块数_用于_切分);
}
typedef索引;
本征设备函数本征强内联索引行()常量{return chunk;}
特征设备特征强内联索引cols()常量{返回m_arg.size()/chunk;}
typedef typename internal::ref_selector::type Nested;
typedef typename internal::ref_selector::type DerivedTypeNested;
DerivedTypeNested m_arg;
};
命名空间内部{
模板
结构计算器
:公共评估员{
typedef斩波表达式XprType;
typedef typename nested_eval::type DerivedNested;
typedef typename remove_all::type derivednestedcleanned;
typedef typename XprType::CoeffReturnType CoeffReturnType;
枚举{
CoeffReadCost=评估器::CoeffReadCost,
Flags=traits::Flags,IsRowMajor=0
};
求值器(constxprtype&xpr):m_argImpl(xpr.m_arg){}
特征值设备功能特征值强内联系数返回类型系数(索引行,索引列)常数
{返回m_argImpl.coeff(col*chunk+row);}
评估员m_Arginpl;
};
}//命名空间内部
}//名称空间特征
模板特征值总是内联的
特征设备功能静态特征::斩波表达式
chop_expr(常数特征::矩阵基和expr)
{return Eigen::ChoppedExpression(expr.derived());}
#定义MAXV-1
本征::矩阵混合形状(2,1);
int main(){
对于(int i=0;i<2;++i)_混合形状[i]=double(i+10);

std::cout您不需要
evalbeforenstingbit
,但在计算器中传播标志时必须小心。为安全起见,请编写:

Flags = traits<XprType>::Flags&HereditaryBits
Flags=traits::Flags&generativeybits

似乎至少有一些表达式的特征(例如,Eigen::internal::traits::Flags)为零,因此我使用了evaluator::Flags。但您肯定指出了问题所在。