1#ifndef LAMBDA_LANCZOS_H_
2#define LAMBDA_LANCZOS_H_
32template <
typename T,
typename LT>
34 const std::vector<T>& beta,
35 const std::vector<std::vector<LT>>& u,
36 const bool find_maximum,
37 const size_t num_of_eigenvalues) -> std::vector<std::vector<
decltype(T()+LT())>>{
38 const auto m = alpha.size();
39 const auto n = u[0].size();
41 std::vector<T> tridiagonal_eigenvalues;
42 std::vector<std::vector<T>> tridiagonal_eigenvectors;
46 std::vector<std::vector<LT>> eigenvectors;
47 for(
size_t i = 0; i < num_of_eigenvalues; ++i) {
48 eigenvectors.emplace_back(n);
51 for(
size_t index = 0; index < num_of_eigenvalues; index++) {
52 size_t index_tri = find_maximum ? m - index - 1 : index;
53 for (
size_t k = m; k-- > 0;) {
54 for (
size_t i = 0; i < n; ++i) {
55 eigenvectors[index][i] += tridiagonal_eigenvectors[index_tri][k] * u[k][i];
81 static void init(std::vector<T>& v) {
82 std::random_device dev;
83 std::mt19937 mt(dev());
84 std::uniform_real_distribution<T> rand((T)(-1.0), (T)(1.0));
87 for(
size_t i = 0; i < n; ++i) {
97 static void init(std::vector<std::complex<T>>& v) {
98 std::random_device dev;
99 std::mt19937 mt(dev());
100 std::uniform_real_distribution<T> rand((T)(-1.0), (T)(1.0));
103 for(
size_t i = 0; i < n; ++i) {
104 v[i] = std::complex<T>(rand(mt), rand(mt));
119 template <
typename n_type>
130 std::function<void(
const std::vector<T>& in, std::vector<T>& out)>
mv_mul;
216 template <
typename Iterable>
218 std::vector<std::vector<T>>& eigvecs,
220 Iterable orthogonalizeTo)
const {
221 std::vector<std::vector<T>> u;
222 std::vector<real_t<T>> alpha;
223 std::vector<real_t<T>> beta;
225 u.reserve(this->initial_vector_size);
226 alpha.reserve(this->initial_vector_size);
227 beta.reserve(this->initial_vector_size);
236 std::vector<real_t<T>> evs;
237 std::vector<real_t<T>> pevs;
242 std::vector<T> au(n, 0.0);
244 for(
size_t i = 0; i < n; ++i) {
250 u.push_back(std::move(au));
251 for(
size_t i = 0; i < n; ++i) {
253 u[k][i] = u[k][i] - alpha[k-1]*u[k-1][i];
255 u[k][i] = u[k][i] - beta[k-2]*u[k-2][i] - alpha[k-1]*u[k-1][i];
264 size_t num_eigs_to_calculate = std::min(nroot, alpha.size());
265 evs = std::vector<real_t<T>>();
267 std::vector<real_t<T>> eigvals_all(alpha.size());
269 if(this->find_maximum) {
270 for(
size_t i = 0; i < num_eigs_to_calculate; ++i) {
271 evs.push_back(eigvals_all[eigvals_all.size()-i-1]);
274 for(
size_t i = 0; i < num_eigs_to_calculate; ++i) {
275 evs.push_back(eigvals_all[i]);
279 const real_t<T> zero_threshold = std::numeric_limits<real_t<T>>::epsilon() * 1e1;
280 if(beta.back() < zero_threshold) {
290 bool break_cond =
true;
291 if(pevs.size() != evs.size()) {
294 for(
size_t iroot = 0; iroot < nroot; ++iroot) {
295 const auto& ev = evs[iroot];
296 const auto& pev = pevs[iroot];
297 if (std::abs(ev - pev) >= std::min(std::abs(ev), std::abs(pev)) * this->eps){
313 eigvecs.resize(eigvalues.size());
317 for(
size_t i = 0; i < eigvalues.size(); ++i) {
330 void run(std::vector<
real_t<T>>& eigenvalues, std::vector<std::vector<T>>& eigenvectors) {
331 this->iter_counts = std::vector<size_t>();
335 std::vector<real_t<T>> eigenvalues_current;
336 std::vector<std::vector<T>> eigenvectors_current;
341 eigenvectors_current,
344 this->iter_counts.push_back(iter_count);
346 bool nothing_added = ep_manager.
insertEigenpairs(eigenvalues_current, eigenvectors_current);
354 eigenvalues = std::vector<real_t<T>>();
355 eigenvalues.reserve(eigenpairs.size());
356 eigenvectors = std::vector<std::vector<T>>();
357 eigenvectors.reserve(eigenvectors.size());
359 for(
auto& eigenpair : eigenpairs) {
360 eigenvalues.push_back(std::move(eigenpair.first));
361 eigenvectors.push_back(std::move(eigenpair.second));
373 std::tuple<std::vector<real_t<T>>, std::vector<std::vector<T>>>
run() {
374 std::vector<real_t<T>> eigenvalues;
375 std::vector<std::vector<T>> eigenvectors;
376 for(
size_t i = 0; i < this->
num_eigs; ++i) {
377 eigenvectors.emplace_back(this->matrix_size);
380 this->
run(eigenvalues, eigenvectors);
382 return {eigenvalues, eigenvectors};
392 const size_t num_eigs_tmp = this->
num_eigs;
395 std::vector<real_t<T>> eigenvalues(1);
396 std::vector<std::vector<T>> eigenvectors(1);
398 this->
run(eigenvalues, eigenvectors);
400 this->num_eigs = num_eigs_tmp;
402 eigenvalue = eigenvalues[0];
403 eigenvector = std::move(eigenvectors[0]);
Calculation engine for Lanczos algorithm.
Definition: lambda_lanczos.hpp:114
size_t max_iteration
Iteration limit of Lanczos algorithm, set to matrix_size automatically.
Definition: lambda_lanczos.hpp:142
std::tuple< std::vector< real_t< T > >, std::vector< std::vector< T > > > run()
Executes Lanczos algorithm and return result as a tuple.
Definition: lambda_lanczos.hpp:373
size_t num_eigs_per_iteration
(Not necessary to change)
Definition: lambda_lanczos.hpp:177
util::real_t< n_type > real_t
See util::real_t for details.
Definition: lambda_lanczos.hpp:120
real_t< T > eps
Convergence threshold of Lanczos iteration.
Definition: lambda_lanczos.hpp:154
LambdaLanczos(std::function< void(const std::vector< T > &, std::vector< T > &)> mv_mul, size_t matrix_size, bool find_maximum, size_t num_eigs)
Constructs Lanczos calculation engine.
Definition: lambda_lanczos.hpp:206
std::function< void(const std::vector< T > &in, std::vector< T > &out)> mv_mul
Matrix-vector multiplication routine.
Definition: lambda_lanczos.hpp:130
void run(std::vector< real_t< T > > &eigenvalues, std::vector< std::vector< T > > &eigenvectors)
Executes Lanczos algorithm and stores the result into reference variables passed as arguments.
Definition: lambda_lanczos.hpp:330
size_t run_iteration(std::vector< real_t< T > > &eigvalues, std::vector< std::vector< T > > &eigvecs, size_t nroot, Iterable orthogonalizeTo) const
Not documented (In most cases, run() is preferred).
Definition: lambda_lanczos.hpp:217
std::function< void(std::vector< T > &vec)> init_vector
Function to initialize the initial Lanczos vector.
Definition: lambda_lanczos.hpp:137
size_t num_eigs
Number of eigenpairs to be calculated.
Definition: lambda_lanczos.hpp:160
std::vector< size_t > iter_counts
Iteration counts of the latest run.
Definition: lambda_lanczos.hpp:192
size_t matrix_size
Dimension of the matrix to be diagonalized.
Definition: lambda_lanczos.hpp:140
real_t< T > eigenvalue_offset
Shifts the eigenvalues of the given matrix A.
Definition: lambda_lanczos.hpp:169
const std::vector< size_t > & getIterationCounts() const
Returns the latest iteration counts.
Definition: lambda_lanczos.hpp:409
bool find_maximum
true to calculate maximum eigenvalue, false to calculate minimum one.
Definition: lambda_lanczos.hpp:157
size_t initial_vector_size
(Not necessary to change)
Definition: lambda_lanczos.hpp:185
void run(real_t< T > &eigenvalue, std::vector< T > &eigenvector)
Executes Lanczos algorithm that calculate one eigenpair regardless of num_eigs.
Definition: lambda_lanczos.hpp:391
Class to manage calculated eigenpairs.
Definition: eigenpair_manager.hpp:23
size_t size() const
Definition: eigenpair_manager.hpp:50
decltype(eigenpairs) & getEigenpairs()
Definition: eigenpair_manager.hpp:80
lambda_lanczos::util::MapValueIterable< decltype(eigenpairs)> getEigenvectors() const
Definition: eigenpair_manager.hpp:76
bool insertEigenpairs(std::vector< real_t< T > > &eigenvalues, std::vector< std::vector< T > > &eigenvectors)
Definition: eigenpair_manager.hpp:54
size_t tridiagonal_eigenvalues(const std::vector< T > &alpha, const std::vector< T > &beta, std::vector< T > &eigenvalues)
Computes all eigenvalues for given tri-diagonal matrix using the Implicitly Shifted QR algorithm.
Definition: lambda_lanczos_tridiagonal_impl.hpp:373
size_t tridiagonal_eigenpairs(const std::vector< T > &alpha, const std::vector< T > &beta, std::vector< T > &eigenvalues, std::vector< std::vector< T > > &eigenvectors, bool compute_eigenvector=true)
Computes all eigenpairs (eigenvalues and eigenvectors) for given tri-diagonal matrix using the Implic...
Definition: lambda_lanczos_tridiagonal_impl.hpp:302
void normalize(std::vector< T > &vec)
Normalizes given vector.
Definition: lambda_lanczos_util.hpp:180
real_t< T > norm(const std::vector< T > &vec)
Returns Euclidean norm of given vector.
Definition: lambda_lanczos_util.hpp:161
T inner_prod(const std::vector< T > &v1, const std::vector< T > &v2)
Returns "mathematical" inner product of v1 and v2.
Definition: lambda_lanczos_util.hpp:148
void schmidt_orth(std::vector< T > &uorth, ForwardIterator first, ForwardIterator last)
Orthogonalizes vector uorth with respect to orthonormal vectors defined by given iterators.
Definition: lambda_lanczos_util.hpp:206
typename realTypeMap< T >::type real_t
Type mapper from T to real type of T.
Definition: lambda_lanczos_util.hpp:103
Definition: eigenpair_manager.hpp:10
auto compute_eigenvectors(const std::vector< T > &alpha, const std::vector< T > &beta, const std::vector< std::vector< LT > > &u, const bool find_maximum, const size_t num_of_eigenvalues) -> std::vector< std::vector< decltype(T()+LT())> >
Computes the eigenvectors from Krylov subspace information.
Definition: lambda_lanczos.hpp:33
static void init(std::vector< std::complex< T > > &v)
Definition: lambda_lanczos.hpp:97
Template class to implement random vector initializer.
Definition: lambda_lanczos.hpp:73
static void init(std::vector< T > &v)
Initialize given vector randomly in the range of [-1, 1].
Definition: lambda_lanczos.hpp:81