30 template<
class Derived>
31 class col_iterator :
public boost::random_access_iterator_helper<col_iterator<Derived>,
32 typename Eigen::MatrixBase<Derived>::ColXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::ColXpr> {
35 using iterator_category = std::input_iterator_tag;
37 col_iterator(Eigen::MatrixBase<Derived> &m, Eigen::Index index) : m_(std::addressof(m)),
40 bool operator==(
const self_type &rhs)
const {
41 RSMESH_ASSERT(m_ == rhs.m_);
42 return index_ == rhs.m_;
46 RSMESH_ASSERT(index_ < m_->cols());
52 RSMESH_ASSERT(index_ > 0);
57 typename self_type::reference operator*()
const {
58 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
59 return m_->col(index_);
62 typename self_type::pointer operator->()
const =
delete;
64 bool operator<(
const self_type &rhs)
const {
65 RSMESH_ASSERT(m_ == rhs.m_);
66 return index_ < rhs.index_;
69 self_type &operator+=(
typename self_type::difference_type n) {
70 RSMESH_ASSERT(index_ + n < m_->cols());
75 self_type &operator-=(
typename self_type::difference_type n) {
76 RSMESH_ASSERT(index_ - n >= 0);
81 friend typename self_type::difference_type
83 RSMESH_ASSERT(lhs.m_ == rhs.m_);
84 return lhs.index_ - rhs.index_;
88 Eigen::MatrixBase<Derived> *m_;
92 template<
class Derived>
93 class const_col_iterator :
public boost::random_access_iterator_helper<const_col_iterator<Derived>,
94 typename Eigen::MatrixBase<Derived>::ConstColXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::ConstColXpr> {
97 using iterator_category = std::input_iterator_tag;
99 const_col_iterator(
const Eigen::MatrixBase<Derived>& m, Eigen::Index index) : m_(std::addressof(m)), index_(index) {}
101 bool operator==(
const self_type& rhs)
const {
102 RSMESH_ASSERT(m_ == rhs.m_);
103 return index_ == rhs.index_;
107 RSMESH_ASSERT(index_ < m_->cols());
113 RSMESH_ASSERT(index_ > 0);
118 typename self_type::reference operator*()
const {
119 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
120 return m_->col(index_);
123 typename self_type::pointer operator->()
const =
delete;
125 bool operator<(
const self_type& rhs)
const {
126 RSMESH_ASSERT(m_ == rhs.m_);
127 return index_ < rhs.index_;
130 self_type& operator+=(
typename self_type::difference_type n) {
131 RSMESH_ASSERT(index_ + n < m_->cols());
136 self_type& operator-=(
typename self_type::difference_type n) {
137 RSMESH_ASSERT(index_ - n >= 0);
142 friend typename self_type::difference_type operator-(
const self_type& lhs,
const self_type &rhs) {
143 RSMESH_ASSERT(lhs.m_ == rhs.m_);
144 return lhs.index_ - rhs.index_;
147 const Eigen::MatrixBase<Derived> *m_;
151 template <
class Derived>
152 class row_iterator :
public boost::random_access_iterator_helper<row_iterator<Derived>,
153 typename Eigen::MatrixBase<Derived>::RowXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::RowXpr> {
157 using iterator_category = std::input_iterator_tag;
159 row_iterator(Eigen::MatrixBase<Derived>& m, Eigen::Index index) : m_(std::addressof(m)), index_(index) {}
161 bool operator==(
const self_type& rhs)
const {
162 RSMESH_ASSERT(m_ == rhs.m_);
163 return index_ == rhs.index_;
167 RSMESH_ASSERT(index_ < m_->rows());
173 RSMESH_ASSERT(index_ > 0);
178 typename self_type::reference operator*()
const {
179 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
180 return m_->row(index_);
183 typename self_type::pointer operator->()
const =
delete;
185 bool operator<(
const self_type& rhs)
const {
186 RSMESH_ASSERT(m_ == rhs.m_);
187 return index_ < rhs.index_;
190 self_type& operator+=(
typename self_type::difference_type n) {
191 RSMESH_ASSERT(index_ + n < m_->rows());
196 self_type& operator-=(
typename self_type::difference_type n) {
197 RSMESH_ASSERT(index_ - n >= 0);
202 friend typename self_type::difference_type operator-(
const self_type& lhs,
const self_type &rhs) {
203 RSMESH_ASSERT(lhs.m_ == rhs.m_);
204 return lhs.index_ - rhs.index_;
208 Eigen::MatrixBase<Derived> *m_;
212 template<
class Derived>
214 typename Eigen::MatrixBase<Derived>::ConstRowXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::ConstRowXpr> {
218 using iterator_category = std::input_iterator_tag;
220 const_row_iterator(
const Eigen::MatrixBase<Derived>& m, Eigen::Index index) : m_(std::addressof(m)), index_(index) {}
222 bool operator==(
const self_type& rhs)
const {
223 RSMESH_ASSERT(m_ == rhs.m_);
224 return index_ == rhs.index_;
228 RSMESH_ASSERT(index_ < m_->rows());
234 RSMESH_ASSERT(index_ > 0);
239 typename self_type::reference operator*()
const {
240 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
241 return m_->row(index_);
244 typename self_type::pointer operator->()
const =
delete;
246 bool operator<(
const self_type& rhs)
const {
247 RSMESH_ASSERT(m_ == rhs.m_);
248 return index_ < rhs.index_;
251 self_type& operator+=(
typename self_type::difference_type n) {
252 RSMESH_ASSERT(index_ + n < m_->rows());
257 self_type& operator-=(
typename self_type::difference_type n) {
258 RSMESH_ASSERT(index_ - n >= 0);
263 friend typename self_type::difference_type operator-(
const self_type& lhs,
const self_type &rhs) {
264 RSMESH_ASSERT(lhs.m_ == rhs.m_);
265 return lhs.index_ - rhs.index_;
269 const Eigen::MatrixBase<Derived> *m_;
275 template<
class Derived>
276 auto col_begin(Eigen::MatrixBase<Derived>& m) {
280 template<
class Derived>
281 auto col_end(Eigen::MatrixBase<Derived>& m) {
282 return detail::col_iterator<Derived>(m, m.cols());
285 template<
class Derived>
286 auto col_begin(
const Eigen::MatrixBase<Derived>& m) {
287 return detail::const_col_iterator<Derived>(m, 0);
290 template<
class Derived>
291 auto col_end(
const Eigen::MatrixBase<Derived>& m) {
292 return detail::const_col_iterator<Derived>(m, m.cols());
295 template<
class Derived>
296 auto row_begin(Eigen::MatrixBase<Derived>& m) {
297 return detail::row_iterator<Derived>(m, 0);
300 template<
class Derived>
301 auto row_end(Eigen::MatrixBase<Derived>& m) {
302 return detail::row_iterator<Derived>(m, m.rows());
305 template<
class Derived>
306 auto row_begin(
const Eigen::MatrixBase<Derived>& m) {
307 return detail::const_row_iterator<Derived>(m, 0);
310 template<
class Derived>
311 auto row_end(
const Eigen::MatrixBase<Derived>& m) {
312 return detail::const_row_iterator<Derived>(m, m.rows());
316 template <
class Derived>
321 auto begin() {
return col_begin(m_);}
323 auto end() {
return col_end(m_);}
326 Eigen::MatrixBase<Derived>& m_;
329 template <
class Derived>
334 auto begin() {
return col_begin(m_);}
336 auto end() {
return col_end(m_);}
339 const Eigen::MatrixBase<Derived>& m_;
342 template <
class Derived>
347 auto begin() {
return row_begin(m_);}
349 auto end() {
return row_end(m_);}
352 Eigen::MatrixBase<Derived>& m_;
355 template <
class Derived>
360 auto begin() {
return row_begin(m_);}
362 auto end() {
return row_end(m_);}
364 Eigen::MatrixBase<Derived> *m_;
368 template <
class Derived>
369 auto col_range(Eigen::MatrixBase<Derived>& m) {
373 template <
class Derived>
374 auto col_range(
const Eigen::MatrixBase<Derived>& m) {
375 return detail::const_col_range_wrapper<Derived>(m);
378 template <
class Derived>
379 auto row_range(Eigen::MatrixBase<Derived>& m) {
380 return detail::row_range_wrapper<Derived>(m);
383 template <
class Derived>
384 auto row_range(
const Eigen::MatrixBase<Derived>& m) {
385 return detail::const_row_range_wrapper<Derived>(m);
390 template <
class Derived>
391 Eigen::Index common_cols(
const Eigen::MatrixBase<Derived>& m) {
395 template <
class Derived,
class ...Args>
396 Eigen::Index common_cols(
const Eigen::MatrixBase<Derived>& m,
const Args&&... args) {
397 if(m.cols() != common_cols(std::forward<Args>(args)...)) {
398 throw std::invalid_argument(
"All inputs must have the same number of columns.");
405 template<
class Derived,
class ...Args>
406 Eigen::Index common_rows(
const Eigen::MatrixBase<Derived>& m) {
410 template <
class Derived,
class ...Args>
411 Eigen::Index common_rows(
const Eigen::MatrixBase<Derived>& m, Args&&... args) {
412 if(m.rows() != common_rows(std::forward<Args>(args)...)) {
413 throw std::invalid_argument(
"All inputs must have the same number of rows");
418 template <
class ResultDerived,
class Derived>
419 void concatenate_cols_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>& m) {
423 template <
class ResultDerived,
class Derived,
class... Args>
424 void concatenate_cols_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>&m, Args&&... args) {
425 result.leftCols(m.cols()) = m;
426 auto result_tail = result.rightCols(result.cols() - m.cols());
427 concatenate_cols_impl(result_tail, std::forward<Args>(args)...);
430 template <
class ResultDerived,
class Derived>
431 void concatenate_rows_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>& m) {
435 template <
class ResultDerived,
class Derived,
class ...Args>
436 void concatenate_rows_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>& m, Args&&... args) {
437 result.topRows(m.rows()) = m;
439 auto result_tail = result.bottomRows(result.rows() - m.rows());
440 concatenate_rows_impl(result_tail, std::forward<Args>(args)...);
443 template <
class ResultDerived,
class Derived>
444 void take_cols_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>& m, Eigen::Index index) {
445 result.col(0) = m.col(index);
448 template <
class ResultDerived,
class Derived,
class... Ts>
449 void take_cols_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>& m, Eigen::Index index, Ts... indices) {
450 result.col(0) = m.col(index);
451 auto result_tail = result.rightCols(result.cols() - 1);
452 take_cols_impl(result, m, indices...);
455 template <
class ResultDerived,
class Derived>
456 void take_rows_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>& m, Eigen::Index index) {
457 result.row(0) = m.row(index);
460 template <
class ResultDerived,
class Derived,
class... Ts>
461 void take_rows_impl(Eigen::MatrixBase<ResultDerived>& result,
const Eigen::MatrixBase<Derived>& m, Eigen::Index index, Ts... indices) {
462 result.row(0) = m.row(index);
463 auto result_tail = result.bottomRows(result.rows() - 1);
464 take_rows_impl(result, m, indices...);
469 template <
class ...Args>
470 auto concatenate_cols(Args&&... args) {
471 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> result (
472 detail::common_rows(std::forward<Args>(args)...),
476 detail::concatenate_cols_impl(result, std::forward<Args>(args)...);
480 template <
class ...Args>
481 auto concatenate_rows(Args&&... args) {
482 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> result (
483 common::fold_left(std::plus<>(), args.rows()...),
484 detail::common_cols(std::forward<Args>(args)...)
487 detail::concatenate_rows_impl(result, std::forward<Args>(args)...);
491 template <
class Derived,
class... Ts>
492 auto take_cols(
const Eigen::MatrixBase<Derived>& m, Ts... indices) {
494 typename Eigen::MatrixBase<Derived>::Scalar,
495 Eigen::MatrixBase<Derived>::RowsAtCompileTime,
497 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
498 > result(m.rows(), sizeof...(indices));
500 detail::take_cols_impl(result, m, indices...);
505 template <
class Derived,
class ForwardRange>
506 auto take_cols(
const Eigen::MatrixBase<Derived>& m, ForwardRange indices) {
507 Eigen::Index n_cols = std::distance(indices.begin(), indices.end());
510 typename Eigen::MatrixBase<Derived>::Scalar,
511 Eigen::MatrixBase<Derived>::RowsAtCompileTime,
513 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
514 > result(m.rows(), n_cols);
516 auto it = indices.begin();
517 for (Eigen::Index i = 0; i < n_cols; i ++) {
518 result.col(i) = m.col(*it ++);
523 template <
class Derived>
524 auto take_cols(
const Eigen::MatrixBase<Derived>& m,
const std::vector<Eigen::Index> &indices) {
525 return take_cols(m, make_range(indices.begin(), indices.end()));
528 template <
class Derived,
class... Ts>
529 auto take_rows(
const Eigen::MatrixBase<Derived>& m, Ts... indices) {
531 typename Eigen::MatrixBase<Derived>::Scalar,
533 Eigen::MatrixBase<Derived>::ColsAtCompileTime,
534 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
535 > result(sizeof...(indices), m.cols());
537 detail::take_rows_impl(result, m, indices...);
542 template <
class Derived,
class ForwardRange>
543 auto take_rows(
const Eigen::MatrixBase<Derived>& m, ForwardRange indices) {
544 Eigen::Index n_rows = std::distance(indices.begin(), indices.end());
547 typename Eigen::MatrixBase<Derived>::Scalar,
549 Eigen::MatrixBase<Derived>::ColsAtCompileTime,
550 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
551 > result(n_rows, m.cols());
553 auto it = indices.begin();
554 for(Eigen::Index i = 0; i < n_rows; i ++) {
555 result.row(i) = m.row(i);
560 template <
class Derived>
561 auto take_rows(
const Eigen::MatrixBase<Derived>& m,
const std::vector<Eigen::Index>& indices) {
562 return take_rows(m, make_range(indices.begin(), indices.end()));