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> 28 DEAL_II_NAMESPACE_OPEN
32 template <
typename number>
40 template <
typename number>
49 template <
typename number>
57 template <
typename number>
62 state = LAPACKSupport::matrix;
67 template <
typename number>
72 state = LAPACKSupport::matrix;
76 template <
typename number>
82 state = LAPACKSupport::matrix;
86 template <
typename number>
87 template <
typename number2>
93 for (
size_type i=0; i<this->n_rows(); ++i)
94 for (
size_type j=0; j<this->n_cols(); ++j)
95 (*
this)(i,j) = M(i,j);
97 state = LAPACKSupport::matrix;
102 template <
typename number>
103 template <
typename number2>
109 for (
size_type i=0; i<this->n_rows(); ++i)
110 for (
size_type j=0; j<this->n_cols(); ++j)
111 (*
this)(i,j) = M.
el(i,j);
113 state = LAPACKSupport::matrix;
118 template <
typename number>
125 if (this->n_elements() != 0)
126 this->reset_values();
128 state = LAPACKSupport::matrix;
133 template <
typename number>
137 Assert(state == LAPACKSupport::matrix ||
138 state == LAPACKSupport::inverse_matrix,
141 for (
unsigned int column = 0; column<this->n(); ++column)
142 for (
unsigned int row = 0; row<this->m(); ++row)
143 (*
this)(row,column) *= factor;
149 template <
typename number>
153 Assert(state == LAPACKSupport::matrix ||
154 state == LAPACKSupport::inverse_matrix,
160 for (
unsigned int column = 0; column<this->n(); ++column)
161 for (
unsigned int row = 0; row<this->m(); ++row)
162 (*
this)(row,column) /= factor;
168 template <
typename number>
173 const bool adding)
const 175 const int mm = this->n_rows();
176 const int nn = this->n_cols();
177 const number alpha = 1.;
178 const number beta = (adding ? 1. : 0.);
179 const number null = 0.;
189 gemv(
"N", &mm, &nn, &alpha, &this->values[0], &mm, v.
val, &one, &beta, w.val, &one);
197 work.resize(std::max(mm,nn));
198 gemv(
"N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.
val, &one, &null, &work[0], &one);
203 gemv(
"N", &mm, &mm, &alpha, &svd_u->values[0], &mm, &work[0], &one, &beta, w.val, &one);
211 work.resize(std::max(mm,nn));
212 gemv(
"T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.
val, &one, &null, &work[0], &one);
217 gemv(
"T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, &work[0], &one, &beta, w.val, &one);
226 template <
typename number>
231 const bool adding)
const 233 const int mm = this->n_rows();
234 const int nn = this->n_cols();
235 const number alpha = 1.;
236 const number beta = (adding ? 1. : 0.);
237 const number null = 0.;
247 gemv(
"T", &mm, &nn, &alpha, &this->values[0], &mm, v.
val, &one, &beta, w.val, &one);
256 work.resize(std::max(mm,nn));
257 gemv(
"T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.
val, &one, &null, &work[0], &one);
262 gemv(
"T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, &work[0], &one, &beta, w.val, &one);
270 work.resize(std::max(mm,nn));
271 gemv(
"N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.
val, &one, &null, &work[0], &one);
276 gemv(
"N", &mm, &mm, &alpha, &svd_u->values[0], &mm, &work[0], &one, &beta, w.val, &one);
286 template <
typename number>
295 template <
typename number>
304 template <
typename number>
308 const bool adding)
const 310 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
312 Assert(C.state == matrix || C.state == inverse_matrix,
ExcState(state));
316 const int mm = this->n_rows();
317 const int nn = B.
n_cols();
318 const int kk = this->n_cols();
319 const number alpha = 1.;
320 const number beta = (adding ? 1. : 0.);
322 gemm(
"N",
"N", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.
values[0],
323 &kk, &beta, &C.values[0], &mm);
327 template <
typename number>
331 const bool adding)
const 333 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
338 const int mm = this->n_rows();
339 const int nn = B.
n_cols();
340 const int kk = this->n_cols();
341 const number alpha = 1.;
342 const number beta = (adding ? 1. : 0.);
346 gemm(
"T",
"T", &nn, &mm, &kk, &alpha, &B.
values[0], &kk, &this->values[0],
347 &mm, &beta, &C(0,0), &nn);
352 template <
typename number>
356 const bool adding)
const 358 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
360 Assert(C.state == matrix || C.state == inverse_matrix,
ExcState(state));
364 const int mm = this->n_cols();
365 const int nn = B.
n_cols();
366 const int kk = B.
n_rows();
367 const number alpha = 1.;
368 const number beta = (adding ? 1. : 0.);
370 gemm(
"T",
"N", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.
values[0],
371 &kk, &beta, &C.values[0], &mm);
375 template <
typename number>
379 const bool adding)
const 381 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
386 const int mm = this->n_cols();
387 const int nn = B.
n_cols();
388 const int kk = B.
n_rows();
389 const number alpha = 1.;
390 const number beta = (adding ? 1. : 0.);
394 gemm(
"T",
"N", &nn, &mm, &kk, &alpha, &B.
values[0], &kk, &this->values[0],
395 &kk, &beta, &C(0,0), &nn);
399 template <
typename number>
403 const bool adding)
const 405 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
407 Assert(C.state == matrix || C.state == inverse_matrix,
ExcState(state));
411 const int mm = this->n_rows();
412 const int nn = B.
n_rows();
413 const int kk = B.
n_cols();
414 const number alpha = 1.;
415 const number beta = (adding ? 1. : 0.);
417 gemm(
"N",
"T", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.
values[0],
418 &nn, &beta, &C.values[0], &mm);
423 template <
typename number>
427 const bool adding)
const 429 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
434 const int mm = this->n_rows();
435 const int nn = B.
n_rows();
436 const int kk = B.
n_cols();
437 const number alpha = 1.;
438 const number beta = (adding ? 1. : 0.);
442 gemm(
"N",
"T", &nn, &mm, &kk, &alpha, &B.
values[0], &nn, &this->values[0],
443 &mm, &beta, &C(0,0), &nn);
447 template <
typename number>
451 const bool adding)
const 453 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
455 Assert(C.state == matrix || C.state == inverse_matrix,
ExcState(state));
459 const int mm = this->n_cols();
460 const int nn = B.
n_rows();
461 const int kk = B.
n_cols();
462 const number alpha = 1.;
463 const number beta = (adding ? 1. : 0.);
465 gemm(
"T",
"T", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.
values[0],
466 &nn, &beta, &C.values[0], &mm);
470 template <
typename number>
474 const bool adding)
const 476 Assert(state == matrix || state == inverse_matrix,
ExcState(state));
481 const int mm = this->n_cols();
482 const int nn = B.
n_rows();
483 const int kk = B.
n_cols();
484 const number alpha = 1.;
485 const number beta = (adding ? 1. : 0.);
489 gemm(
"N",
"N", &nn, &mm, &kk, &alpha, &B.
values[0], &nn, &this->values[0],
490 &kk, &beta, &C(0,0), &nn);
494 template <
typename number>
499 state = LAPACKSupport::unusable;
501 const int mm = this->n_rows();
502 const int nn = this->n_cols();
503 number *values =
const_cast<number *
> (&this->values[0]);
506 getrf(&mm, &nn, values, &mm, &ipiv[0], &info);
517 template <
typename number>
522 state = LAPACKSupport::unusable;
524 const int mm = this->n_rows();
525 const int nn = this->n_cols();
526 number *values =
const_cast<number *
> (&this->values[0]);
527 wr.resize(std::max(mm,nn));
528 std::fill(wr.begin(), wr.end(), 0.);
533 number *
mu =
const_cast<number *
> (&svd_u->values[0]);
534 number *mvt =
const_cast<number *
> (&svd_vt->values[0]);
540 gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
541 &wr[0],
mu, &mm, mvt, &nn,
542 &work[0], &lwork, &ipiv[0], &info);
546 lwork =
static_cast<int>(work[0] + 1);
550 gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
551 &wr[0],
mu, &mm, mvt, &nn,
552 &work[0], &lwork, &ipiv[0], &info);
558 state = LAPACKSupport::svd;
562 template <
typename number>
566 if (state == LAPACKSupport::matrix)
571 const double lim = wr[0]*threshold;
579 state = LAPACKSupport::inverse_svd;
583 template <
typename number>
587 Assert(state == matrix || state == lu,
589 const int mm = this->n_rows();
590 const int nn = this->n_cols();
593 number *values =
const_cast<number *
> (&this->values[0]);
599 getrf(&mm, &nn, values, &mm, &ipiv[0], &info);
605 inv_work.resize (mm);
606 getri(&mm, values, &mm, &ipiv[0], &inv_work[0], &mm, &info);
611 state = inverse_matrix;
615 template <
typename number>
618 const bool transposed)
const 621 Assert(this->n_rows() == this->n_cols(),
625 const char *trans = transposed ? &T : &N;
626 const int nn = this->n_cols();
627 const number *values = &this->values[0];
630 getrs(trans, &nn, &one, values, &nn, &ipiv[0],
631 v.
begin(), &nn, &info);
637 template <
typename number>
640 const bool transposed)
const 647 const char *trans = transposed ? &T : &N;
648 const int nn = this->n_cols();
649 const int kk = B.
n_cols();
650 const number *values = &this->values[0];
653 getrs(trans, &nn, &kk, values, &nn, &ipiv[0], &B.
values[0], &nn, &info);
659 template <
typename number>
665 const int nn = this->n_cols();
668 if (right) vr.resize(nn*nn);
669 if (left) vl.resize(nn*nn);
671 number *values =
const_cast<number *
> (&this->values[0]);
675 const char *
const jobvr = (right) ? (&V) : (&N);
676 const char *
const jobvl = (left) ? (&V) : (&N);
690 geev(jobvl, jobvr, &nn, values, &nn,
692 &vl[0], &nn, &vr[0], &nn,
693 &work[0], &lwork, &info);
699 lwork =
static_cast<int>(work[0] + 1);
705 geev(jobvl, jobvr, &nn, values, &nn,
707 &vl[0], &nn, &vr[0], &nn,
708 &work[0], &lwork, &info);
714 std::cerr <<
"LAPACK error in geev" << std::endl;
716 state = LAPACKSupport::State(eigenvalues | unusable);
720 template <
typename number>
723 const number upper_bound,
724 const number abs_accuracy,
729 const int nn = (this->n_cols() > 0 ? this->n_cols() : 1);
735 number *values_A =
const_cast<number *
> (&this->values[0]);
736 number *values_eigenvectors =
const_cast<number *
> (&matrix_eigenvectors.
values[0]);
741 const char *
const jobz(&V);
742 const char *
const uplo(&U);
743 const char *
const range(&V);
744 const int *
const dummy(&one);
745 std::vector<int> iwork(static_cast<size_type> (5*nn));
746 std::vector<int> ifail(static_cast<size_type> (nn));
761 uplo, &nn, values_A, &nn,
762 &lower_bound, &upper_bound,
763 dummy, dummy, &abs_accuracy,
764 &n_eigenpairs, &wr[0], values_eigenvectors,
765 &nn, &work[0], &lwork, &iwork[0],
772 lwork =
static_cast<int>(work[0] + 1);
773 work.resize(static_cast<size_type> (lwork));
777 uplo, &nn, values_A, &nn,
778 &lower_bound, &upper_bound,
779 dummy, dummy, &abs_accuracy,
780 &n_eigenpairs, &wr[0], values_eigenvectors,
781 &nn, &work[0], &lwork, &iwork[0],
787 std::cerr <<
"LAPACK error in syevx" << std::endl;
789 eigenvalues.reinit(n_eigenpairs);
790 eigenvectors.
reinit(nn, n_eigenpairs,
true);
792 for (
size_type i=0; i < static_cast<size_type> (n_eigenpairs); ++i)
794 eigenvalues(i) = wr[i];
796 for (
size_type j=0; j < static_cast<size_type> (nn); ++j)
798 eigenvectors(j,i) = values_eigenvectors[col_begin+j];
802 state = LAPACKSupport::State(unusable);
806 template <
typename number>
810 const number lower_bound,
811 const number upper_bound,
812 const number abs_accuracy,
818 const int nn = (this->n_cols() > 0 ? this->n_cols() : 1);
827 number *values_A =
const_cast<number *
> (&this->values[0]);
828 number *values_B =
const_cast<number *
> (&B.
values[0]);
829 number *values_eigenvectors =
const_cast<number *
> (&matrix_eigenvectors.
values[0]);
834 const char *
const jobz(&V);
835 const char *
const uplo(&U);
836 const char *
const range(&V);
837 const int *
const dummy(&one);
838 std::vector<int> iwork(static_cast<size_type> (5*nn));
839 std::vector<int> ifail(static_cast<size_type> (nn));
853 sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
854 values_B, &nn, &lower_bound, &upper_bound,
855 dummy, dummy, &abs_accuracy, &n_eigenpairs,
856 &wr[0], values_eigenvectors, &nn, &work[0],
857 &lwork, &iwork[0], &ifail[0], &info);
863 lwork =
static_cast<int>(work[0] + 1);
866 work.resize(static_cast<size_type> (lwork));
869 sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
870 values_B, &nn, &lower_bound, &upper_bound,
871 dummy, dummy, &abs_accuracy, &n_eigenpairs,
872 &wr[0], values_eigenvectors, &nn, &work[0],
873 &lwork, &iwork[0], &ifail[0], &info);
878 std::cerr <<
"LAPACK error in sygvx" << std::endl;
880 eigenvalues.reinit(n_eigenpairs);
881 eigenvectors.resize(n_eigenpairs);
883 for (
size_type i=0; i < static_cast<size_type> (n_eigenpairs); ++i)
885 eigenvalues(i) = wr[i];
887 eigenvectors[i].reinit(nn,
true);
888 for (
size_type j=0; j < static_cast<size_type> (nn); ++j)
890 eigenvectors[i](j) = values_eigenvectors[col_begin+j];
894 state = LAPACKSupport::State(unusable);
898 template <
typename number>
906 const int nn = this->n_cols();
912 ExcMessage (
"eigenvectors.size() > matrix.n_cols()"));
918 number *values_A =
const_cast<number *
> (&this->values[0]);
919 number *values_B =
const_cast<number *
> (&B.
values[0]);
923 const char *
const jobz = (eigenvectors.size() > 0) ? (&V) : (&N);
924 const char *
const uplo = (&U);
937 sygv (&itype, jobz, uplo, &nn, values_A, &nn,
939 &wr[0], &work[0], &lwork, &info);
945 lwork =
static_cast<int>(work[0] + 1);
948 work.resize(static_cast<size_type>(lwork));
951 sygv (&itype, jobz, uplo, &nn, values_A, &nn,
953 &wr[0], &work[0], &lwork, &info);
958 std::cerr <<
"LAPACK error in sygv" << std::endl;
960 for (
size_type i=0; i < eigenvectors.size(); ++i)
963 eigenvectors[i].reinit(nn,
true);
964 for (
size_type j=0; j < static_cast<size_type>(nn); ++j)
966 eigenvectors[i](j) = values_A[col_begin+j];
969 state = LAPACKSupport::State(eigenvalues | unusable);
973 template <
typename number>
977 const unsigned int precision,
978 const bool scientific,
979 const unsigned int width_,
980 const char *zero_string,
981 const double denominator,
982 const double threshold)
const 984 unsigned int width = width_;
986 Assert ((!this->empty()) || (this->n_cols()+this->n_rows()==0),
988 Assert (state == LAPACKSupport::matrix ||
989 state == LAPACKSupport::inverse_matrix,
994 std::ios::fmtflags old_flags = out.flags();
995 unsigned int old_precision = out.precision (precision);
999 out.setf (std::ios::scientific, std::ios::floatfield);
1001 width = precision+7;
1005 out.setf (std::ios::fixed, std::ios::floatfield);
1007 width = precision+2;
1010 for (
size_type i=0; i<this->n_rows(); ++i)
1012 for (
size_type j=0; j<this->n_cols(); ++j)
1013 if (std::fabs(this->el(i,j)) > threshold)
1014 out << std::setw(width)
1015 << this->el(i,j) * denominator <<
' ';
1017 out << std::setw(width) << zero_string <<
' ';
1023 out.flags (old_flags);
1024 out.precision(old_precision);
1030 template <
typename number>
1039 template <
typename number>
1049 template <
typename number>
1055 matrix->apply_lu_factorization(dst,
false);
1059 template <
typename number>
1065 matrix->apply_lu_factorization(dst,
true);
1069 template <
typename number>
1077 matrix->apply_lu_factorization(*aux,
false);
1082 template <
typename number>
1090 matrix->apply_lu_factorization(*aux,
true);
1096 #include "lapack_full_matrix.inst" 1099 DEAL_II_NAMESPACE_CLOSE
LAPACKFullMatrix(const size_type size=0)
#define AssertDimension(dim1, dim2)
void TmTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
LAPACKFullMatrix< number > & operator/=(const number factor)
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
static ::ExceptionBase & ExcIO()
LAPACKSupport::State state
static ::ExceptionBase & ExcScalarAssignmentOnlyForZeroValue()
TableBase< N, T > & operator=(const TableBase< N, T > &src)
static ::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
void compute_eigenvalues_symmetric(const number lower_bound, const number upper_bound, const number abs_accuracy, Vector< number > &eigenvalues, FullMatrix< number > &eigenvectors)
unsigned int n_cols() const
void reinit(const size_type size)
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
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
unsigned int n_rows() const
static ::ExceptionBase & ExcErrorCode(char *arg1, int arg2)
void compute_lu_factorization()
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=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 int itype=1)
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
LAPACKFullMatrix< number > & operator*=(const number factor)
void compute_inverse_svd(const double threshold=0.)
static ::ExceptionBase & ExcNotQuadratic()
LAPACKFullMatrix< number > & operator=(const LAPACKFullMatrix< number > &)
number el(const size_type i, const size_type j) const
void Tvmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
void compute_eigenvalues(const bool right_eigenvectors=false, const bool left_eigenvectors=false)
void apply_lu_factorization(Vector< number > &v, const bool transposed) const
AlignedVector< number > values
void reinit(const unsigned int size1, const unsigned int size2, const bool omit_default_initialization=false)
static ::ExceptionBase & ExcZero()
#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 ::ExceptionBase & ExcInternalError()