代码之家  ›  专栏  ›  技术社区  ›  Daiver

特征:沿一维复制项,而不进行无用的分配

  •  2
  • Daiver  · 技术社区  · 7 年前

    Eigen::VectorXf vec(5);
    vec << 1, 2, 3, 4, 5;
    const auto vec2 = vec.someAwesomeEigenMagic<3>();
    //vec2 should contains (1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5)^T
    //Not (1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5)^T
    

    MatrixXf tmp = vec.replicate(1, 3).transpose();
    const Map<VectorXf> vec2(tmp.data(), vec.rows() * 3, 1);
    

    vec2 成为某种“特征模板表达式”,而不需要联合(vec可能相当大,我会经常调用此例程)和立即计算值。(vec包含逐顶点权重,我想将其用于加权最小二乘法)

    我考虑过使用1的向量的克罗内克乘积技巧,但我不确定它是否针对逐个乘积进行了优化。此外,我更喜欢避免不支持的模块

    1 回复  |  直到 7 年前
        1
  •  5
  •   ggael    7 年前

    使用devel分支,可以使用LinSpaced生成索引序列,然后索引输入向量:

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    using namespace std;
    
    int main()
    {
      VectorXf vec(5);
      vec << 1, 2, 3, 4, 5;
      auto vecrep = vec(ArrayXi::LinSpaced(5*3,0,4));
      cout << vecrep.transpose() << endl;
    }
    

    然后,您可以将关键行包装在一个自由函数中 auto ,在c++14中:

    template<typename XprType>
    auto magic_rep(const XprType &xpr, Index K) {
      return xpr(Eigen::ArrayXi::LinSpaced(xpr.size()*K,0,xpr.size()-1));
    }
    

    总的来说:

    cout << magic_rep(vec,3).transpose() << endl;