make_circulant2.cpp 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include <Eigen/Core>
  2. #include <iostream>
  3. using namespace Eigen;
  4. // [circulant_func]
  5. template<class ArgType>
  6. class circulant_functor {
  7. const ArgType &m_vec;
  8. public:
  9. circulant_functor(const ArgType& arg) : m_vec(arg) {}
  10. const typename ArgType::Scalar& operator() (Index row, Index col) const {
  11. Index index = row - col;
  12. if (index < 0) index += m_vec.size();
  13. return m_vec(index);
  14. }
  15. };
  16. // [circulant_func]
  17. // [square]
  18. template<class ArgType>
  19. struct circulant_helper {
  20. typedef Matrix<typename ArgType::Scalar,
  21. ArgType::SizeAtCompileTime,
  22. ArgType::SizeAtCompileTime,
  23. ColMajor,
  24. ArgType::MaxSizeAtCompileTime,
  25. ArgType::MaxSizeAtCompileTime> MatrixType;
  26. };
  27. // [square]
  28. // [makeCirculant]
  29. template <class ArgType>
  30. CwiseNullaryOp<circulant_functor<ArgType>, typename circulant_helper<ArgType>::MatrixType>
  31. makeCirculant(const Eigen::MatrixBase<ArgType>& arg)
  32. {
  33. typedef typename circulant_helper<ArgType>::MatrixType MatrixType;
  34. return MatrixType::NullaryExpr(arg.size(), arg.size(), circulant_functor<ArgType>(arg.derived()));
  35. }
  36. // [makeCirculant]
  37. // [main]
  38. int main()
  39. {
  40. Eigen::VectorXd vec(4);
  41. vec << 1, 2, 4, 8;
  42. Eigen::MatrixXd mat;
  43. mat = makeCirculant(vec);
  44. std::cout << mat << std::endl;
  45. }
  46. // [main]