Nektar++
MatrixFuncs.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: MatrixFuncs.h
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Matrix functions that depend on storage policy. Putting
32 // methods in these separate classes makes it easier to use them from
33 // normal, scaled, and block matrices.
34 //
35 ///////////////////////////////////////////////////////////////////////////////
36 
37 #ifndef NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_FUNCS_H
38 #define NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_FUNCS_H
39 
40 #include <limits>
41 #include <tuple>
45 
46 namespace Nektar
47 {
49  {
50  /// \brief Calculates and returns the storage size required.
51  ///
52  /// This method assumes that the matrix will be used with LU factorizationa and
53  /// allocates additional storage as appropriate.
54  static unsigned int GetRequiredStorageSize(unsigned int totalRows, unsigned int totalColumns,
55  unsigned int subDiags, unsigned int superDiags);
56 
57  static unsigned int CalculateNumberOfDiags(unsigned int totalRows, unsigned int diags);
58 
59  static unsigned int CalculateNumberOfRows(unsigned int totalRows, unsigned int subDiags, unsigned int superDiags);
60 
61  static unsigned int CalculateIndex(unsigned int totalRows,
62  unsigned int totalColumns,
63  unsigned int row, unsigned int column,
64  unsigned int sub, unsigned int super);
65 
66 
67  static std::tuple<unsigned int, unsigned int>
68  Advance(const unsigned int totalRows, const unsigned int totalColumns,
69  const unsigned int curRow, const unsigned int curColumn);
70  };
71 
73  {
74 
75  static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
76  static unsigned int CalculateIndex(unsigned int totalRows, unsigned int totalColumns, unsigned int curRow, unsigned int curColumn);
77 
78 
79  static std::tuple<unsigned int, unsigned int>
80  Advance(const unsigned int totalRows, const unsigned int totalColumns,
81  const unsigned int curRow, const unsigned int curColumn);
82 
83  template<typename DataType>
84  static void Invert(unsigned int rows, unsigned int columns,
86  const char transpose)
87  {
88  ASSERTL0(rows==columns, "Only square matrices can be inverted.");
89  ASSERTL0(transpose=='N', "Only untransposed matrices may be inverted.");
90 
91  int m = rows;
92  int n = columns;
93  int info = 0;
94  Array<OneD, int> ipivot(n);
95  Array<OneD, DataType> work(n);
96 
97  Lapack::Dgetrf(m, n, data.get(), m, ipivot.get(), info);
98 
99  if( info < 0 )
100  {
101  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dgetrf";
102  ASSERTL0(false, message.c_str());
103  }
104  else if( info > 0 )
105  {
106  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dgetrf";
107  ASSERTL0(false, message.c_str());
108  }
109 
110  Lapack::Dgetri(n, data.get(), n, ipivot.get(),
111  work.get(), n, info);
112 
113  if( info < 0 )
114  {
115  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dgetri";
116  ASSERTL0(false, message.c_str());
117  }
118  else if( info > 0 )
119  {
120  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dgetri";
121  ASSERTL0(false, message.c_str());
122  }
123  }
124 
125  static void EigenSolve(unsigned int n,
127  Array<OneD, NekDouble> &EigValReal,
128  Array<OneD, NekDouble> &EigValImag,
130  {
131  int lda = n,info = 0;
132  NekDouble dum;
133  char uplo = 'N';
134 
135  if(EigVecs != NullNekDouble1DArray) // calculate Right Eigen Vectors
136  {
137  int lwork = 4*lda;
138  Array<OneD,NekDouble> work(4*lda);
139  char lrev = 'V';
140  Lapack::Dgeev(uplo,lrev,lda, A.get(),lda,
141  EigValReal.get(),
142  EigValImag.get(),
143  &dum,1,
144  EigVecs.get(),lda,
145  &work[0],lwork,info);
146  }
147  else
148  {
149  int lwork = 3*lda;
150  Array<OneD,NekDouble> work(3*lda);
151  char lrev = 'N';
152  Lapack::Dgeev(uplo,lrev,lda,
153  A.get(),lda,
154  EigValReal.get(),
155  EigValImag.get(),
156  &dum,1,&dum,1,
157  &work[0],lwork,info);
158  }
159  ASSERTL0(info == 0,"Info is not zero");
160 
161  }
162  };
163 
165  {
166  static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
167  };
168 
170  {
171  static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn);
172 
173  static std::tuple<unsigned int, unsigned int>
174  Advance(const unsigned int totalRows, const unsigned int totalColumns,
175  const unsigned int curRow, const unsigned int curColumn);
176  };
177 
178 
180  {
181  static unsigned int CalculateIndex(unsigned int totalColumns, unsigned int curRow, unsigned int curColumn);
182 
183  static std::tuple<unsigned int, unsigned int>
184  Advance(const unsigned int totalRows, const unsigned int totalColumns,
185  const unsigned int curRow, const unsigned int curColumn,
186  char transpose = 'N');
187  };
188 
189  /// \internal
190  /// Symmetric matrices use upper triangular packed storage.
192  {
194 
195  static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn);
196 
197  template<typename DataType>
198  static void Invert(unsigned int rows, unsigned int columns,
199  Array<OneD, DataType>& data)
200  {
201  ASSERTL0(rows==columns, "Only square matrices can be inverted.");
202 
203  int n = columns;
204  int info = 0;
205  Array<OneD, int> ipivot(n);
206  Array<OneD, DataType> work(n);
207 
208  Lapack::Dsptrf('U', n, data.get(), ipivot.get(), info);
209 
210  if( info < 0 )
211  {
212  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dsptrf";
213  ASSERTL0(false, message.c_str());
214  }
215  else if( info > 0 )
216  {
217  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dsptrf";
218  ASSERTL0(false, message.c_str());
219  }
220 
221  Lapack::Dsptri('U', n, data.get(), ipivot.get(),
222  work.get(), info);
223 
224  if( info < 0 )
225  {
226  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dsptri";
227  ASSERTL0(false, message.c_str());
228  }
229  else if( info > 0 )
230  {
231  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dsptri";
232  ASSERTL0(false, message.c_str());
233  }
234  }
235 
236  static std::tuple<unsigned int, unsigned int>
237  Advance(const unsigned int totalRows, const unsigned int totalColumns,
238  const unsigned int curRow, const unsigned int curColumn);
239  };
240 
242  {
243  static std::tuple<unsigned int, unsigned int>
244  Advance(const unsigned int totalRows, const unsigned int totalColumns,
245  const unsigned int curRow, const unsigned int curColumn);
246 
247  template<typename DataType>
248  static void Invert(unsigned int rows, unsigned int columns,
249  Array<OneD, DataType>& data)
250  {
251  ASSERTL0(rows==columns, "Only square matrices can be inverted.");
252  for(unsigned int i = 0; i < rows; ++i)
253  {
254  data[i] = 1.0/data[i];
255  }
256  }
257 
258  static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
259 
260  static unsigned int CalculateIndex(unsigned int row, unsigned int col);
261  };
262 
263 
265  {
266  static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns,
267  unsigned int nSubSuperDiags);
268  };
269 
271  {
272  };
273 
275  {
276  };
277 
278  /// \internal
279  /// Symmetric banded matrices use upper triangular banded packed storage.
281  {
283 
284  static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn,
285  unsigned int nSuperDiags);
286  };
287 
288 }
289 
290 #endif //NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_FUNCS_H
static void Dgetrf(const int &m, const int &n, double *a, const int &lda, int *ipiv, int &info)
General matrix LU factorisation.
Definition: Lapack.hpp:183
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
static void Dgetri(const int &n, double *a, const int &lda, const int *ipiv, double *wk, const int &lwk, int &info)
Generate matrix inverse.
Definition: Lapack.hpp:198
static Array< OneD, NekDouble > NullNekDouble1DArray
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data, const char transpose)
Definition: MatrixFuncs.h:84
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns)
static void Dgeev(const char &uplo, const char &lrev, const int &n, const double *a, const int &lda, double *wr, double *wi, double *rev, const int &ldr, double *lev, const int &ldv, double *work, const int &lwork, int &info)
Solve general real matrix eigenproblem.
Definition: Lapack.hpp:211
static void Dsptri(const char &uplo, const int &n, const double *ap, const int *ipiv, double *work, int &info)
Invert a real symmetric matrix problem.
Definition: Lapack.hpp:123
#define LIB_UTILITIES_EXPORT
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns, unsigned int nSubSuperDiags)
double NekDouble
static void EigenSolve(unsigned int n, const Array< OneD, const double > &A, Array< OneD, NekDouble > &EigValReal, Array< OneD, NekDouble > &EigValImag, Array< OneD, NekDouble > &EigVecs=NullNekDouble1DArray)
Definition: MatrixFuncs.h:125
static void Dsptrf(const char &uplo, const int &n, double *ap, int *ipiv, int &info)
factor a real packed-symmetric matrix using Bunch-Kaufman pivoting.
Definition: Lapack.hpp:107
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data)
Definition: MatrixFuncs.h:198
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data)
Definition: MatrixFuncs.h:248