OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
Matrix.h
Go to the documentation of this file.
1 #ifndef CLASSIC_Matrix_HH
2 #define CLASSIC_Matrix_HH
3 
4 // ------------------------------------------------------------------------
5 // $RCSfile: Matrix.h,v $
6 // ------------------------------------------------------------------------
7 // $Revision: 1.2.2.3 $
8 // ------------------------------------------------------------------------
9 // Copyright: see Copyright.readme
10 // ------------------------------------------------------------------------
11 //
12 // Template class: Matrix
13 //
14 // ------------------------------------------------------------------------
15 // Class category: Algebra
16 // ------------------------------------------------------------------------
17 //
18 // $Date: 2004/11/18 22:18:05 $
19 // $Author: jsberg $
20 //
21 // ------------------------------------------------------------------------
22 
23 #include "Algebra/Array2D.h"
24 #include "Algebra/Vector.h"
25 #include "Utilities/SizeError.h"
26 #include <algorithm>
27 #include <functional>
28 #include <numeric>
29 
30 
31 // Template class Matrix<T>
32 // ------------------------------------------------------------------------
34 // A templated representation for matrices.
35 // This class implements the basic algebraic operations on general matrices,
36 // which need not be square.
37 
38 template<class T>
39 class Matrix: public Array2D<T> {
40 
41 public:
42 
44  // Constructs undefined matrix.
45  Matrix();
46 
48  // From two-dimensional array.
49  Matrix(const Array2D<T> &);
50 
52  // Reserve [b]rows[/b] x [b]cols[/b] elements and leave them undefined.
53  Matrix(int rows, int cols);
54 
56  // Reserve [b]rows[/b] x [b]cols[/b] elements and set them to t.
57  Matrix(int rows, int cols, const T &t);
58 
59  Matrix(const Matrix &);
60  ~Matrix();
61  Matrix<T> &operator=(const Matrix<T> &);
62 
64  Matrix<T> &operator=(const Array2D<T> &);
65 
67  Matrix<T> &operator*=(const T &);
68 
70  Matrix<T> &operator/=(const T &);
71 
73  Matrix<T> &operator+=(const Matrix<T> &);
74 
76  Matrix<T> &operator-=(const Matrix<T> &);
77 
79  // Add the unit matrix times [b]t[/b] and assign.
80  // Throw SizeError, if matrix is not square.
81  Matrix<T> &operator+=(const T &);
82 
84  // Subtract the unit matrix times [b]t[/b] and assign.
85  // Throw SizeError, if matrix is not square.
86  Matrix<T> &operator-=(const T &);
87 
89  Matrix<T> &operator*=(const Matrix<T> &);
90 
92  Matrix<T> transpose() const;
93 
95  Matrix<T> dotm(const Matrix<T> &) const;
96 
98  Vector<T> dotcv(const Vector<T> &) const;
99 
101  Vector<T> dotrv(const Vector<T> &) const;
102 };
103 
104 
105 // Global Operators on Matrix<T>
106 // ------------------------------------------------------------------------
107 
109 template <class T> Matrix<T> operator+(const Matrix<T> &, const Matrix<T> &);
110 
112 template <class T> Matrix<T> operator-(const Matrix<T> &, const Matrix<T> &);
113 
115 template <class T> Matrix<T> operator-(const Matrix<T> &);
116 
118 template <class T> Matrix<T> operator*(const Matrix<T> &, const Matrix<T> &);
119 
121 template <class T> Vector<T> operator*(const Matrix<T> &, const Vector<T> &);
122 
124 template <class T> Vector<T> operator*(const Vector<T> &, const Matrix<T> &);
125 
127 template <class T> Matrix<T> operator*(const Matrix<T> &, const T &);
128 
130 template <class T> Matrix<T> operator*(const T &, const Matrix<T> &);
131 
133 template <class T> Matrix<T> operator/(const Matrix<T> &, const T &);
134 
135 
136 // Public methods of Matrix<T>.
137 // ------------------------------------------------------------------------
138 
139 template<class T>
141  Array2D<T>()
142 {}
143 
144 
145 template<class T>
147  Array2D<T>(rhs)
148 {}
149 
150 
151 template<class T>
153  Array2D<T>(rhs)
154 {}
155 
156 
157 template<class T>
158 Matrix<T>::Matrix(int rows, int cols):
159  Array2D<T>(rows, cols)
160 {}
161 
162 
163 template<class T>
164 Matrix<T>::Matrix(int rows, int cols, const T &/*val*/):
165  Array2D<T>(rows, cols, T(0)) {
166  for(int i = std::min(rows, cols); i-- > 0;) {
167  this->data[i * (cols + 1)] = T(1);
168  }
169 }
170 
171 
172 template<class T>
174 {}
175 
176 
177 template<class T>
180  return *this;
181 }
182 
183 
184 template<class T>
187  return *this;
188 }
189 
190 
191 template<class T>
193  std::transform(this->begin(), this->end(), this->begin(),
194  std::bind(std::multiplies<T>(), std::placeholders::_2, val));
195  return *this;
196 }
197 
198 
199 template<class T>
201  std::transform(this->begin(), this->end(), this->begin(),
202  std::bind(std::divides<T>(), std::placeholders::_2, val));
203  return *this;
204 }
205 
206 
207 template<class T>
209  if(this->nrows() != array.nrows() || this->ncols() != array.ncols()) {
210  throw SizeError("Matrix::operator+=()", "Dimensions inconsistent.");
211  }
212  std::transform(this->begin(), this->end(), array.begin(), this->begin(),
213  std::plus<T>());
214  return *this;
215 }
216 
217 
218 template<class T>
220  if(this->nrows() != array.nrows() || this->ncols() != array.ncols()) {
221  throw SizeError("Matrix::operator-=()", "Dimensions inconsistent.");
222  }
223  std::transform(this->begin(), this->end(), array.begin(), this->begin(),
224  std::minus<T>());
225  return *this;
226 }
227 
228 
229 template<class T>
231  if(this->nrows() != this->ncols()) {
232  throw SizeError("Matrix::operator+=()", "Matrix is not square.");
233  }
234  int n = std::min(this->nrows(), this->ncols());
235  for(int i = 0; i < n; i++) this->col_begin(i)[i] += val;
236  return *this;
237 }
238 
239 
240 template<class T>
242  if(this->nrows() != this->ncols()) {
243  throw SizeError("Matrix::operator-=()", "Matrix is not square.");
244  }
245  int n = std::min(this->nrows(), this->ncols());
246  for(int i = 0; i < n; i++) this->col_begin(i)[i] -= val;
247  return *this;
248 }
249 
250 
251 template<class T>
253  *this = (*this).dotm(array);
254  return *this;
255 }
256 
257 
258 template <class T>
260  int nr = this->nrows();
261  int nc = this->ncols();
262  Matrix<T> R(nc, nr);
263 
264  for(int i = 0; i < nr; ++i) {
265  std::copy(this->row_begin(i), this->row_end(i), R.col_begin(i));
266  }
267 
268  return R;
269 }
270 
271 
272 // Global functions acting on Matrix<T>.
273 // ------------------------------------------------------------------------
274 
275 template<class T>
276 Matrix<T> operator+(const Matrix<T> &lhs, const Matrix<T> &rhs) {
277  Matrix<T> result = lhs;
278  return result += rhs;
279 }
280 
281 
282 template<class T>
283 Matrix<T> operator-(const Matrix<T> &lhs, const Matrix<T> &rhs) {
284  Matrix<T> result = lhs;
285  return result -= rhs;
286 }
287 
288 
289 template<class T>
291  Matrix<T> result(arg.nrows(), arg.ncols());
292  std::transform(arg.begin(), arg.end(), result.begin(), std::negate<T>());
293  return result;
294 }
295 
296 
297 template<class T>
298 Matrix<T> operator*(const Matrix<T> &lhs, const Matrix<T> &rhs) {
299  return lhs.dotm(rhs);
300 }
301 
302 
303 template<class T>
304 Vector<T> operator*(const Matrix<T> &M, const Vector<T> &V) {
305  return M.dotcv(V);
306 }
307 
308 
309 template<class T>
310 Vector<T> operator*(const Vector<T> &V, const Matrix<T> &M) {
311  return M.dotrv(V);
312 }
313 
314 
315 template<class T>
316 Matrix<T> operator*(const Matrix<T> &M, const T &val) {
317  Matrix<T> R(M);
318  return R *= val;
319 }
320 
321 
322 template<class T>
323 Matrix<T> operator*(const T &val, const Matrix<T> &M) {
324  Matrix<T> R(M);
325  return R *= val;
326 }
327 
328 
329 template<class T>
330 Matrix<T> operator/(const Matrix<T> &M, const T &val) {
331  Matrix<T> R(M);
332  return R /= val;
333 }
334 
335 
336 // Protected methods of Matrix<T>.
337 // ------------------------------------------------------------------------
338 
339 template<class T>
341  if(this->ncols() != B.nrows()) {
342  throw SizeError("Matrix::dotm()", "Inconsistent dimensions.");
343  }
344 
345  const int nr1 = this->nrows();
346  const int nc2 = B.ncols();
347  Matrix<T> R(nr1, nc2, T(0.0));
348 
349  for(int i = 0; i < nr1; i++) {
350  typename Array2D<T>::const_row_iterator i1 = this->row_begin(i);
351  typename Array2D<T>::const_row_iterator i2 = this->row_end(i);
352 
353  for(int j = 0; j < nc2; j++) {
354  R(i, j) = std::inner_product(i1, i2, B.col_begin(j), T(0));
355  }
356  }
357 
358  return R;
359 }
360 
361 template<class T>
363  if(this->ncols() != B.size()) {
364  throw SizeError("Matrix::dotcv()", "Inconsistent dimensions.");
365  }
366 
367  int nr = this->nrows();
368  Vector<T> R(nr, T(0));
369 
370  for(int i = 0; i < nr; ++i) {
371  R(i) = std::inner_product(this->row_begin(i), this->row_end(i), B.begin(),
372  T(0));
373  }
374 
375  return R;
376 }
377 
378 template<class T>
380  if(this->nrows() != B.size()) {
381  throw SizeError("Matrix::dotrv()", "Inconsistent dimensions.");
382  }
383 
384  int nc = this->ncols();
385  Vector<T> R(nc, T(0));
386 
387  for(int j = 0; j < nc; j++) {
388  R(j) = std::inner_product(B.begin(), B.end(), this->col_begin(j), T(0));
389  }
390 
391  return R;
392 }
393 
394 #endif // CLASSIC_Matrix_HH
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:276
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:330
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:298
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:283
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
const int nr
Definition: ClassicRandom.h:24
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
arg(a))
iterator begin()
Get beginning of data.
Definition: Array1D.h:204
int size() const
Get array size.
Definition: Array1D.h:228
iterator end()
Get end of data.
Definition: Array1D.h:210
Two-dimensional array.
Definition: Array2D.h:40
iterator begin()
Get pointer to beginning of data.
Definition: Array2D.h:319
const T * const_row_iterator
The iterator type for access by rows for a constant array.
Definition: Array2D.h:58
int nrows() const
Get number of rows.
Definition: Array2D.h:301
Array2D< T > & operator=(const Array2D< T > &)
Definition: Array2D.h:265
int rows
Definition: Array2D.h:220
T * data
Definition: Array2D.h:225
int cols
Definition: Array2D.h:221
col_iterator col_begin(int c)
Get column iterator.
Definition: Array2D.h:391
int ncols() const
Get number of columns.
Definition: Array2D.h:307
Matrix.
Definition: Matrix.h:39
Vector< T > dotrv(const Vector< T > &) const
Row vector times matrix.
Definition: Matrix.h:379
Matrix< T > transpose() const
Matrix transpose.
Definition: Matrix.h:259
Matrix< T > & operator-=(const Matrix< T > &)
Subtract matrix and assign.
Definition: Matrix.h:219
Matrix< T > & operator*=(const T &)
Multiply by scalar and assign.
Definition: Matrix.h:192
~Matrix()
Definition: Matrix.h:173
Matrix< T > & operator=(const Matrix< T > &)
Definition: Matrix.h:178
Matrix()
Default constructor.
Definition: Matrix.h:140
Vector< T > dotcv(const Vector< T > &) const
Matrix times column vector.
Definition: Matrix.h:362
Matrix< T > dotm(const Matrix< T > &) const
Matrix product.
Definition: Matrix.h:340
Matrix< T > & operator+=(const Matrix< T > &)
Add matrix and assign..
Definition: Matrix.h:208
Matrix< T > & operator/=(const T &)
Divide by scalar and assign.
Definition: Matrix.h:200
Vector.
Definition: Vector.h:37
Size error exception.
Definition: SizeError.h:33