MCKL
Monte Carlo Kernel Library
matrix.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/core/matrix.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_CORE_MATRIX_HPP
33 #define MCKL_CORE_MATRIX_HPP
34 
35 #include <mckl/internal/common.hpp>
36 #include <mckl/core/is_equal.hpp>
37 #include <mckl/core/iterator.hpp>
38 
39 namespace mckl {
40 
47 template <typename T, MatrixLayout Layout = ColMajor,
48  typename Alloc = Allocator<T>>
49 class Matrix
50 {
51  using layout_dispatch = std::integral_constant<MatrixLayout, Layout>;
52  using row_major = std::integral_constant<MatrixLayout, RowMajor>;
53  using col_major = std::integral_constant<MatrixLayout, ColMajor>;
54 
55  Vector<T, Alloc> data_;
56 
57  public:
58  using value_type = T;
59  using allocator_type = Alloc;
60  using size_type = std::size_t;
61  using difference_type = std::ptrdiff_t;
62  using reference = value_type &;
63  using const_reference = const value_type &;
64  using pointer = value_type *;
65  using const_pointer = const value_type *;
66 
67  using iterator = pointer;
69  using reverse_iterator = std::reverse_iterator<iterator>;
70  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
71 
72  using row_iterator =
73  std::conditional_t<Layout == RowMajor, pointer, StepIterator<pointer>>;
74  using const_row_iterator = std::conditional_t<Layout == RowMajor,
76  using reverse_row_iterator = std::reverse_iterator<row_iterator>;
78  std::reverse_iterator<const_row_iterator>;
79 
80  using col_iterator =
81  std::conditional_t<Layout == ColMajor, pointer, StepIterator<pointer>>;
82  using const_col_iterator = std::conditional_t<Layout == ColMajor,
83  const_pointer, StepIterator<const_pointer>>;
84  using reverse_col_iterator = std::reverse_iterator<col_iterator>;
86  std::reverse_iterator<const_col_iterator>;
87 
92 
97 
98  using transpose_type =
100 
102  Matrix() noexcept(
103  std::is_nothrow_default_constructible<Vector<T, Alloc>>::value)
104  : nrow_(0), ncol_(0)
105  {
106  }
107 
110  : data_(nrow * ncol), nrow_(nrow), ncol_(ncol)
111  {
112  }
113 
115  Matrix(const Matrix &) = default;
116 
118  Matrix(Matrix &&other) noexcept(
119  std::is_nothrow_move_constructible<Vector<T, Alloc>>::value)
120  : data_(std::move(other.data_)), nrow_(other.nrow_), ncol_(other.ncol_)
121  {
122  other.nrow_ = 0;
123  other.ncol_ = 0;
124  }
125 
127  Matrix &operator=(const Matrix &) = default;
128 
130  Matrix &operator=(Matrix &&other) noexcept(
131  noexcept(data_.swap(other.data_)))
132  {
133  if (this != &other) {
134  data_.swap(other.data_);
135  std::swap(nrow_, other.nrow_);
136  std::swap(ncol_, other.ncol_);
137  }
138 
139  return *this;
140  }
141 
143  explicit operator transpose_type() const
144  {
145  transpose_type mat(nrow_, ncol_);
146 
147  if (Layout == RowMajor) {
148  for (size_type i = 0; i != nrow_; ++i) {
149  for (size_type j = 0; j != ncol_; ++j) {
150  mat(i, j) = operator()(i, j);
151  }
152  }
153  }
154  if (Layout == ColMajor) {
155  for (size_type j = 0; j != ncol_; ++j) {
156  for (size_type i = 0; i != nrow_; ++i) {
157  mat(i, j) = operator()(i, j);
158  }
159  }
160  }
161 
162  return mat;
163  }
164 
166  allocator_type get_allocator() const { return data_.get_allocator(); }
167 
169  iterator begin() { return data(); }
170 
172  const_iterator begin() const { return cbegin(); }
173 
175  const_iterator cbegin() const { return data(); }
176 
178  iterator end() { return begin() + nrow_ * ncol_; }
179 
181  const_iterator end() const { return cend(); }
182 
184  const_iterator cend() const { return begin() + nrow_ * ncol_; }
185 
188 
190  const_reverse_iterator rbegin() const { return crbegin(); }
191 
194  {
195  return const_reverse_iterator(cend());
196  }
197 
200 
202  const_reverse_iterator rend() const { return crend(); }
203 
206  {
207  return const_reverse_iterator(cbegin());
208  }
209 
212  {
213  return row_begin_dispatch(i, layout_dispatch());
214  }
215 
218 
221  {
222  return row_begin_dispatch(i, layout_dispatch());
223  }
224 
226  row_iterator row_end(size_type i) { return row_begin(i) + ncol_; }
227 
230 
233  {
234  return row_cbegin(i) + ncol_;
235  }
236 
239  {
240  return reverse_row_iterator(row_end(i));
241  }
242 
245  {
246  return row_crbegin(i);
247  }
248 
251  {
253  }
254 
257  {
258  return reverse_row_iterator(row_begin(i));
259  }
260 
263  {
264  return row_crend(i);
265  }
266 
269  {
271  }
272 
275  {
276  return col_begin_dispatch(i, layout_dispatch());
277  }
278 
281 
284  {
285  return col_begin_dispatch(j, layout_dispatch());
286  }
287 
289  col_iterator col_end(size_type j) { return col_begin(j) + nrow_; }
290 
293 
296  {
297  return col_cbegin(j) + nrow_;
298  }
299 
302  {
303  return reverse_col_iterator(col_end(j));
304  }
305 
308  {
309  return col_crbegin(j);
310  }
311 
314  {
316  }
317 
320  {
321  return reverse_col_iterator(col_begin(j));
322  }
323 
326  {
327  return col_crend(j);
328  }
329 
332  {
334  }
335 
338 
341  {
342  return const_row_range(row_begin(i), row_end(i));
343  }
344 
347  {
348  return const_row_range(row_cbegin(i), row_cend(i));
349  }
350 
353  {
354  return reverse_row_range(row_rbegin(i), row_rend(i));
355  }
356 
359  {
361  }
362 
365  {
367  }
368 
371 
374  {
375  return const_col_range(col_begin(i), col_end(i));
376  }
377 
380  {
381  return const_col_range(col_cbegin(i), col_cend(i));
382  }
383 
386  {
387  return reverse_col_range(col_rbegin(i), col_rend(i));
388  }
389 
392  {
394  }
395 
398  {
400  }
401 
404  {
405  runtime_assert<std::out_of_range>(
406  i < nrow_, "**Matrix::at** row index out of range");
407  runtime_assert<std::out_of_range>(
408  j < ncol_, "**Matrix::at** column index out of range");
409 
410  return at_dispatch(i, j, layout_dispatch());
411  }
412 
415  {
416  runtime_assert<std::out_of_range>(
417  i < nrow_, "**Matrix::at** row index out of range");
418  runtime_assert<std::out_of_range>(
419  j < ncol_, "**Matrix::at** column index out of range");
420 
421  return at_dispatch(i, j, layout_dispatch());
422  }
423 
426  {
427  return at_dispatch(i, j, layout_dispatch());
428  }
429 
432  {
433  return at_dispatch(i, j, layout_dispatch());
434  }
435 
437  pointer data() { return data_.data(); }
438 
440  const_pointer data() const { return data_.data(); }
441 
444  {
445  return row_data_dispatch(i, layout_dispatch());
446  }
447 
450  {
451  return row_data_dispatch(i, layout_dispatch());
452  }
453 
456  {
457  return row_stride_dispatch(layout_dispatch());
458  }
459 
462  {
463  return col_data_dispatch(j, layout_dispatch());
464  }
465 
468  {
469  return col_data_dispatch(j, layout_dispatch());
470  }
471 
474  {
475  return col_stride_dispatch(layout_dispatch());
476  }
477 
479  static constexpr MatrixLayout layout() { return Layout; }
480 
482  bool empty() const { return nrow_ == 0 || ncol_ == 0; }
483 
485  size_type nrow() const { return nrow_; }
486 
488  size_type ncol() const { return ncol_; }
489 
491  size_type ldim() const { return ldim_dispatch(layout_dispatch()); }
492 
494  size_type size() const { return nrow_ * ncol_; }
495 
497  void reserve(size_type n, size_type m) { data_.reserve(n * m); }
498 
507  {
508  if (nrow * ncol == 0) {
509  data_.clear();
510  nrow_ = nrow;
511  ncol_ = ncol;
512  return;
513  }
514 
515  if (nrow == nrow_ && ncol_ == ncol) {
516  return;
517  }
518 
519  resize_dispatch(nrow, ncol, layout_dispatch());
520  }
521 
523  void shrink_to_fit() { data_.shrink_to_fit(); }
524 
526  void clear()
527  {
528  data_.clear();
529  nrow_ = 0;
530  ncol_ = 0;
531  }
532 
534  template <typename InputIter>
535  void push_back_row(InputIter first)
536  {
537  resize(nrow_ + 1, ncol_);
538  std::copy_n(first, ncol_, row_begin(nrow_ - 1));
539  }
540 
542  template <typename InputIter>
543  void push_back_col(InputIter first)
544  {
545  resize(nrow_, ncol_ + 1);
546  std::copy_n(first, nrow_, col_begin(ncol_ - 1));
547  }
548 
550  void swap(Matrix &other) noexcept(noexcept(data_.swap(other.data_)))
551  {
552  std::swap(nrow_, other.nrow_);
553  std::swap(ncol_, other.ncol_);
554  data_.swap(other.data_);
555  }
556 
558  friend void swap(Matrix &m1, Matrix &m2) noexcept(noexcept(m1.swap(m2)))
559  {
560  m1.swap(m2);
561  }
562 
564  friend bool operator==(const Matrix &m1, const Matrix &m2)
565  {
566  if (m1.nrow_ != m2.nrow_) {
567  return false;
568  }
569  if (m1.ncol_ != m2.ncol_) {
570  return false;
571  }
572  return m1.data_ == m2.data_;
573  }
574 
576  friend bool operator!=(const Matrix &m1, const Matrix &m2)
577  {
578  return !(m1 == m2);
579  }
580 
582  friend bool is_equal(const Matrix &m1, const Matrix &m2)
583  {
584  if (m1.nrow_ != m2.nrow_) {
585  return false;
586  }
587  if (m1.ncol_ != m2.ncol_) {
588  return false;
589  }
590  return is_equal(m1.data_, m2.data_);
591  }
592 
593  private:
594  std::size_t nrow_;
595  std::size_t ncol_;
596 
597  // Layout == RowMajor
598 
599  size_type ldim_dispatch(row_major) const { return ncol_; }
600 
601  pointer row_begin_dispatch(size_type i, row_major) { return row_data(i); }
602 
603  const_pointer row_begin_dispatch(size_type i, row_major) const
604  {
605  return row_data(i);
606  }
607 
608  StepIterator<pointer> col_begin_dispatch(size_type j, row_major)
609  {
610  return StepIterator<pointer>(
611  col_data(j), static_cast<difference_type>(col_stride()));
612  }
613 
614  StepIterator<const_pointer> col_begin_dispatch(
615  size_type j, row_major) const
616  {
617  return StepIterator<const_pointer>(
618  col_data(j), static_cast<difference_type>(col_stride()));
619  }
620 
621  reference at_dispatch(size_type i, size_type j, row_major)
622  {
623  return data_[i * ncol_ + j];
624  }
625 
626  const_reference at_dispatch(size_type i, size_type j, row_major) const
627  {
628  return data_[i * ncol_ + j];
629  }
630 
631  size_type row_stride_dispatch(row_major) const { return 1; }
632 
633  pointer row_data_dispatch(size_type i, row_major)
634  {
635  return data() + i * ncol_;
636  }
637 
638  const_pointer row_data_dispatch(size_type i, row_major) const
639  {
640  return data() + i * ncol_;
641  }
642 
643  size_type col_stride_dispatch(row_major) const { return ncol_; }
644 
645  pointer col_data_dispatch(size_type j, row_major) { return data() + j; }
646 
647  const_pointer col_data_dispatch(size_type j, row_major) const
648  {
649  return data() + j;
650  }
651 
652  void resize_dispatch(size_type nrow, size_type ncol, row_major)
653  {
654  if (ncol == ncol_) {
655  data_.resize(nrow * ncol);
656  nrow_ = nrow;
657  return;
658  }
659 
660  Matrix tmp(nrow, ncol);
661  const size_type n = std::min(nrow, nrow_);
662  const size_type m = std::min(ncol, ncol_);
663  for (size_type i = 0; i != n; ++i) {
664  std::copy_n(row_data(i), m, tmp.row_data(i));
665  }
666  swap(tmp);
667  }
668 
669  // Layout == ColMajor
670 
671  size_type ldim_dispatch(col_major) const { return nrow_; }
672 
673  StepIterator<pointer> row_begin_dispatch(size_type i, col_major)
674  {
675  return StepIterator<pointer>(
676  row_data(i), static_cast<difference_type>(row_stride()));
677  }
678 
679  StepIterator<const_pointer> row_begin_dispatch(
680  size_type i, col_major) const
681  {
682  return StepIterator<const_pointer>(
683  row_data(i), static_cast<difference_type>(row_stride()));
684  }
685 
686  pointer col_begin_dispatch(size_type j, col_major) { return col_data(j); }
687 
688  const_pointer col_begin_dispatch(size_type j, col_major) const
689  {
690  return col_data(j);
691  }
692 
693  reference at_dispatch(size_type i, size_type j, col_major)
694  {
695  return data_[j * nrow_ + i];
696  }
697 
698  const_reference at_dispatch(size_type i, size_type j, col_major) const
699  {
700  return data_[j * nrow_ + i];
701  }
702 
703  size_type row_stride_dispatch(col_major) const { return nrow_; }
704 
705  pointer row_data_dispatch(size_type i, col_major) { return data() + i; }
706 
707  const_pointer row_data_dispatch(size_type i, col_major) const
708  {
709  return data() + i;
710  }
711 
712  size_type col_stride_dispatch(col_major) const { return 1; }
713 
714  pointer col_data_dispatch(size_type j, col_major)
715  {
716  return data() + j * nrow_;
717  }
718 
719  const_pointer col_data_dispatch(size_type j, col_major) const
720  {
721  return data() + j * nrow_;
722  }
723 
724  void resize_dispatch(size_type nrow, size_type ncol, col_major)
725  {
726  if (nrow == nrow_) {
727  data_.resize(nrow * ncol);
728  ncol_ = ncol;
729  return;
730  }
731 
732  Matrix tmp(nrow, ncol);
733  const size_type n = std::min(nrow, nrow_);
734  const size_type m = std::min(ncol, ncol_);
735  for (size_type i = 0; i != m; ++i) {
736  std::copy_n(col_data(i), n, tmp.col_data(i));
737  }
738  swap(tmp);
739  }
740 }; // class Matrix
741 
743 template <typename CharT, typename Traits, typename T, MatrixLayout Layout,
744  typename Alloc>
745 inline std::basic_ostream<CharT, Traits> &operator<<(
746  std::basic_ostream<CharT, Traits> &os, const Matrix<T, Layout, Alloc> &mat)
747 {
748  if (!os) {
749  return os;
750  }
751 
752  os << mat.nrow() << ' ' << mat.ncol();
753  if (!os) {
754  return os;
755  }
756 
757  for (std::size_t j = 0; j != mat.ncol(); ++j) {
758  for (std::size_t i = 0; i != mat.nrow(); ++i) {
759  os << ' ' << mat(i, j);
760  }
761  }
762 
763  return os;
764 }
765 
767 template <typename CharT, typename Traits, typename T, MatrixLayout Layout,
768  typename Alloc>
769 inline std::basic_istream<CharT, Traits> &operator>>(
770  std::basic_istream<CharT, Traits> &is, Matrix<T, Layout, Alloc> &mat)
771 {
772  if (!is) {
773  return is;
774  }
775 
776  std::size_t nrow = 0;
777  std::size_t ncol = 0;
778  is >> nrow >> std::ws >> ncol;
779  if (!is) {
780  return is;
781  }
782 
783  Matrix<T, Layout, Alloc> tmp(nrow, ncol);
784  for (std::size_t j = 0; j != mat.ncol(); ++j) {
785  for (std::size_t i = 0; i != mat.nrow(); ++i) {
786  is >> std::ws >> tmp(i, j);
787  }
788  }
789  if (is) {
790  mat = std::move(tmp);
791  }
792 
793  return is;
794 }
795 
796 } // namespace mckl
797 
798 #endif // MCKL_CORE_MATRIX_HPP
const_col_range col(size_type i) const
Range of a column.
Definition: matrix.hpp:373
std::conditional_t< Layout==RowMajor, const_pointer, StepIterator< const_pointer > > const_row_iterator
Definition: matrix.hpp:75
Range< const_reverse_row_iterator > const_reverse_row_range
Definition: matrix.hpp:91
const_reverse_col_iterator col_rend(size_type j) const
Iterator to one before the beginning of a column.
Definition: matrix.hpp:325
const_col_range ccol(size_type i) const
Range of a column.
Definition: matrix.hpp:379
Matrix(size_type nrow, size_type ncol)
Construct an nrow by ncol matrix.
Definition: matrix.hpp:109
std::reverse_iterator< const_row_iterator > const_reverse_row_iterator
Definition: matrix.hpp:78
void clear()
Clear the matrix of all elements.
Definition: matrix.hpp:526
allocator_type get_allocator() const
Return the associated allocator.
Definition: matrix.hpp:166
size_type ncol() const
The number of columns.
Definition: matrix.hpp:488
void resize(size_type nrow, size_type ncol)
Resize the matrix.
Definition: matrix.hpp:506
Matrix() noexcept(std::is_nothrow_default_constructible< Vector< T, Alloc >>::value)
Construct an empty matrix.
Definition: matrix.hpp:102
friend bool operator==(const Matrix &m1, const Matrix &m2)
Compare equality.
Definition: matrix.hpp:564
const_row_iterator row_cbegin(size_type i) const
Iterator to the beginning of a row.
Definition: matrix.hpp:220
reverse_col_iterator col_rbegin(size_type j)
Iterator to the end of a column.
Definition: matrix.hpp:301
const_col_iterator col_end(size_type j) const
Iterator to one pass the end of a column.
Definition: matrix.hpp:292
const_iterator begin() const
Iterator to the upper left corner of the matrix.
Definition: matrix.hpp:172
reverse_row_iterator row_rbegin(size_type i)
Iterator to the end of a row.
Definition: matrix.hpp:238
Range< reverse_row_iterator > reverse_row_range
Definition: matrix.hpp:90
const_reference operator()(size_type i, size_type j) const
Access an element in the matrix.
Definition: matrix.hpp:431
const_iterator end() const
Iterator to one pass the lower right corner of the matrix.
Definition: matrix.hpp:181
const_reverse_iterator rend() const
Iterator one before the upper left corner of the matrix.
Definition: matrix.hpp:202
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
Definition: memory.hpp:435
STL namespace.
std::reverse_iterator< col_iterator > reverse_col_iterator
Definition: matrix.hpp:84
void swap(Matrix &other) noexcept(noexcept(data_.swap(other.data_)))
Swap two matrices.
Definition: matrix.hpp:550
Matrix container.
Definition: matrix.hpp:49
const_reverse_iterator crend() const
Iterator one before the upper left corner of the matrix.
Definition: matrix.hpp:205
const_row_iterator row_end(size_type i) const
Iterator to one pass the end of a row.
Definition: matrix.hpp:229
Range< const_row_iterator > const_row_range
Definition: matrix.hpp:89
bool empty() const
If the matrix is empty, i.e., nrow() * ncol() == 0
Definition: matrix.hpp:482
const_reverse_iterator rbegin() const
Iterator to the lower right corner of the matrix.
Definition: matrix.hpp:190
const_reference at(size_type i, size_type j) const
Access an element in the matrix with bound checking.
Definition: matrix.hpp:414
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: matrix.hpp:70
const_pointer row_data(size_type i) const
Pointer to the first element of a row.
Definition: matrix.hpp:449
reverse_row_range rrow(size_type i)
Range of a row in reverse order.
Definition: matrix.hpp:352
iterator end()
Iterator to one pass the lower right corner of the matrix.
Definition: matrix.hpp:178
const_iterator cend() const
Iterator to one pass the lower right corner of the matrix.
Definition: matrix.hpp:184
col_range col(size_type i)
Range of a column.
Definition: matrix.hpp:370
value_type * pointer
Definition: matrix.hpp:64
Range< const_col_iterator > const_col_range
Definition: matrix.hpp:94
std::reverse_iterator< row_iterator > reverse_row_iterator
Definition: matrix.hpp:76
pointer row_data(size_type i)
Pointer to the first element of a row.
Definition: matrix.hpp:443
const_reverse_col_iterator col_rbegin(size_type j) const
Iterator to the end of a column.
Definition: matrix.hpp:307
std::size_t size_type
Definition: matrix.hpp:60
const_col_iterator col_begin(size_type j) const
Iterator to the beginning of a column.
Definition: matrix.hpp:280
pointer col_data(size_type j)
Pointer to the beginning of a column.
Definition: matrix.hpp:461
row_iterator row_end(size_type i)
Iterator to one pass the end of a row.
Definition: matrix.hpp:226
static constexpr MatrixLayout layout()
The layout of the matrix.
Definition: matrix.hpp:479
size_type ldim() const
The number of elements in the leading dimension.
Definition: matrix.hpp:491
const_reverse_col_iterator col_crend(size_type j) const
Iterator to one before the beginning of a column.
Definition: matrix.hpp:331
size_type row_stride() const
The stride of row-wise access through row_data()
Definition: matrix.hpp:455
friend bool is_equal(const Matrix &m1, const Matrix &m2)
Compare equality.
Definition: matrix.hpp:582
void push_back_col(InputIter first)
Insert a new coloumn at the right.
Definition: matrix.hpp:543
reverse_iterator rend()
Iterator one before the upper left corner of the matrix.
Definition: matrix.hpp:199
const_row_iterator row_begin(size_type i) const
Iterator to the beginning of a row.
Definition: matrix.hpp:217
Matrix & operator=(Matrix &&other) noexcept(noexcept(data_.swap(other.data_)))
Move assignment operator.
Definition: matrix.hpp:130
pointer data()
Pointer to the upper left corner of the matrix.
Definition: matrix.hpp:437
Range< row_iterator > row_range
Definition: matrix.hpp:88
void shrink_to_fit()
Release memory no longer needed.
Definition: matrix.hpp:523
const_reverse_col_iterator col_crbegin(size_type j) const
Iterator to the end of a column.
Definition: matrix.hpp:313
const_reverse_col_range crcol(size_type i) const
Range of a column in reverse order.
Definition: matrix.hpp:397
const_reverse_row_range crrow(size_type i) const
Range of a row in reverse order.
Definition: matrix.hpp:364
std::reverse_iterator< iterator > reverse_iterator
Definition: matrix.hpp:69
Range< col_iterator > col_range
Definition: matrix.hpp:93
const_row_iterator row_cend(size_type i) const
Iterator to one pass the end of a row.
Definition: matrix.hpp:232
friend bool operator!=(const Matrix &m1, const Matrix &m2)
Compare inequality.
Definition: matrix.hpp:576
size_type size() const
The total number of elements.
Definition: matrix.hpp:494
iterator begin()
Iterator to the upper left corner of the matrix.
Definition: matrix.hpp:169
value_type & reference
Definition: matrix.hpp:62
const_pointer col_data(size_type j) const
Pointer to the beginning of a column.
Definition: matrix.hpp:467
row_iterator row_begin(size_type i)
Iterator to the beginning of a row.
Definition: matrix.hpp:211
col_iterator col_begin(size_type i)
Iterator to the beginning of a column.
Definition: matrix.hpp:274
friend void swap(Matrix &m1, Matrix &m2) noexcept(noexcept(m1.swap(m2)))
Swap two matrices.
Definition: matrix.hpp:558
const_reverse_row_range rrow(size_type i) const
Range of a row in reverse order.
Definition: matrix.hpp:358
const_reverse_row_iterator row_crbegin(size_type i) const
Iterator to the end of a row.
Definition: matrix.hpp:250
const value_type * const_pointer
Definition: matrix.hpp:65
Range< reverse_col_iterator > reverse_col_range
Definition: matrix.hpp:95
std::conditional_t< Layout==ColMajor, const_pointer, StepIterator< const_pointer > > const_col_iterator
Definition: matrix.hpp:83
row_range row(size_type i)
Range of a row.
Definition: matrix.hpp:337
const_pointer data() const
Pointer to the upper left corner of the matrix.
Definition: matrix.hpp:440
Range< const_reverse_col_iterator > const_reverse_col_range
Definition: matrix.hpp:96
Definition: mcmc.hpp:40
constexpr MatrixLayout ColMajor
Definition: defines.hpp:48
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Matrix< T, Layout, Alloc > &mat)
Output operator.
Definition: matrix.hpp:745
reverse_row_iterator row_rend(size_type i)
Iterator to one before the beginning of a row.
Definition: matrix.hpp:256
const_col_iterator col_cbegin(size_type j) const
Iterator to the beginning of a column.
Definition: matrix.hpp:283
const_col_iterator col_cend(size_type j) const
Iterator to one pass the end of a column.
Definition: matrix.hpp:295
Iterator adapter which increment the base iterator in multiple steps.
Definition: iterator.hpp:44
Matrix(Matrix &&other) noexcept(std::is_nothrow_move_constructible< Vector< T, Alloc >>::value)
Move constructor.
Definition: matrix.hpp:118
void reserve(size_type n, size_type m)
Reserve storage space for the matrix.
Definition: matrix.hpp:497
Matrix< T, Layout==RowMajor ? ColMajor :RowMajor, Alloc > transpose_type
Definition: matrix.hpp:99
Standard library compatible allocator with policies.
Definition: memory.hpp:322
const_reverse_row_iterator row_rbegin(size_type i) const
Iterator to the end of a row.
Definition: matrix.hpp:244
col_iterator col_end(size_type j)
Iterator to one pass the end of a column.
Definition: matrix.hpp:289
size_type col_stride() const
The stride size of column-wise access through col_data()
Definition: matrix.hpp:473
size_type nrow() const
The number of rows.
Definition: matrix.hpp:485
std::conditional_t< Layout==ColMajor, pointer, StepIterator< pointer > > col_iterator
Definition: matrix.hpp:81
reverse_col_range rcol(size_type i)
Range of a column in reverse order.
Definition: matrix.hpp:385
reverse_col_iterator col_rend(size_type j)
Iterator to one before the beginning of a column.
Definition: matrix.hpp:319
std::reverse_iterator< const_col_iterator > const_reverse_col_iterator
Definition: matrix.hpp:86
std::ptrdiff_t difference_type
Definition: matrix.hpp:61
const value_type & const_reference
Definition: matrix.hpp:63
void push_back_row(InputIter first)
Insert a new row at the bottom.
Definition: matrix.hpp:535
const_reverse_iterator crbegin() const
Iterator to the lower right corner of the matrix.
Definition: matrix.hpp:193
reference operator()(size_type i, size_type j)
Access an element in the matrix.
Definition: matrix.hpp:425
std::conditional_t< Layout==RowMajor, pointer, StepIterator< pointer > > row_iterator
Definition: matrix.hpp:73
const_pointer const_iterator
Definition: matrix.hpp:68
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, Matrix< T, Layout, Alloc > &mat)
Input operator.
Definition: matrix.hpp:769
Matrix & operator=(const Matrix &)=default
Copy assignment operator.
reference at(size_type i, size_type j)
Access an element in the matrix with bound checking.
Definition: matrix.hpp:403
const_reverse_col_range rcol(size_type i) const
Range of a column in reverse order.
Definition: matrix.hpp:391
const_reverse_row_iterator row_crend(size_type i) const
Iterator to one before the beginning of a row.
Definition: matrix.hpp:268
reverse_iterator rbegin()
Iterator to the lower right corner of the matrix.
Definition: matrix.hpp:187
const_row_range crow(size_type i) const
Range of a row.
Definition: matrix.hpp:346
const_iterator cbegin() const
Iterator to the upper left corner of the matrix.
Definition: matrix.hpp:175
const_row_range row(size_type i) const
Range of a row.
Definition: matrix.hpp:340
MatrixLayout
Matrix layout.
Definition: defines.hpp:46
const_reverse_row_iterator row_rend(size_type i) const
Iterator to one before the beginning of a row.
Definition: matrix.hpp:262