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  if(std::is_floating_point<DataType>::value)
98  {
99  switch ( sizeof(DataType) )
100  {
101  case sizeof(NekDouble):
102  break;
103  case sizeof(NekSingle):
104  break;
105  default:
106  ASSERTL0(false,
107  "Invert DataType is neither NekDouble nor NekSingle");
108  break;
109  }
110  }
111  else
112  {
113  ASSERTL0(false,
114  "FullMatrixFuncs::Invert DataType is not floating point");
115  }
116 
117  Lapack::DoSgetrf(m, n, data.get(), m, ipivot.get(), info);
118 
119  if( info < 0 )
120  {
121  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dgetrf";
122  ASSERTL0(false, message.c_str());
123  }
124  else if( info > 0 )
125  {
126  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dgetrf";
127  ASSERTL0(false, message.c_str());
128  }
129 
130  Lapack::DoSgetri(n, data.get(), n, ipivot.get(),
131  work.get(), n, info);
132 
133  if( info < 0 )
134  {
135  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dgetri";
136  ASSERTL0(false, message.c_str());
137  }
138  else if( info > 0 )
139  {
140  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dgetri";
141  ASSERTL0(false, message.c_str());
142  }
143  }
144 
145  template<typename DataType>
146  static void EigenSolve(unsigned int n,
148  Array<OneD, DataType> &EigValReal,
149  Array<OneD, DataType> &EigValImag,
150  Array<OneD, DataType> &EigVecs)
151  {
152  int lda = n,info = 0;
153  DataType dum;
154  char uplo = 'N';
155 
156  if(EigVecs.size() != 0) // calculate Right Eigen Vectors
157  {
158  int lwork = 4*lda;
159  Array<OneD,DataType> work(4*lda);
160  char lrev = 'V';
161  Lapack::DoSgeev(uplo,lrev,lda, A.get(),lda,
162  EigValReal.get(),
163  EigValImag.get(),
164  &dum,1,
165  EigVecs.get(),lda,
166  &work[0],lwork,info);
167  }
168  else
169  {
170  int lwork = 3*lda;
171  Array<OneD,DataType> work(3*lda);
172  char lrev = 'N';
173  Lapack::DoSgeev(uplo,lrev,lda,
174  A.get(),lda,
175  EigValReal.get(),
176  EigValImag.get(),
177  &dum,1,&dum,1,
178  &work[0],lwork,info);
179  }
180  ASSERTL0(info == 0,"Info is not zero");
181 
182  }
183  };
184 
186  {
187  static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
188  };
189 
191  {
192  static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn);
193 
194  static std::tuple<unsigned int, unsigned int>
195  Advance(const unsigned int totalRows, const unsigned int totalColumns,
196  const unsigned int curRow, const unsigned int curColumn);
197  };
198 
199 
201  {
202  static unsigned int CalculateIndex(unsigned int totalColumns, unsigned int curRow, unsigned int curColumn);
203 
204  static std::tuple<unsigned int, unsigned int>
205  Advance(const unsigned int totalRows, const unsigned int totalColumns,
206  const unsigned int curRow, const unsigned int curColumn,
207  char transpose = 'N');
208  };
209 
210  /// \internal
211  /// Symmetric matrices use upper triangular packed storage.
213  {
215 
216  static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn);
217 
218  template<typename DataType>
219  static void Invert(unsigned int rows, unsigned int columns,
220  Array<OneD, DataType>& data)
221  {
222  ASSERTL0(rows==columns, "Only square matrices can be inverted.");
223 
224  int n = columns;
225  int info = 0;
226  Array<OneD, int> ipivot(n);
227  Array<OneD, DataType> work(n);
228 
229  Lapack::DoSsptrf('U', n, data.get(), ipivot.get(), info);
230 
231  if( info < 0 )
232  {
233  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dsptrf";
234  ASSERTL0(false, message.c_str());
235  }
236  else if( info > 0 )
237  {
238  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dsptrf";
239  ASSERTL0(false, message.c_str());
240  }
241 
242  Lapack::DoSsptri('U', n, data.get(), ipivot.get(),
243  work.get(), info);
244 
245  if( info < 0 )
246  {
247  std::string message = "ERROR: The " + std::to_string(-info) + "th parameter had an illegal parameter for dsptri";
248  ASSERTL0(false, message.c_str());
249  }
250  else if( info > 0 )
251  {
252  std::string message = "ERROR: Element u_" + std::to_string(info) + std::to_string(info) + " is 0 from dsptri";
253  ASSERTL0(false, message.c_str());
254  }
255  }
256 
257  static std::tuple<unsigned int, unsigned int>
258  Advance(const unsigned int totalRows, const unsigned int totalColumns,
259  const unsigned int curRow, const unsigned int curColumn);
260  };
261 
263  {
264  static std::tuple<unsigned int, unsigned int>
265  Advance(const unsigned int totalRows, const unsigned int totalColumns,
266  const unsigned int curRow, const unsigned int curColumn);
267 
268  template<typename DataType>
269  static void Invert(unsigned int rows, unsigned int columns,
270  Array<OneD, DataType>& data)
271  {
272  ASSERTL0(rows==columns, "Only square matrices can be inverted.");
273  for(unsigned int i = 0; i < rows; ++i)
274  {
275  data[i] = 1.0/data[i];
276  }
277  }
278 
279  static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
280 
281  static unsigned int CalculateIndex(unsigned int row, unsigned int col);
282  };
283 
284 
286  {
287  static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns,
288  unsigned int nSubSuperDiags);
289  };
290 
292  {
293  };
294 
296  {
297  };
298 
299  /// \internal
300  /// Symmetric banded matrices use upper triangular banded packed storage.
302  {
304 
305  static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn,
306  unsigned int nSuperDiags);
307  };
308 
309 }
310 
311 #endif //NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_FUNCS_H
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define LIB_UTILITIES_EXPORT
1D Array of constant elements with garbage collection and bounds checking.
Definition: SharedArray.hpp:59
size_type size() const
Returns the array's size.
static void DoSsptrf(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:167
static void DoSsptri(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:217
static void DoSgetrf(const int &m, const int &n, double *a, const int &lda, int *ipiv, int &info)
General matrix LU factorisation.
Definition: Lapack.hpp:291
static void DoSgetri(const int &n, double *a, const int &lda, const int *ipiv, double *wk, const int &lwk, int &info)
Generate matrix inverse.
Definition: Lapack.hpp:320
static void DoSgeev(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:347
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
double NekDouble
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data)
Definition: MatrixFuncs.h:269
static void EigenSolve(unsigned int n, const Array< OneD, const DataType > &A, Array< OneD, DataType > &EigValReal, Array< OneD, DataType > &EigValImag, Array< OneD, DataType > &EigVecs)
Definition: MatrixFuncs.h:146
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data, const char transpose)
Definition: MatrixFuncs.h:84
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data)
Definition: MatrixFuncs.h:219
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns, unsigned int nSubSuperDiags)
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns)