lambda-lanczos 2.1.1
Loading...
Searching...
No Matches
exponentiator.hpp
Go to the documentation of this file.
1#ifndef LAMBDA_LANCZOS_EXPONENTIATOR_H_
2#define LAMBDA_LANCZOS_EXPONENTIATOR_H_
3
4#include <algorithm>
5#include <cassert>
6#include <cmath>
7#include <functional>
8#include <iomanip>
9#include <iostream>
10#include <limits>
11#include <numeric>
12#include <random>
13#include <tuple>
14#include <vector>
15
16#include "lambda_lanczos.hpp"
18
19namespace lambda_lanczos {
20
24template <typename T>
26 private:
30 template <typename n_type>
32
33 public:
41 std::function<void(const std::vector<T>& in, std::vector<T>& out)> mv_mul;
42
58 real_t<T> eps = std::numeric_limits<real_t<T>>::epsilon() * 1e2;
59
63 bool full_orthogonalize = false;
64
71 size_t initial_vector_size = 200;
72
80 Exponentiator(std::function<void(const std::vector<T>&, std::vector<T>&)> mv_mul, size_t matrix_size)
82
87 size_t run(const T& a, const std::vector<T>& input, std::vector<T>& output) const {
88 assert(input.size() == this->matrix_size);
89
90 std::vector<std::vector<T>> u; // Lanczos vectors
91 std::vector<real_t<T>> alpha; // Diagonal elements of an approximated tridiagonal matrix
92 std::vector<real_t<T>> beta; // Subdiagonal elements of an approximated tridiagonal matrix
93
94 u.reserve(this->initial_vector_size);
95 alpha.reserve(this->initial_vector_size);
96 beta.reserve(this->initial_vector_size);
97
98 const auto n = this->matrix_size;
99
100 u.push_back(input);
101 util::normalize(u[0]);
102
103 std::vector<T> coeff_prev;
104
105 size_t itern = this->max_iteration;
106 for (size_t k = 1; k <= this->max_iteration; ++k) {
107 u.emplace_back(n, 0.0);
108 this->mv_mul(u[k - 1], u[k]);
109
110 alpha.push_back(std::real(util::inner_prod(u[k - 1], u[k])));
111
112 for (size_t i = 0; i < n; ++i) {
113 if (k == 1) {
114 u[k][i] = u[k][i] - alpha[k - 1] * u[k - 1][i];
115 } else {
116 u[k][i] = u[k][i] - beta[k - 2] * u[k - 2][i] - alpha[k - 1] * u[k - 1][i];
117 }
118 }
119
120 if (this->full_orthogonalize) {
121 util::schmidt_orth(u[k], u.begin(), u.end() - 1);
122 }
123
124 std::vector<real_t<T>> ev(alpha.size());
125 std::vector<std::vector<real_t<T>>> p(alpha.size());
127
128 std::vector<T> coeff(alpha.size(), 0.0);
129 for (size_t i = 0; i < alpha.size(); ++i) {
130 for (size_t j = 0; j < alpha.size(); ++j) {
131 coeff[i] += p[j][i] * std::exp(a * ev[j]) * p[j][0];
132 }
133 }
134
135 /*std::cout << "beta:" << std::endl;
136 for(size_t i = 0; i < beta.size(); ++i) {
137 std::cout << i << " : " << beta[i] << std::endl;
138 }
139
140 std::cout << "coeff:" << std::endl;
141 for(size_t i = 0; i < coeff.size(); ++i) {
142 std::cout << i << " : " << coeff[i] << std::endl;
143 }*/
144
145 beta.push_back(util::norm(u[k]));
146
147 T overlap = 0.0;
148 for (size_t i = 0; i < coeff_prev.size(); ++i) {
149 overlap += util::typed_conj(coeff_prev[i]) * coeff[i]; // Last element of coeff is not used here
150 }
151
152 coeff_prev = std::move(coeff);
153
154 const real_t<T> beta_threshold = std::numeric_limits<real_t<T>>::epsilon();
155 if (std::abs(1 - std::abs(overlap)) < eps || beta.back() < beta_threshold) {
156 itern = k;
157 break;
158 }
159
160 util::normalize(u[k]);
161 }
162
163 output.resize(n);
164 std::fill(output.begin(), output.end(), T());
165 const T norm = util::norm(input);
166 for (size_t l = 0; l < coeff_prev.size(); ++l) {
167 for (size_t i = 0; i < n; ++i) {
168 output[i] += norm * coeff_prev[l] * u[l][i];
169 }
170 }
171
172 return itern;
173 }
174
175 size_t taylor_run(const T& a, const std::vector<T>& input, std::vector<T>& output) {
176 const size_t n = this->matrix_size;
177 assert(this->matrix_size == input.size());
178
179 if (a == T()) { // Zero check
180 output = input;
181 return 1;
182 }
183
184 std::vector<std::vector<T>> taylors;
185 taylors.push_back(input);
186
187 T factor = 1.0;
188 for (size_t k = 1;; ++k) {
189 factor *= a / (T)k;
190 taylors.emplace_back(n, 0.0);
191 mv_mul(taylors[k - 1], taylors[k]);
192
193 if (lambda_lanczos::util::norm(taylors[k]) * std::abs(factor) < eps) {
194 break;
195 }
196 }
197
198 /* Sum Taylor series backward */
199 output.resize(n);
200 std::fill(output.begin(), output.end(), 0.0);
201 for (size_t k = taylors.size(); k-- > 0;) {
202 for (size_t i = 0; i < n; ++i) {
203 output[i] += taylors[k][i] * factor;
204 }
205
206 factor *= (T)k / a;
207 }
208
209 return taylors.size();
210 }
211};
212
213} /* namespace lambda_lanczos */
214
215#endif /* LAMBDA_LANCZOS_EXPONENTIATOR_H_ */
size_t taylor_run(const T &a, const std::vector< T > &input, std::vector< T > &output)
Definition exponentiator.hpp:175
real_t< T > eps
Convergence threshold of Lanczos iteration.
Definition exponentiator.hpp:58
size_t max_iteration
Iteration limit of Lanczos algorithm, set to matrix_size automatically.
Definition exponentiator.hpp:46
size_t matrix_size
Dimension of the matrix to be exponentiated.
Definition exponentiator.hpp:44
std::function< void(const std::vector< T > &in, std::vector< T > &out)> mv_mul
Matrix-vector multiplication routine.
Definition exponentiator.hpp:41
size_t initial_vector_size
(Not necessary to change)
Definition exponentiator.hpp:71
util::real_t< n_type > real_t
See util::real_t for details.
Definition exponentiator.hpp:31
size_t run(const T &a, const std::vector< T > &input, std::vector< T > &output) const
Apply matrix exponentiation exp(a*A) to input and store the result into output.
Definition exponentiator.hpp:87
Exponentiator(std::function< void(const std::vector< T > &, std::vector< T > &)> mv_mul, size_t matrix_size)
Constructs Lanczos exponetiation engine.
Definition exponentiator.hpp:80
bool full_orthogonalize
Flag to execute explicit Lanczos-vector orthogonalization.
Definition exponentiator.hpp:63
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:291
void normalize(std::vector< T > &vec)
Normalizes given vector.
Definition linear_algebra.hpp:78
real_t< T > norm(const std::vector< T > &vec)
Returns Euclidean norm of given vector.
Definition linear_algebra.hpp:57
typename realTypeMap< T >::type real_t
Type mapper from T to real type of T.
Definition common.hpp:102
T typed_conj(const T &val)
Complex conjugate with type. This function returns the argument itself for real type,...
Definition common.hpp:132
T inner_prod(const std::vector< T > &v1, const std::vector< T > &v2)
Returns "mathematical" inner product of v1 and v2.
Definition linear_algebra.hpp:30
void schmidt_orth(std::vector< T > &uorth, ForwardIterator first, ForwardIterator last)
Orthogonalizes vector uorth with respect to orthonormal vectors defined by given iterators.
Definition linear_algebra.hpp:133
Definition eigenpair_manager.hpp:9