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>
91 Assert (this->
n_rows() == M.n_rows(), ExcDimensionMismatch(this->
n_rows(), M.n_rows()));
95 (*
this)(i,j) = M(i,j);
97 state = LAPACKSupport::matrix;
102 template <
typename number>
103 template <
typename number2>
111 (*
this)(i,j) = M.
el(i,j);
113 state = LAPACKSupport::matrix;
118 template <
typename number>
123 Assert (d==0, ExcScalarAssignmentOnlyForZeroValue());
128 state = LAPACKSupport::matrix;
133 template <
typename number>
138 const bool adding)
const 140 const int mm = this->
n_rows();
141 const int nn = this->
n_cols();
142 const number alpha = 1.;
143 const number beta = (adding ? 1. : 0.);
144 const number null = 0.;
154 gemv(
"N", &mm, &nn, &alpha, &this->
values[0], &mm, v.
val, &one, &beta, w.
val, &one);
162 work.resize(std::max(mm,nn));
163 gemv(
"N", &nn, &nn, &alpha, &
svd_vt->values[0], &nn, v.
val, &one, &null, &
work[0], &one);
168 gemv(
"N", &mm, &mm, &alpha, &
svd_u->values[0], &mm, &
work[0], &one, &beta, w.
val, &one);
176 work.resize(std::max(mm,nn));
177 gemv(
"T", &mm, &mm, &alpha, &
svd_u->values[0], &mm, v.
val, &one, &null, &
work[0], &one);
182 gemv(
"T", &nn, &nn, &alpha, &
svd_vt->values[0], &nn, &
work[0], &one, &beta, w.
val, &one);
191 template <
typename number>
196 const bool adding)
const 198 const int mm = this->
n_rows();
199 const int nn = this->
n_cols();
200 const number alpha = 1.;
201 const number beta = (adding ? 1. : 0.);
202 const number null = 0.;
212 gemv(
"T", &mm, &nn, &alpha, &this->
values[0], &mm, v.
val, &one, &beta, w.
val, &one);
221 work.resize(std::max(mm,nn));
222 gemv(
"T", &mm, &mm, &alpha, &
svd_u->values[0], &mm, v.
val, &one, &null, &
work[0], &one);
227 gemv(
"T", &nn, &nn, &alpha, &
svd_vt->values[0], &nn, &
work[0], &one, &beta, w.
val, &one);
235 work.resize(std::max(mm,nn));
236 gemv(
"N", &nn, &nn, &alpha, &
svd_vt->values[0], &nn, v.
val, &one, &null, &
work[0], &one);
241 gemv(
"N", &mm, &mm, &alpha, &
svd_u->values[0], &mm, &
work[0], &one, &beta, w.
val, &one);
251 template <
typename number>
260 template <
typename number>
269 template <
typename number>
273 const bool adding)
const 281 const int mm = this->
n_rows();
282 const int nn = B.
n_cols();
283 const int kk = this->
n_cols();
284 const number alpha = 1.;
285 const number beta = (adding ? 1. : 0.);
287 gemm(
"N",
"N", &mm, &nn, &kk, &alpha, &this->
values[0], &mm, &B.
values[0],
288 &kk, &beta, &C.
values[0], &mm);
292 template <
typename number>
296 const bool adding)
const 302 Assert (C.n_rows() == this->
n_rows(), ExcDimensionMismatch(this->
n_rows(), C.n_rows()));
303 const int mm = this->
n_rows();
304 const int nn = B.
n_cols();
305 const int kk = this->
n_cols();
306 const number alpha = 1.;
307 const number beta = (adding ? 1. : 0.);
311 gemm(
"T",
"T", &nn, &mm, &kk, &alpha, &B.
values[0], &kk, &this->values[0],
312 &mm, &beta, &C(0,0), &nn);
317 template <
typename number>
321 const bool adding)
const 329 const int mm = this->
n_cols();
330 const int nn = B.
n_cols();
331 const int kk = B.
n_rows();
332 const number alpha = 1.;
333 const number beta = (adding ? 1. : 0.);
335 gemm(
"T",
"N", &mm, &nn, &kk, &alpha, &this->
values[0], &kk, &B.
values[0],
336 &kk, &beta, &C.
values[0], &mm);
340 template <
typename number>
344 const bool adding)
const 350 Assert (C.n_rows() == this->
n_cols(), ExcDimensionMismatch(this->
n_cols(), C.n_rows()));
351 const int mm = this->
n_cols();
352 const int nn = B.
n_cols();
353 const int kk = B.
n_rows();
354 const number alpha = 1.;
355 const number beta = (adding ? 1. : 0.);
359 gemm(
"T",
"N", &nn, &mm, &kk, &alpha, &B.
values[0], &kk, &this->values[0],
360 &kk, &beta, &C(0,0), &nn);
364 template <
typename number>
368 const bool adding)
const 376 const int mm = this->
n_rows();
377 const int nn = B.
n_rows();
378 const int kk = B.
n_cols();
379 const number alpha = 1.;
380 const number beta = (adding ? 1. : 0.);
382 gemm(
"N",
"T", &mm, &nn, &kk, &alpha, &this->
values[0], &mm, &B.
values[0],
383 &nn, &beta, &C.
values[0], &mm);
388 template <
typename number>
392 const bool adding)
const 398 Assert (C.n_rows() == this->
n_rows(), ExcDimensionMismatch(this->
n_rows(), C.n_rows()));
399 const int mm = this->
n_rows();
400 const int nn = B.
n_rows();
401 const int kk = B.
n_cols();
402 const number alpha = 1.;
403 const number beta = (adding ? 1. : 0.);
407 gemm(
"N",
"T", &nn, &mm, &kk, &alpha, &B.
values[0], &nn, &this->values[0],
408 &mm, &beta, &C(0,0), &nn);
412 template <
typename number>
416 const bool adding)
const 424 const int mm = this->
n_cols();
425 const int nn = B.
n_rows();
426 const int kk = B.
n_cols();
427 const number alpha = 1.;
428 const number beta = (adding ? 1. : 0.);
430 gemm(
"T",
"T", &mm, &nn, &kk, &alpha, &this->
values[0], &kk, &B.
values[0],
431 &nn, &beta, &C.
values[0], &mm);
435 template <
typename number>
439 const bool adding)
const 445 Assert (C.n_rows() == this->
n_cols(), ExcDimensionMismatch(this->
n_cols(), C.n_rows()));
446 const int mm = this->
n_cols();
447 const int nn = B.
n_rows();
448 const int kk = B.
n_cols();
449 const number alpha = 1.;
450 const number beta = (adding ? 1. : 0.);
454 gemm(
"N",
"N", &nn, &mm, &kk, &alpha, &B.
values[0], &nn, &this->values[0],
455 &kk, &beta, &C(0,0), &nn);
459 template <
typename number>
464 const int mm = this->
n_rows();
465 const int nn = this->
n_cols();
466 number *
values =
const_cast<number *
> (&this->values[0]);
469 getrf(&mm, &nn, values, &mm, &
ipiv[0], &info);
472 AssertThrow(info == 0, LACExceptions::ExcSingular());
478 template <
typename number>
483 state = LAPACKSupport::unusable;
485 const int mm = this->
n_rows();
486 const int nn = this->
n_cols();
487 number *
values =
const_cast<number *
> (&this->values[0]);
488 wr.resize(std::max(mm,nn));
489 std::fill(
wr.begin(),
wr.end(), 0.);
494 number *
mu =
const_cast<number *
> (&
svd_u->values[0]);
495 number *mvt =
const_cast<number *
> (&
svd_vt->values[0]);
501 gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
502 &
wr[0], mu, &mm, mvt, &nn,
504 AssertThrow (info==0, LAPACKSupport::ExcErrorCode(
"gesdd", info));
507 lwork =
static_cast<int>(
work[0] + 1);
511 gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
512 &
wr[0], mu, &mm, mvt, &nn,
514 AssertThrow (info==0, LAPACKSupport::ExcErrorCode(
"gesdd", info));
519 state = LAPACKSupport::svd;
523 template <
typename number>
527 if (
state == LAPACKSupport::matrix)
532 const double lim =
wr[0]*threshold;
540 state = LAPACKSupport::inverse_svd;
544 template <
typename number>
550 const int mm = this->
n_rows();
551 const int nn = this->
n_cols();
552 Assert (nn == mm, ExcNotQuadratic());
554 number *
values =
const_cast<number *
> (&this->values[0]);
560 getrf(&mm, &nn, values, &mm, &
ipiv[0], &info);
563 AssertThrow(info == 0, LACExceptions::ExcSingular());
567 getri(&mm, values, &mm, &
ipiv[0], &
inv_work[0], &mm, &info);
570 AssertThrow(info == 0, LACExceptions::ExcSingular());
572 state = inverse_matrix;
576 template <
typename number>
579 const bool transposed)
const 583 LACExceptions::ExcNotQuadratic());
586 const char *trans = transposed ? &T : &N;
587 const int nn = this->
n_cols();
588 const number *
values = &this->values[0];
591 getrs(trans, &nn, &one, values, &nn, &
ipiv[0],
592 v.
begin(), &nn, &info);
598 template <
typename number>
601 const bool transposed)
const 608 const char *trans = transposed ? &T : &N;
609 const int nn = this->
n_cols();
610 const int kk = B.
n_cols();
611 const number *
values = &this->values[0];
614 getrs(trans, &nn, &kk, values, &nn, &
ipiv[0], &B.
values[0], &nn, &info);
620 template <
typename number>
626 const int nn = this->
n_cols();
629 if (right)
vr.resize(nn*nn);
630 if (left)
vl.resize(nn*nn);
632 number *
values =
const_cast<number *
> (&this->values[0]);
636 const char *
const jobvr = (right) ? (&V) : (&N);
637 const char *
const jobvl = (left) ? (&V) : (&N);
651 geev(jobvl, jobvr, &nn, values, &nn,
653 &
vl[0], &nn, &
vr[0], &nn,
654 &
work[0], &lwork, &info);
657 Assert (info == 0, ExcInternalError());
660 lwork =
static_cast<int>(
work[0] + 1);
666 geev(jobvl, jobvr, &nn, values, &nn,
668 &
vl[0], &nn, &
vr[0], &nn,
669 &
work[0], &lwork, &info);
672 Assert (info >=0, ExcInternalError());
675 std::cerr <<
"LAPACK error in geev" << std::endl;
677 state = LAPACKSupport::State(eigenvalues | unusable);
681 template <
typename number>
684 const number upper_bound,
685 const number abs_accuracy,
690 const int nn = (this->
n_cols() > 0 ? this->
n_cols() : 1);
691 Assert(static_cast<size_type>(nn) == this->
n_rows(), ExcNotQuadratic());
696 number *values_A =
const_cast<number *
> (&this->
values[0]);
697 number *values_eigenvectors =
const_cast<number *
> (&matrix_eigenvectors.
values[0]);
702 const char *
const jobz(&V);
703 const char *
const uplo(&U);
704 const char *
const range(&V);
705 const int *
const dummy(&one);
706 std::vector<int> iwork(static_cast<size_type> (5*nn));
707 std::vector<int> ifail(static_cast<size_type> (nn));
722 uplo, &nn, values_A, &nn,
723 &lower_bound, &upper_bound,
724 dummy, dummy, &abs_accuracy,
725 &n_eigenpairs, &
wr[0], values_eigenvectors,
726 &nn, &
work[0], &lwork, &iwork[0],
730 Assert (info == 0, ExcInternalError());
733 lwork =
static_cast<int>(
work[0] + 1);
734 work.resize(static_cast<size_type> (lwork));
738 uplo, &nn, values_A, &nn,
739 &lower_bound, &upper_bound,
740 dummy, dummy, &abs_accuracy,
741 &n_eigenpairs, &
wr[0], values_eigenvectors,
742 &nn, &
work[0], &lwork, &iwork[0],
746 Assert (info >=0, ExcInternalError());
748 std::cerr <<
"LAPACK error in syevx" << std::endl;
750 eigenvalues.
reinit(n_eigenpairs);
751 eigenvectors.
reinit(nn, n_eigenpairs,
true);
753 for (
size_type i=0; i < static_cast<size_type> (n_eigenpairs); ++i)
755 eigenvalues(i) =
wr[i];
757 for (
size_type j=0; j < static_cast<size_type> (nn); ++j)
759 eigenvectors(j,i) = values_eigenvectors[col_begin+j];
763 state = LAPACKSupport::State(unusable);
767 template <
typename number>
771 const number lower_bound,
772 const number upper_bound,
773 const number abs_accuracy,
779 const int nn = (this->
n_cols() > 0 ? this->
n_cols() : 1);
780 Assert(static_cast<size_type>(nn) == this->
n_rows(), ExcNotQuadratic());
783 ExcDimensionMismatch (nn, B.
n_cols()));
788 number *values_A =
const_cast<number *
> (&this->
values[0]);
789 number *values_B =
const_cast<number *
> (&B.
values[0]);
790 number *values_eigenvectors =
const_cast<number *
> (&matrix_eigenvectors.
values[0]);
795 const char *
const jobz(&V);
796 const char *
const uplo(&U);
797 const char *
const range(&V);
798 const int *
const dummy(&one);
799 std::vector<int> iwork(static_cast<size_type> (5*nn));
800 std::vector<int> ifail(static_cast<size_type> (nn));
814 sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
815 values_B, &nn, &lower_bound, &upper_bound,
816 dummy, dummy, &abs_accuracy, &n_eigenpairs,
817 &
wr[0], values_eigenvectors, &nn, &
work[0],
818 &lwork, &iwork[0], &ifail[0], &info);
821 Assert (info == 0, ExcInternalError());
824 lwork =
static_cast<int>(
work[0] + 1);
827 work.resize(static_cast<size_type> (lwork));
830 sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
831 values_B, &nn, &lower_bound, &upper_bound,
832 dummy, dummy, &abs_accuracy, &n_eigenpairs,
833 &
wr[0], values_eigenvectors, &nn, &
work[0],
834 &lwork, &iwork[0], &ifail[0], &info);
837 Assert (info >=0, ExcInternalError());
839 std::cerr <<
"LAPACK error in sygvx" << std::endl;
841 eigenvalues.
reinit(n_eigenpairs);
842 eigenvectors.resize(n_eigenpairs);
844 for (
size_type i=0; i < static_cast<size_type> (n_eigenpairs); ++i)
846 eigenvalues(i) =
wr[i];
848 eigenvectors[i].reinit(nn,
true);
849 for (
size_type j=0; j < static_cast<size_type> (nn); ++j)
851 eigenvectors[i](j) = values_eigenvectors[col_begin+j];
855 state = LAPACKSupport::State(unusable);
859 template <
typename number>
867 const int nn = this->
n_cols();
868 Assert(static_cast<size_type>(nn) == this->
n_rows(), ExcNotQuadratic());
871 ExcDimensionMismatch (nn, B.
n_cols()));
873 ExcMessage (
"eigenvectors.size() > matrix.n_cols()"));
879 number *values_A =
const_cast<number *
> (&this->
values[0]);
880 number *values_B =
const_cast<number *
> (&B.
values[0]);
884 const char *
const jobz = (eigenvectors.size() > 0) ? (&V) : (&N);
885 const char *
const uplo = (&U);
898 sygv (&itype, jobz, uplo, &nn, values_A, &nn,
900 &
wr[0], &
work[0], &lwork, &info);
903 Assert (info == 0, ExcInternalError());
906 lwork =
static_cast<int>(
work[0] + 1);
912 sygv (&itype, jobz, uplo, &nn, values_A, &nn,
914 &
wr[0], &
work[0], &lwork, &info);
917 Assert (info >=0, ExcInternalError());
919 std::cerr <<
"LAPACK error in sygv" << std::endl;
921 for (
size_type i=0; i < eigenvectors.size(); ++i)
924 eigenvectors[i].reinit(nn,
true);
925 for (
size_type j=0; j < static_cast<size_type>(nn); ++j)
927 eigenvectors[i](j) = values_A[col_begin+j];
930 state = LAPACKSupport::State(eigenvalues | unusable);
934 template <
typename number>
938 const unsigned int precision,
939 const bool scientific,
940 const unsigned int width_,
941 const char *zero_string,
942 const double denominator,
943 const double threshold)
const 945 unsigned int width = width_;
952 std::ios::fmtflags old_flags = out.flags();
953 unsigned int old_precision = out.precision (precision);
957 out.setf (std::ios::scientific, std::ios::floatfield);
963 out.setf (std::ios::fixed, std::ios::floatfield);
971 if (std::fabs(this->
el(i,j)) > threshold)
972 out << std::setw(width)
973 << this->
el(i,j) * denominator <<
' ';
975 out << std::setw(width) << zero_string <<
' ';
981 out.flags (old_flags);
982 out.precision(old_precision);
988 template <
typename number>
997 template <
typename number>
1007 template <
typename number>
1013 matrix->apply_lu_factorization(dst,
false);
1017 template <
typename number>
1023 matrix->apply_lu_factorization(dst,
true);
1027 template <
typename number>
1032 Assert(mem != 0, ExcNotInitialized());
1035 matrix->apply_lu_factorization(*aux,
false);
1040 template <
typename number>
1045 Assert(mem != 0, ExcNotInitialized());
1048 matrix->apply_lu_factorization(*aux,
true);
1054 #include "lapack_full_matrix.inst" 1057 DEAL_II_NAMESPACE_CLOSE
LAPACKFullMatrix(const size_type size=0)
std_cxx11::shared_ptr< LAPACKFullMatrix< number > > svd_u
std::vector< number > work
#define AssertDimension(dim1, dim2)
void TmTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
LAPACKSupport::State state
AlignedVector< number >::reference el(const unsigned int i, const unsigned int j)
::ExceptionBase & ExcMessage(std::string arg1)
TableBase< N, T > & operator=(const TableBase< N, T > &src)
#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)
size_type n_elements() const
void Tmmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
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)
std_cxx11::shared_ptr< LAPACKFullMatrix< number > > svd_vt
#define Assert(cond, exc)
std::vector< number > inv_work
unsigned int n_rows() const
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
void compute_inverse_svd(const double threshold=0.)
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
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
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)
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