16 #include <deal.II/base/numbers.h> 18 #include <deal.II/lac/block_vector.h> 19 #include <deal.II/lac/full_matrix.h> 20 #include <deal.II/lac/lapack_full_matrix.h> 21 #include <deal.II/lac/lapack_support.h> 22 #include <deal.II/lac/lapack_templates.h> 23 #include <deal.II/lac/sparse_matrix.h> 24 #include <deal.II/lac/utilities.h> 25 #include <deal.II/lac/vector.h> 30 DEAL_II_NAMESPACE_OPEN
36 namespace LAPACKFullMatrixImplementation
46 geev_helper(
const char vl,
50 std::vector<T> & real_part_eigenvalues,
51 std::vector<T> & imag_part_eigenvalues,
52 std::vector<T> & left_eigenvectors,
53 std::vector<T> & right_eigenvectors,
54 std::vector<T> & real_work,
59 static_assert(std::is_same<T, double>::value ||
60 std::is_same<T, float>::value,
61 "Only implemented for double and float");
62 Assert(matrix.
size() ==
static_cast<std::size_t
>(n_rows * n_rows),
64 Assert(static_cast<std::size_t>(n_rows) <= real_part_eigenvalues.size(),
66 Assert(static_cast<std::size_t>(n_rows) <= imag_part_eigenvalues.size(),
69 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
70 left_eigenvectors.size(),
73 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
74 right_eigenvectors.size(),
77 static_cast<std::size_t>(2 * n_rows) <= real_work.size(),
79 Assert(work_flag == -1 || std::max<long int>(1, 3 * n_rows) <= work_flag,
86 real_part_eigenvalues.data(),
87 imag_part_eigenvalues.data(),
88 left_eigenvectors.data(),
90 right_eigenvectors.data(),
99 geev_helper(
const char vl,
105 std::vector<std::complex<T>> &left_eigenvectors,
106 std::vector<std::complex<T>> &right_eigenvectors,
107 std::vector<std::complex<T>> &complex_work,
108 std::vector<T> & real_work,
113 std::is_same<T, double>::value || std::is_same<T, float>::value,
114 "Only implemented for std::complex<double> and std::complex<float>");
115 Assert(matrix.
size() ==
static_cast<std::size_t
>(n_rows * n_rows),
120 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
121 left_eigenvectors.size(),
124 Assert(static_cast<std::size_t>(n_rows * n_rows) <=
125 right_eigenvectors.size(),
127 Assert(std::max<std::size_t>(1, work_flag) <= real_work.size(),
130 std::max<long int>(1, 2 * n_rows) <= (work_flag),
139 left_eigenvectors.data(),
141 right_eigenvectors.data(),
151 template <
typename T>
153 gesdd_helper(
const char job,
157 std::vector<T> & singular_values,
160 std::vector<T> & real_work,
162 std::vector<types::blas_int> &integer_work,
166 Assert(job ==
'A' || job ==
'S' || job ==
'O' || job ==
'N',
168 Assert(static_cast<std::size_t>(n_rows * n_cols) == matrix.
size(),
170 Assert(std::min<std::size_t>(n_rows, n_cols) <= singular_values.size(),
172 Assert(8 * std::min<std::size_t>(n_rows, n_cols) <= integer_work.size(),
175 static_cast<std::size_t>(work_flag) <= real_work.size(),
182 singular_values.data(),
195 template <
typename T>
197 gesdd_helper(
const char job,
201 std::vector<T> & singular_values,
204 std::vector<std::complex<T>> & work,
205 std::vector<T> & real_work,
206 std::vector<types::blas_int> & integer_work,
210 Assert(job ==
'A' || job ==
'S' || job ==
'O' || job ==
'N',
212 Assert(static_cast<std::size_t>(n_rows * n_cols) == matrix.
size(),
214 Assert(static_cast<std::size_t>(std::min(n_rows, n_cols)) <=
215 singular_values.size(),
217 Assert(8 * std::min<std::size_t>(n_rows, n_cols) <= integer_work.size(),
220 static_cast<std::size_t>(work_flag) <= real_work.size(),
228 singular_values.data(),
242 template <
typename number>
250 template <
typename number>
258 template <
typename number>
266 template <
typename number>
278 template <
typename number>
288 template <
typename number>
292 const size_type s = std::min(std::min(this->
m(), n), this->
n());
297 (*
this)(i, j) = copy(i, j);
302 template <
typename number>
318 const size_type jj = (j < col ? j : j + 1);
321 const size_type ii = (i < row ? i : i + 1);
322 (*this)(i, j) = copy(ii, jj);
329 template <
typename number>
338 template <
typename number>
339 template <
typename number2>
347 (*
this)(i, j) = M(i, j);
355 template <
typename number>
356 template <
typename number2>
364 (*
this)(i, j) = M.
el(i, j);
372 template <
typename number>
387 template <
typename number>
396 const char type =
'G';
397 const number cfrom = 1.;
404 number *
values = &this->values[0];
406 lascl(&type, &kl, &kl, &cfrom, &factor, &m, &n, values, &lda, &info);
415 template <
typename number>
426 const char type =
'G';
427 const number cto = 1.;
434 number *
values = &this->values[0];
436 lascl(&type, &kl, &kl, &factor, &cto, &m, &n, values, &lda, &info);
446 template <
typename number>
464 number *
values = &this->values[0];
465 const number * values_A = &A.
values[0];
467 axpy(&n, &a, values_A, &inc, values, &inc);
474 template <
typename number>
503 const std::array<number, 3> csr =
509 const number t = A(i, k);
510 A(i, k) = csr[0] * A(i, k) + csr[1] * z(i);
511 z(i) = -csr[1] * t + csr[0] * z(i);
546 const std::array<number, 3> csr =
552 const number t = A(i, k);
553 A(i, k) = csr[0] * A(i, k) - csr[1] * z(i);
554 z(i) = -csr[1] * t + csr[0] * z(i);
561 template <
typename number>
564 const std::complex<number> ,
565 const Vector<std::complex<number>> & )
573 template <
typename number>
601 (*
this)(i, j) = (*
this)(j, i);
605 cholesky_rank1(*
this, a, v);
613 template <
typename number>
617 const bool adding)
const 621 const number alpha = 1.;
622 const number beta = (adding ? 1. : 0.);
623 const number null = 0.;
627 (mm == nn) &&
state == matrix)
634 const char diag =
'N';
635 const char trans =
'N';
645 trmv(&uplo, &trans, &diag, &N, &this->
values[0], &lda, &w[0], &incx);
677 work.resize(std::max(mm, nn));
712 work.resize(std::max(mm, nn));
747 template <
typename number>
751 const bool adding)
const 755 const number alpha = 1.;
756 const number beta = (adding ? 1. : 0.);
757 const number null = 0.;
761 (mm == nn) &&
state == matrix)
768 const char diag =
'N';
769 const char trans =
'T';
779 trmv(&uplo, &trans, &diag, &N, &this->
values[0], &lda, &w[0], &incx);
813 work.resize(std::max(mm, nn));
849 work.resize(std::max(mm, nn));
884 template <
typename number>
893 template <
typename number>
902 template <
typename number>
906 const bool adding)
const 917 const number alpha = 1.;
918 const number beta = (adding ? 1. : 0.);
936 template <
typename number>
940 const bool adding)
const 950 const number alpha = 1.;
951 const number beta = (adding ? 1. : 0.);
972 template <
typename number>
977 const bool adding)
const 1001 work.resize(kk * nn);
1008 Assert(j * kk + i < static_cast<types::blas_int>(
work.size()),
1010 work[j * kk + i] = V(i) * B(i, j);
1014 const number alpha = 1.;
1015 const number beta = (adding ? 1. : 0.);
1034 template <
typename number>
1051 template <
typename number>
1055 const bool adding)
const 1066 const number alpha = 1.;
1067 const number beta = (adding ? 1. : 0.);
1108 template <
typename number>
1112 const bool adding)
const 1122 const number alpha = 1.;
1123 const number beta = (adding ? 1. : 0.);
1143 template <
typename number>
1147 const bool adding)
const 1158 const number alpha = 1.;
1159 const number beta = (adding ? 1. : 0.);
1201 template <
typename number>
1205 const bool adding)
const 1215 const number alpha = 1.;
1216 const number beta = (adding ? 1. : 0.);
1236 template <
typename number>
1240 const bool adding)
const 1251 const number alpha = 1.;
1252 const number beta = (adding ? 1. : 0.);
1270 template <
typename number>
1274 const bool adding)
const 1284 const number alpha = 1.;
1285 const number beta = (adding ? 1. : 0.);
1305 template <
typename number>
1314 number *
const values = &this->values[0];
1317 getrf(&mm, &nn, values, &mm,
ipiv.data(), &info);
1329 template <
typename number>
1338 template <
typename number>
1342 const char type(
'O');
1348 template <
typename number>
1352 const char type(
'I');
1358 template <
typename number>
1362 const char type(
'F');
1368 template <
typename number>
1376 ExcMessage(
"norms can be called in matrix state only."));
1380 const number *
const values = &this->values[0];
1385 (type ==
'I' || type ==
'O') ? std::max<types::blas_int>(1, N) : 0;
1393 (type ==
'I') ? std::max<types::blas_int>(1, M) : 0;
1395 return lange(&type, &M, &N, values, &lda,
work.data());
1401 template <
typename number>
1407 ExcMessage(
"Trace can be called in matrix state only."));
1412 tr += (*
this)(i, i);
1419 template <
typename number>
1432 number *
const values = &this->values[0];
1446 template <
typename number>
1455 const number *
values = &this->values[0];
1479 template <
typename number>
1489 const number *
const values = &this->values[0];
1495 const char norm =
'1';
1496 const char diag =
'N';
1517 template <
typename number>
1526 wr.resize(std::max(mm, nn));
1527 std::fill(
wr.begin(),
wr.end(), 0.);
1528 ipiv.resize(8 * mm);
1530 svd_u = std_cxx14::make_unique<LAPACKFullMatrix<number>>(mm, mm);
1531 svd_vt = std_cxx14::make_unique<LAPACKFullMatrix<number>>(nn, nn);
1539 std::vector<typename numbers::NumberTraits<number>::real_type> real_work;
1543 std::size_t min = std::min(this->
m(), this->
n());
1544 std::size_t max = std::max(this->
m(), this->
n());
1546 std::max(5 * min * min + 5 * min, 2 * max * min + 2 * min * min + min));
1593 template <
typename number>
1603 const double lim = std::abs(
wr[0]) * threshold;
1606 if (std::abs(
wr[i]) > lim)
1607 wr[i] = one /
wr[i];
1616 template <
typename number>
1619 const unsigned int kernel_size)
1627 const unsigned int n_wr =
wr.size();
1628 for (
size_type i = 0; i < n_wr - kernel_size; ++i)
1629 wr[i] = one /
wr[i];
1630 for (
size_type i = n_wr - kernel_size; i < n_wr; ++i)
1637 template <
typename number>
1646 number *
const values = &this->values[0];
1651 if (
state == matrix)
1656 getri(&mm, values, &mm,
ipiv.data(),
inv_work.data(), &mm, &info);
1660 if (
state == matrix)
1669 this->
el(i, j) = this->
el(j, i);
1680 template <
typename number>
1686 const char * trans = transposed ? &T : &N;
1688 const number *
const values = &this->values[0];
1695 trans, &nn, &n_rhs, values, &nn,
ipiv.data(), v.
begin(), &nn, &info);
1709 &uplo, trans,
"N", &nn, &n_rhs, values, &lda, v.
begin(), &ldb, &info);
1715 "The matrix has to be either factorized or triangular."));
1723 template <
typename number>
1726 const bool transposed)
const 1732 const char * trans = transposed ? &T : &N;
1734 const number *
const values = &this->values[0];
1741 trans, &nn, &n_rhs, values, &nn,
ipiv.data(), &B.
values[0], &nn, &info);
1770 "The matrix has to be either factorized or triangular."));
1778 template <
typename number>
1781 const bool transposed)
const 1783 solve(v, transposed);
1788 template <
typename number>
1791 const bool transposed)
const 1793 solve(B, transposed);
1798 template <
typename number>
1829 template <
typename number>
1844 const char jobvr = (right) ? V : N;
1845 const char jobvl = (left) ? V : N;
1859 std::vector<typename numbers::NumberTraits<number>::real_type> real_work;
1862 real_work.resize(2 * this->
m());
1863 internal::LAPACKFullMatrixImplementation::geev_helper(jobvl,
1887 internal::LAPACKFullMatrixImplementation::geev_helper(jobvl,
1903 std::cerr <<
"LAPACK error in geev" << std::endl;
1909 template <
typename number>
1912 const number lower_bound,
1913 const number upper_bound,
1914 const number abs_accuracy,
1925 number *
const values_A = &this->
values[0];
1926 number *
const values_eigenvectors = &matrix_eigenvectors.
values[0];
1929 const char *
const jobz(&V);
1930 const char *
const uplo(&U);
1931 const char *
const range(&V);
1933 std::vector<types::blas_int>
iwork(static_cast<size_type>(5 * nn));
1934 std::vector<types::blas_int> ifail(static_cast<size_type>(nn));
1961 values_eigenvectors,
1974 work.resize(static_cast<size_type>(lwork));
1990 values_eigenvectors,
2001 std::cerr <<
"LAPACK error in syevx" << std::endl;
2003 eigenvalues.
reinit(n_eigenpairs);
2004 eigenvectors.
reinit(nn, n_eigenpairs,
true);
2006 for (
size_type i = 0; i < static_cast<size_type>(n_eigenpairs); ++i)
2010 for (
size_type j = 0; j < static_cast<size_type>(nn); ++j)
2012 eigenvectors(j, i) = values_eigenvectors[col_begin + j];
2020 template <
typename number>
2024 const number lower_bound,
2025 const number upper_bound,
2026 const number abs_accuracy,
2040 number *
const values_A = &this->
values[0];
2041 number *
const values_B = &B.
values[0];
2042 number *
const values_eigenvectors = &matrix_eigenvectors.
values[0];
2045 const char *
const jobz(&V);
2046 const char *
const uplo(&U);
2047 const char *
const range(&V);
2049 iwork.resize(static_cast<size_type>(5 * nn));
2050 std::vector<types::blas_int> ifail(static_cast<size_type>(nn));
2080 values_eigenvectors,
2095 work.resize(static_cast<size_type>(lwork));
2114 values_eigenvectors,
2125 std::cerr <<
"LAPACK error in sygvx" << std::endl;
2127 eigenvalues.
reinit(n_eigenpairs);
2130 for (
size_type i = 0; i < static_cast<size_type>(n_eigenpairs); ++i)
2135 for (
size_type j = 0; j < static_cast<size_type>(nn); ++j)
2137 eigenvectors[i](j) = values_eigenvectors[col_begin + j];
2145 template <
typename number>
2158 ExcMessage(
"eigenvectors.size() > matrix.n()"));
2164 number *
const values_A = &this->
values[0];
2165 number *
const values_B = &B.
values[0];
2169 const char *
const jobz = (
eigenvectors.size() > 0) ? (&V) : (&N);
2170 const char *
const uplo = (&U);
2203 work.resize(static_cast<size_type>(lwork));
2222 std::cerr <<
"LAPACK error in sygv" << std::endl;
2228 for (
size_type j = 0; j < static_cast<size_type>(nn); ++j)
2237 template <
typename number>
2240 const unsigned int precision,
2241 const bool scientific,
2242 const unsigned int width_,
2243 const char * zero_string,
2244 const double denominator,
2245 const double threshold)
const 2247 unsigned int width = width_;
2257 std::ios::fmtflags old_flags = out.flags();
2258 std::streamsize old_precision = out.precision(precision);
2262 out.setf(std::ios::scientific, std::ios::floatfield);
2264 width = precision + 7;
2268 out.setf(std::ios::fixed, std::ios::floatfield);
2270 width = precision + 2;
2280 if (std::isnan(std::abs((*
this)(i, j))))
2281 out << std::setw(width) << (*this)(i, j) <<
' ';
2282 else if (std::abs(this->
el(i, j)) > threshold)
2283 out << std::setw(width) << this->
el(i, j) * denominator <<
' ';
2285 out << std::setw(width) << zero_string <<
' ';
2291 out.flags(old_flags);
2292 out.precision(old_precision);
2298 template <
typename number>
2307 template <
typename number>
2317 template <
typename number>
2323 matrix->apply_lu_factorization(dst,
false);
2327 template <
typename number>
2333 matrix->apply_lu_factorization(dst,
true);
2337 template <
typename number>
2345 matrix->apply_lu_factorization(*aux,
false);
2350 template <
typename number>
2358 matrix->apply_lu_factorization(*aux,
true);
2364 #include "lapack_full_matrix.inst" 2367 DEAL_II_NAMESPACE_CLOSE
LAPACKFullMatrix(const size_type size=0)
void Tmmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
std::vector< number > work
#define AssertDimension(dim1, dim2)
void rank1_update(const number a, const Vector< number > &v)
number linfty_norm() const
void mTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
std::unique_ptr< LAPACKFullMatrix< number > > svd_vt
LAPACKFullMatrix< number > & operator/=(const number factor)
number reciprocal_condition_number() const
Contents is actually a matrix.
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 & ExcIO()
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
LAPACKSupport::State state
void remove_row_and_column(const size_type row, const size_type col)
static::ExceptionBase & ExcScalarAssignmentOnlyForZeroValue()
Matrix is upper triangular.
std::vector< types::blas_int > ipiv
Contents is the inverse of a matrix.
#define AssertIndexRange(index, range)
number norm(const char type) const
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
static::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
static::ExceptionBase & ExcErrorCode(std::string arg1, types::blas_int arg2)
void solve(Vector< number > &v, const bool transposed=false) const
void vmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
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)
void Tvmult_add(Vector< number2 > &w, const Vector< number2 > &v) 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
static::ExceptionBase & ExcSingular()
void apply_lu_factorization(Vector< number > &v, const bool transposed) const
number el(const size_type i, const size_type j) const
std::vector< types::blas_int > iwork
static::ExceptionBase & ExcState(State arg1)
static::ExceptionBase & ExcMessage(std::string arg1)
Contents is a Cholesky decomposition.
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#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 TmTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
number frobenius_norm() const
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)
std::vector< number > inv_work
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()
std::unique_ptr< LAPACKFullMatrix< number > > svd_u
std::unique_ptr< Number[], decltype(&free)> values
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()
size_type n_elements() const
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
LAPACKFullMatrix< number > & operator=(const LAPACKFullMatrix< number > &)
TableBase< N, T > & operator=(const TableBase< N, T > &src)
std::array< NumberType, 3 > givens_rotation(const NumberType &x, const NumberType &y)
std::vector< typename numbers::NumberTraits< number >::real_type > wr
Matrix contains singular value decomposition,.
void set_property(const LAPACKSupport::Property property)
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
reference el(const size_type i, const size_type j)
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()
number determinant() const
void mmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) 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)
static bool equal(const T *p1, const T *p2)
static::ExceptionBase & ExcInternalError()
Contents is an LU decomposition.