16 #include <deal.II/base/numbers.h> 18 #include <deal.II/lac/blas_extension_templates.h> 19 #include <deal.II/lac/block_vector.h> 20 #include <deal.II/lac/full_matrix.h> 21 #include <deal.II/lac/lapack_full_matrix.h> 22 #include <deal.II/lac/lapack_support.h> 23 #include <deal.II/lac/lapack_templates.h> 24 #include <deal.II/lac/sparse_matrix.h> 25 #include <deal.II/lac/utilities.h> 26 #include <deal.II/lac/vector.h> 31 DEAL_II_NAMESPACE_OPEN
37 namespace LAPACKFullMatrixImplementation
47 geev_helper(
const char vl,
51 std::vector<T> & real_part_eigenvalues,
52 std::vector<T> & imag_part_eigenvalues,
53 std::vector<T> & left_eigenvectors,
54 std::vector<T> & right_eigenvectors,
55 std::vector<T> & real_work,
60 static_assert(std::is_same<T, double>::value ||
61 std::is_same<T, float>::value,
62 "Only implemented for double and float");
63 Assert(
matrix.size() ==
static_cast<std::size_t
>(n_rows * n_rows),
65 Assert(static_cast<std::size_t>(n_rows) <= real_part_eigenvalues.size(),
67 Assert(static_cast<std::size_t>(n_rows) <= imag_part_eigenvalues.size(),
70 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
71 left_eigenvectors.size(),
74 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
75 right_eigenvectors.size(),
78 static_cast<std::size_t>(2 * n_rows) <= real_work.size(),
80 Assert(work_flag == -1 || std::max<long int>(1, 3 * n_rows) <= work_flag,
87 real_part_eigenvalues.data(),
88 imag_part_eigenvalues.data(),
89 left_eigenvectors.data(),
91 right_eigenvectors.data(),
100 geev_helper(
const char vl,
106 std::vector<std::complex<T>> &left_eigenvectors,
107 std::vector<std::complex<T>> &right_eigenvectors,
108 std::vector<std::complex<T>> &complex_work,
109 std::vector<T> & real_work,
114 std::is_same<T, double>::value || std::is_same<T, float>::value,
115 "Only implemented for std::complex<double> and std::complex<float>");
116 Assert(
matrix.size() ==
static_cast<std::size_t
>(n_rows * n_rows),
121 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
122 left_eigenvectors.size(),
125 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
126 right_eigenvectors.size(),
128 Assert(std::max<std::size_t>(1, work_flag) <= real_work.size(),
131 std::max<long int>(1, 2 * n_rows) <= (work_flag),
140 left_eigenvectors.data(),
142 right_eigenvectors.data(),
152 template <
typename T>
154 gesdd_helper(
const char job,
158 std::vector<T> & singular_values,
161 std::vector<T> & real_work,
163 std::vector<types::blas_int> &integer_work,
167 Assert(job ==
'A' || job ==
'S' || job ==
'O' || job ==
'N',
169 Assert(static_cast<std::size_t>(n_rows * n_cols) ==
matrix.size(),
171 Assert(std::min<std::size_t>(n_rows, n_cols) <= singular_values.size(),
173 Assert(8 * std::min<std::size_t>(n_rows, n_cols) <= integer_work.size(),
176 static_cast<std::size_t>(work_flag) <= real_work.size(),
183 singular_values.data(),
186 right_vectors.
data(),
196 template <
typename T>
198 gesdd_helper(
const char job,
202 std::vector<T> & singular_values,
205 std::vector<std::complex<T>> & work,
206 std::vector<T> & real_work,
207 std::vector<types::blas_int> & integer_work,
211 Assert(job ==
'A' || job ==
'S' || job ==
'O' || job ==
'N',
213 Assert(static_cast<std::size_t>(n_rows * n_cols) ==
matrix.size(),
215 Assert(static_cast<std::size_t>(std::min(n_rows, n_cols)) <=
216 singular_values.size(),
218 Assert(8 * std::min<std::size_t>(n_rows, n_cols) <= integer_work.size(),
221 static_cast<std::size_t>(work_flag) <= real_work.size(),
229 singular_values.data(),
232 right_vectors.
data(),
243 template <
typename number>
251 template <
typename number>
259 template <
typename number>
267 template <
typename number>
279 template <
typename number>
289 template <
typename number>
293 const size_type s = std::min(std::min(this->m(), n), this->n());
298 (*
this)(i, j) = copy(i, j);
303 template <
typename number>
306 const std::array<number, 3> &csr,
319 const number t = A(i, j);
320 A(i, j) = csr[0] * A(i, j) + csr[1] * A(k, j);
321 A(k, j) = -csr[1] * t + csr[0] * A(k, j);
328 const number t = A(j, i);
329 A(j, i) = csr[0] * A(j, i) + csr[1] * A(j, k);
330 A(j, k) = -csr[1] * t + csr[0] * A(j, k);
337 template <
typename number>
353 const size_type jj = (j < col ? j : j + 1);
356 const size_type ii = (i < row ? i : i + 1);
357 (*this)(i, j) = copy(ii, jj);
364 template <
typename number>
373 template <
typename number>
374 template <
typename number2>
380 for (
size_type i = 0; i < this->m(); ++i)
381 for (
size_type j = 0; j < this->n(); ++j)
382 (*
this)(i, j) = M(i, j);
390 template <
typename number>
391 template <
typename number2>
397 for (
size_type i = 0; i < this->m(); ++i)
398 for (
size_type j = 0; j < this->n(); ++j)
399 (*
this)(i, j) = M.
el(i, j);
407 template <
typename number>
414 if (this->n_elements() != 0)
415 this->reset_values();
422 template <
typename number>
431 const char type =
'G';
432 const number cfrom = 1.;
439 number * values = this->values.data();
441 lascl(&type, &kl, &kl, &cfrom, &factor, &m, &n, values, &lda, &info);
450 template <
typename number>
461 const char type =
'G';
462 const number cto = 1.;
469 number * values = this->values.data();
471 lascl(&type, &kl, &kl, &factor, &cto, &m, &n, values, &lda, &info);
481 template <
typename number>
499 number * values = this->values.data();
502 axpy(&n, &a, values_A, &inc, values, &inc);
509 template <
typename number>
538 const std::array<number, 3> csr =
544 const number t = A(i, k);
545 A(i, k) = csr[0] * A(i, k) + csr[1] * z(i);
546 z(i) = -csr[1] * t + csr[0] * z(i);
581 const std::array<number, 3> csr =
587 const number t = A(i, k);
588 A(i, k) = csr[0] * A(i, k) - csr[1] * z(i);
589 z(i) = -csr[1] * t + csr[0] * z(i);
596 template <
typename number>
599 const std::complex<number> ,
600 const Vector<std::complex<number>> & )
608 template <
typename number>
627 syr(&uplo, &N, &a, v.
begin(), &incx, this->values.begin(), &lda);
636 (*
this)(i, j) = (*
this)(j, i);
640 cholesky_rank1(*
this, a, v);
648 template <
typename number>
652 const bool adding)
const 656 const number alpha = 1.;
657 const number beta = (adding ? 1. : 0.);
658 const number null = 0.;
662 (mm == nn) && state ==
matrix)
669 const char diag =
'N';
670 const char trans =
'N';
681 &uplo, &trans, &diag, &N, this->values.data(), &lda, w.data(), &incx);
709 std::lock_guard<std::mutex> lock(mutex);
713 work.resize(std::max(mm, nn));
718 svd_vt->values.data(),
726 for (
size_type i = 0; i < wr.size(); ++i)
733 svd_u->values.data(),
744 std::lock_guard<std::mutex> lock(mutex);
748 work.resize(std::max(mm, nn));
753 svd_u->values.data(),
761 for (
size_type i = 0; i < wr.size(); ++i)
768 svd_vt->values.data(),
783 template <
typename number>
787 const bool adding)
const 791 const number alpha = 1.;
792 const number beta = (adding ? 1. : 0.);
793 const number null = 0.;
797 (mm == nn) && state ==
matrix)
804 const char diag =
'N';
805 const char trans =
'T';
816 &uplo, &trans, &diag, &N, this->values.data(), &lda, w.data(), &incx);
845 std::lock_guard<std::mutex> lock(mutex);
850 work.resize(std::max(mm, nn));
855 svd_u->values.data(),
863 for (
size_type i = 0; i < wr.size(); ++i)
870 svd_vt->values.data(),
881 std::lock_guard<std::mutex> lock(mutex);
886 work.resize(std::max(mm, nn));
891 svd_vt->values.data(),
899 for (
size_type i = 0; i < wr.size(); ++i)
906 svd_u->values.data(),
921 template <
typename number>
930 template <
typename number>
939 template <
typename number>
943 const bool adding)
const 954 const number alpha = 1.;
955 const number beta = (adding ? 1. : 0.);
973 template <
typename number>
977 const bool adding)
const 987 const number alpha = 1.;
988 const number beta = (adding ? 1. : 0.);
1000 this->values.data(),
1009 template <
typename number>
1014 const bool adding)
const 1036 std::lock_guard<std::mutex> lock(mutex);
1038 work.resize(kk * nn);
1045 Assert(j * kk + i < static_cast<types::blas_int>(work.size()),
1047 work[j * kk + i] = V(i) * B(i, j);
1051 const number alpha = 1.;
1052 const number beta = (adding ? 1. : 0.);
1060 this->values.data(),
1071 template <
typename number>
1080 #ifdef DEAL_II_LAPACK_WITH_MKL 1081 const number one = 1.;
1091 template <
typename number>
1108 template <
typename number>
1112 const bool adding)
const 1123 const number alpha = 1.;
1124 const number beta = (adding ? 1. : 0.);
1133 this->values.data(),
1154 this->values.data(),
1165 template <
typename number>
1169 const bool adding)
const 1179 const number alpha = 1.;
1180 const number beta = (adding ? 1. : 0.);
1192 this->values.data(),
1200 template <
typename number>
1204 const bool adding)
const 1215 const number alpha = 1.;
1216 const number beta = (adding ? 1. : 0.);
1225 this->values.data(),
1246 this->values.data(),
1258 template <
typename number>
1262 const bool adding)
const 1272 const number alpha = 1.;
1273 const number beta = (adding ? 1. : 0.);
1285 this->values.data(),
1293 template <
typename number>
1297 const bool adding)
const 1308 const number alpha = 1.;
1309 const number beta = (adding ? 1. : 0.);
1317 this->values.data(),
1327 template <
typename number>
1331 const bool adding)
const 1341 const number alpha = 1.;
1342 const number beta = (adding ? 1. : 0.);
1354 this->values.data(),
1362 template <
typename number>
1371 number *
const values = this->values.data();
1374 getrf(&mm, &nn, values, &mm, ipiv.data(), &info);
1386 template <
typename number>
1395 template <
typename number>
1399 const char type(
'O');
1405 template <
typename number>
1409 const char type(
'I');
1415 template <
typename number>
1419 const char type(
'F');
1425 template <
typename number>
1429 std::lock_guard<std::mutex> lock(mutex);
1433 ExcMessage(
"norms can be called in matrix state only."));
1437 const number *
const values = this->values.data();
1442 (type ==
'I' || type ==
'O') ? std::max<types::blas_int>(1, N) : 0;
1450 (type ==
'I') ? std::max<types::blas_int>(1, M) : 0;
1452 return lange(&type, &M, &N, values, &lda, work.data());
1458 template <
typename number>
1464 ExcMessage(
"Trace can be called in matrix state only."));
1468 for (
size_type i = 0; i < this->m(); ++i)
1469 tr += (*
this)(i, i);
1476 template <
typename number>
1489 number *
const values = this->values.data();
1503 template <
typename number>
1507 std::lock_guard<std::mutex> lock(mutex);
1512 const number * values = this->values.data();
1536 template <
typename number>
1540 std::lock_guard<std::mutex> lock(mutex);
1546 const number *
const values = this->values.data();
1552 const char norm =
'1';
1553 const char diag =
'N';
1574 template <
typename number>
1583 wr.resize(std::max(mm, nn));
1584 std::fill(wr.begin(), wr.end(), 0.);
1585 ipiv.resize(8 * mm);
1587 svd_u = std_cxx14::make_unique<LAPACKFullMatrix<number>>(mm, mm);
1588 svd_vt = std_cxx14::make_unique<LAPACKFullMatrix<number>>(nn, nn);
1596 std::vector<typename numbers::NumberTraits<number>::real_type> real_work;
1600 std::size_t
min = std::min(this->m(), this->n());
1601 std::size_t
max = std::max(this->m(), this->n());
1650 template <
typename number>
1660 const double lim = std::abs(wr[0]) * threshold;
1661 for (
size_type i = 0; i < wr.size(); ++i)
1663 if (std::abs(wr[i]) > lim)
1664 wr[i] = one / wr[i];
1673 template <
typename number>
1676 const unsigned int kernel_size)
1684 const unsigned int n_wr = wr.size();
1685 for (
size_type i = 0; i < n_wr - kernel_size; ++i)
1686 wr[i] = one / wr[i];
1687 for (
size_type i = n_wr - kernel_size; i < n_wr; ++i)
1694 template <
typename number>
1703 number *
const values = this->values.data();
1709 compute_lu_factorization();
1712 inv_work.resize(mm);
1713 getri(&mm, values, &mm, ipiv.data(), inv_work.data(), &mm, &info);
1718 compute_cholesky_factorization();
1726 this->el(i, j) = this->el(j, i);
1737 template <
typename number>
1743 const char * trans = transposed ? &T : &N;
1745 const number *
const values = this->values.data();
1752 trans, &nn, &n_rhs, values, &nn, ipiv.data(), v.
begin(), &nn, &info);
1766 &uplo, trans,
"N", &nn, &n_rhs, values, &lda, v.
begin(), &ldb, &info);
1772 "The matrix has to be either factorized or triangular."));
1780 template <
typename number>
1783 const bool transposed)
const 1789 const char * trans = transposed ? &T : &N;
1791 const number *
const values = this->values.data();
1840 "The matrix has to be either factorized or triangular."));
1848 template <
typename number>
1851 const bool transposed)
const 1853 solve(v, transposed);
1858 template <
typename number>
1861 const bool transposed)
const 1863 solve(B, transposed);
1868 template <
typename number>
1892 for (
size_type i = 0; i < this->m(); ++i)
1894 (ipiv[i] ==
types::blas_int(i + 1) ? this->el(i, i) : -this->el(i, i));
1899 template <
typename number>
1914 const char jobvr = (right) ? V : N;
1915 const char jobvl = (left) ? V : N;
1929 std::vector<typename numbers::NumberTraits<number>::real_type> real_work;
1932 real_work.resize(2 * this->m());
1933 internal::LAPACKFullMatrixImplementation::geev_helper(jobvl,
1957 internal::LAPACKFullMatrixImplementation::geev_helper(jobvl,
1973 std::cerr <<
"LAPACK error in geev" << std::endl;
1979 template <
typename number>
1982 const number lower_bound,
1983 const number upper_bound,
1984 const number abs_accuracy,
1995 number *
const values_A = this->values.data();
1996 number *
const values_eigenvectors = matrix_eigenvectors.
values.
data();
1999 const char *
const jobz(&V);
2000 const char *
const uplo(&U);
2001 const char *
const range(&V);
2003 std::vector<types::blas_int> iwork(static_cast<size_type>(5 * nn));
2004 std::vector<types::blas_int> ifail(static_cast<size_type>(nn));
2031 values_eigenvectors,
2044 work.resize(static_cast<size_type>(lwork));
2060 values_eigenvectors,
2071 std::cerr <<
"LAPACK error in syevx" << std::endl;
2076 for (
size_type i = 0; i < static_cast<size_type>(n_eigenpairs); ++i)
2080 for (
size_type j = 0; j < static_cast<size_type>(nn); ++j)
2082 eigenvectors(j, i) = values_eigenvectors[col_begin + j];
2090 template <
typename number>
2094 const number lower_bound,
2095 const number upper_bound,
2096 const number abs_accuracy,
2110 number *
const values_A = this->values.data();
2112 number *
const values_eigenvectors = matrix_eigenvectors.
values.
data();
2115 const char *
const jobz(&V);
2116 const char *
const uplo(&U);
2117 const char *
const range(&V);
2119 iwork.resize(static_cast<size_type>(5 * nn));
2120 std::vector<types::blas_int> ifail(static_cast<size_type>(nn));
2150 values_eigenvectors,
2165 work.resize(static_cast<size_type>(lwork));
2184 values_eigenvectors,
2195 std::cerr <<
"LAPACK error in sygvx" << std::endl;
2200 for (
size_type i = 0; i < static_cast<size_type>(n_eigenpairs); ++i)
2205 for (
size_type j = 0; j < static_cast<size_type>(nn); ++j)
2207 eigenvectors[i](j) = values_eigenvectors[col_begin + j];
2215 template <
typename number>
2228 ExcMessage(
"eigenvectors.size() > matrix.n()"));
2234 number *
const values_A = this->values.data();
2239 const char *
const jobz = (
eigenvectors.size() > 0) ? (&V) : (&N);
2240 const char *
const uplo = (&U);
2273 work.resize(static_cast<size_type>(lwork));
2292 std::cerr <<
"LAPACK error in sygv" << std::endl;
2298 for (
size_type j = 0; j < static_cast<size_type>(nn); ++j)
2307 template <
typename number>
2310 const unsigned int precision,
2311 const bool scientific,
2312 const unsigned int width_,
2313 const char * zero_string,
2314 const double denominator,
2315 const double threshold)
const 2317 unsigned int width = width_;
2327 std::ios::fmtflags old_flags = out.flags();
2328 std::streamsize old_precision = out.precision(precision);
2332 out.setf(std::ios::scientific, std::ios::floatfield);
2334 width = precision + 7;
2338 out.setf(std::ios::fixed, std::ios::floatfield);
2340 width = precision + 2;
2343 for (
size_type i = 0; i < this->m(); ++i)
2350 if (std::isnan(std::abs((*
this)(i, j))))
2351 out << std::setw(width) << (*this)(i, j) <<
' ';
2352 else if (std::abs(this->el(i, j)) > threshold)
2353 out << std::setw(width) << this->el(i, j) * denominator <<
' ';
2355 out << std::setw(width) << zero_string <<
' ';
2361 out.flags(old_flags);
2362 out.precision(old_precision);
2368 template <
typename number>
2377 template <
typename number>
2387 template <
typename number>
2393 matrix->apply_lu_factorization(dst,
false);
2397 template <
typename number>
2403 matrix->apply_lu_factorization(dst,
true);
2407 template <
typename number>
2415 matrix->apply_lu_factorization(*aux,
false);
2420 template <
typename number>
2428 matrix->apply_lu_factorization(*aux,
true);
2434 #include "lapack_full_matrix.inst" 2437 DEAL_II_NAMESPACE_CLOSE
LAPACKFullMatrix(const size_type size=0)
#define AssertDimension(dim1, dim2)
void rank1_update(const number a, const Vector< number > &v)
void TmTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
LAPACKFullMatrix< number > & operator/=(const number factor)
Contents is actually a matrix.
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
static ::ExceptionBase & ExcIO()
LAPACKSupport::State state
typename TableBase< 2, T >::size_type size_type
void remove_row_and_column(const size_type row, const size_type col)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
static ::ExceptionBase & ExcScalarAssignmentOnlyForZeroValue()
Matrix is upper triangular.
Contents is the inverse of a matrix.
#define AssertIndexRange(index, range)
void apply_givens_rotation(const std::array< number, 3 > &csr, const size_type i, const size_type k, const bool left=true)
static ::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcErrorCode(std::string arg1, types::blas_int arg2)
void compute_eigenvalues_symmetric(const number lower_bound, const number upper_bound, const number abs_accuracy, Vector< number > &eigenvalues, FullMatrix< number > &eigenvectors)
void reinit(const size_type size)
number norm(const char type) const
void Tmmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
LinearAlgebra::distributed::Vector< Number > Vector
static ::ExceptionBase & ExcSingular()
static ::ExceptionBase & ExcState(State arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
void mTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
Contents is a Cholesky decomposition.
VectorizedArray< Number > min(const ::VectorizedArray< Number > &x, const ::VectorizedArray< Number > &y)
#define Assert(cond, exc)
void compute_inverse_svd_with_kernel(const unsigned int kernel_size)
std::make_unsigned< types::blas_int >::type size_type
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void add(const number a, const LAPACKFullMatrix< number > &B)
void reinit(const size_type size1, const size_type size2, const bool omit_default_initialization=false)
void transpose(LAPACKFullMatrix< number > &B) const
Contents is something useless.
std::array< NumberType, 3 > hyperbolic_rotation(const NumberType &x, const NumberType &y)
Matrix is the inverse of a singular value decomposition.
void compute_lu_factorization()
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
void print_formatted(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const unsigned int width=0, const char *zero_string=" ", const double denominator=1., const double threshold=0.) const
void grow_or_shrink(const size_type size)
void scale_rows(const Vector< number > &V)
LAPACKFullMatrix< number > & operator*=(const number factor)
void compute_inverse_svd(const double threshold=0.)
static ::ExceptionBase & ExcNotQuadratic()
void compute_cholesky_factorization()
number linfty_norm() const
LAPACKFullMatrix< number > & operator=(const LAPACKFullMatrix< number > &)
TableBase< N, T > & operator=(const TableBase< N, T > &src)
number el(const size_type i, const size_type j) const
std::array< NumberType, 3 > givens_rotation(const NumberType &x, const NumberType &y)
number determinant() const
number frobenius_norm() const
void Tvmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
Matrix contains singular value decomposition,.
void set_property(const LAPACKSupport::Property property)
void solve(Vector< number > &v, const bool transposed=false) const
void compute_generalized_eigenvalues_symmetric(LAPACKFullMatrix< number > &B, const number lower_bound, const number upper_bound, const number abs_accuracy, Vector< number > &eigenvalues, std::vector< Vector< number >> &eigenvectors, const types::blas_int itype=1)
void compute_eigenvalues(const bool right_eigenvectors=false, const bool left_eigenvectors=false)
static ::ExceptionBase & ExcNotImplemented()
static constexpr const number & conjugate(const number &x)
void apply_lu_factorization(Vector< number > &v, const bool transposed) const
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
number reciprocal_condition_number() const
Eigenvalue vector is filled.
AlignedVector< number > values
static ::ExceptionBase & ExcProperty(Property arg1)
LAPACKSupport::Property property
static ::ExceptionBase & ExcZero()
Matrix is lower triangular.
#define AssertIsFinite(number)
void vmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
VectorizedArray< Number > max(const ::VectorizedArray< Number > &x, const ::VectorizedArray< Number > &y)
void mmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
static bool equal(const T *p1, const T *p2)
static ::ExceptionBase & ExcInternalError()
Contents is an LU decomposition.