| #include <Eigen/Core> |
| #include <iostream> |
| |
| // [circulant_func] |
| template<class ArgType> |
| class circulant_functor { |
| const ArgType &m_vec; |
| public: |
| circulant_functor(const ArgType& arg) : m_vec(arg) {} |
| |
| const typename ArgType::Scalar& operator() (Eigen::Index row, Eigen::Index col) const { |
| Eigen::Index index = row - col; |
| if (index < 0) index += m_vec.size(); |
| return m_vec(index); |
| } |
| }; |
| // [circulant_func] |
| |
| // [square] |
| template<class ArgType> |
| struct circulant_helper { |
| typedef Eigen::Matrix<typename ArgType::Scalar, |
| ArgType::SizeAtCompileTime, |
| ArgType::SizeAtCompileTime, |
| Eigen::ColMajor, |
| ArgType::MaxSizeAtCompileTime, |
| ArgType::MaxSizeAtCompileTime> MatrixType; |
| }; |
| // [square] |
| |
| // [makeCirculant] |
| template <class ArgType> |
| Eigen::CwiseNullaryOp<circulant_functor<ArgType>, typename circulant_helper<ArgType>::MatrixType> |
| makeCirculant(const Eigen::MatrixBase<ArgType>& arg) |
| { |
| typedef typename circulant_helper<ArgType>::MatrixType MatrixType; |
| return MatrixType::NullaryExpr(arg.size(), arg.size(), circulant_functor<ArgType>(arg.derived())); |
| } |
| // [makeCirculant] |
| |
| // [main] |
| int main() |
| { |
| Eigen::VectorXd vec(4); |
| vec << 1, 2, 4, 8; |
| Eigen::MatrixXd mat; |
| mat = makeCirculant(vec); |
| std::cout << mat << std::endl; |
| } |
| // [main] |