Chemical Data Processing Library C++ API - Version 1.2.0
Matrix.hpp
Go to the documentation of this file.
1 /*
2  * Matrix.hpp
3  *
4  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
27 #ifndef CDPL_MATH_MATRIX_HPP
28 #define CDPL_MATH_MATRIX_HPP
29 
30 #include <cstddef>
31 #include <cstdint>
32 #include <algorithm>
33 #include <vector>
34 #include <limits>
35 #include <unordered_map>
36 #include <type_traits>
37 #include <utility>
38 #include <initializer_list>
39 #include <memory>
40 
41 #include "CDPL/Math/Check.hpp"
45 #include "CDPL/Math/Functional.hpp"
46 #include "CDPL/Math/TypeTraits.hpp"
49 #include "CDPL/Base/Exceptions.hpp"
50 
51 
52 namespace CDPL
53 {
54 
55  namespace Math
56  {
57 
58  template <typename M>
59  class MatrixReference : public MatrixExpression<MatrixReference<M> >
60  {
61 
63 
64  public:
65  typedef M MatrixType;
66  typedef typename M::ValueType ValueType;
67  typedef typename std::conditional<std::is_const<M>::value,
68  typename M::ConstReference,
69  typename M::Reference>::type Reference;
70  typedef typename M::ConstReference ConstReference;
71  typedef typename M::SizeType SizeType;
72  typedef typename M::DifferenceType DifferenceType;
74  typedef const SelfType ConstClosureType;
75 
77  data(m) {}
78 
80  {
81  return data(i, j);
82  }
83 
85  {
86  return data(i, j);
87  }
88 
90  {
91  return data.getSize1();
92  }
93 
95  {
96  return data.getSize2();
97  }
98 
100  {
101  return data.getMaxSize();
102  }
103 
105  {
106  return data.getMaxSize1();
107  }
108 
110  {
111  return data.getMaxSize2();
112  }
113 
114  bool isEmpty() const
115  {
116  return data.isEmpty();
117  }
118 
119  const MatrixType& getData() const
120  {
121  return data;
122  }
123 
125  {
126  return data;
127  }
128 
130  {
131  data.operator=(r.data);
132  return *this;
133  }
134 
135  template <typename E>
137  {
138  data.operator=(e);
139  return *this;
140  }
141 
142  template <typename E>
144  {
145  data.operator+=(e);
146  return *this;
147  }
148 
149  template <typename E>
151  {
152  data.operator-=(e);
153  return *this;
154  }
155 
156  template <typename T>
157  typename std::enable_if<IsScalar<T>::value, MatrixReference>::type& operator*=(const T& t)
158  {
159  data.operator*=(t);
160  return *this;
161  }
162 
163  template <typename T>
164  typename std::enable_if<IsScalar<T>::value, MatrixReference>::type& operator/=(const T& t)
165  {
166  data.operator/=(t);
167  return *this;
168  }
169 
170  template <typename E>
172  {
173  data.assign(e);
174  return *this;
175  }
176 
177  template <typename E>
179  {
180  data.plusAssign(e);
181  return *this;
182  }
183 
184  template <typename E>
186  {
187  data.minusAssign(e);
188  return *this;
189  }
190 
192  {
193  data.swap(r.data);
194  }
195 
196  friend void swap(MatrixReference& r1, MatrixReference& r2)
197  {
198  r1.swap(r2);
199  }
200 
201  private:
202  MatrixType& data;
203  };
204 
205  template <typename T, typename A>
206  class Matrix;
207  template <typename T, typename A>
208  class Vector;
209 
210  template <typename T>
211  class InitListMatrix : public MatrixContainer<InitListMatrix<T> >
212  {
213 
214  public:
216  typedef std::initializer_list<std::initializer_list<T> > InitializerListType;
217  typedef typename InitializerListType::value_type::value_type ValueType;
218  typedef typename InitializerListType::value_type::const_reference ConstReference;
219  typedef typename InitializerListType::value_type::reference Reference;
220  typedef typename InitializerListType::size_type SizeType;
221  typedef typename std::ptrdiff_t DifferenceType;
223  typedef const SelfType ConstClosureType;
226 
228  list(l), size2(0)
229  {
230  for (const auto& r : l)
231  size2 = std::max(size2, r.size());
232  }
233 
235  {
236  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
237 
238  if (j >= (list.begin() + i)->size())
239  return zero;
240 
241  return *((list.begin() + i)->begin() + j);
242  }
243 
245  {
246  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
247 
248  if (j >= (list.begin() + i)->size())
249  return zero;
250 
251  return *((list.begin() + i)->begin() + j);
252  }
253 
255  {
256  return list.size();
257  }
258 
260  {
261  return size2;
262  }
263 
264  bool isEmpty() const
265  {
266  return (size2 == 0 || list.size() == 0);
267  }
268 
269  private:
270  InitializerListType list;
271  SizeType size2;
272  static const ValueType zero;
273  };
274 
275  template <typename T>
276  const typename InitListMatrix<T>::ValueType InitListMatrix<T>::zero = InitListMatrix<T>::ValueType();
277 
278  template <typename T, typename A = std::vector<T> >
279  class Matrix : public MatrixContainer<Matrix<T, A> >
280  {
281 
282  typedef Matrix<T, A> SelfType;
283 
284  public:
285  typedef T ValueType;
286  typedef T& Reference;
287  typedef const T& ConstReference;
288  typedef typename A::size_type SizeType;
289  typedef typename A::difference_type DifferenceType;
290  typedef A ArrayType;
291  typedef T* Pointer;
292  typedef const T* ConstPointer;
297  typedef std::shared_ptr<SelfType> SharedPointer;
298  typedef std::initializer_list<std::initializer_list<T> > InitializerListType;
299 
301  size1(0), size2(0), data() {}
302 
304  size1(m), size2(n), data(storageSize(m, n)) {}
305 
307  size1(m), size2(n), data(storageSize(m, n), v) {}
308 
309  Matrix(const Matrix& m):
310  size1(m.size1), size2(m.size2), data(m.data) {}
311 
313  size1(0), size2(0), data()
314  {
315  swap(m);
316  }
317 
319  size1(0), size2(0), data()
320  {
321  assign(l);
322  }
323 
324  template <typename E>
326  size1(e().getSize1()), size2(e().getSize2()), data(storageSize(e().getSize1(), e().getSize2()))
327  {
328  matrixAssignMatrix<ScalarAssignment>(*this, e);
329  }
330 
332  {
333  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
334  return data[i * getSize2() + j];
335  }
336 
338  {
339  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
340  return data[i * getSize2() + j];
341  }
342 
343  bool isEmpty() const
344  {
345  return data.empty();
346  }
347 
349  {
350  return size1;
351  }
352 
354  {
355  return size2;
356  }
357 
359  {
360  return data.max_size();
361  }
362 
364  {
365  return data;
366  }
367 
368  const ArrayType& getData() const
369  {
370  return data;
371  }
372 
374  {
375  data = m.data;
376  size1 = m.size1;
377  size2 = m.size2;
378  return *this;
379  }
380 
382  {
383  swap(m);
384  return *this;
385  }
386 
387  template <typename C>
389  {
390  return assign(c);
391  }
392 
394  {
395  return assign(l);
396  }
397 
398  template <typename E>
400  {
401  Matrix tmp(e);
402  swap(tmp);
403  return *this;
404  }
405 
406  template <typename C>
408  {
409  return plusAssign(c);
410  }
411 
413  {
414  return plusAssign(l);
415  }
416 
417  template <typename E>
419  {
420  Matrix tmp(*this + e);
421  swap(tmp);
422  return *this;
423  }
424 
425  template <typename C>
427  {
428  return minusAssign(c);
429  }
430 
432  {
433  return minusAssign(l);
434  }
435 
436  template <typename E>
438  {
439  Matrix tmp(*this - e);
440  swap(tmp);
441  return *this;
442  }
443 
444  template <typename T1>
445  typename std::enable_if<IsScalar<T1>::value, Matrix>::type& operator*=(const T1& t)
446  {
447  matrixAssignScalar<ScalarMultiplicationAssignment>(*this, t);
448  return *this;
449  }
450 
451  template <typename T1>
452  typename std::enable_if<IsScalar<T1>::value, Matrix>::type& operator/=(const T1& t)
453  {
454  matrixAssignScalar<ScalarDivisionAssignment>(*this, t);
455  return *this;
456  }
457 
458  template <typename E>
460  {
461  resize(e().getSize1(), e().getSize2(), false);
462  matrixAssignMatrix<ScalarAssignment>(*this, e);
463  return *this;
464  }
465 
467  {
469  resize(ilm.getSize1(), ilm.getSize2(), false);
470  matrixAssignMatrix<ScalarAssignment>(*this, ilm);
471  return *this;
472  }
473 
474  template <typename E>
476  {
477  matrixAssignMatrix<ScalarAdditionAssignment>(*this, e);
478  return *this;
479  }
480 
482  {
483  matrixAssignMatrix<ScalarAdditionAssignment>(*this, InitListMatrix<ValueType>(l));
484  return *this;
485  }
486 
487  template <typename E>
489  {
490  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, e);
491  return *this;
492  }
493 
495  {
496  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, InitListMatrix<ValueType>(l));
497  return *this;
498  }
499 
500  void swap(Matrix& m)
501  {
502  if (this != &m) {
503  std::swap(data, m.data);
504  std::swap(size1, m.size1);
505  std::swap(size2, m.size2);
506  }
507  }
508 
509  friend void swap(Matrix& m1, Matrix& m2)
510  {
511  m1.swap(m2);
512  }
513 
514  void clear(const ValueType& v = ValueType())
515  {
516  std::fill(data.begin(), data.end(), v);
517  }
518 
519  void resize(SizeType m, SizeType n, bool preserve = true, const ValueType& v = ValueType())
520  {
521  if (size1 == m && size2 == n)
522  return;
523 
524  if (preserve) {
525  Matrix tmp(m, n, v);
526 
527  for (SizeType i = 0, min_size1 = std::min(size1, m); i < min_size1; i++)
528  for (SizeType j = 0, min_size2 = std::min(size2, n); j < min_size2; j++)
529  tmp(i, j) = (*this)(i, j);
530 
531  swap(tmp);
532 
533  } else {
534  data.resize(storageSize(m, n), v);
535  size1 = m;
536  size2 = n;
537  }
538  }
539 
540  private:
541  SizeType storageSize(SizeType m, SizeType n)
542  {
543  CDPL_MATH_CHECK(n == 0 || m <= data.max_size() / n, "Maximum size exceeded", Base::SizeError);
544  return (m * n);
545  }
546 
547  SizeType size1;
548  SizeType size2;
549  ArrayType data;
550  };
551 
552  template <typename T, typename A = std::unordered_map<std::uint64_t, T> >
553  class SparseMatrix : public MatrixContainer<SparseMatrix<T, A> >
554  {
555 
556  typedef SparseMatrix<T> SelfType;
557 
558  public:
559  typedef T ValueType;
560  typedef typename A::key_type KeyType;
562  typedef const T& ConstReference;
563  typedef std::uint32_t SizeType;
564  typedef std::ptrdiff_t DifferenceType;
565  typedef A ArrayType;
566  typedef T* Pointer;
567  typedef const T* ConstPointer;
572  typedef std::shared_ptr<SelfType> SharedPointer;
573  typedef std::initializer_list<std::initializer_list<T> > InitializerListType;
574 
576  size1(0), size2(0), data() {}
577 
579  size1(m), size2(n), data()
580  {
581  CDPL_MATH_CHECK((n == 0 || m <= data.max_size() / n), "Maximum size exceeded", Base::SizeError);
582  }
583 
585  size1(m.size1), size2(m.size2), data(m.data) {}
586 
588  size1(0), size2(0), data()
589  {
590  swap(m);
591  }
592 
594  size1(0), size2(0), data()
595  {
596  assign(l);
597  }
598 
599  template <typename E>
601  size1(e().getSize1()), size2(e().getSize2()), data()
602  {
603  CDPL_MATH_CHECK((size1 == 0 || size2 <= data.max_size() / size1), "Maximum size exceeded", Base::SizeError);
604  matrixAssignMatrix<ScalarAssignment>(*this, e);
605  }
606 
608  {
609  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
610 
611  return Reference(*this, makeKey(i, j));
612  }
613 
615  {
616  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
617 
618  typename ArrayType::const_iterator it = data.find(makeKey(i, j));
619 
620  if (it == data.end())
621  return zero;
622 
623  return it->second;
624  }
625 
627  {
628  return data.size();
629  }
630 
631  bool isEmpty() const
632  {
633  return (size1 == 0 || size2 == 0);
634  }
635 
637  {
638  return size1;
639  }
640 
642  {
643  return size2;
644  }
645 
646  typename ArrayType::size_type getMaxSize() const
647  {
648  return data.max_size();
649  }
650 
652  {
653  return data;
654  }
655 
656  const ArrayType& getData() const
657  {
658  return data;
659  }
660 
662  {
663  data = m.data;
664  size1 = m.size1;
665  size2 = m.size2;
666  return *this;
667  }
668 
670  {
671  swap(m);
672  return *this;
673  }
674 
675  template <typename C>
677  {
678  return assign(c);
679  }
680 
682  {
683  return assign(l);
684  }
685 
686  template <typename E>
688  {
689  SparseMatrix tmp(e);
690  swap(tmp);
691  return *this;
692  }
693 
694  template <typename C>
696  {
697  return plusAssign(c);
698  }
699 
701  {
702  return plusAssign(l);
703  }
704 
705  template <typename E>
707  {
708  SparseMatrix tmp(*this + e);
709  swap(tmp);
710  return *this;
711  }
712 
713  template <typename C>
715  {
716  return minusAssign(c);
717  }
718 
720  {
721  return minusAssign(l);
722  }
723 
724  template <typename E>
726  {
727  SparseMatrix tmp(*this - e);
728  swap(tmp);
729  return *this;
730  }
731 
732  template <typename T1>
733  typename std::enable_if<IsScalar<T1>::value, SparseMatrix>::type& operator*=(const T1& t)
734  {
735  matrixAssignScalar<ScalarMultiplicationAssignment>(*this, t);
736  return *this;
737  }
738 
739  template <typename T1>
740  typename std::enable_if<IsScalar<T1>::value, SparseMatrix>::type& operator/=(const T1& t)
741  {
742  matrixAssignScalar<ScalarDivisionAssignment>(*this, t);
743  return *this;
744  }
745 
746  template <typename E>
748  {
749  resize(e().getSize1(), e().getSize2());
750  matrixAssignMatrix<ScalarAssignment>(*this, e);
751  return *this;
752  }
753 
755  {
757  resize(ilm.getSize1(), ilm.getSize2());
758  matrixAssignMatrix<ScalarAssignment>(*this, ilm);
759  return *this;
760  }
761 
762  template <typename E>
764  {
765  matrixAssignMatrix<ScalarAdditionAssignment>(*this, e);
766  return *this;
767  }
768 
770  {
771  matrixAssignMatrix<ScalarAdditionAssignment>(*this, InitListMatrix<ValueType>(l));
772  return *this;
773  }
774 
775  template <typename E>
777  {
778  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, e);
779  return *this;
780  }
781 
783  {
784  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, InitListMatrix<ValueType>(l));
785  return *this;
786  }
787 
789  {
790  if (this != &m) {
791  std::swap(data, m.data);
792  std::swap(size1, m.size1);
793  std::swap(size2, m.size2);
794  }
795  }
796 
797  friend void swap(SparseMatrix& m1, SparseMatrix& m2)
798  {
799  m1.swap(m2);
800  }
801 
802  void clear()
803  {
804  data.clear();
805  }
806 
808  {
809  CDPL_MATH_CHECK((n == 0 || m <= data.max_size() / n), "Maximum size exceeded", Base::SizeError);
810 
811  for (typename ArrayType::iterator it = data.begin(); it != data.end();) {
812  const KeyType& key = it->first;
813 
814  if (getRowIdx(key) >= m || getColIdx(key) >= n)
815  it = data.erase(it);
816  else
817  ++it;
818  }
819 
820  size1 = m;
821  size2 = n;
822  }
823 
824  private:
825  static KeyType makeKey(SizeType i, SizeType j)
826  {
827  return ((KeyType(i) << (sizeof(SizeType) * 8)) + j);
828  }
829 
830  static SizeType getRowIdx(const KeyType& key)
831  {
832  return (key >> (sizeof(SizeType) * 8));
833  }
834 
835  static SizeType getColIdx(const KeyType& key)
836  {
837  return (key & KeyType(~SizeType()));
838  }
839 
840  SizeType size1;
841  SizeType size2;
842  ArrayType data;
843  static const ValueType zero;
844  };
845 
846  template <typename T, typename A>
847  const typename SparseMatrix<T, A>::ValueType SparseMatrix<T, A>::zero = SparseMatrix<T, A>::ValueType();
848 
849  template <typename T, std::size_t N>
850  class BoundedVector;
851 
852  template <typename T, std::size_t M, std::size_t N>
853  class BoundedMatrix : public MatrixContainer<BoundedMatrix<T, M, N> >
854  {
855 
857 
858  public:
859  typedef T ValueType;
860  typedef T& Reference;
861  typedef const T& ConstReference;
862  typedef std::size_t SizeType;
863  typedef std::ptrdiff_t DifferenceType;
864  typedef ValueType ArrayType[M][N];
865  typedef T (*ArrayPointer)[N];
866  typedef const T (*ConstArrayPointer)[N];
867  typedef T* Pointer;
868  typedef const T* ConstPointer;
873  typedef std::shared_ptr<SelfType> SharedPointer;
874  typedef std::initializer_list<std::initializer_list<T> > InitializerListType;
875 
876  static const SizeType MaxSize1 = M;
877  static const SizeType MaxSize2 = N;
878 
880  size1(0), size2(0) {}
881 
883  size1(0), size2(0)
884  {
885  resize(m, n);
886  }
887 
889  size1(0), size2(0)
890  {
891  resize(m, n, v);
892  }
893 
895  size1(m.size1), size2(m.size2)
896  {
897  for (SizeType i = 0; i < size1; i++)
898  std::copy(m.data[i], m.data[i] + size2, data[i]);
899  }
900 
902  size1(0), size2(0)
903  {
904  assign(l);
905  }
906 
907  template <typename E>
909  size1(0), size2(0)
910  {
911  resize(e().getSize1(), e().getSize2());
912  matrixAssignMatrix<ScalarAssignment>(*this, e);
913  }
914 
916  {
917  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
918  return data[i][j];
919  }
920 
922  {
923  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
924  return data[i][j];
925  }
926 
927  bool isEmpty() const
928  {
929  return (size1 == 0 || size2 == 0);
930  }
931 
933  {
934  return size1;
935  }
936 
938  {
939  return size2;
940  }
941 
943  {
944  return M;
945  }
946 
948  {
949  return N;
950  }
951 
953  {
954  return data;
955  }
956 
958  {
959  return data;
960  }
961 
963  {
964  if (this != &m) {
965  for (SizeType i = 0; i < m.size1; i++)
966  std::copy(m.data[i], m.data[i] + m.size2, data[i]);
967 
968  size1 = m.size1;
969  size2 = m.size2;
970  }
971 
972  return *this;
973  }
974 
975  template <typename C>
977  {
978  return assign(c);
979  }
980 
982  {
983  return assign(l);
984  }
985 
986  template <typename E>
988  {
989  BoundedMatrix tmp(e);
990  return this-> operator=(tmp);
991  }
992 
993  template <typename C>
995  {
996  return plusAssign(c);
997  }
998 
1000  {
1001  return plusAssign(l);
1002  }
1003 
1004  template <typename E>
1006  {
1007  BoundedMatrix tmp(*this + e);
1008  return this-> operator=(tmp);
1009  }
1010 
1011  template <typename C>
1013  {
1014  return minusAssign(c);
1015  }
1016 
1018  {
1019  return minusAssign(l);
1020  }
1021 
1022  template <typename E>
1024  {
1025  BoundedMatrix tmp(*this - e);
1026  return this-> operator=(tmp);
1027  }
1028 
1029  template <typename T1>
1030  typename std::enable_if<IsScalar<T1>::value, BoundedMatrix>::type& operator*=(const T1& v)
1031  {
1032  matrixAssignScalar<ScalarMultiplicationAssignment>(*this, v);
1033  return *this;
1034  }
1035 
1036  template <typename T1>
1037  typename std::enable_if<IsScalar<T1>::value, BoundedMatrix>::type& operator/=(const T1& v)
1038  {
1039  matrixAssignScalar<ScalarDivisionAssignment>(*this, v);
1040  return *this;
1041  }
1042 
1043  template <typename E>
1045  {
1046  resize(e().getSize1(), e().getSize2());
1047  matrixAssignMatrix<ScalarAssignment>(*this, e);
1048  return *this;
1049  }
1050 
1052  {
1054  resize(ilm.getSize1(), ilm.getSize2());
1055  matrixAssignMatrix<ScalarAssignment>(*this, ilm);
1056  return *this;
1057  }
1058 
1059  template <typename E>
1061  {
1062  matrixAssignMatrix<ScalarAdditionAssignment>(*this, e);
1063  return *this;
1064  }
1065 
1067  {
1068  matrixAssignMatrix<ScalarAdditionAssignment>(*this, InitListMatrix<ValueType>(l));
1069  return *this;
1070  }
1071 
1072  template <typename E>
1074  {
1075  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, e);
1076  return *this;
1077  }
1078 
1080  {
1081  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, InitListMatrix<ValueType>(l));
1082  return *this;
1083  }
1084 
1086  {
1087  if (this != &m) {
1088  SizeType max_size1 = std::max(size1, m.size1);
1089  SizeType max_size2 = std::max(size2, m.size2);
1090 
1091  for (SizeType i = 0; i < max_size1; i++)
1092  std::swap_ranges(data[i], data[i] + max_size2, m.data[i]);
1093 
1094  std::swap(size1, m.size1);
1095  std::swap(size2, m.size2);
1096  }
1097  }
1098 
1099  friend void swap(BoundedMatrix& m1, BoundedMatrix& m2)
1100  {
1101  m1.swap(m2);
1102  }
1103 
1104  void clear(const ValueType& v = ValueType())
1105  {
1106  for (SizeType i = 0; i < size1; i++)
1107  std::fill(data[i], data[i] + size2, v);
1108  }
1109 
1111  {
1114 
1115  size1 = m;
1116  size2 = n;
1117  }
1118 
1119  void resize(SizeType m, SizeType n, const ValueType& v)
1120  {
1123 
1124  if (n > size2) {
1125  SizeType min_size1 = std::min(size1, m);
1126 
1127  for (SizeType i = 0; i < min_size1; i++)
1128  std::fill(data[i] + size2, data[i] + n, v);
1129  }
1130 
1131  if (m > size1)
1132  for (SizeType i = size1; i < m; i++)
1133  std::fill(data[i], data[i] + n, v);
1134 
1135  size1 = m;
1136  size2 = n;
1137  }
1138 
1139  private:
1140  SizeType size1;
1141  SizeType size2;
1142  ArrayType data;
1143  };
1144 
1145  template <typename T, std::size_t M, std::size_t N>
1147  template <typename T, std::size_t M, std::size_t N>
1149 
1150  template <typename T, std::size_t M, std::size_t N>
1151  class CMatrix : public MatrixContainer<CMatrix<T, M, N> >
1152  {
1153 
1154  typedef CMatrix<T, M, N> SelfType;
1155 
1156  public:
1157  typedef T ValueType;
1158  typedef T& Reference;
1159  typedef const T& ConstReference;
1160  typedef std::size_t SizeType;
1161  typedef std::ptrdiff_t DifferenceType;
1162  typedef ValueType ArrayType[M][N];
1163  typedef T (*ArrayPointer)[N];
1164  typedef const T (*ConstArrayPointer)[N];
1165  typedef T* Pointer;
1166  typedef const T* ConstPointer;
1171  typedef std::shared_ptr<SelfType> SharedPointer;
1172  typedef std::initializer_list<std::initializer_list<T> > InitializerListType;
1173 
1174  static const SizeType Size1 = M;
1175  static const SizeType Size2 = N;
1176 
1178  {
1179  for (SizeType i = 0; i < M; i++)
1180  std::fill(data[i], data[i] + N, ValueType());
1181  }
1182 
1183  explicit CMatrix(const ValueType& v)
1184  {
1185  for (SizeType i = 0; i < M; i++)
1186  std::fill(data[i], data[i] + N, v);
1187  }
1188 
1190  {
1191  for (SizeType i = 0; i < M; i++)
1192  std::copy(m.data[i], m.data[i] + N, data[i]);
1193  }
1194 
1196  {
1197  assign(l);
1198  }
1199 
1200  template <typename E>
1202  {
1203  matrixAssignMatrix<ScalarAssignment>(*this, e);
1204  }
1205 
1207  {
1208  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
1209  return data[i][j];
1210  }
1211 
1213  {
1214  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
1215  return data[i][j];
1216  }
1217 
1218  bool isEmpty() const
1219  {
1220  return (M == 0 || N == 0);
1221  }
1222 
1224  {
1225  return M;
1226  }
1227 
1229  {
1230  return N;
1231  }
1232 
1234  {
1235  return M;
1236  }
1237 
1239  {
1240  return N;
1241  }
1242 
1244  {
1245  return data;
1246  }
1247 
1249  {
1250  return data;
1251  }
1252 
1254  {
1255  if (this != &m) {
1256  for (SizeType i = 0; i < M; i++)
1257  std::copy(m.data[i], m.data[i] + N, data[i]);
1258  }
1259 
1260  return *this;
1261  }
1262 
1263  template <typename C>
1265  {
1266  return assign(c);
1267  }
1268 
1269  template <typename T1>
1271  {
1272  return assign(l);
1273  }
1274 
1275  template <typename E>
1277  {
1278  CMatrix tmp(e);
1279  return this->operator=(tmp);
1280  }
1281 
1282  template <typename C>
1284  {
1285  return plusAssign(c);
1286  }
1287 
1289  {
1290  return plusAssign(l);
1291  }
1292 
1293  template <typename E>
1295  {
1296  CMatrix tmp(*this + e);
1297  return this->operator=(tmp);
1298  }
1299 
1300  template <typename C>
1302  {
1303  return minusAssign(c);
1304  }
1305 
1307  {
1308  return minusAssign(l);
1309  }
1310 
1311  template <typename E>
1313  {
1314  CMatrix tmp(*this - e);
1315  return this->operator=(tmp);
1316  }
1317 
1318  template <typename T1>
1319  typename std::enable_if<IsScalar<T1>::value, CMatrix>::type& operator*=(const T1& t)
1320  {
1321  matrixAssignScalar<ScalarMultiplicationAssignment>(*this, t);
1322  return *this;
1323  }
1324 
1325  template <typename T1>
1326  typename std::enable_if<IsScalar<T1>::value, CMatrix>::type& operator/=(const T1& t)
1327  {
1328  matrixAssignScalar<ScalarDivisionAssignment>(*this, t);
1329  return *this;
1330  }
1331 
1332  template <typename E>
1334  {
1335  matrixAssignMatrix<ScalarAssignment>(*this, e);
1336  return *this;
1337  }
1338 
1340  {
1342 
1343  for (SizeType i = 0; i < n_rows; i++) {
1344  const auto& row = *(l.begin() + i);
1345 
1346  if (row.size() < N) {
1347  std::copy(row.begin(), row.end(), data[i]);
1348  std::fill(data[i] + row.size(), data[i] + N, ValueType());
1349 
1350  } else {
1352  std::copy(row.begin(), row.begin() + N, data[i]);
1353  }
1354  }
1355 
1356  for (SizeType i = n_rows; i < M; i++)
1357  std::fill(data[i], data[i] + N, ValueType());
1358 
1359  return *this;
1360  }
1361 
1362  template <typename E>
1364  {
1365  matrixAssignMatrix<ScalarAdditionAssignment>(*this, e);
1366  return *this;
1367  }
1368 
1370  {
1371  matrixAssignMatrix<ScalarAdditionAssignment>(*this, InitListMatrix<ValueType>(l));
1372  return *this;
1373  }
1374 
1375  template <typename E>
1377  {
1378  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, e);
1379  return *this;
1380  }
1381 
1383  {
1384  matrixAssignMatrix<ScalarSubtractionAssignment>(*this, InitListMatrix<ValueType>(l));
1385  return *this;
1386  }
1387 
1388  void swap(CMatrix& m)
1389  {
1390  if (this != &m) {
1391  for (SizeType i = 0; i < M; i++)
1392  std::swap_ranges(data[i], data[i] + N, m.data[i]);
1393  }
1394  }
1395 
1396  friend void swap(CMatrix& m1, CMatrix& m2)
1397  {
1398  m1.swap(m2);
1399  }
1400 
1401  void clear(const ValueType& v = ValueType())
1402  {
1403  for (SizeType i = 0; i < M; i++)
1404  std::fill(data[i], data[i] + N, v);
1405  }
1406 
1407  private:
1408  ArrayType data;
1409  };
1410 
1411  template <typename T, std::size_t M, std::size_t N>
1413  template <typename T, std::size_t M, std::size_t N>
1415 
1416  template <typename T>
1417  class ZeroMatrix : public MatrixContainer<ZeroMatrix<T> >
1418  {
1419 
1420  typedef ZeroMatrix<T> SelfType;
1421 
1422  public:
1423  typedef T ValueType;
1424  typedef const T& Reference;
1425  typedef const T& ConstReference;
1426  typedef std::size_t SizeType;
1427  typedef std::ptrdiff_t DifferenceType;
1432 
1434  size1(0), size2(0) {}
1435 
1437  size1(m), size2(n) {}
1438 
1440  size1(m.size1), size2(m.size2) {}
1441 
1443  {
1444  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
1445  return zero;
1446  }
1447 
1448  bool isEmpty() const
1449  {
1450  return (size1 == 0 || size2 == 0);
1451  }
1452 
1454  {
1455  return size1;
1456  }
1457 
1459  {
1460  return size2;
1461  }
1462 
1464  {
1465  return std::numeric_limits<SizeType>::max();
1466  }
1467 
1469  {
1470  return std::numeric_limits<SizeType>::max();
1471  }
1472 
1474  {
1475  if (this != &m) {
1476  size1 = m.size1;
1477  size2 = m.size2;
1478  }
1479 
1480  return *this;
1481  }
1482 
1484  {
1485  if (this != &m) {
1486  std::swap(size1, m.size1);
1487  std::swap(size2, m.size2);
1488  }
1489  }
1490 
1491  friend void swap(ZeroMatrix& m1, ZeroMatrix& m2)
1492  {
1493  m1.swap(m2);
1494  }
1495 
1497  {
1498  size1 = m;
1499  size2 = n;
1500  }
1501 
1502  private:
1503  SizeType size1;
1504  SizeType size2;
1505  static const ValueType zero;
1506  };
1507 
1508  template <typename T>
1509  const typename ZeroMatrix<T>::ValueType ZeroMatrix<T>::zero = ZeroMatrix<T>::ValueType();
1510 
1511  template <typename T>
1512  class ScalarMatrix : public MatrixContainer<ScalarMatrix<T> >
1513  {
1514 
1515  typedef ScalarMatrix<T> SelfType;
1516 
1517  public:
1518  typedef T ValueType;
1519  typedef const T& Reference;
1520  typedef const T& ConstReference;
1521  typedef std::size_t SizeType;
1522  typedef std::ptrdiff_t DifferenceType;
1527 
1529  size1(0), size2(0), value() {}
1530 
1532  size1(m), size2(n), value(v) {}
1533 
1535  size1(m.size1), size2(m.size2), value(m.value) {}
1536 
1538  {
1539  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
1540  return value;
1541  }
1542 
1543  bool isEmpty() const
1544  {
1545  return (size1 == 0 || size2 == 0);
1546  }
1547 
1549  {
1550  return size1;
1551  }
1552 
1554  {
1555  return size2;
1556  }
1557 
1559  {
1560  return std::numeric_limits<SizeType>::max();
1561  }
1562 
1564  {
1565  return std::numeric_limits<SizeType>::max();
1566  }
1567 
1569  {
1570  if (this != &m) {
1571  size1 = m.size1;
1572  size2 = m.size2;
1573  value = m.value;
1574  }
1575 
1576  return *this;
1577  }
1578 
1580  {
1581  if (this != &m) {
1582  std::swap(size1, m.size1);
1583  std::swap(size2, m.size2);
1584  std::swap(value, m.value);
1585  }
1586  }
1587 
1588  friend void swap(ScalarMatrix& m1, ScalarMatrix& m2)
1589  {
1590  m1.swap(m2);
1591  }
1592 
1594  {
1595  size1 = m;
1596  size2 = n;
1597  }
1598 
1599  private:
1600  SizeType size1;
1601  SizeType size2;
1602  ValueType value;
1603  };
1604 
1605  template <typename T>
1606  class IdentityMatrix : public MatrixContainer<IdentityMatrix<T> >
1607  {
1608 
1609  typedef IdentityMatrix<T> SelfType;
1610 
1611  public:
1612  typedef T ValueType;
1613  typedef const T& Reference;
1614  typedef const T& ConstReference;
1615  typedef std::size_t SizeType;
1616  typedef std::ptrdiff_t DifferenceType;
1621 
1623  size1(0), size2(0) {}
1624 
1626  size1(m), size2(n) {}
1627 
1629  size1(m.size1), size2(m.size2) {}
1630 
1632  {
1633  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
1634  return (i == j ? one : zero);
1635  }
1636 
1637  bool isEmpty() const
1638  {
1639  return (size1 == 0 || size2 == 0);
1640  }
1641 
1643  {
1644  return size1;
1645  }
1646 
1648  {
1649  return size2;
1650  }
1651 
1653  {
1654  return std::numeric_limits<SizeType>::max();
1655  }
1656 
1658  {
1659  return std::numeric_limits<SizeType>::max();
1660  }
1661 
1663  {
1664  if (this != &m) {
1665  size1 = m.size1;
1666  size2 = m.size2;
1667  }
1668 
1669  return *this;
1670  }
1671 
1673  {
1674  if (this != &m) {
1675  std::swap(size1, m.size1);
1676  std::swap(size2, m.size2);
1677  }
1678  }
1679 
1680  friend void swap(IdentityMatrix& m1, IdentityMatrix& m2)
1681  {
1682  m1.swap(m2);
1683  }
1684 
1686  {
1687  size1 = m;
1688  size2 = n;
1689  }
1690 
1691  private:
1692  SizeType size1;
1693  SizeType size2;
1694  static const ValueType zero;
1695  static const ValueType one;
1696  };
1697 
1698  template <typename T>
1699  const typename IdentityMatrix<T>::ValueType IdentityMatrix<T>::zero = IdentityMatrix<T>::ValueType();
1700  template <typename T>
1701  const typename IdentityMatrix<T>::ValueType IdentityMatrix<T>::one = IdentityMatrix<T>::ValueType(1);
1702 
1703  template <typename M>
1705  {};
1706 
1707  template <typename M>
1709  {};
1710 
1711  template <typename M>
1713  {};
1714 
1715  template <typename M>
1717  {};
1718 
1719  template <typename E>
1720  typename E::ValueType
1722  {
1723  typedef typename E::ValueType ValueType;
1724  typedef typename Matrix<ValueType>::SizeType SizeType;
1725 
1726  Matrix<ValueType> lu(e);
1727  std::vector<SizeType> pv(lu.getSize1());
1728  std::size_t num_row_swaps;
1729 
1730  luDecompose(lu, pv, num_row_swaps);
1731 
1732  ValueType res(1);
1733  SizeType size = std::min(lu.getSize1(), lu.getSize2());
1734 
1735  for (SizeType i = 0; i < size; i++)
1736  res *= lu(i, i);
1737 
1738  return (num_row_swaps % 2 == 0 ? res : -res);
1739  }
1740 
1741  template <typename C>
1742  typename C::ValueType
1744  {
1745  typedef typename C::ValueType ValueType;
1746  typedef typename MatrixTemporaryTraits<C>::Type CTemporaryType;
1747  typedef typename CTemporaryType::SizeType SizeType;
1748 
1749  CTemporaryType lu(c);
1750  std::vector<SizeType> pv(lu.getSize1());
1751  std::size_t num_row_swaps;
1752 
1753  luDecompose(lu, pv, num_row_swaps);
1754 
1755  ValueType res(1);
1756  SizeType size = std::min(lu.getSize1(), lu.getSize2());
1757 
1758  for (SizeType i = 0; i < size; i++)
1759  res *= lu(i, i);
1760 
1761  return (num_row_swaps % 2 == 0 ? res : -res);
1762  }
1763 
1764  template <typename E, typename C>
1765  bool
1767  {
1768  typedef typename C::ValueType ValueType;
1769  typedef typename MatrixTemporaryTraits<C>::Type CTemporaryType;
1770  typedef typename CTemporaryType::SizeType SizeType;
1771 
1772  CTemporaryType lu(e);
1773  std::vector<SizeType> pv(lu.getSize1());
1774  std::size_t num_row_swaps;
1775 
1776  if (luDecompose(lu, pv, num_row_swaps) > 0)
1777  return false;
1778 
1779  c().assign(IdentityMatrix<ValueType>(lu.getSize1(), lu.getSize2()));
1780 
1781  return luSubstitute(lu, pv, c);
1782  }
1783 
1784  template <typename C>
1785  bool
1787  {
1788  return invert(c, c);
1789  }
1790 
1795 
1800 
1805 
1810 
1815 
1820 
1825 
1830 
1835 
1840 
1845 
1850 
1855 
1860 
1865 
1870 
1875 
1880 
1885 
1890 
1895 
1900 
1905  } // namespace Math
1906 } // namespace CDPL
1907 
1908 #endif // CDPL_MATH_MATRIX_HPP
Definition of exception classes.
Definition of various preprocessor macros for error checking.
#define CDPL_MATH_CHECK_MAX_SIZE(size, max_size, e)
Definition: Check.hpp:64
#define CDPL_MATH_CHECK(expr, msg, e)
Definition: Check.hpp:36
Definition of a proxy type for direct assignment of vector and matrix expressions.
Definition of various functors.
Implementation of matrix LU-decomposition and associated operations.
Implementation of matrix assignment routines.
Definition of various matrix expression types and operations.
Definition of an element proxy for sparse data types.
Definition of type traits.
Thrown to indicate that an index is out of range.
Definition: Base/Exceptions.hpp:152
Thrown to indicate that the size of a (multidimensional) array is not correct.
Definition: Base/Exceptions.hpp:133
Definition: Matrix.hpp:854
BoundedMatrix & operator-=(InitializerListType l)
Definition: Matrix.hpp:1017
std::initializer_list< std::initializer_list< T > > InitializerListType
Definition: Matrix.hpp:874
SizeType getSize1() const
Definition: Matrix.hpp:932
T(* ArrayPointer)[N]
Definition: Matrix.hpp:865
SizeType getSize2() const
Definition: Matrix.hpp:937
BoundedMatrix(const BoundedMatrix &m)
Definition: Matrix.hpp:894
T * Pointer
Definition: Matrix.hpp:867
friend void swap(BoundedMatrix &m1, BoundedMatrix &m2)
Definition: Matrix.hpp:1099
BoundedMatrix & operator=(InitializerListType l)
Definition: Matrix.hpp:981
void clear(const ValueType &v=ValueType())
Definition: Matrix.hpp:1104
BoundedMatrix & operator+=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:994
void swap(BoundedMatrix &m)
Definition: Matrix.hpp:1085
const MatrixReference< const SelfType > ConstClosureType
Definition: Matrix.hpp:870
std::enable_if< IsScalar< T1 >::value, BoundedMatrix >::type & operator*=(const T1 &v)
Definition: Matrix.hpp:1030
BoundedMatrix & minusAssign(InitializerListType l)
Definition: Matrix.hpp:1079
std::enable_if< IsScalar< T1 >::value, BoundedMatrix >::type & operator/=(const T1 &v)
Definition: Matrix.hpp:1037
std::size_t SizeType
Definition: Matrix.hpp:862
BoundedMatrix & operator-=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1023
static const SizeType MaxSize1
Definition: Matrix.hpp:876
BoundedMatrix & operator=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:987
const T & ConstReference
Definition: Matrix.hpp:861
const T(* ConstArrayPointer)[N]
Definition: Matrix.hpp:866
BoundedMatrix & operator+=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1005
std::shared_ptr< SelfType > SharedPointer
Definition: Matrix.hpp:873
BoundedMatrix(const MatrixExpression< E > &e)
Definition: Matrix.hpp:908
BoundedMatrix & operator-=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:1012
ConstArrayPointer getData() const
Definition: Matrix.hpp:957
BoundedMatrix & plusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1060
T & Reference
Definition: Matrix.hpp:860
BoundedMatrix & assign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1044
void resize(SizeType m, SizeType n, const ValueType &v)
Definition: Matrix.hpp:1119
BoundedMatrix(SizeType m, SizeType n, const ValueType &v)
Definition: Matrix.hpp:888
BoundedMatrix & assign(InitializerListType l)
Definition: Matrix.hpp:1051
BoundedMatrix & operator+=(InitializerListType l)
Definition: Matrix.hpp:999
T ValueType
Definition: Matrix.hpp:859
const T * ConstPointer
Definition: Matrix.hpp:868
BoundedMatrix & plusAssign(InitializerListType l)
Definition: Matrix.hpp:1066
Reference operator()(SizeType i, SizeType j)
Definition: Matrix.hpp:915
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:921
SelfType MatrixTemporaryType
Definition: Matrix.hpp:871
BoundedVector< T, M *N > VectorTemporaryType
Definition: Matrix.hpp:872
BoundedMatrix(InitializerListType l)
Definition: Matrix.hpp:901
BoundedMatrix()
Definition: Matrix.hpp:879
BoundedMatrix(SizeType m, SizeType n)
Definition: Matrix.hpp:882
static const SizeType MaxSize2
Definition: Matrix.hpp:877
ArrayPointer getData()
Definition: Matrix.hpp:952
SizeType getMaxSize2() const
Definition: Matrix.hpp:947
void resize(SizeType m, SizeType n)
Definition: Matrix.hpp:1110
SizeType getMaxSize1() const
Definition: Matrix.hpp:942
MatrixReference< SelfType > ClosureType
Definition: Matrix.hpp:869
BoundedMatrix & operator=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:976
ValueType ArrayType[M][N]
Definition: Matrix.hpp:864
BoundedMatrix & operator=(const BoundedMatrix &m)
Definition: Matrix.hpp:962
std::ptrdiff_t DifferenceType
Definition: Matrix.hpp:863
BoundedMatrix & minusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1073
bool isEmpty() const
Definition: Matrix.hpp:927
Definition: Vector.hpp:785
Definition: Matrix.hpp:1152
MatrixReference< SelfType > ClosureType
Definition: Matrix.hpp:1167
T * Pointer
Definition: Matrix.hpp:1165
CMatrix & operator-=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:1301
CMatrix & operator=(InitializerListType l)
Definition: Matrix.hpp:1270
SizeType getSize2() const
Definition: Matrix.hpp:1228
CMatrix & assign(InitializerListType l)
Definition: Matrix.hpp:1339
ValueType ArrayType[M][N]
Definition: Matrix.hpp:1162
ConstArrayPointer getData() const
Definition: Matrix.hpp:1248
ArrayPointer getData()
Definition: Matrix.hpp:1243
std::initializer_list< std::initializer_list< T > > InitializerListType
Definition: Matrix.hpp:1172
T(* ArrayPointer)[N]
Definition: Matrix.hpp:1163
CMatrix & operator+=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1294
BoundedVector< T, M *N > VectorTemporaryType
Definition: Matrix.hpp:1170
CMatrix & minusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1376
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:1212
CMatrix(const ValueType &v)
Definition: Matrix.hpp:1183
CMatrix()
Definition: Matrix.hpp:1177
std::enable_if< IsScalar< T1 >::value, CMatrix >::type & operator*=(const T1 &t)
Definition: Matrix.hpp:1319
Reference operator()(SizeType i, SizeType j)
Definition: Matrix.hpp:1206
void clear(const ValueType &v=ValueType())
Definition: Matrix.hpp:1401
std::size_t SizeType
Definition: Matrix.hpp:1160
CMatrix(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1201
CMatrix(InitializerListType l)
Definition: Matrix.hpp:1195
CMatrix & operator-=(InitializerListType l)
Definition: Matrix.hpp:1306
bool isEmpty() const
Definition: Matrix.hpp:1218
T ValueType
Definition: Matrix.hpp:1157
std::enable_if< IsScalar< T1 >::value, CMatrix >::type & operator/=(const T1 &t)
Definition: Matrix.hpp:1326
const T * ConstPointer
Definition: Matrix.hpp:1166
void swap(CMatrix &m)
Definition: Matrix.hpp:1388
CMatrix & operator=(const CMatrix &m)
Definition: Matrix.hpp:1253
CMatrix & operator=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:1264
const T(* ConstArrayPointer)[N]
Definition: Matrix.hpp:1164
SizeType getMaxSize1() const
Definition: Matrix.hpp:1233
SizeType getMaxSize2() const
Definition: Matrix.hpp:1238
CMatrix & operator+=(InitializerListType l)
Definition: Matrix.hpp:1288
static const SizeType Size1
Definition: Matrix.hpp:1174
CMatrix & plusAssign(InitializerListType l)
Definition: Matrix.hpp:1369
CMatrix & operator-=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1312
const T & ConstReference
Definition: Matrix.hpp:1159
std::shared_ptr< SelfType > SharedPointer
Definition: Matrix.hpp:1171
CMatrix(const CMatrix &m)
Definition: Matrix.hpp:1189
CMatrix & assign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1333
friend void swap(CMatrix &m1, CMatrix &m2)
Definition: Matrix.hpp:1396
const MatrixReference< const SelfType > ConstClosureType
Definition: Matrix.hpp:1168
SizeType getSize1() const
Definition: Matrix.hpp:1223
CMatrix & operator+=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:1283
T & Reference
Definition: Matrix.hpp:1158
BoundedMatrix< T, M, N > MatrixTemporaryType
Definition: Matrix.hpp:1169
CMatrix & minusAssign(InitializerListType l)
Definition: Matrix.hpp:1382
CMatrix & operator=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1276
CMatrix & plusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1363
static const SizeType Size2
Definition: Matrix.hpp:1175
std::ptrdiff_t DifferenceType
Definition: Matrix.hpp:1161
Definition: Matrix.hpp:1607
SizeType getMaxSize2() const
Definition: Matrix.hpp:1657
T ValueType
Definition: Matrix.hpp:1612
IdentityMatrix & operator=(const IdentityMatrix &m)
Definition: Matrix.hpp:1662
const T & Reference
Definition: Matrix.hpp:1613
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:1631
void resize(SizeType m, SizeType n)
Definition: Matrix.hpp:1685
IdentityMatrix(SizeType m, SizeType n)
Definition: Matrix.hpp:1625
const MatrixReference< const SelfType > ConstClosureType
Definition: Matrix.hpp:1618
SizeType getMaxSize1() const
Definition: Matrix.hpp:1652
bool isEmpty() const
Definition: Matrix.hpp:1637
MatrixReference< SelfType > ClosureType
Definition: Matrix.hpp:1617
SizeType getSize1() const
Definition: Matrix.hpp:1642
friend void swap(IdentityMatrix &m1, IdentityMatrix &m2)
Definition: Matrix.hpp:1680
std::ptrdiff_t DifferenceType
Definition: Matrix.hpp:1616
IdentityMatrix()
Definition: Matrix.hpp:1622
Matrix< T > MatrixTemporaryType
Definition: Matrix.hpp:1619
IdentityMatrix(const IdentityMatrix &m)
Definition: Matrix.hpp:1628
std::size_t SizeType
Definition: Matrix.hpp:1615
void swap(IdentityMatrix &m)
Definition: Matrix.hpp:1672
SizeType getSize2() const
Definition: Matrix.hpp:1647
const T & ConstReference
Definition: Matrix.hpp:1614
Vector< T, std::vector< T > > VectorTemporaryType
Definition: Matrix.hpp:1620
Definition: Matrix.hpp:212
Matrix< T, std::vector< T > > MatrixTemporaryType
Definition: Matrix.hpp:224
std::initializer_list< std::initializer_list< T > > InitializerListType
Definition: Matrix.hpp:216
SizeType getSize2() const
Definition: Matrix.hpp:259
std::ptrdiff_t DifferenceType
Definition: Matrix.hpp:221
Reference operator()(SizeType i, SizeType j)
Definition: Matrix.hpp:234
InitializerListType::value_type::reference Reference
Definition: Matrix.hpp:219
bool isEmpty() const
Definition: Matrix.hpp:264
InitListMatrix(InitializerListType l)
Definition: Matrix.hpp:227
InitListMatrix SelfType
Definition: Matrix.hpp:215
Vector< T, std::vector< T > > VectorTemporaryType
Definition: Matrix.hpp:225
InitializerListType::value_type::const_reference ConstReference
Definition: Matrix.hpp:218
SelfType ClosureType
Definition: Matrix.hpp:222
const SelfType ConstClosureType
Definition: Matrix.hpp:223
InitializerListType::size_type SizeType
Definition: Matrix.hpp:220
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:244
InitializerListType::value_type::value_type ValueType
Definition: Matrix.hpp:217
SizeType getSize1() const
Definition: Matrix.hpp:254
Definition: Expression.hpp:164
Definition: Expression.hpp:76
Definition: Matrix.hpp:60
M::ConstReference ConstReference
Definition: Matrix.hpp:70
Reference operator()(SizeType i, SizeType j)
Definition: Matrix.hpp:79
MatrixReference & operator=(const MatrixReference &r)
Definition: Matrix.hpp:129
std::conditional< std::is_const< M >::value, typename M::ConstReference, typename M::Reference >::type Reference
Definition: Matrix.hpp:69
bool isEmpty() const
Definition: Matrix.hpp:114
MatrixReference & assign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:171
const MatrixType & getData() const
Definition: Matrix.hpp:119
friend void swap(MatrixReference &r1, MatrixReference &r2)
Definition: Matrix.hpp:196
std::enable_if< IsScalar< T >::value, MatrixReference >::type & operator*=(const T &t)
Definition: Matrix.hpp:157
SizeType getMaxSize() const
Definition: Matrix.hpp:99
M::SizeType SizeType
Definition: Matrix.hpp:71
MatrixReference & operator-=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:150
SizeType getMaxSize1() const
Definition: Matrix.hpp:104
MatrixReference & operator=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:136
std::enable_if< IsScalar< T >::value, MatrixReference >::type & operator/=(const T &t)
Definition: Matrix.hpp:164
MatrixReference & operator+=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:143
SizeType getSize1() const
Definition: Matrix.hpp:89
const SelfType ConstClosureType
Definition: Matrix.hpp:74
MatrixReference & minusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:185
MatrixReference(MatrixType &m)
Definition: Matrix.hpp:76
SizeType getSize2() const
Definition: Matrix.hpp:94
MatrixReference & plusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:178
SelfType ClosureType
Definition: Matrix.hpp:73
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:84
M::ValueType ValueType
Definition: Matrix.hpp:66
M MatrixType
Definition: Matrix.hpp:65
void swap(MatrixReference &r)
Definition: Matrix.hpp:191
M::DifferenceType DifferenceType
Definition: Matrix.hpp:72
SizeType getMaxSize2() const
Definition: Matrix.hpp:109
MatrixType & getData()
Definition: Matrix.hpp:124
Definition: Matrix.hpp:280
A::size_type SizeType
Definition: Matrix.hpp:288
MatrixReference< SelfType > ClosureType
Definition: Matrix.hpp:293
Matrix(SizeType m, SizeType n, const ValueType &v)
Definition: Matrix.hpp:306
std::enable_if< IsScalar< T1 >::value, Matrix >::type & operator/=(const T1 &t)
Definition: Matrix.hpp:452
SizeType getSize2() const
Definition: Matrix.hpp:353
Matrix(const MatrixExpression< E > &e)
Definition: Matrix.hpp:325
Matrix & operator+=(InitializerListType l)
Definition: Matrix.hpp:412
std::enable_if< IsScalar< T1 >::value, Matrix >::type & operator*=(const T1 &t)
Definition: Matrix.hpp:445
SizeType getSize1() const
Definition: Matrix.hpp:348
bool isEmpty() const
Definition: Matrix.hpp:343
Matrix & operator=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:399
Matrix(Matrix &&m)
Definition: Matrix.hpp:312
Matrix(const Matrix &m)
Definition: Matrix.hpp:309
Matrix & assign(InitializerListType l)
Definition: Matrix.hpp:466
std::shared_ptr< SelfType > SharedPointer
Definition: Matrix.hpp:297
Vector< T, A > VectorTemporaryType
Definition: Matrix.hpp:296
const ArrayType & getData() const
Definition: Matrix.hpp:368
Matrix & operator-=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:437
Matrix & operator=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:388
Matrix()
Definition: Matrix.hpp:300
Matrix(InitializerListType l)
Definition: Matrix.hpp:318
const T & ConstReference
Definition: Matrix.hpp:287
Matrix & plusAssign(InitializerListType l)
Definition: Matrix.hpp:481
const T * ConstPointer
Definition: Matrix.hpp:292
Matrix & operator-=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:426
SizeType getMaxSize() const
Definition: Matrix.hpp:358
T * Pointer
Definition: Matrix.hpp:291
Reference operator()(SizeType i, SizeType j)
Definition: Matrix.hpp:331
SelfType MatrixTemporaryType
Definition: Matrix.hpp:295
friend void swap(Matrix &m1, Matrix &m2)
Definition: Matrix.hpp:509
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:337
void swap(Matrix &m)
Definition: Matrix.hpp:500
Matrix & assign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:459
Matrix & operator-=(InitializerListType l)
Definition: Matrix.hpp:431
Matrix & operator=(Matrix &&m)
Definition: Matrix.hpp:381
A ArrayType
Definition: Matrix.hpp:290
void resize(SizeType m, SizeType n, bool preserve=true, const ValueType &v=ValueType())
Definition: Matrix.hpp:519
Matrix & operator=(const Matrix &m)
Definition: Matrix.hpp:373
Matrix & operator=(InitializerListType l)
Definition: Matrix.hpp:393
const MatrixReference< const SelfType > ConstClosureType
Definition: Matrix.hpp:294
std::initializer_list< std::initializer_list< T > > InitializerListType
Definition: Matrix.hpp:298
Matrix & plusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:475
T & Reference
Definition: Matrix.hpp:286
Matrix & operator+=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:418
T ValueType
Definition: Matrix.hpp:285
Matrix(SizeType m, SizeType n)
Definition: Matrix.hpp:303
ArrayType & getData()
Definition: Matrix.hpp:363
Matrix & minusAssign(InitializerListType l)
Definition: Matrix.hpp:494
A::difference_type DifferenceType
Definition: Matrix.hpp:289
Matrix & minusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:488
Matrix & operator+=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:407
void clear(const ValueType &v=ValueType())
Definition: Matrix.hpp:514
Definition: Matrix.hpp:1513
std::size_t SizeType
Definition: Matrix.hpp:1521
std::ptrdiff_t DifferenceType
Definition: Matrix.hpp:1522
SizeType getMaxSize2() const
Definition: Matrix.hpp:1563
SizeType getSize2() const
Definition: Matrix.hpp:1553
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:1537
const MatrixReference< const SelfType > ConstClosureType
Definition: Matrix.hpp:1524
ScalarMatrix(const ScalarMatrix &m)
Definition: Matrix.hpp:1534
void swap(ScalarMatrix &m)
Definition: Matrix.hpp:1579
const T & ConstReference
Definition: Matrix.hpp:1520
friend void swap(ScalarMatrix &m1, ScalarMatrix &m2)
Definition: Matrix.hpp:1588
SizeType getSize1() const
Definition: Matrix.hpp:1548
Vector< T, std::vector< T > > VectorTemporaryType
Definition: Matrix.hpp:1526
SizeType getMaxSize1() const
Definition: Matrix.hpp:1558
void resize(SizeType m, SizeType n)
Definition: Matrix.hpp:1593
T ValueType
Definition: Matrix.hpp:1518
bool isEmpty() const
Definition: Matrix.hpp:1543
ScalarMatrix()
Definition: Matrix.hpp:1528
Matrix< T > MatrixTemporaryType
Definition: Matrix.hpp:1525
ScalarMatrix & operator=(const ScalarMatrix &m)
Definition: Matrix.hpp:1568
ScalarMatrix(SizeType m, SizeType n, const ValueType &v=ValueType())
Definition: Matrix.hpp:1531
MatrixReference< SelfType > ClosureType
Definition: Matrix.hpp:1523
const T & Reference
Definition: Matrix.hpp:1519
Definition: SparseContainerElement.hpp:42
Definition: Matrix.hpp:554
const MatrixReference< const SelfType > ConstClosureType
Definition: Matrix.hpp:569
std::ptrdiff_t DifferenceType
Definition: Matrix.hpp:564
ArrayType::size_type getMaxSize() const
Definition: Matrix.hpp:646
SparseMatrix & operator=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:687
std::enable_if< IsScalar< T1 >::value, SparseMatrix >::type & operator*=(const T1 &t)
Definition: Matrix.hpp:733
const T * ConstPointer
Definition: Matrix.hpp:567
SparseContainerElement< SelfType > Reference
Definition: Matrix.hpp:561
SparseMatrix & operator=(const SparseMatrix &m)
Definition: Matrix.hpp:661
T ValueType
Definition: Matrix.hpp:559
const T & ConstReference
Definition: Matrix.hpp:562
void resize(SizeType m, SizeType n)
Definition: Matrix.hpp:807
SparseMatrix & assign(InitializerListType l)
Definition: Matrix.hpp:754
Reference operator()(SizeType i, SizeType j)
Definition: Matrix.hpp:607
SparseMatrix()
Definition: Matrix.hpp:575
void clear()
Definition: Matrix.hpp:802
std::initializer_list< std::initializer_list< T > > InitializerListType
Definition: Matrix.hpp:573
SizeType getSize1() const
Definition: Matrix.hpp:636
SparseMatrix & operator=(SparseMatrix &&m)
Definition: Matrix.hpp:669
SelfType MatrixTemporaryType
Definition: Matrix.hpp:570
SparseMatrix & operator+=(InitializerListType l)
Definition: Matrix.hpp:700
SparseMatrix & minusAssign(InitializerListType l)
Definition: Matrix.hpp:782
void swap(SparseMatrix &m)
Definition: Matrix.hpp:788
SparseMatrix(SizeType m, SizeType n)
Definition: Matrix.hpp:578
std::enable_if< IsScalar< T1 >::value, SparseMatrix >::type & operator/=(const T1 &t)
Definition: Matrix.hpp:740
SparseMatrix & operator-=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:725
SparseMatrix(const SparseMatrix &m)
Definition: Matrix.hpp:584
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:614
SparseMatrix & assign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:747
const ArrayType & getData() const
Definition: Matrix.hpp:656
SparseMatrix & operator-=(InitializerListType l)
Definition: Matrix.hpp:719
SparseMatrix(SparseMatrix &&m)
Definition: Matrix.hpp:587
A ArrayType
Definition: Matrix.hpp:565
SizeType getSize2() const
Definition: Matrix.hpp:641
T * Pointer
Definition: Matrix.hpp:566
MatrixReference< SelfType > ClosureType
Definition: Matrix.hpp:568
std::shared_ptr< SelfType > SharedPointer
Definition: Matrix.hpp:572
SparseMatrix & operator-=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:714
SparseMatrix(InitializerListType l)
Definition: Matrix.hpp:593
SparseMatrix & operator=(InitializerListType l)
Definition: Matrix.hpp:681
SparseMatrix & plusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:763
SparseMatrix & plusAssign(InitializerListType l)
Definition: Matrix.hpp:769
friend void swap(SparseMatrix &m1, SparseMatrix &m2)
Definition: Matrix.hpp:797
SparseMatrix & operator+=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:695
SizeType getNumElements() const
Definition: Matrix.hpp:626
ArrayType & getData()
Definition: Matrix.hpp:651
Vector< T, std::vector< T > > VectorTemporaryType
Definition: Matrix.hpp:571
SparseMatrix(const MatrixExpression< E > &e)
Definition: Matrix.hpp:600
SparseMatrix & operator+=(const MatrixExpression< E > &e)
Definition: Matrix.hpp:706
SparseMatrix & minusAssign(const MatrixExpression< E > &e)
Definition: Matrix.hpp:776
bool isEmpty() const
Definition: Matrix.hpp:631
A::key_type KeyType
Definition: Matrix.hpp:560
std::uint32_t SizeType
Definition: Matrix.hpp:563
SparseMatrix & operator=(const MatrixContainer< C > &c)
Definition: Matrix.hpp:676
Definition: Vector.hpp:258
Definition: Matrix.hpp:1418
friend void swap(ZeroMatrix &m1, ZeroMatrix &m2)
Definition: Matrix.hpp:1491
T ValueType
Definition: Matrix.hpp:1423
std::ptrdiff_t DifferenceType
Definition: Matrix.hpp:1427
const T & ConstReference
Definition: Matrix.hpp:1425
SizeType getSize1() const
Definition: Matrix.hpp:1453
SizeType getMaxSize2() const
Definition: Matrix.hpp:1468
ConstReference operator()(SizeType i, SizeType j) const
Definition: Matrix.hpp:1442
Vector< T, std::vector< T > > VectorTemporaryType
Definition: Matrix.hpp:1431
bool isEmpty() const
Definition: Matrix.hpp:1448
const T & Reference
Definition: Matrix.hpp:1424
SizeType getSize2() const
Definition: Matrix.hpp:1458
void swap(ZeroMatrix &m)
Definition: Matrix.hpp:1483
void resize(SizeType m, SizeType n)
Definition: Matrix.hpp:1496
const MatrixReference< const SelfType > ConstClosureType
Definition: Matrix.hpp:1429
ZeroMatrix & operator=(const ZeroMatrix &m)
Definition: Matrix.hpp:1473
Matrix< T > MatrixTemporaryType
Definition: Matrix.hpp:1430
SizeType getMaxSize1() const
Definition: Matrix.hpp:1463
ZeroMatrix(const ZeroMatrix &m)
Definition: Matrix.hpp:1439
ZeroMatrix()
Definition: Matrix.hpp:1433
MatrixReference< SelfType > ClosureType
Definition: Matrix.hpp:1428
std::size_t SizeType
Definition: Matrix.hpp:1426
ZeroMatrix(SizeType m, SizeType n)
Definition: Matrix.hpp:1436
constexpr unsigned int A
A generic type that covers any element except hydrogen.
Definition: AtomType.hpp:637
constexpr unsigned int M
A generic type that covers any element that is a metal.
Definition: AtomType.hpp:657
constexpr unsigned int N
Specifies Nitrogen.
Definition: AtomType.hpp:97
constexpr unsigned int T
Specifies Hydrogen (Tritium).
Definition: AtomType.hpp:67
constexpr unsigned int r
Specifies that the stereocenter has r configuration.
Definition: CIPDescriptor.hpp:76
constexpr unsigned int m
Specifies that the stereocenter has m configuration.
Definition: CIPDescriptor.hpp:116
CMatrix< long, 2, 2 > Matrix2L
A bounded 2x2 matrix holding signed integers of type long.
Definition: Matrix.hpp:1859
CMatrix< float, 3, 3 > Matrix3F
A bounded 3x3 matrix holding floating point values of type float.
Definition: Matrix.hpp:1834
ZeroMatrix< double > DZeroMatrix
Definition: Matrix.hpp:1792
bool luSubstitute(const MatrixExpression< E1 > &lu, VectorExpression< E2 > &b)
Definition: LUDecomposition.hpp:157
CMatrix< unsigned long, 3, 3 > Matrix3UL
A bounded 3x3 matrix holding unsigned integers of type unsigned long.
Definition: Matrix.hpp:1879
Matrix< double > DMatrix
An unbounded dense matrix holding floating point values of type double..
Definition: Matrix.hpp:1814
ScalarMatrix< float > FScalarMatrix
Definition: Matrix.hpp:1796
ZeroMatrix< long > LZeroMatrix
Definition: Matrix.hpp:1793
ScalarMatrix< double > DScalarMatrix
Definition: Matrix.hpp:1797
SparseMatrix< unsigned long > SparseULMatrix
An unbounded sparse matrix holding unsigned integers of type unsigned long.
Definition: Matrix.hpp:1904
ZeroMatrix< float > FZeroMatrix
Definition: Matrix.hpp:1791
IdentityMatrix< double > DIdentityMatrix
Definition: Matrix.hpp:1802
CMatrix< long, 3, 3 > Matrix3L
A bounded 3x3 matrix holding signed integers of type long.
Definition: Matrix.hpp:1864
Matrix< unsigned long > ULMatrix
An unbounded dense matrix holding unsigned integers of type unsigned long.
Definition: Matrix.hpp:1824
CMatrix< double, 2, 2 > Matrix2D
A bounded 2x2 matrix holding floating point values of type double.
Definition: Matrix.hpp:1844
SparseMatrix< float > SparseFMatrix
An unbounded sparse matrix holding floating point values of type float..
Definition: Matrix.hpp:1889
IdentityMatrix< long > LIdentityMatrix
Definition: Matrix.hpp:1803
MatrixRow< M > row(MatrixExpression< M > &e, typename MatrixRow< M >::SizeType i)
Definition: MatrixProxy.hpp:716
E::ValueType det(const MatrixExpression< E > &e)
Definition: Matrix.hpp:1721
CMatrix< unsigned long, 4, 4 > Matrix4UL
A bounded 4x4 matrix holding unsigned integers of type unsigned long.
Definition: Matrix.hpp:1884
CMatrix< double, 4, 4 > Matrix4D
A bounded 4x4 matrix holding floating point values of type double.
Definition: Matrix.hpp:1854
SparseMatrix< long > SparseLMatrix
An unbounded sparse matrix holding signed integers of type long.
Definition: Matrix.hpp:1899
CMatrix< float, 4, 4 > Matrix4F
A bounded 4x4 matrix holding floating point values of type float.
Definition: Matrix.hpp:1839
Matrix< long > LMatrix
An unbounded dense matrix holding signed integers of type long.
Definition: Matrix.hpp:1819
Matrix< float > FMatrix
An unbounded dense matrix holding floating point values of type float..
Definition: Matrix.hpp:1809
IdentityMatrix< unsigned long > ULIdentityMatrix
Definition: Matrix.hpp:1804
ZeroMatrix< unsigned long > ULZeroMatrix
Definition: Matrix.hpp:1794
CMatrix< long, 4, 4 > Matrix4L
A bounded 4x4 matrix holding signed integers of type long.
Definition: Matrix.hpp:1869
CMatrix< double, 3, 3 > Matrix3D
A bounded 3x3 matrix holding floating point values of type double.
Definition: Matrix.hpp:1849
SparseMatrix< double > SparseDMatrix
An unbounded sparse matrix holding floating point values of type double..
Definition: Matrix.hpp:1894
ScalarMatrix< unsigned long > ULScalarMatrix
Definition: Matrix.hpp:1799
IdentityMatrix< float > FIdentityMatrix
Definition: Matrix.hpp:1801
bool invert(const MatrixExpression< E > &e, MatrixContainer< C > &c)
Definition: Matrix.hpp:1766
E::SizeType luDecompose(MatrixExpression< E > &e)
Definition: LUDecomposition.hpp:45
CMatrix< unsigned long, 2, 2 > Matrix2UL
A bounded 2x2 matrix holding unsigned integers of type unsigned long.
Definition: Matrix.hpp:1874
CMatrix< float, 2, 2 > Matrix2F
A bounded 2x2 matrix holding floating point values of type float.
Definition: Matrix.hpp:1829
ScalarMatrix< long > LScalarMatrix
Definition: Matrix.hpp:1798
The namespace of the Chemical Data Processing Library.
Definition: TypeTraits.hpp:186
M::MatrixTemporaryType Type
Definition: TypeTraits.hpp:188
Definition: TypeTraits.hpp:179