37#ifndef NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_FUNCS_H
38#define NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_FUNCS_H
58 static unsigned int GetRequiredStorageSize(
unsigned int totalRows,
59 unsigned int totalColumns,
60 unsigned int subDiags,
61 unsigned int superDiags);
63 static unsigned int CalculateNumberOfDiags(
unsigned int totalRows,
66 static unsigned int CalculateNumberOfRows(
unsigned int totalRows,
67 unsigned int subDiags,
68 unsigned int superDiags);
70 static unsigned int CalculateIndex(
unsigned int totalRows,
71 unsigned int totalColumns,
72 unsigned int row,
unsigned int column,
73 unsigned int sub,
unsigned int super);
75 static std::tuple<unsigned int, unsigned int> Advance(
76 const unsigned int totalRows,
const unsigned int totalColumns,
77 const unsigned int curRow,
const unsigned int curColumn);
83 static unsigned int GetRequiredStorageSize(
unsigned int rows,
84 unsigned int columns);
85 static unsigned int CalculateIndex(
unsigned int totalRows,
86 unsigned int totalColumns,
88 unsigned int curColumn);
90 static std::tuple<unsigned int, unsigned int> Advance(
91 const unsigned int totalRows,
const unsigned int totalColumns,
92 const unsigned int curRow,
const unsigned int curColumn);
94 template <
typename DataType>
95 static void Invert(
unsigned int rows,
unsigned int columns,
98 ASSERTL0(rows == columns,
"Only square matrices can be inverted.");
100 "Only untransposed matrices may be inverted.");
108 if (std::is_floating_point_v<DataType>)
110 switch (
sizeof(DataType))
119 "Invert DataType is neither NekDouble nor NekSingle");
126 "FullMatrixFuncs::Invert DataType is not floating point");
133 std::string message =
134 "ERROR: The " + std::to_string(-info) +
135 "th parameter had an illegal parameter for dgetrf";
140 std::string message =
"ERROR: Element u_" + std::to_string(info) +
141 std::to_string(info) +
" is 0 from dgetrf";
150 std::string message =
151 "ERROR: The " + std::to_string(-info) +
152 "th parameter had an illegal parameter for dgetri";
157 std::string message =
"ERROR: Element u_" + std::to_string(info) +
158 std::to_string(info) +
" is 0 from dgetri";
165 template <
typename DataType>
175 int min_mn = std::min(m, n);
183 DataType wkopt = 0.0;
204 if (
sizeof(DataType) ==
sizeof(
NekDouble))
207 (
double *)s.data(), (
double *)u.data(), ldu,
208 (
double *)vt.data(), ldvt, (
double *)&wkopt, lwork,
211 else if (
sizeof(DataType) ==
sizeof(
NekSingle))
214 (
float *)s.data(), (
float *)u.data(), ldu,
215 (
float *)vt.data(), ldvt, (
float *)&wkopt, lwork,
222 "PseudoInverse DataType is neither NekDouble nor NekSingle");
224 lwork =
static_cast<int>(wkopt);
226 if (
sizeof(DataType) ==
sizeof(
NekDouble))
229 (
double *)s.data(), (
double *)u.data(), ldu,
230 (
double *)vt.data(), ldvt, (
double *)work.data(),
233 else if (
sizeof(DataType) ==
sizeof(
NekSingle))
236 (
float *)s.data(), (
float *)u.data(), ldu,
237 (
float *)vt.data(), ldvt, (
float *)work.data(),
242 std::string message =
"ERROR: The " + std::to_string(-info) +
243 "th parameter had an illegal value for gesvd";
248 std::string message =
"ERROR: SVD did not converge in gesvd";
253 DataType tol = std::numeric_limits<DataType>::epsilon() *
254 std::max(m, n) * std::abs(s[0]);
256 for (
int i = 0; i < min_mn; ++i)
258 if (std::abs(s[i]) > tol)
260 sinv[i] = 1.0 / s[i];
270 for (
int i = 0; i < min_mn; ++i)
272 for (
int j = 0; j < m; ++j)
274 temp[i + j * min_mn] = sinv[i] * u[j + i * ldu];
281 DataType alpha = 1.0;
283 if (
sizeof(DataType) ==
sizeof(
NekDouble))
285 Blas::Gemm(transa, transb, n, m, min_mn, alpha, (
double *)vt.data(),
286 ldvt, (
double *)temp.data(), min_mn,
beta,
287 (
double *)data.data(), n);
289 else if (
sizeof(DataType) ==
sizeof(
NekSingle))
291 Blas::Gemm(transa, transb, n, m, min_mn, (
float)alpha,
292 (
float *)vt.data(), ldvt, (
float *)temp.data(), min_mn,
293 (
float)
beta, (
float *)data.data(), n);
297 template <
typename DataType>
303 int lda = n, info = 0;
307 if (EigVecs.size() != 0)
313 EigValImag.data(), &dum, 1, EigVecs.data(), lda,
314 &work[0], lwork, info);
322 EigValImag.data(), &dum, 1, &dum, 1, &work[0],
325 ASSERTL0(info == 0,
"Info is not zero");
331 static unsigned int GetRequiredStorageSize(
unsigned int rows,
332 unsigned int columns);
338 static unsigned int CalculateIndex(
unsigned int curRow,
339 unsigned int curColumn);
341 static std::tuple<unsigned int, unsigned int> Advance(
342 const unsigned int totalRows,
const unsigned int totalColumns,
343 const unsigned int curRow,
const unsigned int curColumn);
349 static unsigned int CalculateIndex(
unsigned int totalColumns,
351 unsigned int curColumn);
353 static std::tuple<unsigned int, unsigned int> Advance(
354 const unsigned int totalRows,
const unsigned int totalColumns,
355 const unsigned int curRow,
const unsigned int curColumn,
356 char transpose =
'N');
363 using TriangularMatrixFuncs::GetRequiredStorageSize;
365 static unsigned int CalculateIndex(
unsigned int curRow,
366 unsigned int curColumn);
368 template <
typename DataType>
369 static void Invert(
unsigned int rows,
unsigned int columns,
372 ASSERTL0(rows == columns,
"Only square matrices can be inverted.");
383 std::string message =
384 "ERROR: The " + std::to_string(-info) +
385 "th parameter had an illegal parameter for dsptrf";
390 std::string message =
"ERROR: Element u_" + std::to_string(info) +
391 std::to_string(info) +
" is 0 from dsptrf";
399 std::string message =
400 "ERROR: The " + std::to_string(-info) +
401 "th parameter had an illegal parameter for dsptri";
406 std::string message =
"ERROR: Element u_" + std::to_string(info) +
407 std::to_string(info) +
" is 0 from dsptri";
412 static std::tuple<unsigned int, unsigned int> Advance(
413 const unsigned int totalRows,
const unsigned int totalColumns,
414 const unsigned int curRow,
const unsigned int curColumn);
419 static std::tuple<unsigned int, unsigned int> Advance(
420 const unsigned int totalRows,
const unsigned int totalColumns,
421 const unsigned int curRow,
const unsigned int curColumn);
423 template <
typename DataType>
424 static void Invert(
unsigned int rows,
unsigned int columns,
427 ASSERTL0(rows == columns,
"Only square matrices can be inverted.");
428 for (
unsigned int i = 0; i < rows; ++i)
430 data[i] = 1.0 / data[i];
434 static unsigned int GetRequiredStorageSize(
unsigned int rows,
435 unsigned int columns);
437 static unsigned int CalculateIndex(
unsigned int row,
unsigned int col);
442 static unsigned int GetRequiredStorageSize(
unsigned int rows,
443 unsigned int columns,
444 unsigned int nSubSuperDiags);
462 using TriangularBandedMatrixFuncs::GetRequiredStorageSize;
464 static unsigned int CalculateIndex(
unsigned int curRow,
465 unsigned int curColumn,
466 unsigned int nSuperDiags);
#define ASSERTL0(condition, msg)
#define LIB_UTILITIES_EXPORT
static void Gemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
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.
static void DoSsptri(const char &uplo, const int &n, const double *ap, const int *ipiv, double *work, int &info)
Invert a real packed-symmetric matrix problem.
static void DoSgetrf(const int &m, const int &n, double *a, const int &lda, int *ipiv, int &info)
General matrix LU factorisation.
static void Sgesvd(const char &jobu, const char &jobvt, const int &m, const int &n, float *a, const int &lda, float *s, float *u, const int &ldu, float *vt, const int &ldvt, float *work, const int &lwork, int &info)
Singular Value Decomposition (SVD) of a real matrix (single precision)
static void DoSgetri(const int &n, double *a, const int &lda, const int *ipiv, double *wk, const int &lwk, int &info)
General matrix inverse.
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.
static void Dgesvd(const char &jobu, const char &jobvt, const int &m, const int &n, double *a, const int &lda, double *s, double *u, const int &ldu, double *vt, const int &ldvt, double *work, const int &lwork, int &info)
Singular Value Decomposition (SVD) of a real matrix (double precision)
@ beta
Gauss Radau pinned at x=-1,.
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data)
static void PseudoInverse(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data)
static void EigenSolve(unsigned int n, const Array< OneD, const DataType > &A, Array< OneD, DataType > &EigValReal, Array< OneD, DataType > &EigValImag, Array< OneD, DataType > &EigVecs)
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data, const char transpose)
static void Invert(unsigned int rows, unsigned int columns, Array< OneD, DataType > &data)