OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
MMatrix.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Chris Rogers
3 * All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * 1. Redistributions of source code must retain the above copyright notice,
7 * this list of conditions and the following disclaimer.
8 * 2. Redistributions in binary form must reproduce the above copyright notice,
9 * this list of conditions and the following disclaimer in the documentation
10 * and/or other materials provided with the distribution.
11 * 3. Neither the name of STFC nor the names of its contributors may be used to
12 * endorse or promote products derived from this software without specific
13 * prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef _SRC_COMMON_CPP_MATHS_MMATRIX_HH_
29#define _SRC_COMMON_CPP_MATHS_MMATRIX_HH_
30
31#include <iostream>
32#include <vector>
33
34#include "Utilities/GSLBLAS.h"
35#include "Utilities/GSLMatrix.h"
36
38
40
41namespace interpolation {
42
44
61 template <class Tmplt>
62 class MMatrix {
63 public:
66 MMatrix();
67
71
80 MMatrix(size_t nrows, size_t ncols, Tmplt* data_beginning);
81
88 MMatrix(size_t nrows, size_t ncols, Tmplt value);
89
95 MMatrix(size_t nrows, size_t ncols);
96
105 static MMatrix<Tmplt> Diagonal(size_t i, Tmplt diag_value, Tmplt off_diag_value);
106
109 ~MMatrix();
110
113 size_t num_row() const;
114
117 size_t num_col() const;
118
122 Tmplt trace() const;
123
127 Tmplt determinant() const;
128
131 MMatrix<Tmplt> inverse() const;
132
135 void invert();
136
140
145 MVector<m_complex> eigenvalues() const; // return vector of eigenvalues
146 std::pair<MVector<m_complex>, MMatrix<m_complex> > eigenvectors()
147 const; // return pair of eigenvalues, eigenvectors (access using my_pair.first or
148 // my_pair.second)
149
150 // return a submatrix, with data from min_row to max_row and min_row to max_row inclusive;
151 // indexing starts at 1
152 MMatrix<Tmplt> sub(size_t min_row, size_t max_row, size_t min_col, size_t max_col) const;
153 // create a column vector from the column^th column
154 MVector<Tmplt> get_mvector(size_t column) const;
155 // return a reference to the datum; indexing starts at 1, goes to num_row (inclusive)
156 const Tmplt& operator()(size_t row, size_t column) const;
157 Tmplt& operator()(size_t row, size_t column);
158
160
161 // TODO - implement iterator
162 // class iterator
163 //{
164 // }
165
174 template <class Tmplt2>
176
177 friend class MMatrix<double>; // To do the eigenvector problem, MMatrix<double> needs to
178 // see MMatrix<complex>'s _matrix
179
180 private:
181 // build the matrix with size i,j, data not initialised
182 void build_matrix(size_t i, size_t j);
183 // build the matrix with size i,j, data initialised to data in temp
184 void build_matrix(size_t i, size_t j, Tmplt* temp);
185 // delete the matrix and set it to null
187 // return the matrix overloaded to the correct type or throw
188 // if _matrix == nullptr
191 // gsl object
192 void* _matrix;
193 };
194
195 // Operators do what you would expect - i.e. normal mathematical functions
199 MMatrix<m_complex>& m1, MMatrix<m_complex> m2); // M1 *= M2 returns M1 = M1*M2
201 MMatrix<double>& m1, MMatrix<double> m2); // M1 *= M2 returns M1 = M1*M2
206
207 template <class Tmplt>
209
210 template <class Tmplt>
212 template <class Tmplt>
214 template <class Tmplt>
216 template <class Tmplt>
218
219 template <class Tmplt>
221 template <class Tmplt>
223 template <class Tmplt>
224 MMatrix<Tmplt> operator-(MMatrix<Tmplt>); // unary minus returns matrix*(-1)
225
226 template <class Tmplt>
227 bool operator==(const MMatrix<Tmplt>& c1, const MMatrix<Tmplt>& c2);
228 template <class Tmplt>
229 bool operator!=(const MMatrix<Tmplt>& c1, const MMatrix<Tmplt>& c2);
230
231 // format is
232 // num_row num_col
233 // m11 m12 m13 ...
234 // m21 m22 m23 ...
235 // ...
236 template <class Tmplt>
237 std::ostream& operator<<(std::ostream& out, MMatrix<Tmplt> mat);
238 template <class Tmplt>
239 std::istream& operator>>(std::istream& in, MMatrix<Tmplt>& mat);
240
241 // return matrix of doubles filled with either real or imaginary part of m
244 // return matrix of m_complex filled with real and imaginary parts
247
249
251
252 template <>
253 inline size_t MMatrix<double>::num_row() const {
254 if (_matrix) return ((gsl_matrix*)_matrix)->size1;
255 return 0;
256 }
257 template <>
258 inline size_t MMatrix<m_complex>::num_row() const {
259 if (_matrix) return ((gsl_matrix_complex*)_matrix)->size1;
260 return 0;
261 }
262 template <>
263 inline size_t MMatrix<double>::num_col() const {
264 if (_matrix) return ((gsl_matrix*)_matrix)->size2;
265 return 0;
266 }
267
268 template <>
269 inline size_t MMatrix<m_complex>::num_col() const {
270 if (_matrix) return ((gsl_matrix_complex*)_matrix)->size2;
271 return 0;
272 }
273
278
281 return m;
282 }
283
292
300
305
308 return m1;
309 }
310
311 template <class Tmplt>
313 for (size_t i = 1; i <= m1.num_row(); i++)
314 for (size_t j = 1; j <= m1.num_col(); j++)
315 m1(i, j) = -1. * m1(i, j);
316 return m1;
317 }
318
319 template <class Tmplt>
321 return m1 *= m2;
322 }
323
324 template <class Tmplt>
326 return m *= v;
327 }
328
329 template <class Tmplt>
331 return m *= t;
332 }
333
334 template <class Tmplt>
336 return m *= 1. / t;
337 }
338 template <class Tmplt>
340 return m /= t;
341 }
342
343 template <class Tmplt>
345 MMatrix<Tmplt> m3 = m1 += m2;
346 return m3;
347 }
348
349 template <class Tmplt>
351 return m1 += -m2;
352 }
353 template <class Tmplt>
355 return m1 -= m2;
356 }
357
358 template <>
359 const double inline& MMatrix<double>::operator()(size_t i, size_t j) const {
360 return *gsl_matrix_ptr((gsl_matrix*)_matrix, i - 1, j - 1);
361 }
362 template <>
363 const m_complex inline& MMatrix<m_complex>::operator()(size_t i, size_t j) const {
364 return *gsl_matrix_complex_ptr((gsl_matrix_complex*)_matrix, i - 1, j - 1);
365 }
366
367 template <>
368 double inline& MMatrix<double>::operator()(size_t i, size_t j) {
369 return *gsl_matrix_ptr((gsl_matrix*)_matrix, i - 1, j - 1);
370 }
371 template <>
372 m_complex inline& MMatrix<m_complex>::operator()(size_t i, size_t j) {
373 return *gsl_matrix_complex_ptr((gsl_matrix_complex*)_matrix, i - 1, j - 1);
374 }
375
376 template <class Tmplt>
377 bool operator==(const MMatrix<Tmplt>& lhs, const MMatrix<Tmplt>& rhs) {
378 if (lhs.num_row() != rhs.num_row() || lhs.num_col() != rhs.num_col()) return false;
379 for (size_t i = 1; i <= lhs.num_row(); i++)
380 for (size_t j = 1; j <= lhs.num_col(); j++)
381 if (lhs(i, j) != rhs(i, j)) return false;
382 return true;
383 }
384
385 template <class Tmplt>
386 bool inline operator!=(const MMatrix<Tmplt>& lhs, const MMatrix<Tmplt>& rhs) {
387 return !(lhs == rhs);
388 }
389
390 // iostream
391 template <class Tmplt>
392 std::ostream& operator<<(std::ostream& out, MMatrix<Tmplt>);
393 // template <class Tmplt> std::istream& operator>>(std::istream& in, MMatrix<Tmplt>);
394
395 template <class Tmplt>
397 if (m._matrix == nullptr)
399 "MMatrix::get_matrix", "Attempt to access uninitialised matrix"));
400 return (gsl_matrix*)m._matrix;
401 }
402
403 template <class Tmplt>
405 if (m._matrix == nullptr)
407 "MMatrix::get_matrix", "Attempt to access uninitialised matrix"));
408 return (gsl_matrix_complex*)m._matrix;
409 }
410
412} // namespace interpolation
413
414#endif
@ CblasNoTrans
Definition GSLBLAS.h:32
void gsl_blas_zgemv(CBLAS_TRANSPOSE TransA, gsl_complex alpha, const gsl_matrix_complex *A, const gsl_vector_complex *x, gsl_complex beta, gsl_vector_complex *y)
Complex matrix-vector multiply and accumulate.
Definition GSLBLAS.h:194
void gsl_blas_dgemv(CBLAS_TRANSPOSE TransA, double alpha, const gsl_matrix *A, const gsl_vector *x, double beta, gsl_vector *y)
Real matrix-vector multiply and accumulate.
Definition GSLBLAS.h:144
void gsl_matrix_complex_scale(gsl_matrix_complex *m, gsl_complex x)
Scale a complex matrix in-place.
Definition GSLMatrix.h:335
void gsl_matrix_scale(gsl_matrix *m, double x)
Scale a matrix in-place.
Definition GSLMatrix.h:324
double * gsl_matrix_ptr(gsl_matrix *m, size_t i, size_t j)
Return pointer to element in a real matrix.
Definition GSLMatrix.h:199
void gsl_matrix_complex_add(gsl_matrix_complex *a, const gsl_matrix_complex *b)
Add another complex matrix in-place.
Definition GSLMatrix.h:360
gsl_complex * gsl_matrix_complex_ptr(gsl_matrix_complex *m, size_t i, size_t j)
Return pointer to element in a complex matrix.
Definition GSLMatrix.h:217
void gsl_matrix_add(gsl_matrix *a, const gsl_matrix *b)
Add another matrix in-place.
Definition GSLMatrix.h:346
void build_matrix(size_t i, size_t j, Tmplt *temp)
friend MVector< double > operator*(MMatrix< double > m, MVector< double > v)
Definition MMatrix.h:293
void invert()
turns this matrix into its inverse
static gsl_matrix * get_matrix(const MMatrix< double > &m)
Definition MMatrix.h:396
MVector< Tmplt > get_mvector(size_t column) const
Definition MMatrix.cpp:421
size_t num_col() const
returns number of columns in the matrix
MVector< m_complex > eigenvalues() const
returns a vector of eigenvalues. Throws an exception if either this matrix is not square or the eigen...
Definition MMatrix.cpp:296
void build_matrix(size_t i, size_t j)
MMatrix< Tmplt > & operator=(const MMatrix< Tmplt > &mm)
friend MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition MMatrix.h:284
MMatrix(const MMatrix< Tmplt > &mv)
Copy constructor makes a deep copy of mv.
friend MMatrix< double > & operator*=(MMatrix< double > &m, double d)
Definition MMatrix.h:279
MMatrix< Tmplt > T() const
returns matrix transpose T (such that M(i,j) = T(j,i))
Tmplt & operator()(size_t row, size_t column)
size_t num_row() const
returns number of rows in the matrix
std::pair< MVector< m_complex >, MMatrix< m_complex > > eigenvectors() const
Definition MMatrix.cpp:315
MMatrix< Tmplt > inverse() const
returns matrix inverse leaving this matrix unchanged
Definition MMatrix.cpp:213
friend MMatrix< double > & operator+=(MMatrix< double > &m1, const MMatrix< double > &m2)
Definition MMatrix.h:306
MMatrix< Tmplt > sub(size_t min_row, size_t max_row, size_t min_col, size_t max_col) const
Definition MMatrix.cpp:272
friend MMatrix< m_complex > & operator*=(MMatrix< m_complex > &m, m_complex c)
Definition MMatrix.h:274
static MMatrix< Tmplt > Diagonal(size_t i, Tmplt diag_value, Tmplt off_diag_value)
Construct a square matrix filling on and off diagonal values.
Definition MMatrix.cpp:137
friend MMatrix< m_complex > & operator+=(MMatrix< m_complex > &m1, const MMatrix< m_complex > &m2)
Definition MMatrix.h:301
Tmplt determinant() const
returns matrix determinant; throws an exception if matrix is not square
static gsl_matrix_complex * get_matrix(const MMatrix< m_complex > &m)
Definition MMatrix.h:404
friend MMatrix< Tmplt2 > operator+(MMatrix< Tmplt2 > m1, const MMatrix< Tmplt2 > m2)
MMatrix()
default constructor makes an empty MMatrix of size (0,0)
Definition MMatrix.cpp:41
const Tmplt & operator()(size_t row, size_t column) const
Tmplt trace() const
returns sum of terms with row == column, even if matrix is not square
Definition MMatrix.cpp:286
MMatrix< Tmplt > operator/(MMatrix< Tmplt >, Tmplt)
Definition MMatrix.h:339
m_complex m_complex_build(double r, double i)
Definition MVector.h:60
Mesh::Iterator operator+(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
Mesh::Iterator operator-(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
bool operator==(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
MMatrix< m_complex > complex(MMatrix< double > real)
Definition MMatrix.cpp:399
bool operator!=(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
Mesh::Iterator & operator+=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition MMatrix.h:284
template std::istream & operator>>(std::istream &in, MMatrix< double > &mat)
MMatrix< double > re(MMatrix< m_complex > mc)
Definition MMatrix.cpp:383
std::ostream & operator<<(std::ostream &out, const Mesh::Iterator &it)
Definition Mesh.cpp:33
MMatrix< Tmplt > inline & operator/=(MMatrix< Tmplt > &m, Tmplt t)
Definition MMatrix.h:335
MMatrix< double > & operator*=(MMatrix< double > &m1, MMatrix< double > m2)
Definition MMatrix.cpp:337
MMatrix< double > im(MMatrix< m_complex > mc)
Definition MMatrix.cpp:391
Mesh::Iterator & operator-=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
Complex number stored as .
Definition GSLComplex.h:27
Dense complex matrix in row-major storage.
Definition GSLMatrix.h:45
Dense real matrix in row-major storage.
Definition GSLMatrix.h:29
Dense complex vector with stride.
Definition GSLMatrix.h:76
Dense real vector with stride.
Definition GSLMatrix.h:61