1 #include "../../include/monolish_blas.hpp"
2 #include "../../include/monolish_eigen.hpp"
3 #include "../../include/monolish_vml.hpp"
4 #include "../internal/lapack/monolish_lapack.hpp"
5 #include "../internal/monolish_internal.hpp"
9 template <
typename MATRIX,
typename T>
11 MATRIX &A, MATRIX &B, vector<T> &l, matrix::Dense<T> &xinout,
int itype) {
20 if (A.get_col() != xinout.get_col()) {
21 throw std::runtime_error(
"error, A.col != x.col");
23 if (A.get_col() != B.get_col() || A.get_row() != B.get_row()) {
24 throw std::runtime_error(
"error, A shape != B shape");
26 if (l.size() != xinout.get_row()) {
27 throw std::runtime_error(
"error, l.size != x.row");
30 this->precond.create_precond(A);
34 const std::size_t m = l.size();
36 const std::size_t n = A.get_col();
40 matrix::Dense<T> wxp(3 * m, n);
41 matrix::Dense<T> WXP(3 * m, n);
42 matrix::Dense<T> BWXP(3 * m, n);
44 matrix::Dense<T> wxp_p(3 * m, n);
45 matrix::Dense<T> WXP_p(3 * m, n);
46 matrix::Dense<T> BWXP_p(3 * m, n);
48 matrix::Dense<T> twxp(n, 3 * m);
59 std::vector<view1D<matrix::Dense<T>, T>> w;
60 std::vector<view1D<matrix::Dense<T>, T>> x;
61 std::vector<view1D<matrix::Dense<T>, T>> p;
62 std::vector<view1D<matrix::Dense<T>, T>> W;
63 std::vector<view1D<matrix::Dense<T>, T>> X;
64 std::vector<view1D<matrix::Dense<T>, T>> P;
65 std::vector<view1D<matrix::Dense<T>, T>> BW;
66 std::vector<view1D<matrix::Dense<T>, T>> BX;
67 std::vector<view1D<matrix::Dense<T>, T>> BP;
68 std::vector<view1D<matrix::Dense<T>, T>> wp;
69 std::vector<view1D<matrix::Dense<T>, T>> xp;
70 std::vector<view1D<matrix::Dense<T>, T>> pp;
71 std::vector<view1D<matrix::Dense<T>, T>> Wp;
72 std::vector<view1D<matrix::Dense<T>, T>> Xp;
73 std::vector<view1D<matrix::Dense<T>, T>> Pp;
74 std::vector<view1D<matrix::Dense<T>, T>> BWp;
75 std::vector<view1D<matrix::Dense<T>, T>> BXp;
76 std::vector<view1D<matrix::Dense<T>, T>> BPp;
77 for (std::size_t i = 0; i < m; ++i) {
78 w.push_back(view1D<matrix::Dense<T>, T>(wxp, i * n, (i + 1) * n));
79 x.push_back(view1D<matrix::Dense<T>, T>(wxp, (m + i) * n, (m + i + 1) * n));
81 view1D<matrix::Dense<T>, T>(wxp, (2 * m + i) * n, (2 * m + i + 1) * n));
82 W.push_back(view1D<matrix::Dense<T>, T>(WXP, i * n, (i + 1) * n));
83 X.push_back(view1D<matrix::Dense<T>, T>(WXP, (m + i) * n, (m + i + 1) * n));
85 view1D<matrix::Dense<T>, T>(WXP, (2 * m + i) * n, (2 * m + i + 1) * n));
86 BW.push_back(view1D<matrix::Dense<T>, T>(BWXP, i * n, (i + 1) * n));
88 view1D<matrix::Dense<T>, T>(BWXP, (m + i) * n, (m + i + 1) * n));
89 BP.push_back(view1D<matrix::Dense<T>, T>(BWXP, (2 * m + i) * n,
90 (2 * m + i + 1) * n));
91 wp.push_back(view1D<matrix::Dense<T>, T>(wxp_p, i * n, (i + 1) * n));
93 view1D<matrix::Dense<T>, T>(wxp_p, (m + i) * n, (m + i + 1) * n));
94 pp.push_back(view1D<matrix::Dense<T>, T>(wxp_p, (2 * m + i) * n,
95 (2 * m + i + 1) * n));
96 Wp.push_back(view1D<matrix::Dense<T>, T>(WXP_p, i * n, (i + 1) * n));
98 view1D<matrix::Dense<T>, T>(WXP_p, (m + i) * n, (m + i + 1) * n));
99 Pp.push_back(view1D<matrix::Dense<T>, T>(WXP_p, (2 * m + i) * n,
100 (2 * m + i + 1) * n));
101 BWp.push_back(view1D<matrix::Dense<T>, T>(BWXP_p, i * n, (i + 1) * n));
103 view1D<matrix::Dense<T>, T>(BWXP_p, (m + i) * n, (m + i + 1) * n));
104 BPp.push_back(view1D<matrix::Dense<T>, T>(BWXP_p, (2 * m + i) * n,
105 (2 * m + i + 1) * n));
110 for (std::size_t i = 0; i < m; ++i) {
121 for (std::size_t i = 0; i < m; ++i) {
122 view1D<matrix::Dense<T>, T> xinout_i(xinout, i * n, (i + 1) * n);
127 if (A.get_device_mem_stat() ==
true) {
129 vtmp2, zero, xinout);
132 for (std::size_t i = 0; i < m; ++i) {
152 bool is_singular =
false;
154 matrix::Dense<T> Sam(3 * m, 3 * m);
155 matrix::Dense<T> Sbm(3 * m, 3 * m);
156 vector<T> lambda(3 * m);
157 if (A.get_device_mem_stat() ==
true) {
161 for (std::size_t iter = 0; iter < this->get_maxiter(); iter++) {
162 if (A.get_device_mem_stat() ==
true) {
165 if (iter == 0 || is_singular) {
174 wxp_p.set_row(2 * m);
177 WXP_p.set_row(2 * m);
179 BWXP_p.set_row(2 * m);
181 if (A.get_device_mem_stat() ==
true) {
186 if (A.get_device_mem_stat() ==
true) {
195 if (A.get_device_mem_stat() ==
true) {
201 const char jobz =
'V';
202 const char uplo =
'L';
203 int info = internal::lapack::sygvd(Sam, Sbm, lambda, 1, &jobz, &uplo);
209 if (iter == 0 || is_singular) {
213 if (lbound < info && info <= ubound) {
214 if (this->get_print_rhistory()) {
215 *this->rhistory_stream << iter + 1 <<
"\t"
216 <<
"singular; restart the step" << std::endl;
221 }
else if (info != 0 && info <
static_cast<int>(m)) {
222 std::string s =
"sygvd returns ";
223 s += std::to_string(info);
224 s +=
": internal LAPACK sygvd returned error";
225 throw std::runtime_error(s);
227 if (A.get_device_mem_stat() ==
true) {
235 vector<T> residual(m);
236 for (std::size_t i = 0; i < m; ++i) {
242 if (iter == 0 || is_singular) {
247 if (iter == 0 || is_singular) {
250 for (std::size_t j = 2 * m; j < 3 * m; ++j) {
261 for (std::size_t j = 0; j < m; ++j) {
303 this->precond.apply_precond(vtmp2, vtmp1);
308 if (this->get_print_rhistory()) {
309 *this->rhistory_stream << iter + 1 <<
"\t" << i <<
"\t"
310 << std::scientific << residual[i] << std::endl;
312 if (std::isnan(residual[i])) {
313 for (std::size_t j = 0; j < m; ++j) {
314 view1D<matrix::Dense<T>, T> xinout_j(xinout, j * n, (j + 1) * n);
329 if (
vml::max(residual) < this->get_tol() &&
330 this->get_miniter() < iter + 1) {
331 for (std::size_t i = 0; i < m; ++i) {
332 view1D<matrix::Dense<T>, T> xinout_i(xinout, i * n, (i + 1) * n);
340 if (iter == 0 || is_singular) {
347 wxp_p.set_row(3 * m);
350 WXP_p.set_row(3 * m);
352 BWXP_p.set_row(3 * m);
355 for (std::size_t i = 0; i < m; ++i) {
356 view1D<matrix::Dense<T>, T> xinout_i(xinout, i * n, (i + 1) * n);
364 generalized_eigen::LOBPCG<matrix::Dense<double>,
double>::monolish_LOBPCG(
365 matrix::Dense<double> &A, matrix::Dense<double> &B, vector<double> &l,
366 matrix::Dense<double> &x,
int itype = 1);
368 generalized_eigen::LOBPCG<matrix::Dense<float>,
float>::monolish_LOBPCG(
369 matrix::Dense<float> &A, matrix::Dense<float> &B, vector<float> &l,
370 matrix::Dense<float> &x,
int itype = 1);
372 generalized_eigen::LOBPCG<matrix::CRS<double>,
double>::monolish_LOBPCG(
373 matrix::CRS<double> &A, matrix::CRS<double> &B, vector<double> &l,
374 matrix::Dense<double> &x,
int itype = 1);
376 generalized_eigen::LOBPCG<matrix::CRS<float>,
float>::monolish_LOBPCG(
377 matrix::CRS<float> &A, matrix::CRS<float> &B, vector<float> &l,
378 matrix::Dense<float> &x,
int itype = 1);
379 template int generalized_eigen::LOBPCG<matrix::LinearOperator<double>,
double>::
380 monolish_LOBPCG(matrix::LinearOperator<double> &A,
381 matrix::LinearOperator<double> &B, vector<double> &l,
382 matrix::Dense<double> &x,
int itype = 1);
383 template int generalized_eigen::LOBPCG<matrix::LinearOperator<float>,
float>::
384 monolish_LOBPCG(matrix::LinearOperator<float> &A,
385 matrix::LinearOperator<float> &B, vector<float> &l,
386 matrix::Dense<float> &x,
int itype = 1);
388 template <
typename MATRIX,
typename T>
397 if (this->get_lib() == 0) {
398 ret = monolish_LOBPCG(A, B, l, x, itype);
405 template int generalized_eigen::LOBPCG<matrix::Dense<double>,
double>::solve(
406 matrix::Dense<double> &A, matrix::Dense<double> &B, vector<double> &l,
407 matrix::Dense<double> &x,
int itype);
408 template int generalized_eigen::LOBPCG<matrix::Dense<float>,
float>::solve(
409 matrix::Dense<float> &A, matrix::Dense<float> &B, vector<float> &l,
410 matrix::Dense<float> &x,
int itype);
411 template int generalized_eigen::LOBPCG<matrix::CRS<double>,
double>::solve(
412 matrix::CRS<double> &A, matrix::CRS<double> &B, vector<double> &l,
413 matrix::Dense<double> &x,
int itype);
414 template int generalized_eigen::LOBPCG<matrix::CRS<float>,
float>::solve(
415 matrix::CRS<float> &A, matrix::CRS<float> &B, vector<float> &l,
416 matrix::Dense<float> &x,
int itype);
418 generalized_eigen::LOBPCG<matrix::LinearOperator<double>,
double>::solve(
419 matrix::LinearOperator<double> &A, matrix::LinearOperator<double> &B,
420 vector<double> &l, matrix::Dense<double> &x,
int itype);
422 generalized_eigen::LOBPCG<matrix::LinearOperator<float>,
float>::solve(
423 matrix::LinearOperator<float> &A, matrix::LinearOperator<float> &B,
424 vector<float> &l, matrix::Dense<float> &x,
int itype);