OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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 <numeric>
28 
29 
30 // Template class Matrix<T>
31 // ------------------------------------------------------------------------
33 // A templated representation for matrices.
34 // This class implements the basic algebraic operations on general matrices,
35 // which need not be square.
36 
37 template<class T>
38 class Matrix: public Array2D<T> {
39 
40 public:
41 
43  // Constructs undefined matrix.
44  Matrix();
45 
47  // From two-dimensional array.
48  Matrix(const Array2D<T> &);
49 
51  // Reserve [b]rows[/b] x [b]cols[/b] elements and leave them undefined.
52  Matrix(int rows, int cols);
53 
55  // Reserve [b]rows[/b] x [b]cols[/b] elements and set them to t.
56  Matrix(int rows, int cols, const T &t);
57 
58  Matrix(const Matrix &);
59  ~Matrix();
60  Matrix<T> &operator=(const Matrix<T> &);
61 
63  Matrix<T> &operator=(const Array2D<T> &);
64 
66  Matrix<T> &operator*=(const T &);
67 
69  Matrix<T> &operator/=(const T &);
70 
72  Matrix<T> &operator+=(const Matrix<T> &);
73 
75  Matrix<T> &operator-=(const Matrix<T> &);
76 
78  // Add the unit matrix times [b]t[/b] and assign.
79  // Throw SizeError, if matrix is not square.
80  Matrix<T> &operator+=(const T &);
81 
83  // Subtract the unit matrix times [b]t[/b] and assign.
84  // Throw SizeError, if matrix is not square.
85  Matrix<T> &operator-=(const T &);
86 
88  Matrix<T> &operator*=(const Matrix<T> &);
89 
91  Matrix<T> transpose() const;
92 
94  Matrix<T> dotm(const Matrix<T> &) const;
95 
97  Vector<T> dotcv(const Vector<T> &) const;
98 
100  Vector<T> dotrv(const Vector<T> &) const;
101 };
102 
103 
104 // Global Operators on Matrix<T>
105 // ------------------------------------------------------------------------
106 
108 template <class T> Matrix<T> operator+(const Matrix<T> &, const Matrix<T> &);
109 
111 template <class T> Matrix<T> operator-(const Matrix<T> &, const Matrix<T> &);
112 
114 template <class T> Matrix<T> operator-(const Matrix<T> &);
115 
117 template <class T> Matrix<T> operator*(const Matrix<T> &, const Matrix<T> &);
118 
120 template <class T> Vector<T> operator*(const Matrix<T> &, const Vector<T> &);
121 
123 template <class T> Vector<T> operator*(const Vector<T> &, const Matrix<T> &);
124 
126 template <class T> Matrix<T> operator*(const Matrix<T> &, const T &);
127 
129 template <class T> Matrix<T> operator*(const T &, const Matrix<T> &);
130 
132 template <class T> Matrix<T> operator/(const Matrix<T> &, const T &);
133 
134 
135 // Public methods of Matrix<T>.
136 // ------------------------------------------------------------------------
137 
138 template<class T>
140  Array2D<T>()
141 {}
142 
143 
144 template<class T>
146  Array2D<T>(rhs)
147 {}
148 
149 
150 template<class T>
152  Array2D<T>(rhs)
153 {}
154 
155 
156 template<class T>
157 Matrix<T>::Matrix(int rows, int cols):
158  Array2D<T>(rows, cols)
159 {}
160 
161 
162 template<class T>
163 Matrix<T>::Matrix(int rows, int cols, const T &val):
164  Array2D<T>(rows, cols, T(0)) {
165  for(int i = std::min(rows, cols); i-- > 0;) {
166  this->data[i * (cols + 1)] = T(1);
167  }
168 }
169 
170 
171 template<class T>
173 {}
174 
175 
176 template<class T>
179  return *this;
180 }
181 
182 
183 template<class T>
186  return *this;
187 }
188 
189 
190 template<class T>
192  std::transform(this->begin(), this->end(), this->begin(),
193  std::bind2nd(std::multiplies<T>(), val));
194  return *this;
195 }
196 
197 
198 template<class T>
200  std::transform(this->begin(), this->end(), this->begin(),
201  std::bind2nd(std::divides<T>(), val));
202  return *this;
203 }
204 
205 
206 template<class T>
208  if(this->nrows() != array.nrows() || this->ncols() != array.ncols()) {
209  throw SizeError("Matrix::operator+=()", "Dimensions inconsistent.");
210  }
211  std::transform(this->begin(), this->end(), array.begin(), this->begin(),
212  std::plus<T>());
213  return *this;
214 }
215 
216 
217 template<class T>
219  if(this->nrows() != array.nrows() || this->ncols() != array.ncols()) {
220  throw SizeError("Matrix::operator-=()", "Dimensions inconsistent.");
221  }
222  std::transform(this->begin(), this->end(), array.begin(), this->begin(),
223  std::minus<T>());
224  return *this;
225 }
226 
227 
228 template<class T>
230  if(this->nrows() != this->ncols()) {
231  throw SizeError("Matrix::operator+=()", "Matrix is not square.");
232  }
233  int n = std::min(this->nrows(), this->ncols());
234  for(int i = 0; i < n; i++) this->col_begin(i)[i] += val;
235  return *this;
236 }
237 
238 
239 template<class T>
241  if(this->nrows() != this->ncols()) {
242  throw SizeError("Matrix::operator-=()", "Matrix is not square.");
243  }
244  int n = std::min(this->nrows(), this->ncols());
245  for(int i = 0; i < n; i++) this->col_begin(i)[i] -= val;
246  return *this;
247 }
248 
249 
250 template<class T>
252  *this = (*this).dotm(array);
253  return *this;
254 }
255 
256 
257 template <class T>
259  int nr = this->nrows();
260  int nc = this->ncols();
261  Matrix<T> R(nc, nr);
262 
263  for(int i = 0; i < nr; ++i) {
264  std::copy(this->row_begin(i), this->row_end(i), R.col_begin(i));
265  }
266 
267  return R;
268 }
269 
270 
271 // Global functions acting on Matrix<T>.
272 // ------------------------------------------------------------------------
273 
274 template<class T>
275 Matrix<T> operator+(const Matrix<T> &lhs, const Matrix<T> &rhs) {
276  Matrix<T> result = lhs;
277  return result += rhs;
278 }
279 
280 
281 template<class T>
282 Matrix<T> operator-(const Matrix<T> &lhs, const Matrix<T> &rhs) {
283  Matrix<T> result = lhs;
284  return result -= rhs;
285 }
286 
287 
288 template<class T>
290  Matrix<T> result(arg.nrows(), arg.ncols());
291  std::transform(arg.begin(), arg.end(), result.begin(), std::negate<T>());
292  return result;
293 }
294 
295 
296 template<class T>
297 Matrix<T> operator*(const Matrix<T> &lhs, const Matrix<T> &rhs) {
298  return lhs.dotm(rhs);
299 }
300 
301 
302 template<class T>
303 Vector<T> operator*(const Matrix<T> &M, const Vector<T> &V) {
304  return M.dotcv(V);
305 }
306 
307 
308 template<class T>
309 Vector<T> operator*(const Vector<T> &V, const Matrix<T> &M) {
310  return M.dotrv(V);
311 }
312 
313 
314 template<class T>
315 Matrix<T> operator*(const Matrix<T> &M, const T &val) {
316  Matrix<T> R(M);
317  return R *= val;
318 }
319 
320 
321 template<class T>
322 Matrix<T> operator*(const T &val, const Matrix<T> &M) {
323  Matrix<T> R(M);
324  return R *= val;
325 }
326 
327 
328 template<class T>
329 Matrix<T> operator/(const Matrix<T> &M, const T &val) {
330  Matrix<T> R(M);
331  return R /= val;
332 }
333 
334 
335 // Protected methods of Matrix<T>.
336 // ------------------------------------------------------------------------
337 
338 template<class T>
340  if(this->ncols() != B.nrows()) {
341  throw SizeError("Matrix::dotm()", "Inconsistent dimensions.");
342  }
343 
344  const int nr1 = this->nrows();
345  const int nc2 = B.ncols();
346  Matrix<T> R(nr1, nc2, T(0.0));
347 
348  for(int i = 0; i < nr1; i++) {
349  typename Array2D<T>::const_row_iterator i1 = this->row_begin(i);
350  typename Array2D<T>::const_row_iterator i2 = this->row_end(i);
351 
352  for(int j = 0; j < nc2; j++) {
353  R(i, j) = std::inner_product(i1, i2, B.col_begin(j), T(0));
354  }
355  }
356 
357  return R;
358 }
359 
360 template<class T>
362  if(this->ncols() != B.size()) {
363  throw SizeError("Matrix::dotcv()", "Inconsistent dimensions.");
364  }
365 
366  int nr = this->nrows();
367  Vector<T> R(nr, T(0));
368 
369  for(int i = 0; i < nr; ++i) {
370  R(i) = std::inner_product(this->row_begin(i), this->row_end(i), B.begin(),
371  T(0));
372  }
373 
374  return R;
375 }
376 
377 template<class T>
379  if(this->nrows() != B.size()) {
380  throw SizeError("Matrix::dotrv()", "Inconsistent dimensions.");
381  }
382 
383  int nc = this->ncols();
384  Vector<T> R(nc, T(0));
385 
386  for(int j = 0; j < nc; j++) {
387  R(j) = std::inner_product(B.begin(), B.end(), this->col_begin(j), T(0));
388  }
389 
390  return R;
391 }
392 
393 #endif // CLASSIC_Matrix_HH
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
Array2D< T > & operator=(const Array2D< T > &)
Definition: Array2D.h:265
iterator begin()
Get pointer to beginning of data.
Definition: Array2D.h:319
int rows
Definition: Array2D.h:220
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:329
Matrix< T > & operator/=(const T &)
Divide by scalar and assign.
Definition: Matrix.h:199
Definition: rbendmap.h:8
col_iterator col_begin(int c)
Get column iterator.
Definition: Array2D.h:391
Size error exception.
Definition: SizeError.h:33
const int nr
Definition: ClassicRandom.h:24
iterator end()
Get end of data.
Definition: Array1D.h:210
int ncols() const
Get number of columns.
Definition: Array2D.h:307
T * data
Definition: Array2D.h:225
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:297
Vector< T > dotrv(const Vector< T > &) const
Row vector times matrix.
Definition: Matrix.h:378
~Matrix()
Definition: Matrix.h:172
int size() const
Get array size.
Definition: Array1D.h:228
const T * const_row_iterator
The iterator type for access by rows for a constant array.
Definition: Array2D.h:58
Matrix< T > transpose() const
Matrix transpose.
Definition: Matrix.h:258
iterator begin()
Get beginning of data.
Definition: Array1D.h:204
Matrix< T > & operator+=(const Matrix< T > &)
Add matrix and assign..
Definition: Matrix.h:207
Two-dimensional array.
Definition: Array2D.h:40
Matrix< T > & operator*=(const T &)
Multiply by scalar and assign.
Definition: Matrix.h:191
iterator end()
Get pointer past end of data.
Definition: Array2D.h:325
arg(a))
Matrix< T > & operator-=(const Matrix< T > &)
Subtract matrix and assign.
Definition: Matrix.h:218
int cols
Definition: Array2D.h:221
Vector< T > dotcv(const Vector< T > &) const
Matrix times column vector.
Definition: Matrix.h:361
Matrix.
Definition: Matrix.h:38
Matrix< T > dotm(const Matrix< T > &) const
Matrix product.
Definition: Matrix.h:339
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
Vector.
int nrows() const
Get number of rows.
Definition: Array2D.h:301
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
Matrix< T > & operator=(const Matrix< T > &)
Definition: Matrix.h:177
Matrix()
Default constructor.
Definition: Matrix.h:139