OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
38template<class T>
39class Matrix: public Array2D<T> {
40
41public:
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();
62
65
67 Matrix<T> &operator*=(const T &);
68
70 Matrix<T> &operator/=(const T &);
71
74
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
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
109template <class T> Matrix<T> operator+(const Matrix<T> &, const Matrix<T> &);
110
112template <class T> Matrix<T> operator-(const Matrix<T> &, const Matrix<T> &);
113
115template <class T> Matrix<T> operator-(const Matrix<T> &);
116
118template <class T> Matrix<T> operator*(const Matrix<T> &, const Matrix<T> &);
119
121template <class T> Vector<T> operator*(const Matrix<T> &, const Vector<T> &);
122
124template <class T> Vector<T> operator*(const Vector<T> &, const Matrix<T> &);
125
127template <class T> Matrix<T> operator*(const Matrix<T> &, const T &);
128
130template <class T> Matrix<T> operator*(const T &, const Matrix<T> &);
131
133template <class T> Matrix<T> operator/(const Matrix<T> &, const T &);
134
135
136// Public methods of Matrix<T>.
137// ------------------------------------------------------------------------
138
139template<class T>
141 Array2D<T>()
142{}
143
144
145template<class T>
147 Array2D<T>(rhs)
148{}
149
150
151template<class T>
153 Array2D<T>(rhs)
154{}
155
156
157template<class T>
158Matrix<T>::Matrix(int rows, int cols):
159 Array2D<T>(rows, cols)
160{}
161
162
163template<class T>
164Matrix<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
172template<class T>
174{}
175
176
177template<class T>
180 return *this;
181}
182
183
184template<class T>
187 return *this;
188}
189
190
191template<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
199template<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
207template<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
218template<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
229template<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
240template<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
251template<class T>
253 *this = (*this).dotm(array);
254 return *this;
255}
256
257
258template <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
275template<class T>
276Matrix<T> operator+(const Matrix<T> &lhs, const Matrix<T> &rhs) {
277 Matrix<T> result = lhs;
278 return result += rhs;
279}
280
281
282template<class T>
283Matrix<T> operator-(const Matrix<T> &lhs, const Matrix<T> &rhs) {
284 Matrix<T> result = lhs;
285 return result -= rhs;
286}
287
288
289template<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
297template<class T>
298Matrix<T> operator*(const Matrix<T> &lhs, const Matrix<T> &rhs) {
299 return lhs.dotm(rhs);
300}
301
302
303template<class T>
305 return M.dotcv(V);
306}
307
308
309template<class T>
311 return M.dotrv(V);
312}
313
314
315template<class T>
316Matrix<T> operator*(const Matrix<T> &M, const T &val) {
317 Matrix<T> R(M);
318 return R *= val;
319}
320
321
322template<class T>
323Matrix<T> operator*(const T &val, const Matrix<T> &M) {
324 Matrix<T> R(M);
325 return R *= val;
326}
327
328
329template<class T>
330Matrix<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
339template<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
361template<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
378template<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
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
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
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