1 #include "../../include/monolish_blas.hpp"
2 #include "../../include/monolish_eigen.hpp"
3 #include "../../include/monolish_solver.hpp"
4 #include "../../include/monolish_vml.hpp"
5 #include "../internal/lapack/monolish_lapack.hpp"
6 #include "../internal/monolish_internal.hpp"
10 template <
typename MATRIX,
typename T>
12 MATRIX &A, vector<T> &l, matrix::Dense<T> &xinout) {
18 if (A.get_col() != xinout.get_col()) {
19 throw std::runtime_error(
"error, A.col != x.col");
21 if (l.size() != xinout.get_row()) {
22 throw std::runtime_error(
"error, l.size != x.row");
25 this->precond.create_precond(A);
29 const std::size_t m = l.size();
31 const std::size_t n = A.get_col();
35 matrix::Dense<T> wxp(3 * m, n);
36 matrix::Dense<T> WXP(3 * m, n);
38 matrix::Dense<T> wxp_p(3 * m, n);
39 matrix::Dense<T> WXP_p(3 * m, n);
41 matrix::Dense<T> twxp(n, 3 * m);
52 std::vector<view1D<matrix::Dense<T>, T>> w;
53 std::vector<view1D<matrix::Dense<T>, T>> x;
54 std::vector<view1D<matrix::Dense<T>, T>> p;
55 std::vector<view1D<matrix::Dense<T>, T>> W;
56 std::vector<view1D<matrix::Dense<T>, T>> X;
57 std::vector<view1D<matrix::Dense<T>, T>> P;
58 std::vector<view1D<matrix::Dense<T>, T>> wp;
59 std::vector<view1D<matrix::Dense<T>, T>> xp;
60 std::vector<view1D<matrix::Dense<T>, T>> pp;
61 std::vector<view1D<matrix::Dense<T>, T>> Wp;
62 std::vector<view1D<matrix::Dense<T>, T>> Xp;
63 std::vector<view1D<matrix::Dense<T>, T>> Pp;
64 for (std::size_t i = 0; i < m; ++i) {
65 w.push_back(view1D<matrix::Dense<T>, T>(wxp, i * n, (i + 1) * n));
66 x.push_back(view1D<matrix::Dense<T>, T>(wxp, (m + i) * n, (m + i + 1) * n));
68 view1D<matrix::Dense<T>, T>(wxp, (2 * m + i) * n, (2 * m + i + 1) * n));
69 W.push_back(view1D<matrix::Dense<T>, T>(WXP, i * n, (i + 1) * n));
70 X.push_back(view1D<matrix::Dense<T>, T>(WXP, (m + i) * n, (m + i + 1) * n));
72 view1D<matrix::Dense<T>, T>(WXP, (2 * m + i) * n, (2 * m + i + 1) * n));
73 wp.push_back(view1D<matrix::Dense<T>, T>(wxp_p, i * n, (i + 1) * n));
75 view1D<matrix::Dense<T>, T>(wxp_p, (m + i) * n, (m + i + 1) * n));
76 pp.push_back(view1D<matrix::Dense<T>, T>(wxp_p, (2 * m + i) * n,
77 (2 * m + i + 1) * n));
78 Wp.push_back(view1D<matrix::Dense<T>, T>(WXP_p, i * n, (i + 1) * n));
80 view1D<matrix::Dense<T>, T>(WXP_p, (m + i) * n, (m + i + 1) * n));
81 Pp.push_back(view1D<matrix::Dense<T>, T>(WXP_p, (2 * m + i) * n,
82 (2 * m + i + 1) * n));
87 for (std::size_t i = 0; i < m; ++i) {
98 for (std::size_t i = 0; i < m; ++i) {
99 view1D<matrix::Dense<T>, T> xinout_i(xinout, i * n, (i + 1) * n);
103 if (A.get_device_mem_stat() ==
true) {
108 for (std::size_t i = 0; i < m; ++i) {
122 bool is_singular =
false;
124 matrix::Dense<T> Sam(3 * m, 3 * m);
125 matrix::Dense<T> Sbm(3 * m, 3 * m);
126 vector<T> lambda(3 * m);
127 if (A.get_device_mem_stat() ==
true) {
131 for (std::size_t iter = 0; iter < this->get_maxiter(); iter++) {
132 if (A.get_device_mem_stat() ==
true) {
135 if (iter == 0 || is_singular) {
144 wxp_p.set_row(2 * m);
147 WXP_p.set_row(2 * m);
149 if (A.get_device_mem_stat() ==
true) {
154 if (A.get_device_mem_stat() ==
true) {
164 if (A.get_device_mem_stat() ==
true) {
170 const char jobz =
'V';
171 const char uplo =
'L';
172 int info = internal::lapack::sygvd(Sam, Sbm, lambda, 1, &jobz, &uplo);
178 if (iter == 0 || is_singular) {
182 if (lbound < info && info <= ubound) {
183 if (this->get_print_rhistory()) {
184 *this->rhistory_stream << iter + 1 <<
"\t"
185 <<
"singular; restart the step" << std::endl;
190 }
else if (info != 0 && info <
static_cast<int>(m)) {
191 std::string s =
"sygvd returns ";
192 s += std::to_string(info);
193 s +=
": internal LAPACK sygvd returned error";
194 throw std::runtime_error(s);
196 if (A.get_device_mem_stat() ==
true) {
203 vector<T> residual(m);
204 for (std::size_t i = 0; i < m; ++i) {
210 if (iter == 0 || is_singular) {
215 if (iter == 0 || is_singular) {
218 for (std::size_t j = 2 * m; j < 3 * m; ++j) {
226 for (std::size_t j = 0; j < m; ++j) {
257 this->precond.apply_precond(vtmp2, vtmp1);
262 if (this->get_print_rhistory()) {
263 *this->rhistory_stream << iter + 1 <<
"\t" << i <<
"\t"
264 << std::scientific << residual[i] << std::endl;
266 if (std::isnan(residual[i])) {
267 for (std::size_t j = 0; j < m; ++j) {
268 view1D<matrix::Dense<T>, T> xinout_j(xinout, j * n, (j + 1) * n);
281 if (
vml::max(residual) < this->get_tol() &&
282 this->get_miniter() < iter + 1) {
283 for (std::size_t i = 0; i < m; ++i) {
284 view1D<matrix::Dense<T>, T> xinout_i(xinout, i * n, (i + 1) * n);
292 if (iter == 0 || is_singular) {
299 wxp_p.set_row(3 * m);
302 WXP_p.set_row(3 * m);
305 for (std::size_t i = 0; i < m; ++i) {
306 view1D<matrix::Dense<T>, T> xinout_i(xinout, i * n, (i + 1) * n);
314 standard_eigen::LOBPCG<matrix::Dense<double>,
double>::monolish_LOBPCG(
315 matrix::Dense<double> &A, vector<double> &l, matrix::Dense<double> &x);
317 standard_eigen::LOBPCG<matrix::Dense<float>,
float>::monolish_LOBPCG(
318 matrix::Dense<float> &A, vector<float> &l, matrix::Dense<float> &x);
320 standard_eigen::LOBPCG<matrix::CRS<double>,
double>::monolish_LOBPCG(
321 matrix::CRS<double> &A, vector<double> &l, matrix::Dense<double> &x);
322 template int standard_eigen::LOBPCG<matrix::CRS<float>,
float>::monolish_LOBPCG(
323 matrix::CRS<float> &A, vector<float> &l, matrix::Dense<float> &x);
333 template <
typename MATRIX,
typename T>
335 matrix::Dense<T> &x) {
340 if (this->get_lib() == 0) {
341 ret = monolish_LOBPCG(A, l, x);
348 template int standard_eigen::LOBPCG<matrix::Dense<double>,
double>::solve(
349 matrix::Dense<double> &A, vector<double> &l, matrix::Dense<double> &x);
350 template int standard_eigen::LOBPCG<matrix::Dense<float>,
float>::solve(
351 matrix::Dense<float> &A, vector<float> &l, matrix::Dense<float> &x);
352 template int standard_eigen::LOBPCG<matrix::CRS<double>,
double>::solve(
353 matrix::CRS<double> &A, vector<double> &l, matrix::Dense<double> &x);
354 template int standard_eigen::LOBPCG<matrix::CRS<float>,
float>::solve(
355 matrix::CRS<float> &A, vector<float> &l, matrix::Dense<float> &x);