CTL  0.6.1
Computed Tomography Library
matrix.h
1 #ifndef CTL_MATRIX_H
2 #define CTL_MATRIX_H
3 
4 #include <algorithm>
5 #include <cmath>
6 #include <functional>
7 #include <numeric>
8 #include <stdexcept>
9 #include <string>
10 
11 /*
12  * NOTE: This is header only.
13  */
14 
15 typedef unsigned int uint;
16 
17 namespace CTL {
18 namespace mat {
19 
20 template <uint Rows, uint Cols>
21 class Matrix;
22 
23 namespace details {
24 
25 // helper function for `subMat()`
26 constexpr uint rangeDim(uint from, uint to);
27 // helper function for vectors' `subMat()`
28 template <uint VecDim> constexpr uint vecRangeDim(uint from, uint to);
29 // helper function for `diag` and `eye` to get smallest dimension
30 constexpr uint minDim(uint m, uint n);
31 // helper function for `eye`
32 template <uint Rows, uint Cols>
33 Matrix<Rows, Cols> eye();
34 
35 } // namespace details
36 
54 // Base class for uniform interface and ressource
55 template <uint Rows, uint Cols>
57 {
58 public:
59  // construction
60  MatrixBase() = default;
61  explicit MatrixBase(double fillValue);
62  explicit MatrixBase(const double (&initArray)[Rows * Cols]);
63  template <typename... Doubles>
64  MatrixBase(double firstElement, Doubles... matrixElements);
65 
66  // select row
67  double* operator[](uint row);
68  const double* operator[](uint row) const;
69 
70  // individual element access with 2 indizes
71  // -> standard access (without boundary check)
72  double& operator()(uint row, uint column);
73  double operator()(uint row, uint column) const;
74  // -> run time boundary check (throws out_of_range)
75  double& at(uint row, uint column) noexcept(false);
76  double at(uint row, uint column) const noexcept(false);
77  // -> compile time boundary check (never fails)
78  template <uint row, uint column>
79  double& get() noexcept;
80  template <uint row, uint column>
81  double get() const noexcept;
82 
83  // individual element access with 1 index
84  // -> standard access (without boundary check)
85  double& operator()(uint n);
86  double operator()(uint n) const;
87  // -> run time boundary check (throws out_of_range)
88  double& at(uint n);
89  double at(uint n) const;
90  // -> compile time boundary check (never fails)
91  template <uint n>
92  double& get() noexcept;
93  template <uint n>
94  double get() const noexcept;
95 
96  // pointer access to array (row-major order)
97  double* data();
98  const double* data() const;
99  const double* constData() const;
100  double* begin();
101  const double* begin() const;
102  const double* constBegin() const;
103  double* end();
104  const double* end() const;
105  const double* constEnd() const;
106 
107  // size
108  constexpr size_t size() const;
109 
110  // convert content to string
112  std::string info(const char* lineModifier = "") const;
113 
114  // Euclidean norm of a vector or absolute value of a scalar
115  double norm() const;
116 
117  // equality operator
118  bool operator==(const MatrixBase<Rows, Cols>& rhs) const;
119  bool operator!=(const MatrixBase<Rows, Cols>& rhs) const;
120 
121 private:
122  // the data
123  double _m[Rows * Cols];
124 };
125 
126 // Actual Matrix class for matrices and vectors
127 template <uint Rows, uint Cols>
128 class Matrix : public MatrixBase<Rows, Cols>
129 {
130 public:
131  Matrix() = default;
132  explicit Matrix(double fillValue);
133  explicit Matrix(const double (&initArray)[Rows * Cols]);
134  template <typename... Doubles,
135  typename = typename std::enable_if<sizeof...(Doubles) + 1u == Rows * Cols>::type>
136  Matrix(double firstElement, Doubles... matrixElements);
137 
138  // factory function that copies (+ cast if necessary) the 'NthMat' matrix from
139  // a Container (stack of matrices)
140  template <class Container>
141  static Matrix<Rows, Cols>
142  fromContainer(const Container& vector, size_t NthMat, bool* ok = nullptr);
143 
144  // sub-matrix extraction
145  template <uint fromRow, uint toRow, uint fromCol, uint toCol>
146  auto subMat() const -> Matrix<details::rangeDim(fromRow, toRow),
147  details::rangeDim(fromCol, toCol)>;
148  // sub-vector extraction
149  template <uint from, uint to>
150  auto subMat() const -> Matrix<details::vecRangeDim<Rows>(from, to),
151  details::vecRangeDim<Cols>(from, to)>;
152 
153  // single vector extraction
154  template <uint i>
155  Matrix<1, Cols> row() const;
156  template <uint j>
157  Matrix<Rows, 1> column() const;
158 
159  // unary operators etc.
160  void fill(double fillValue);
161  void normalize();
163  double trace() const;
165  template <uint NewRows, uint NewCols>
168  Matrix<Rows, Cols> operator-() const;
169  // compound assignment
170  Matrix<Rows, Cols>& operator*=(double scalar);
171  Matrix<Rows, Cols>& operator/=(double scalar);
172  Matrix<Rows, Cols>& operator+=(const Matrix<Rows, Cols>& rhs);
173  Matrix<Rows, Cols>& operator-=(const Matrix<Rows, Cols>& rhs);
176  // binary operators
177  Matrix<Rows, Cols> operator*(double scalar) const;
178  Matrix<Rows, Cols> operator/(double scalar) const;
179  Matrix<Rows, Cols> operator+(const Matrix<Rows, Cols>& rhs) const;
180  Matrix<Rows, Cols> operator-(const Matrix<Rows, Cols>& rhs) const;
181  // standard matrix multiplication
182  template <uint Cols2>
183  Matrix<Rows, Cols2> operator*(const Matrix<Cols, Cols2>& rhs) const;
184  // Hadamard product
186  // Hadamard division
188 };
189 
190 // Scalar specialization
191 template <>
192 class Matrix<1, 1> : public MatrixBase<1, 1>
193 {
194 public:
195  Matrix() = default;
196  Matrix(double value);
197 
198  // dedicated access to scalar value
199  double value() const;
200  double& ref();
201  const double& ref() const;
202 
203  // implicit conversion to 'double'
204  operator double() const;
205 
206  // operations
207  Matrix<1, 1>& operator*=(double scalar);
208  Matrix<1, 1>& operator/=(double scalar);
209  Matrix<1, 1>& operator+=(double scalar);
210  Matrix<1, 1>& operator-=(double scalar);
211 };
212 
213 // Free operators
214 template <uint Rows, uint Cols>
215 Matrix<Rows, Cols> operator*(double scalar, const Matrix<Rows, Cols>& rhs);
216 
217 // Free functions
218 // dot product of vectors
219 template <uint N>
220 double dot(const Matrix<N, 1>& vector1, const Matrix<N, 1>& vector2);
221 template <uint N>
222 double dot(const Matrix<1, N>& vector1, const Matrix<1, N>& vector2);
223 template <uint N>
224 double dot(const Matrix<N, 1>& vector1, const Matrix<1, N>& vector2);
225 template <uint N>
226 double dot(const Matrix<1, N>& vector1, const Matrix<N, 1>& vector2);
227 
228 // diagonal squared matrix
229 template <uint N>
230 Matrix<N, N> diag(const Matrix<N, 1>& diagElements);
231 // diagonal rectangular matrix
232 template <uint Rows, uint Cols>
233 Matrix<Rows, Cols> diag(const Matrix<details::minDim(Rows, Cols), 1>& diagElements);
234 
235 // extract diagonal
236 template <uint Rows, uint Cols>
237 auto diag(const Matrix<Rows, Cols>& m) -> Matrix<details::minDim(Rows, Cols), 1>;
238 
239 // N X N identity matrix
240 template <uint N>
241 Matrix<N, N> eye();
242 // Rows X Cols matrix with ones on the main diagonal and zeros elsewhere
243 template <uint Rows, uint Cols>
244 Matrix<Rows, Cols> eye();
245 
246 // concatenation
247 template <uint Rows, uint Cols1, uint Cols2>
249 
250 template <uint Rows1, uint Rows2, uint Cols>
252 
253 } // namespace mat
254 } // namespace CTL
255 
256 #include "matrix.tpp"
257 
258 #endif // CTL_MATRIX_H
double & at(uint row, uint column) noexcept(false)
Definition: matrix.tpp:134
double trace() const
Definition: matrix.tpp:723
Matrix< Rows, Cols > normalized() const
Definition: matrix.tpp:714
Helper base class that provides an access interface to the Matrix template class and its scalar speci...
Definition: matrix.h:56
Definition: matrix.h:192
double norm() const
Definition: matrix.tpp:430
Matrix< Rows, Cols > & operator%=(const Matrix< Rows, Cols > &rhs)
Definition: matrix.tpp:842
double & get() noexcept
Definition: matrix.tpp:164
Matrix< 1, Cols > row() const
Definition: matrix.tpp:652
const double * constData() const
Definition: matrix.tpp:286
double * operator[](uint row)
Definition: matrix.tpp:95
Matrix< Rows, Cols > & operator|=(const Matrix< Rows, Cols > &rhs)
Definition: matrix.tpp:853
static Matrix< Rows, Cols > fromContainer(const Container &vector, size_t NthMat, bool *ok=nullptr)
Definition: matrix.tpp:533
double & operator()(uint row, uint column)
Definition: matrix.tpp:114
bool operator==(const MatrixBase< Rows, Cols > &rhs) const
Definition: matrix.tpp:448
std::string info(const char *lineModifier="") const
Definition: matrix.tpp:376
double * end()
Definition: matrix.tpp:321
Matrix< Rows, Cols > operator|(const Matrix< Rows, Cols > &rhs) const
Definition: matrix.tpp:956
Matrix< NewRows, NewCols > reshaped() const
Definition: matrix.tpp:762
static char & SEPARATOR_CHARACTER_FOR_INFO_STRING
global separator character for formatting
Definition: matrix.h:111
double _m[Rows *Cols]
array with matrix elements
Definition: matrix.h:123
Matrix< Rows, 1 > column() const
Definition: matrix.tpp:667
Matrix< Rows, Cols > operator%(const Matrix< Rows, Cols > &rhs) const
Definition: matrix.tpp:943
const double * constBegin() const
Definition: matrix.tpp:313
Matrix< Rows *Cols, 1 > reshapedAsVector() const
Definition: matrix.tpp:779
bool operator!=(const MatrixBase< Rows, Cols > &rhs) const
Definition: matrix.tpp:467
unsigned int uint
Qt style alias for unsigned int.
Definition: modulelayout.h:6
void normalize()
Definition: matrix.tpp:699
double * begin()
Definition: matrix.tpp:294
const double * constEnd() const
Definition: matrix.tpp:339
auto subMat() const -> Matrix< details::rangeDim(fromRow, toRow), details::rangeDim(fromCol, toCol)>
Definition: matrix.tpp:577
This template class is an abstraction of a small matrix with a size known at compile time.
Definition: matrix.h:21
constexpr size_t size() const
Definition: matrix.tpp:345
void fill(double fillValue)
Definition: matrix.tpp:686
double * data()
Definition: matrix.tpp:267
Matrix< Cols, Rows > transposed() const
Definition: matrix.tpp:737