8 template <
typename Scalar,
13 if(to_m <= from_k)
return;
17 Vector v(dim_n), w(dim_n);
18 Scalar beta = 0.0, Hii = 0.0;
20 fac_H.tail_cols(ncv - from_k).zeros();
21 fac_H.submat(arma::span(from_k, ncv - 1), arma::span(0, from_k - 1)).zeros();
22 for(
int i = from_k; i <= to_m - 1; i++)
24 beta = arma::norm(fac_f);
27 fac_H(i, i - 1) = beta;
29 op->perform_op(v.memptr(), w.memptr());
32 Hii = arma::dot(v, w);
33 fac_H(i - 1, i) = beta;
36 fac_f = w - beta * fac_V.col(i - 1) - Hii * v;
41 Scalar v1f = arma::dot(fac_f, fac_V.col(0));
42 if(v1f > prec || v1f < -prec)
45 Vf.tail(i) = fac_V.cols(1, i).t() * fac_f;
47 fac_f -= fac_V.head_cols(i + 1) * Vf;
53 template <
typename Scalar,
62 Vector em(ncv, arma::fill::zeros);
65 for(
int i = k; i < ncv; i++)
68 fac_H.diag() -= ritz_val[i];
77 fac_H.diag() += ritz_val[i];
81 Vector fk = fac_f * em[k - 1] + fac_V.col(k) * fac_H(k, k - 1);
82 factorize_from(k, ncv, fk);
87 template <
typename Scalar,
93 Vector rv = arma::abs(ritz_val.head(nev));
94 Vector thresh = tol * arma::clamp(rv, prec, std::max(prec, rv.max()));
95 Vector resid = arma::abs(ritz_vec.tail_rows(1).t()) * arma::norm(fac_f);
97 ritz_conv = (resid < thresh);
99 return arma::sum(ritz_conv);
103 template <
typename Scalar,
111 nev_new = nev + std::min(nconv, (ncv - nev) / 2);
112 if(nev == 1 && ncv >= 6)
114 else if(nev == 1 && ncv > 2)
121 template <
typename Scalar,
130 Vector evals = decomp.eigenvalues();
131 Matrix evecs = decomp.eigenvectors();
133 SortEigenvalue<Scalar, SelectionRule> sorting(evals.memptr(), evals.n_elem);
134 std::vector<int> ind = sorting.index();
146 std::vector<int> ind_copy(ind);
147 for(
int i = 0; i < ncv; i++)
152 ind[i] = ind_copy[i / 2];
154 ind[i] = ind_copy[ncv - 1 - i / 2];
159 for(
int i = 0; i < ncv; i++)
161 ritz_val[i] = evals[ind[i]];
163 for(
int i = 0; i < nev; i++)
165 ritz_vec.col(i) = evecs.col(ind[i]);
173 template <
typename Scalar,
178 SortEigenvalue<Scalar, LARGEST_MAGN> sorting(ritz_val.memptr(), nev);
179 std::vector<int> ind = sorting.index();
181 Vector new_ritz_val(ncv);
182 Matrix new_ritz_vec(ncv, nev);
183 BoolVector new_ritz_conv(nev);
185 for(
int i = 0; i < nev; i++)
187 new_ritz_val[i] = ritz_val[ind[i]];
188 new_ritz_vec.col(i) = ritz_vec.col(ind[i]);
189 new_ritz_conv[i] = ritz_conv[ind[i]];
192 ritz_val.swap(new_ritz_val);
193 ritz_vec.swap(new_ritz_vec);
194 ritz_conv.swap(new_ritz_conv);
200 template <
typename Scalar,
206 fac_V.zeros(dim_n, ncv);
207 fac_H.zeros(ncv, ncv);
210 ritz_vec.zeros(ncv, nev);
211 ritz_conv.zeros(nev);
216 Vector r(init_resid, dim_n,
false);
218 Vector v(fac_V.colptr(0), dim_n,
false);
219 Scalar rnorm = arma::norm(r);
221 throw std::invalid_argument(
"initial residual vector cannot be zero");
225 op->perform_op(v.memptr(), w.memptr());
228 fac_H(0, 0) = arma::dot(v, w);
229 fac_f = w - v * fac_H(0, 0);
233 template <
typename Scalar,
238 Vector init_resid(dim_n, arma::fill::randu);
240 init(init_resid.memptr());
244 template <
typename Scalar,
250 factorize_from(1, ncv, fac_f);
253 int i, nconv = 0, nev_adj;
254 for(i = 0; i < maxit; i++)
256 nconv = num_converged(tol);
260 nev_adj = nev_adjusted(nconv);
268 return std::min(nev, nconv);
272 template <
typename Scalar,
277 int nconv = arma::sum(ritz_conv);
284 for(
int i = 0; i < nev; i++)
288 res[j] = ritz_val[i];
297 template <
typename Scalar,
302 int nconv = arma::sum(ritz_conv);
303 nvec = std::min(nvec, nconv);
304 Matrix res(dim_n, nvec);
309 Matrix ritz_vec_conv(ncv, nvec);
311 for(
int i = 0; i < nev && j < nvec; i++)
315 ritz_vec_conv.col(j) = ritz_vec.col(i);
320 res = fac_V * ritz_vec_conv;
int compute(int maxit=1000, Scalar tol=1e-10)
void compute(const Matrix &mat)
void apply_QtY(Vector &Y)