17 #include <deal.II/lac/lapack_full_matrix.h> 18 #include <deal.II/lac/lapack_templates.h> 19 #include <deal.II/lac/lapack_support.h> 20 #include <deal.II/lac/full_matrix.h> 21 #include <deal.II/lac/sparse_matrix.h> 22 #include <deal.II/lac/vector.h> 23 #include <deal.II/lac/block_vector.h> 25 #include <deal.II/lac/utilities.h> 30 DEAL_II_NAMESPACE_OPEN
34 template <
typename number>
43 template <
typename number>
53 template <
typename number>
62 template <
typename number>
74 template <
typename number>
84 template <
typename number>
88 const size_type s = std::min(std::min(this->m(), n), this->n());
93 (*
this)(i,j) = copy(i,j);
98 template <
typename number>
113 const size_type jj = ( j < col ? j : j+1);
116 const size_type ii = ( i < row ? i : i+1);
117 (*this)(i,j) = copy(ii,jj);
124 template <
typename number>
134 template <
typename number>
135 template <
typename number2>
143 (*
this)(i,j) = M(i,j);
151 template <
typename number>
152 template <
typename number2>
160 (*
this)(i,j) = M.
el(i,j);
168 template <
typename number>
175 if (this->n_elements() != 0)
176 this->reset_values();
183 template <
typename number>
192 const char type =
'G';
193 const number cfrom = 1.;
200 number *values = &this->values[0];
202 lascl(&type,&kl,&kl,&cfrom,&factor,&m,&n,values,&lda,&info);
211 template <
typename number>
222 const char type =
'G';
223 const number cto = 1.;
230 number *values = &this->values[0];
232 lascl(&type,&kl,&kl,&factor,&cto,&m,&n,values,&lda,&info);
242 template <
typename number>
261 number *values = &this->values[0];
262 const number *values_A = &A.
values[0];
264 axpy(&n,&a,values_A,&inc,values,&inc);
271 template <
typename number>
302 const number t = A(i,k);
303 A(i,k) = csr[0] * A(i,k) + csr[1] * z(i);
304 z(i) = -csr[1] * t + csr[0] * z(i);
342 const number t = A(i,k);
343 A(i,k) = csr[0] * A(i,k) - csr[1] * z(i);
344 z(i) = -csr[1] * t + csr[0] * z(i);
351 template <
typename number>
353 const std::complex<number> ,
354 const Vector<std::complex<number> > &)
362 template <
typename number>
383 syr(&uplo, &N, &a, v.
begin(), &incx, this->values.begin(), &lda);
392 (*
this)(i,j) = (*
this)(j,i);
396 cholesky_rank1(*
this, a, v);
404 template <
typename number>
409 const bool adding)
const 413 const number alpha = 1.;
414 const number beta = (adding ? 1. : 0.);
415 const number null = 0.;
429 const char diag =
'N';
430 const char trans =
'N';
439 trmv (&uplo, &trans, &diag,
440 &N, &this->values[0], &lda,
454 gemv(
"N", &mm, &nn, &alpha, &this->values[0], &mm, v.
values.get(), &one, &beta, w.values.get(), &one);
463 work.resize(std::max(mm,nn));
464 gemv(
"N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.
values.get(), &one, &null, work.data(), &one);
469 gemv(
"N", &mm, &mm, &alpha, &svd_u->values[0], &mm, work.data(), &one, &beta, w.values.get(), &one);
478 work.resize(std::max(mm,nn));
479 gemv(
"T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.
values.get(), &one, &null, work.data(), &one);
484 gemv(
"T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, work.data(), &one, &beta, w.values.get(), &one);
493 template <
typename number>
498 const bool adding)
const 502 const number alpha = 1.;
503 const number beta = (adding ? 1. : 0.);
504 const number null = 0.;
518 const char diag =
'N';
519 const char trans =
'T';
528 trmv (&uplo, &trans, &diag,
529 &N, &this->values[0], &lda,
544 gemv(
"T", &mm, &nn, &alpha, &this->values[0], &mm, v.
values.get(), &one, &beta, w.values.get(), &one);
554 work.resize(std::max(mm,nn));
555 gemv(
"T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.
values.get(), &one, &null, work.data(), &one);
560 gemv(
"T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, work.data(), &one, &beta, w.values.get(), &one);
570 work.resize(std::max(mm,nn));
571 gemv(
"N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.
values.get(), &one, &null, work.data(), &one);
576 gemv(
"N", &mm, &mm, &alpha, &svd_u->values[0], &mm, work.data(), &one, &beta, w.values.get(), &one);
585 template <
typename number>
594 template <
typename number>
603 template <
typename number>
607 const bool adding)
const 618 const number alpha = 1.;
619 const number beta = (adding ? 1. : 0.);
621 gemm(
"N",
"N", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.
values[0],
622 &kk, &beta, &C.values[0], &mm);
626 template <
typename number>
630 const bool adding)
const 640 const number alpha = 1.;
641 const number beta = (adding ? 1. : 0.);
645 gemm(
"T",
"T", &nn, &mm, &kk, &alpha, &B.
values[0], &kk, &this->values[0],
646 &mm, &beta, &C(0,0), &nn);
651 template <
typename number>
656 const bool adding)
const 688 work[j*kk+i]=V(i)*B(i,j);
692 const number alpha = 1.;
693 const number beta = (adding ? 1. : 0.);
695 gemm(
"T",
"N", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &work[0],
696 &kk, &beta, &C.values[0], &mm);
701 template <
typename number>
718 template <
typename number>
722 const bool adding)
const 733 const number alpha = 1.;
734 const number beta = (adding ? 1. : 0.);
738 syrk(&
LAPACKSupport::U,
"T",&nn,&kk,&alpha,&this->values[0],&kk,&beta,&C.values[0],&nn);
749 gemm(
"T",
"N", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.
values[0],
750 &kk, &beta, &C.values[0], &mm);
755 template <
typename number>
759 const bool adding)
const 769 const number alpha = 1.;
770 const number beta = (adding ? 1. : 0.);
774 gemm(
"T",
"N", &nn, &mm, &kk, &alpha, &B.
values[0], &kk, &this->values[0],
775 &kk, &beta, &C(0,0), &nn);
779 template <
typename number>
783 const bool adding)
const 794 const number alpha = 1.;
795 const number beta = (adding ? 1. : 0.);
799 syrk(&
LAPACKSupport::U,
"N",&nn,&kk,&alpha,&this->values[0],&nn,&beta,&C.values[0],&nn);
810 gemm(
"N",
"T", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.
values[0],
811 &nn, &beta, &C.values[0], &mm);
817 template <
typename number>
821 const bool adding)
const 831 const number alpha = 1.;
832 const number beta = (adding ? 1. : 0.);
836 gemm(
"N",
"T", &nn, &mm, &kk, &alpha, &B.
values[0], &nn, &this->values[0],
837 &mm, &beta, &C(0,0), &nn);
841 template <
typename number>
845 const bool adding)
const 856 const number alpha = 1.;
857 const number beta = (adding ? 1. : 0.);
859 gemm(
"T",
"T", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.
values[0],
860 &nn, &beta, &C.values[0], &mm);
864 template <
typename number>
868 const bool adding)
const 878 const number alpha = 1.;
879 const number beta = (adding ? 1. : 0.);
883 gemm(
"N",
"N", &nn, &mm, &kk, &alpha, &B.
values[0], &nn, &this->values[0],
884 &kk, &beta, &C(0,0), &nn);
888 template <
typename number>
897 number *
const values = &this->values[0];
900 getrf(&mm, &nn, values, &mm, ipiv.data(), &info);
912 template <
typename number>
921 template <
typename number>
924 const char type(
'O');
930 template <
typename number>
933 const char type(
'I');
939 template <
typename number>
942 const char type(
'F');
948 template <
typename number>
955 ExcMessage(
"norms can be called in matrix state only."));
959 const number *
const values = &this->values[0];
964 std::max<types::blas_int>(1,N) :
973 std::max<types::blas_int>(1,M) :
976 return lange (&type, &M, &N, values, &lda, work.data());
982 template <
typename number>
987 ExcMessage(
"Trace can be called in matrix state only."));
988 Assert (this->n() == this->m(),
1000 template <
typename number>
1013 number *
const values = &this->values[0];
1027 template <
typename number>
1036 const number *values = &this->values[0];
1045 work.data(), iwork.data(), &info);
1054 template <
typename number>
1065 const number *
const values = &this->values[0];
1071 const char norm =
'1';
1072 const char diag =
'N';
1074 trcon(&norm, &uplo, &diag,
1077 work.data(), iwork.data(), &info);
1086 template <
typename number>
1095 number *
const values = &this->values[0];
1096 wr.resize(std::max(mm,nn));
1097 std::fill(wr.begin(), wr.end(), 0.);
1100 svd_u = std_cxx14::make_unique<LAPACKFullMatrix<number>>(mm,mm);
1101 svd_vt = std_cxx14::make_unique<LAPACKFullMatrix<number>>(nn,nn);
1102 number *
const mu = &svd_u->values[0];
1103 number *
const mvt = &svd_vt->values[0];
1110 wr.data(),
mu, &mm, mvt, &nn,
1111 work.data(), &lwork, ipiv.data(), &info);
1120 wr.data(),
mu, &mm, mvt, &nn,
1121 work.data(), &lwork, ipiv.data(), &info);
1131 template <
typename number>
1140 const double lim = std::abs(wr[0])*threshold;
1143 if (std::abs(wr[i]) > lim)
1144 wr[i] = number(1.)/wr[i];
1153 template <
typename number>
1162 const unsigned int n_wr = wr.size();
1163 for (
size_type i=0; i<n_wr-kernel_size; ++i)
1164 wr[i] = number(1.)/wr[i];
1165 for (
size_type i=n_wr-kernel_size; i<n_wr; ++i)
1172 template <
typename number>
1182 number *
const values = &this->values[0];
1188 compute_lu_factorization();
1191 inv_work.resize (mm);
1192 getri(&mm, values, &mm, ipiv.data(), inv_work.data(), &mm, &info);
1197 compute_cholesky_factorization();
1204 this->el(i,j) = this->el(j,i);
1215 template <
typename number>
1218 const bool transposed)
const 1220 Assert(this->m() == this->n(),
1223 const char *trans = transposed ? &T : &N;
1225 const number *
const values = &this->values[0];
1231 getrs(trans, &nn, &n_rhs, values, &nn, ipiv.data(),
1232 v.
begin(), &nn, &info);
1237 values, &nn, v.
begin(), &nn, &info);
1246 trtrs (&uplo, trans,
"N",
1249 v.
begin(), &ldb, &info);
1254 ExcMessage(
"The matrix has to be either factorized or triangular."));
1262 template <
typename number>
1265 const bool transposed)
const 1269 Assert(this->m() == this->n(),
1272 const char *trans = transposed ? &T : &N;
1274 const number *
const values = &this->values[0];
1280 getrs(trans, &nn, &n_rhs, values, &nn, ipiv.data(),
1281 &B.
values[0], &nn, &info);
1286 values, &nn, &B.
values[0], &nn, &info);
1295 trtrs (&uplo, trans,
"N",
1298 &B.
values[0], &ldb, &info);
1303 ExcMessage(
"The matrix has to be either factorized or triangular."));
1311 template <
typename number>
1314 const bool transposed)
const 1316 solve(v,transposed);
1321 template <
typename number>
1324 const bool transposed)
const 1326 solve(B,transposed);
1331 template <
typename number>
1356 det *= ( ipiv[i] ==
types::blas_int(i+1) ? this->el(i,i) : -this->el(i,i) );
1361 template <
typename number>
1370 if (right) vr.resize(nn*nn);
1371 if (left) vl.resize(nn*nn);
1373 number *
const values = &this->values[0];
1377 const char *
const jobvr = (right) ? (&V) : (&N);
1378 const char *
const jobvl = (left) ? (&V) : (&N);
1392 geev(jobvl, jobvr, &nn, values, &nn,
1393 wr.data(), wi.data(),
1394 vl.data(), &nn, vr.data(), &nn,
1395 work.data(), &lwork, &info);
1407 geev(jobvl, jobvr, &nn, values, &nn,
1408 wr.data(), wi.data(),
1409 vl.data(), &nn, vr.data(), &nn,
1410 work.data(), &lwork, &info);
1416 std::cerr <<
"LAPACK error in geev" << std::endl;
1422 template <
typename number>
1425 const number upper_bound,
1426 const number abs_accuracy,
1437 number *
const values_A = &this->values[0];
1438 number *
const values_eigenvectors = &matrix_eigenvectors.
values[0];
1443 const char *
const jobz(&V);
1444 const char *
const uplo(&U);
1445 const char *
const range(&V);
1447 std::vector<types::blas_int> iwork(static_cast<size_type> (5*nn));
1448 std::vector<types::blas_int> ifail(static_cast<size_type> (nn));
1463 uplo, &nn, values_A, &nn,
1464 &lower_bound, &upper_bound,
1465 dummy, dummy, &abs_accuracy,
1466 &n_eigenpairs, wr.data(), values_eigenvectors,
1467 &nn, work.data(), &lwork, iwork.data(),
1468 ifail.data(), &info);
1475 work.resize(static_cast<size_type> (lwork));
1479 uplo, &nn, values_A, &nn,
1480 &lower_bound, &upper_bound,
1481 dummy, dummy, &abs_accuracy,
1482 &n_eigenpairs, wr.data(), values_eigenvectors,
1483 &nn, work.data(), &lwork, iwork.data(),
1484 ifail.data(), &info);
1489 std::cerr <<
"LAPACK error in syevx" << std::endl;
1494 for (
size_type i=0; i < static_cast<size_type> (n_eigenpairs); ++i)
1498 for (
size_type j=0; j < static_cast<size_type> (nn); ++j)
1508 template <
typename number>
1512 const number lower_bound,
1513 const number upper_bound,
1514 const number abs_accuracy,
1523 Assert(static_cast<size_type>(nn) == B.
n(),
1529 number *
const values_A = &this->values[0];
1530 number *
const values_B = &B.
values[0];
1531 number *
const values_eigenvectors = &matrix_eigenvectors.
values[0];
1536 const char *
const jobz(&V);
1537 const char *
const uplo(&U);
1538 const char *
const range(&V);
1540 iwork.resize(static_cast<size_type> (5*nn));
1541 std::vector<types::blas_int> ifail(static_cast<size_type> (nn));
1555 sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
1556 values_B, &nn, &lower_bound, &upper_bound,
1557 dummy, dummy, &abs_accuracy, &n_eigenpairs,
1558 wr.data(), values_eigenvectors, &nn, work.data(),
1559 &lwork, iwork.data(), ifail.data(), &info);
1568 work.resize(static_cast<size_type> (lwork));
1571 sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
1572 values_B, &nn, &lower_bound, &upper_bound,
1573 dummy, dummy, &abs_accuracy, &n_eigenpairs,
1574 wr.data(), values_eigenvectors, &nn, work.data(),
1575 &lwork, iwork.data(), ifail.data(), &info);
1580 std::cerr <<
"LAPACK error in sygvx" << std::endl;
1585 for (
size_type i=0; i < static_cast<size_type> (n_eigenpairs); ++i)
1590 for (
size_type j=0; j < static_cast<size_type> (nn); ++j)
1600 template <
typename number>
1611 Assert(static_cast<size_type>(nn) == B.
n(),
1614 ExcMessage (
"eigenvectors.size() > matrix.n()"));
1620 number *
const values_A = &this->values[0];
1621 number *
const values_B = &B.
values[0];
1625 const char *
const jobz = (
eigenvectors.size() > 0) ? (&V) : (&N);
1626 const char *
const uplo = (&U);
1639 sygv (&itype, jobz, uplo, &nn, values_A, &nn,
1641 wr.data(), work.data(), &lwork, &info);
1650 work.resize(static_cast<size_type>(lwork));
1653 sygv (&itype, jobz, uplo, &nn, values_A, &nn,
1655 wr.data(), work.data(), &lwork, &info);
1660 std::cerr <<
"LAPACK error in sygv" << std::endl;
1666 for (
size_type j=0; j < static_cast<size_type>(nn); ++j)
1675 template <
typename number>
1679 const unsigned int precision,
1680 const bool scientific,
1681 const unsigned int width_,
1682 const char *zero_string,
1683 const double denominator,
1684 const double threshold)
const 1686 unsigned int width = width_;
1688 Assert ((!this->empty()) || (this->n()+this->m()==0),
1697 std::ios::fmtflags old_flags = out.flags();
1698 std::streamsize old_precision = out.precision (precision);
1702 out.setf (std::ios::scientific, std::ios::floatfield);
1704 width = precision+7;
1708 out.setf (std::ios::fixed, std::ios::floatfield);
1710 width = precision+2;
1720 if (std::isnan(std::abs((*
this)(i,j))))
1721 out << std::setw(width) << (*this)(i,j) <<
' ';
1722 else if (std::abs(this->el(i,j)) > threshold)
1723 out << std::setw(width)
1724 << this->el(i,j) * denominator <<
' ';
1726 out << std::setw(width) << zero_string <<
' ';
1732 out.flags (old_flags);
1733 out.precision(old_precision);
1739 template <
typename number>
1748 template <
typename number>
1758 template <
typename number>
1764 matrix->apply_lu_factorization(dst,
false);
1768 template <
typename number>
1774 matrix->apply_lu_factorization(dst,
true);
1778 template <
typename number>
1786 matrix->apply_lu_factorization(*aux,
false);
1791 template <
typename number>
1799 matrix->apply_lu_factorization(*aux,
true);
1805 #include "lapack_full_matrix.inst" 1808 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.
std::array< NumberType, 3 > givens_rotation(const NumberType &x, const NumberType &y)
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
static ::ExceptionBase & ExcIO()
LAPACKSupport::State state
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 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)
TableBase< N, T > & operator=(const TableBase< N, T > &src)
static ::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
std::array< NumberType, 3 > hyperbolic_rotation(const NumberType &x, const NumberType &y)
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 resize(const size_type size_in)
void Tmmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
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
TableBase< 2, T >::size_type size_type
Contents is a Cholesky decomposition.
#define Assert(cond, exc)
void compute_inverse_svd_with_kernel(const unsigned int kernel_size)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcErrorCode(char *arg1, types::blas_int 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)
Contents is something useless.
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
std::unique_ptr< Number[], decltype(&free)> values
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()
std::make_unsigned< types::blas_int >::type size_type
number linfty_norm() const
LAPACKFullMatrix< number > & operator=(const LAPACKFullMatrix< number > &)
number el(const size_type i, const size_type j) const
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_eigenvalues(const bool right_eigenvectors=false, const bool left_eigenvectors=false)
static ::ExceptionBase & ExcNotImplemented()
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
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.