SmallMatrix.h
Go to the documentation of this file.
1 // This file is part of the MercuryDPM project (https://www.mercurydpm.org).
2 // Copyright (c), The MercuryDPM Developers Team. All rights reserved.
3 // License: BSD 3-Clause License; see the LICENSE file in the root directory.
4 
5 /*
6  This file forms part of hpGEM. This package has been developed over a number of years by various people at the University of Twente and a full list of contributors can be found at
7  http://hpgem.org/about-the-code/team
8 
9  This code is distributed using BSD 3-Clause License. A copy of which can found below.
10 
11 
12  Copyright (c) 2014, University of Twente
13  All rights reserved.
14 
15  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
16 
17  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
18 
19  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
20 
21  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
22 
23  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 
27 //Note: This code is copied and adapted from hpGEM (see license above), version 22th of January 2016. It has been
28 //integrated into MercuryDPM at 16th of March 2017.
29 
30 #ifndef MERCURYDPM_SMALLMATRIX_H
31 #define MERCURYDPM_SMALLMATRIX_H
32 
33 #include "GeneralDefine.h"
34 #include "Logger.h"
35 #include "SmallVector.h"
36 
46 template<unsigned int numberOfRows, unsigned int numberOfColumns>
48 {
49 public:
50 
53  : data_()
54  {
55  }
56 
58  : data_()
59  {
60  logger.assert_debug(numberOfColumns == 1, "Trying to construct a matrix with more than 1 columns from a vector");
61  std::copy(other.data(), other.data() + numberOfRows, data_.begin());
62  }
63 
66  : data_()
67  {
68  data_.fill(c);
69  }
70 
71  SmallMatrix(const std::initializer_list<SmallVector<numberOfRows>>& entries)
72  : data_()
73  {
74  logger.assert_debug(entries.size() == numberOfColumns, "expected a matrix with % "
75  "columns, but got a matrix with % columns", numberOfColumns,
76  entries.size());
77  unsigned int column = 0;
78  for (const SmallVector<numberOfRows>& entry : entries)
79  {
80  for (unsigned int i = 0; i < numberOfRows; ++i)
81  {
82  (*this)(i, column) = entry[i];
83  }
84  ++column;
85  }
86  }
87 
89  SmallMatrix(const SmallMatrix& other)
90  : data_()
91  {
92  std::copy(other.data_.begin(), other.data_.end(), data_.begin());
93  }
94 
97  : data_()
98  {
99  for (unsigned int i = 0; i < numberOfRows; ++i)
100  {
101  for (unsigned int j = 0; j < numberOfColumns; ++j)
102  {
103  (*this)(i, j) = entries[j][i];
104  }
105  }
106  }
107 
110  : data_(std::move(other.data_))
111  {
112  }
113 
115  Mdouble& operator()(unsigned int n, unsigned int m)
116  {
117  logger.assert_debug(n < numberOfRows, "Requested row number % for a matrix with only % rows", n, numberOfRows);
118  logger.assert_debug(m < numberOfColumns, "Requested column number % for a matrix with only % columns", m,
119  numberOfColumns);
120  return data_[n + m * numberOfRows];
121  }
122 
124  const Mdouble& operator()(unsigned int n, unsigned int m) const
125  {
126  logger.assert_debug(n < numberOfRows, "Requested row number % for a matrix with only % rows", n, numberOfRows);
127  logger.assert_debug(m < numberOfColumns, "Requested column number % for a matrix with only % columns", m,
128  numberOfColumns);
129  return data_[n + m * numberOfRows];
130  }
131 
133  Mdouble& operator[](const unsigned int n)
134  {
135  logger.assert_debug(n < numberOfRows * numberOfColumns, "Requested entry % for a matrix with only % entries", n,
136  numberOfRows * numberOfColumns);
137  return data_[n];
138  }
139 
140  const Mdouble& operator[](const unsigned int n) const
141  {
142  logger.assert_debug(n < numberOfRows * numberOfColumns, "Requested entry % for a matrix with only % entries", n,
143  numberOfRows * numberOfColumns);
144  return data_[n];
145  }
146 
149 
151 
153  SmallMatrix operator*(const Mdouble& right) const
154  {
155  SmallMatrix result;
156  std::transform(data_.begin(), data_.end(), result.data_.begin(),
157  std::bind(std::multiplies<Mdouble>(), std::placeholders::_1, right));
158  return result;
159  }
160 
162  template<unsigned int K>
164 
165  template<unsigned int K>
167 
169  {
170  std::transform(data_.begin(), data_.end(), other.data_.begin(), data_.begin(), std::plus<Mdouble>());
171  return *this;
172  }
173 
175  {
176  std::transform(data_.begin(), data_.end(), other.data_.begin(), data_.begin(), std::minus<Mdouble>());
177  return *this;
178  }
179 
180  SmallMatrix operator+(const SmallMatrix& other) const
181  {
182  SmallMatrix result;
183  std::transform(data_.begin(), data_.end(), other.data_.begin(), result.data_.begin(), std::plus<Mdouble>());
184  return result;
185  }
186 
187  SmallMatrix operator-(const SmallMatrix& other) const
188  {
189  SmallMatrix result;
190  std::transform(data_.begin(), data_.end(), other.data_.begin(), result.data_.begin(), std::minus<Mdouble>());
191  return result;
192  }
193 
195  {
196  return *this * -1.;
197  }
198 
201  {
202  std::transform(data_.begin(), data_.end(), data_.begin(),
203  std::bind(std::multiplies<Mdouble>(), std::placeholders::_1, scalar));
204  return *this;
205  }
206 
210 
213  {
214  std::transform(data_.begin(), data_.end(), data_.begin(),
215  std::bind(std::divides<Mdouble>(), std::placeholders::_1, scalar));
216  return *this;
217  }
218 
220  SmallMatrix operator/(const Mdouble& scalar) const
221  {
222  SmallMatrix result;
223  std::transform(data_.begin(), data_.end(), result.data_.begin(),
224  std::bind(std::divides<Mdouble>(), std::placeholders::_1, scalar));
225  return result;
226  }
227 
230  {
231  std::copy(right.data_.begin(), right.data_.end(), data_.begin());
232  return *this;
233  }
234 
237  {
238  std::move(right.data_.begin(), right.data_.end(), data_.begin());
239  return *this;
240  }
241 
244 
246  void axpy(Mdouble a, const SmallMatrix& x)
247  {
248  for (unsigned int i = 0; i < numberOfRows * numberOfColumns; ++i)
249  {
250  data_[i] += a * x[i];
251  }
252  }
253 
255  unsigned int size() const
256  {
257  return numberOfRows * numberOfColumns;
258  }
259 
261  unsigned int getNumberOfRows() const
262  {
263  return numberOfRows;
264  }
265 
267  unsigned int getNRows() const
268  {
269  return getNumberOfRows();
270  }
271 
273  unsigned int getNumberOfColumns() const
274  {
275  return numberOfColumns;
276  }
277 
278  unsigned int getNCols() const
279  {
280  return getNumberOfColumns();
281  }
282 
285  {
286  logger.assert_debug(j < numberOfColumns, "Asked for column %, but there are only % columns", j, numberOfColumns);
287  return SmallVector<numberOfRows>(data() + j * numberOfRows);
288  }
289 
292  {
293  logger.assert_debug(i < numberOfRows, "Asked for row %, but there are only % rows", i, numberOfRows);
295  for (unsigned int j = 0; j < numberOfColumns; ++j)
296  {
297  result[j] = (*this)(i, j);
298  }
299  return result;
300  }
301 
304 
305  Mdouble determinant() const;
306 
308  SmallMatrix inverse() const;
309 
311  {
313  for (unsigned int i = 0; i < numberOfRows; ++i)
314  {
315  for (unsigned int j = 0; j < numberOfColumns; ++j)
316  {
317  result(j, i) = (*this)(i, j);
318  }
319  }
320  return result;
321  }
322 
324  template<unsigned int numberOfRightHandSideColumns>
326 
329  void solve(SmallVector<numberOfRows>& b) const;
330 
332  {
333  return data_.data();
334  }
335 
336  const Mdouble* data() const
337  {
338  return data_.data();
339  }
340 
341 private:
343  std::array<Mdouble, numberOfRows * numberOfColumns> data_;
344 };
345 
347 template<unsigned int numberOfRows, unsigned int numberOfColumns>
348 std::ostream& operator<<(std::ostream& os, const SmallMatrix<numberOfRows, numberOfColumns>& A)
349 {
350  for (unsigned int i = 0; i < numberOfRows; ++i)
351  {
352  os << A.getRow(i) << std::endl;
353  }
354  return os;
355 }
356 
358 template<unsigned int numberOfRows, unsigned int numberOfColumns>
361 {
362  return mat * d;
363 }
364 
366 template<unsigned int numberOfRows, unsigned int numberOfColumns>
368 
369 #include "SmallMatrix_impl.h"
370 
371 
372 #endif //MERCURYDPM_SMALLMATRIX_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
double Mdouble
Definition: GeneralDefine.h:13
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
Scalar * b
Definition: benchVecAdd.cpp:17
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
std::ostream & operator<<(std::ostream &s, const DenseBase< Derived > &m)
Definition: IO.h:222
operator*(const MatrixBase< Derived > &matrix, const UniformScaling< Scalar > &s)
Definition: Eigen/src/Geometry/Scaling.h:133
Data type for small dense matrix.
Definition: SmallMatrix.h:48
SmallMatrix(const std::initializer_list< SmallVector< numberOfRows >> &entries)
Definition: SmallMatrix.h:71
std::array< Mdouble, numberOfRows *numberOfColumns > data_
The actually data of the matrix class.
Definition: SmallMatrix.h:343
SmallVector< numberOfRows > getColumn(unsigned int j) const
get the j^th column
Definition: SmallMatrix.h:284
Mdouble & operator[](const unsigned int n)
Access the n linear element in the matrix.
Definition: SmallMatrix.h:133
Mdouble determinant() const
Definition: SmallMatrix_impl.h:241
unsigned int getNCols() const
Definition: SmallMatrix.h:278
SmallMatrix< numberOfColumns, numberOfRows > transpose() const
Definition: SmallMatrix.h:310
SmallMatrix & operator+=(const SmallMatrix &other)
Definition: SmallMatrix.h:168
SmallMatrix operator/(const Mdouble &scalar) const
this does element by divided by a scalar
Definition: SmallMatrix.h:220
SmallMatrix & operator/=(const Mdouble &scalar)
Does matrix A_ij=scalar*A_ij.
Definition: SmallMatrix.h:212
SmallMatrix operator*(const Mdouble &right) const
Does matrix A_ij=scalar*B_ij.
Definition: SmallMatrix.h:153
SmallMatrix operator-(const SmallMatrix &other) const
Definition: SmallMatrix.h:187
SmallMatrix(const SmallMatrix &other)
Construct and copy Matrix from another Matrix i.e. B(A) where B and A are both matrices.
Definition: SmallMatrix.h:89
Mdouble * data()
Definition: SmallMatrix.h:331
void solve(SmallMatrix< numberOfRows, numberOfRightHandSideColumns > &B) const
solves Ax=B where A is the current matrix and B is passed in. The result is returned in B.
Definition: SmallMatrix_impl.h:309
unsigned int size() const
Get total number of Matrix entries.
Definition: SmallMatrix.h:255
SmallVector< numberOfColumns > getRow(unsigned int i) const
get the i^th row
Definition: SmallMatrix.h:291
unsigned int getNRows() const
Definition: SmallMatrix.h:267
SmallVector< numberOfRows > computeWedgeStuffVector() const
computeWedgeStuffVector.
Definition: SmallMatrix_impl.h:181
const Mdouble & operator[](const unsigned int n) const
Definition: SmallMatrix.h:140
SmallMatrix(SmallMatrix &&other)
Move Matrix from another Matrix.
Definition: SmallMatrix.h:109
unsigned int getNumberOfColumns() const
Get the number of columns.
Definition: SmallMatrix.h:273
SmallMatrix & operator=(const SmallMatrix &right)
Assigns one matrix to another.
Definition: SmallMatrix.h:229
SmallMatrix(const Mdouble &c)
Constructs a matrix of size n-rows by m-columns and initialises all entry to a constant.
Definition: SmallMatrix.h:65
Mdouble & operator()(unsigned int n, unsigned int m)
defines the operator(n,m) to access the element on row n and column m
Definition: SmallMatrix.h:115
SmallMatrix & operator-=(const SmallMatrix &other)
Definition: SmallMatrix.h:174
SmallMatrix & operator*=(const Mdouble &scalar)
Does matrix A_ij=scalar*A_ij.
Definition: SmallMatrix.h:200
SmallMatrix LUfactorisation() const
Return the LUfactorisation of the matrix.
Definition: SmallMatrix_impl.h:222
SmallMatrix(const SmallVector< numberOfRows > &other)
Definition: SmallMatrix.h:57
SmallMatrix operator-() const
Definition: SmallMatrix.h:194
const Mdouble * data() const
Definition: SmallMatrix.h:336
SmallMatrix(std::array< SmallVector< numberOfRows >, numberOfColumns > entries)
Glues one or more vectors with the same number of rows together.
Definition: SmallMatrix.h:96
SmallMatrix operator+(const SmallMatrix &other) const
Definition: SmallMatrix.h:180
SmallVector< numberOfRows > operator*(SmallVector< numberOfColumns > &right)
Defines Matrix A times vector B and return vector C i.e. C_,j= A_ij B_,j.
Definition: SmallMatrix_impl.h:61
const Mdouble & operator()(unsigned int n, unsigned int m) const
defines the operator(n,m) to access the element on row n and column m
Definition: SmallMatrix.h:124
SmallMatrix inverse() const
return the inverse in the vector result. The size of result matches the matrix.
Definition: SmallMatrix_impl.h:285
SmallMatrix()
Constructs a matrix of size n-rows by m-columns.
Definition: SmallMatrix.h:52
SmallMatrix & operator=(SmallMatrix &&right)
Assigns one matrix to another.
Definition: SmallMatrix.h:236
unsigned int getNumberOfRows() const
Get the number of rows.
Definition: SmallMatrix.h:261
void axpy(Mdouble a, const SmallMatrix &x)
Applies the matrix y=ax + y, where x is another matrix and a is a scalar.
Definition: SmallMatrix.h:246
Definition: SmallVector.h:42
const Mdouble * data() const
Definition: SmallVector.h:218
Definition: matrices.h:74
EIGEN_DONT_INLINE void transform(const Transformation &t, Data &data)
Definition: geometry.cpp:25
EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:32
const Scalar * a
Definition: level2_cplx_impl.h:32
int * m
Definition: level2_cplx_impl.h:294
std::array< T, N > array
Definition: EmulateArray.h:231
int c
Definition: calibrate.py:100
list x
Definition: plotDoE.py:28
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2