8 template <
typename Scalar,
13 if(to_m <= from_k)
return;
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 = std::sqrt(arma::dot(fac_f, fac_f));
25 fac_V.col(i) = fac_f / beta;
26 fac_H(i, i - 1) = beta;
29 op->perform_op(fac_V.colptr(i), w.memptr());
33 Matrix Vs(fac_V.memptr(), dim_n, i + 1,
false);
35 Vector h(fac_H.colptr(i), i + 1,
false);
43 Scalar v1f = arma::dot(fac_f, fac_V.col(0));
44 if(v1f > prec || v1f < -prec)
47 Vf.tail(i) = fac_V.cols(1, i).t() * fac_f;
55 template <
typename Scalar,
65 Matrix Q(ncv, ncv, arma::fill::eye);
67 for(
int i = k; i < ncv; i++)
69 if(is_complex(ritz_val[i], prec) && is_conj(ritz_val[i], ritz_val[i + 1], prec))
77 Scalar s = 2 * ritz_val[i].real();
78 Scalar t = std::norm(ritz_val[i]);
80 decomp_ds.compute(fac_H, s, t);
83 decomp_ds.apply_YQ(Q);
89 fac_H = decomp_ds.matrix_QtHQ();
94 fac_H.diag() -= ritz_val[i].real();
101 fac_H.diag() += ritz_val[i].real();
107 Matrix Vs(dim_n, k + 1);
109 for(
int i = 0; i < k; i++)
111 nnz = ncv - k + i + 1;
112 Matrix V(fac_V.memptr(), dim_n, nnz,
false);
113 Vector q(Q.colptr(i), nnz,
false);
114 Vector v(Vs.colptr(i), dim_n,
false);
117 Vs.col(k) = fac_V * Q.col(k);
118 fac_V.head_cols(k + 1) = Vs;
120 Vector fk = fac_f * Q(ncv - 1, k - 1) + fac_V.col(k) * fac_H(k, k - 1);
121 factorize_from(k, ncv, fk);
126 template <
typename Scalar,
140 const Scalar f_norm = arma::norm(fac_f);
141 for(
unsigned int i = 0; i < ritz_conv.n_elem; i++)
143 Scalar thresh = tol * std::max(prec, std::abs(ritz_val[i]));
144 Scalar resid = std::abs(ritz_vec(ncv - 1, i)) * f_norm;
145 ritz_conv[i] = (resid < thresh);
148 return arma::sum(ritz_conv);
152 template <
typename Scalar,
161 if(is_complex(ritz_val[nev - 1], prec) &&
162 is_conj(ritz_val[nev - 1], ritz_val[nev], prec))
167 nev_new = nev_new + std::min(nconv, (ncv - nev_new) / 2);
168 if(nev_new == 1 && ncv >= 6)
170 else if(nev_new == 1 && ncv > 3)
173 if(nev_new > ncv - 2)
177 if(is_complex(ritz_val[nev_new - 1], prec) &&
178 is_conj(ritz_val[nev_new - 1], ritz_val[nev_new], prec))
187 template <
typename Scalar,
196 ComplexVector evals = decomp.eigenvalues();
197 ComplexMatrix evecs = decomp.eigenvectors();
199 SortEigenvalue<Complex, SelectionRule> sorting(evals.memptr(), evals.n_elem);
200 std::vector<int> ind = sorting.index();
203 for(
int i = 0; i < ncv; i++)
205 ritz_val[i] = evals[ind[i]];
207 for(
int i = 0; i < nev; i++)
209 ritz_vec.col(i) = evecs.col(ind[i]);
217 template <
typename Scalar,
222 SortEigenvalue<Complex, LARGEST_MAGN> sorting(ritz_val.memptr(), nev);
223 std::vector<int> ind = sorting.index();
225 ComplexVector new_ritz_val(ncv);
226 ComplexMatrix new_ritz_vec(ncv, nev);
227 BoolVector new_ritz_conv(nev);
229 for(
int i = 0; i < nev; i++)
231 new_ritz_val[i] = ritz_val[ind[i]];
232 new_ritz_vec.col(i) = ritz_vec.col(ind[i]);
233 new_ritz_conv[i] = ritz_conv[ind[i]];
236 ritz_val.swap(new_ritz_val);
237 ritz_vec.swap(new_ritz_vec);
238 ritz_conv.swap(new_ritz_conv);
244 template <
typename Scalar,
250 fac_V.zeros(dim_n, ncv);
251 fac_H.zeros(ncv, ncv);
254 ritz_vec.zeros(ncv, nev);
255 ritz_conv.zeros(nev);
260 Vector r(init_resid, dim_n,
false);
262 Vector v(fac_V.colptr(0), dim_n,
false);
263 Scalar rnorm = arma::norm(r);
265 throw std::invalid_argument(
"initial residual vector cannot be zero");
269 op->perform_op(v.memptr(), w.memptr());
272 fac_H(0, 0) = arma::dot(v, w);
273 fac_f = w - v * fac_H(0, 0);
277 template <
typename Scalar,
282 Vector init_resid(dim_n, arma::fill::randu);
284 init(init_resid.memptr());
288 template <
typename Scalar,
294 factorize_from(1, ncv, fac_f);
297 int i, nconv = 0, nev_adj;
298 for(i = 0; i < maxit; i++)
300 nconv = num_converged(tol);
304 nev_adj = nev_adjusted(nconv);
312 return std::min(nev, nconv);
316 template <
typename Scalar,
321 int nconv = arma::sum(ritz_conv);
322 ComplexVector res(nconv);
328 for(
int i = 0; i < nev; i++)
332 res[j] = ritz_val[i];
341 template <
typename Scalar,
346 int nconv = arma::sum(ritz_conv);
347 nvec = std::min(nvec, nconv);
348 ComplexMatrix res(dim_n, nvec);
353 ComplexMatrix ritz_vec_conv(ncv, nvec);
355 for(
int i = 0; i < nev && j < nvec; i++)
359 ritz_vec_conv.col(j) = ritz_vec.col(i);
364 res = fac_V * ritz_vec_conv;
virtual void compute(const Matrix &mat)
virtual Matrix matrix_RQ()
ComplexVector eigenvalues()
int compute(int maxit=1000, Scalar tol=1e-10)
ComplexMatrix eigenvectors()