OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
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 "gsl/gsl_matrix.h"
35 #include "gsl/gsl_blas.h"
36 
38 
40 
41 namespace interpolation {
42 
44 
61 template <class Tmplt>
62 class MMatrix
63 {
64 public:
67  MMatrix();
68 
71  MMatrix(const MMatrix<Tmplt>& mv );
72 
81  MMatrix(size_t nrows, size_t ncols, Tmplt* data_beginning );
82 
89  MMatrix(size_t nrows, size_t ncols, Tmplt value);
90 
96  MMatrix(size_t nrows, size_t ncols);
97 
106  static MMatrix<Tmplt> Diagonal(size_t i, Tmplt diag_value, Tmplt off_diag_value);
107 
110  ~MMatrix();
111 
114  size_t num_row() const;
115 
118  size_t num_col() const;
119 
123  Tmplt trace() const;
124 
128  Tmplt determinant() const;
129 
132  MMatrix<Tmplt> inverse() const;
133 
136  void invert();
137 
140  MMatrix<Tmplt> T() const;
141 
146  MVector<m_complex> eigenvalues() const; //return vector of eigenvalues
147  std::pair<MVector<m_complex>, MMatrix<m_complex> >
148  eigenvectors() const; //return pair of eigenvalues, eigenvectors (access using my_pair.first or my_pair.second)
149 
150  //return a submatrix, with data from min_row to max_row and min_row to max_row inclusive; indexing starts at 1
151  MMatrix<Tmplt> sub(size_t min_row, size_t max_row, size_t min_col, size_t max_col) const;
152  //create a column vector from the column^th column
153  MVector<Tmplt> get_mvector(size_t column) const;
154  //return a reference to the datum; indexing starts at 1, goes to num_row (inclusive)
155  const Tmplt& operator()(size_t row, size_t column) const;
156  Tmplt& operator()(size_t row, size_t column);
157 
159 
160  //TODO - implement iterator
161  //class iterator
162  //{
163  //}
164 
165 
167  friend MMatrix<double>& operator *=(MMatrix<double>& m, double d);
174  template <class Tmplt2> friend MMatrix<Tmplt2> operator + (MMatrix<Tmplt2> m1, const MMatrix<Tmplt2> m2);
175 
176  friend const gsl_matrix* MMatrix_to_gsl(const MMatrix<double>& m);
177  friend const gsl_matrix_complex* MMatrix_to_gsl(const MMatrix<gsl_complex>& m);
178 
179  friend class MMatrix<double>; //To do the eigenvector problem, MMatrix<double> needs to see MMatrix<complex>'s _matrix
180 
181 
182 private:
183  //build the matrix with size i,j, data not initialised
184  void build_matrix(size_t i, size_t j);
185  //build the matrix with size i,j, data initialised to data in temp
186  void build_matrix(size_t i, size_t j, Tmplt* temp);
187  //delete the matrix and set it to null
188  void delete_matrix();
189  //return the matrix overloaded to the correct type or throw
190  //if _matrix == NULL
191  static gsl_matrix* get_matrix(const MMatrix<double>& m);
192  static gsl_matrix_complex* get_matrix(const MMatrix<m_complex>& m);
193  //gsl object
194  void* _matrix;
195 };
196 
197 //Operators do what you would expect - i.e. normal mathematical functions
200 MMatrix<m_complex>& operator *=(MMatrix<m_complex>& m1, MMatrix<m_complex> m2); //M1 *= M2 returns M1 = M1*M2
201 MMatrix<double>& operator *=(MMatrix<double>& m1, MMatrix<double> m2); //M1 *= M2 returns M1 = M1*M2
206 
207 template <class Tmplt> MMatrix<Tmplt>& operator -=(MMatrix<double>& m1, MMatrix<double> m2);
208 
209 template <class Tmplt> MMatrix<Tmplt> operator*(MMatrix<Tmplt>, MMatrix<Tmplt>);
210 template <class Tmplt> MMatrix<Tmplt> operator*(MMatrix<Tmplt>, MVector<Tmplt>);
211 template <class Tmplt> MMatrix<Tmplt> operator*(MMatrix<Tmplt>, Tmplt);
212 template <class Tmplt> MMatrix<Tmplt> operator/(MMatrix<Tmplt>, Tmplt);
213 
214 template <class Tmplt> MMatrix<Tmplt> operator+(MMatrix<Tmplt>, MMatrix<Tmplt>);
215 template <class Tmplt> MMatrix<Tmplt> operator-(MMatrix<Tmplt>, MMatrix<Tmplt>);
216 template <class Tmplt> MMatrix<Tmplt> operator-(MMatrix<Tmplt>); //unary minus returns matrix*(-1)
217 
218 template <class Tmplt> bool operator==(const MMatrix<Tmplt>& c1, const MMatrix<Tmplt>& c2);
219 template <class Tmplt> bool operator!=(const MMatrix<Tmplt>& c1, const MMatrix<Tmplt>& c2);
220 
221 //format is
222 // num_row num_col
223 // m11 m12 m13 ...
224 // m21 m22 m23 ...
225 // ...
226 template <class Tmplt> std::ostream& operator<<(std::ostream& out, MMatrix<Tmplt> mat);
227 template <class Tmplt> std::istream& operator>>(std::istream& in, MMatrix<Tmplt>& mat);
228 
229 //return matrix of doubles filled with either real or imaginary part of m
232 //return matrix of m_complex filled with real and imaginary parts
235 
236 //return pointer to gsl_matrix objects that store matrix data in m
237 const gsl_matrix* MMatrix_to_gsl(const MMatrix<double>& m);
238 const gsl_matrix_complex* MMatrix_to_gsl(const MMatrix<gsl_complex>& m);
239 
241 
242 
243 
245 
246 template <>
247 inline size_t MMatrix<double>::num_row() const
248 {
249  if(_matrix) return ((gsl_matrix*)_matrix)->size1;
250  return 0;
251 }
252 template <>
253 inline size_t MMatrix<m_complex>::num_row() const
254 {
255  if(_matrix) return ((gsl_matrix_complex*)_matrix)->size1;
256  return 0;
257 }
258 template <>
259 inline size_t MMatrix<double>::num_col() const
260 {
261  if(_matrix) return ((gsl_matrix*)_matrix)->size2;
262  return 0;
263 }
264 
265 template <>
266 inline size_t MMatrix<m_complex>::num_col() const
267 {
268  if(_matrix) return ((gsl_matrix_complex*)_matrix)->size2;
269  return 0;
270 }
271 
273 {gsl_matrix_complex_scale((gsl_matrix_complex*)m._matrix, c); return m;}
274 
276 {gsl_matrix_scale((gsl_matrix*)m._matrix, d); return m;}
277 
279 {
280  MVector<m_complex> v0(m.num_row());
281  gsl_blas_zgemv(CblasNoTrans, m_complex_build(1.), (gsl_matrix_complex*)m._matrix, (gsl_vector_complex*)v._vector, m_complex_build(0.), (gsl_vector_complex*)v0._vector);
282  return v0;
283 }
284 
286 {
287  MVector<double> v0(m.num_row());
288  gsl_blas_dgemv(CblasNoTrans, 1., (gsl_matrix*)m._matrix, (gsl_vector*)v._vector, 0., (gsl_vector*)v0._vector);
289  return v0;
290 }
291 
293 {gsl_matrix_complex_add((gsl_matrix_complex*)m1._matrix, (gsl_matrix_complex*)m2._matrix); return m1;}
294 
296 {gsl_matrix_add((gsl_matrix*)m1._matrix, (gsl_matrix*)m2._matrix); return m1;}
297 
298 template <class Tmplt> MMatrix<Tmplt> inline operator - (MMatrix<Tmplt> m1)
299 {for(size_t i=1; i<=m1.num_row(); i++) for(size_t j=1; j<=m1.num_col(); j++) m1(i,j) = -1.*m1(i,j); return m1; }
300 
301 template <class Tmplt> MMatrix<Tmplt> inline operator*(MMatrix<Tmplt> m1, MMatrix<Tmplt> m2)
302 {return m1*=m2;}
303 
304 template <class Tmplt> MMatrix<Tmplt> inline operator*(MMatrix<Tmplt> m, MVector<Tmplt> v)
305 {return m*=v;}
306 
307 template <class Tmplt> MMatrix<Tmplt> inline operator*(MMatrix<Tmplt> m, Tmplt t)
308 {return m*=t;}
309 
310 template <class Tmplt> MMatrix<Tmplt> inline & operator/=(MMatrix<Tmplt>& m, Tmplt t)
311 {return m*=1./t;}
312 template <class Tmplt> MMatrix<Tmplt> inline operator/(MMatrix<Tmplt> m, Tmplt t)
313 {return m/=t;}
314 
315 template <class Tmplt> MMatrix<Tmplt> inline operator+(MMatrix<Tmplt> m1, MMatrix<Tmplt> m2)
316 { MMatrix<Tmplt> m3 = m1+=m2; return m3; }
317 
318 template <class Tmplt> MMatrix<Tmplt> inline & operator-=(MMatrix<Tmplt>& m1, MMatrix<Tmplt> m2)
319 {return m1 += -m2;}
320 template <class Tmplt> MMatrix<Tmplt> inline operator-(MMatrix<Tmplt> m1, MMatrix<Tmplt> m2)
321 {return m1 -= m2;}
322 
323 
324 
325 template <>
326 const double inline & MMatrix<double>::operator()(size_t i, size_t j) const
327 { return *gsl_matrix_ptr((gsl_matrix*)_matrix, i-1, j-1); }
328 template <>
329 const m_complex inline & MMatrix<m_complex>::operator()(size_t i, size_t j) const
330 { return *gsl_matrix_complex_ptr((gsl_matrix_complex*)_matrix, i-1, j-1); }
331 
332 template <>
333 double inline & MMatrix<double>::operator()(size_t i, size_t j)
334 { return *gsl_matrix_ptr((gsl_matrix*)_matrix, i-1, j-1); }
335 template <>
336 m_complex inline & MMatrix<m_complex>::operator()(size_t i, size_t j)
337 { return *gsl_matrix_complex_ptr((gsl_matrix_complex*)_matrix, i-1, j-1); }
338 
339 template <class Tmplt>
340 bool operator==(const MMatrix<Tmplt>& lhs, const MMatrix<Tmplt>& rhs)
341 {
342  if( lhs.num_row() != rhs.num_row() || lhs.num_col() != rhs.num_col() ) return false;
343  for(size_t i=1; i<=lhs.num_row(); i++)
344  for(size_t j=1; j<=lhs.num_col(); j++)
345  if(lhs(i,j) != rhs(i,j)) return false;
346  return true;
347 }
348 
349 template <class Tmplt>
350 bool inline operator!=(const MMatrix<Tmplt>& lhs, const MMatrix<Tmplt>& rhs) {return ! (lhs == rhs);}
351 
352 //iostream
353 template <class Tmplt> std::ostream& operator<<(std::ostream& out, MMatrix<Tmplt>);
354 //template <class Tmplt> std::istream& operator>>(std::istream& in, MMatrix<Tmplt>);
355 
356 template <class Tmplt>
357 gsl_matrix inline* MMatrix<Tmplt>::get_matrix(const MMatrix<double>& m)
358 {
359  if(m._matrix == NULL)
360  throw(GeneralClassicException("MMatrix::get_matrix", "Attempt to access uninitialised matrix"));
361  return (gsl_matrix*)m._matrix;
362 }
363 
364 template <class Tmplt>
365 gsl_matrix_complex inline* MMatrix<Tmplt>::get_matrix(const MMatrix<m_complex>& m)
366 {
367  if(m._matrix == NULL)
368  throw(GeneralClassicException("MMatrix::get_matrix", "Attempt to access uninitialised matrix"));
369  return (gsl_matrix_complex*)m._matrix;
370 
371 }
372 
374 }
375 
376 #endif
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
MMatrix< Tmplt > inverse() const
returns matrix inverse leaving this matrix unchanged
Definition: MMatrix.cpp:222
void build_matrix(size_t i, size_t j)
static gsl_matrix * get_matrix(const MMatrix< double > &m)
Definition: MMatrix.h:357
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:329
gsl_complex m_complex
Definition: MVector.h:60
MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition: MMatrix.h:278
~MMatrix()
destructor
Definition: MMatrix.cpp:155
MMatrix< m_complex > complex(MMatrix< double > real)
Definition: MMatrix.cpp:407
std::pair< MVector< m_complex >, MMatrix< m_complex > > eigenvectors() const
Definition: MMatrix.cpp:316
const Tmplt & operator()(size_t row, size_t column) const
Mesh::Iterator & operator+=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
friend MMatrix< m_complex > & operator+=(MMatrix< m_complex > &m1, const MMatrix< m_complex > &m2)
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:297
m_complex m_complex_build(double r, double i)
Definition: MVector.h:62
MMatrix< Tmplt > operator/(MMatrix< Tmplt >, Tmplt)
Definition: MMatrix.h:312
MMatrix< Tmplt > & operator/=(MMatrix< Tmplt > &m, Tmplt t)
Definition: MMatrix.h:310
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:141
template std::istream & operator>>(std::istream &in, MMatrix< double > &mat)
MMatrix< Tmplt > sub(size_t min_row, size_t max_row, size_t min_col, size_t max_col) const
Definition: MMatrix.cpp:277
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:301
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
Tmplt determinant() const
returns matrix determinant; throws an exception if matrix is not square
friend MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
MVector< Tmplt > get_mvector(size_t column) const
Definition: MMatrix.cpp:428
size_t num_col() const
returns number of columns in the matrix
Mesh::Iterator & operator-=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
bool operator!=(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
Mesh::Iterator operator+(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
const gsl_matrix * MMatrix_to_gsl(const MMatrix< double > &m)
Definition: MMatrix.cpp:377
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
MMatrix< double > im(MMatrix< m_complex > mc)
Definition: MMatrix.cpp:398
MMatrix< double > & operator*=(MMatrix< double > &m1, MMatrix< double > m2)
Definition: MMatrix.cpp:332
friend const gsl_matrix * MMatrix_to_gsl(const MMatrix< double > &m)
Definition: MMatrix.cpp:377
MMatrix< Tmplt > T() const
returns matrix transpose T (such that M(i,j) = T(j,i))
Mesh::Iterator operator-(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
MMatrix< double > re(MMatrix< m_complex > mc)
Definition: MMatrix.cpp:389
bool operator!=(const Offset &off1, const Offset &off2)
Definition: Offset.cpp:225
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
Tmplt trace() const
returns sum of terms with row == column, even if matrix is not square
Definition: MMatrix.cpp:290
friend MMatrix< m_complex > & operator*=(MMatrix< m_complex > &m, m_complex c)
MMatrix< Tmplt > & operator=(const MMatrix< Tmplt > &mm)
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
void invert()
turns this matrix into its inverse
bool operator==(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
size_t num_row() const
returns number of rows in the matrix
bool operator==(const TwoPolynomial &left, const TwoPolynomial &right)