c++ - 模板元编程 Eigen 表达式

标签 c++ eigen template-meta-programming

假设我有一些(短) vector ,其长度在编译时已知,还有另一个较长的 vector ,其长度在编译时我不知道。我可以这样写:

template<int N>
Eigen::ArrayXd do_transformation(Eigen::Array<double,N,1> short_vec, Eigen::ArrayXd long_vec){
    Eigen::ArrayXd return_vector(long_vec.size());
    for(int i=0; i<N; i++){
      return_vector+=short_vec(i)*long_vec.pow(2-i);
    }
    return return_vector;
}

有没有一种方法可以使用表达式模板构造该总和而无需写出:

template<>
Eigen::ArrayXd do_transformation<1>(Eigen::Array<double,1,1> short_vec, Eigen::ArrayXd long_vec){

    return short_vec(0)*long_vec.pow(2);
}

template<>
Eigen::ArrayXd do_transformation<2>(Eigen::Array<double,2,1> short_vec, Eigen::ArrayXd long_vec){

    return short_vec(0)*long_vec.pow(2)+short_vec(1)*long_vec.pow(1);
}

对于 N 的每个值?

理想情况下,这可以在 c++11 中完成。 真正很棒的是函数返回某种特征表达式,这样我就可以做类似的事情:

long_vec+do_transformation(short_vec,long_vec) 并让 Eigen 指示编译器生成只遍历 vector 一次的代码。

最佳答案

在 c++11 中你可以做一个很好的旧递归:

template <int I>
struct do_transformation_impl {
    template<int M>
    static auto run(const Array<double,M,1> &short_vec, const ArrayXd &long_vec)
    -> decltype(short_vec(I)*long_vec.pow(2-I) + do_transformation_impl<I-1>::run(short_vec,long_vec))
    {
        return short_vec(I)*long_vec.pow(2-I) + do_transformation_impl<I-1>::run(short_vec,long_vec);
    }
};

template <>
struct do_transformation_impl<0> {
    template<int M>
    static auto run(const Array<double,M,1> &short_vec, const ArrayXd &long_vec)
    -> decltype(short_vec(0)*long_vec.pow(2))
    {
        return short_vec(0)*long_vec.pow(2);
    }
};

template<int N>
auto do_transformation(const Array<double,N,1> &short_vec, const ArrayXd &long_vec)
-> decltype(do_transformation_impl<N-1>::run(short_vec,long_vec))
{
    return do_transformation_impl<N-1>::run(short_vec,long_vec);
}

演示:https://godbolt.org/z/4xPdVm

在对 max66 的答案进行一些调整后,两种解决方案都产生相同的代码:https://godbolt.org/z/Ha5qMa

关于c++ - 模板元编程 Eigen 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53676287/

相关文章:

c++ - 模板内的模板 : why "` >>' should be ` > >' within a nested template argument list"

linear-algebra - 什么时候使用 eigen 什么时候使用 Blas

C++ 特征矩阵说明

c++ - constexpr 用户定义文字 : Is it allowed?

c++ - 使用 WINRM 在远程主机上推送二进制文件

c++ - boost::variant 递归问题

c++ - 如何理解libcxx对make_integer_sequence的实现?

c++ - 如何确定是否可以从给定的初始化列表构造结构?

c++ - 如何将时间转换为整数

c++ - 如何将 Argb32 加载到 Eigen Matrix 中以获得最佳性能?