lambda-lanczos 2.0.0
Loading...
Searching...
No Matches
lambda_lanczos_util.hpp
Go to the documentation of this file.
1#ifndef LAMBDA_LANCZOS_UTIL_H_
2#define LAMBDA_LANCZOS_UTIL_H_
3
4#include <vector>
5#include <complex>
6#include <limits>
7#include <cmath>
8#include <numeric>
9#include <cassert>
10#include <sstream>
11#include <map>
12#include <functional>
13
14
15namespace lambda_lanczos { namespace util {
16
20template <size_t I, typename container_type>
22private:
23 typename container_type::const_iterator iter;
24
25public:
26 TupleViewIterator(const typename container_type::const_iterator& iter) : iter(iter) {}
27
28 const typename std::tuple_element<I, typename container_type::value_type>::type& operator*() const {
29 return std::get<I>(*iter);
30 }
31
32 bool operator==(const TupleViewIterator& obj) const {
33 return this->iter == obj.iter;
34 }
35
36 bool operator!=(const TupleViewIterator& obj) const {
37 return this->iter != obj.iter;
38 }
39
41 this->iter++;
42 return *this;
43 }
44
46 auto before = *this;
47 this->iter++;
48 return before;
49 }
50};
51
55template <typename map_type>
57
58template <typename map_type>
60private:
61 const typename map_type::const_iterator itr_cbegin;
62 const typename map_type::const_iterator itr_cend;
63
64public:
65 MapValueIterable(const map_type& map) : itr_cbegin(map.cbegin()), itr_cend(map.cend()) {}
66
68 return itr_cbegin;
69 }
70
72 return itr_cend;
73 }
74};
75
76
81template <typename T>
83 typedef T type;
84};
85
86template <typename T>
87struct realTypeMap<std::complex<T>> {
88 typedef T type;
89};
90
102template <typename T>
104
105
114template <typename T>
116 static T invoke(const T& val) {
117 return val;
118 }
119};
120
121template <typename T>
122struct TypedConjugate<std::complex<T>> {
123 static std::complex<T> invoke(const std::complex<T> val) {
124 return std::conj(val);
125 }
126};
127
128
134template <typename T>
135inline T typed_conj(const T& val) {
136 return TypedConjugate<T>::invoke(val);
137}
138
139
147template <typename T>
148inline T inner_prod(const std::vector<T>& v1, const std::vector<T>& v2) {
149 assert(v1.size() == v2.size());
150 return std::inner_product(std::begin(v1), std::end(v1),
151 std::begin(v2), T(),
152 [](const T& v, const T& u) -> T { return v+u; },
153 [](const T& a, const T& b) -> T { return typed_conj(a)*b; });
154 // T() means zero value of type T
155}
156
160template <typename T>
161inline real_t<T> norm(const std::vector<T>& vec) {
162 return std::sqrt(std::real(inner_prod(vec, vec)));
163 // The norm of any complex vector <v|v> is real by definition.
164}
165
169template <typename T1, typename T2>
170inline void scalar_mul(T1 a, std::vector<T2>& vec) {
171 for(auto& elem : vec) {
172 elem *= a;
173 }
174}
175
179template <typename T>
180inline void normalize(std::vector<T>& vec) {
181 scalar_mul(T(1)/norm(vec), vec);
182}
183
184
188template <typename T>
189inline real_t<T> l1_norm(const std::vector<T>& vec) {
190 real_t<T> norm = real_t<T>(); // Zero initialization
191
192 for(const T& element : vec) {
193 norm += std::abs(element);
194 }
195
196 return norm;
197}
198
199
205template <typename ForwardIterator, typename T>
206inline void schmidt_orth(std::vector<T>& uorth,
207 ForwardIterator first,
208 ForwardIterator last) {
209 const auto n = uorth.size();
210
211 for(auto iter = first; iter != last; ++iter) {
212 const auto& uk = *iter;
213 T innprod = util::inner_prod(uk, uorth);
214
215 for(size_t i = 0; i < n; ++i) {
216 uorth[i] -= innprod * uk[i];
217 }
218 }
219}
220
221
225template <typename T>
226void initAsIdentity(std::vector<std::vector<T>>& a, size_t n) {
227 a.resize(n);
228 for(size_t i = 0; i < n; ++i) {
229 a[i].resize(n);
230 std::fill(a[i].begin(), a[i].end(), T());
231 a[i][i] = 1.0;
232 }
233}
234
235
241template <typename T>
242inline void sort_eigenpairs(std::vector<real_t<T>>& eigenvalues,
243 std::vector<std::vector<T>>& eigenvectors,
244 bool sort_eigenvector,
245 const std::function<bool (real_t<T>, real_t<T>)> predicate = std::less<real_t<T>>()) {
246 std::vector<std::pair<real_t<T>, size_t>> ev_index_pairs;
247 ev_index_pairs.reserve(eigenvalues.size());
248 for(size_t i = 0; i < eigenvalues.size(); ++i) {
249 ev_index_pairs.emplace_back(eigenvalues[i], i);
250 }
251
252 std::sort(ev_index_pairs.begin(),
253 ev_index_pairs.end(),
254 [&predicate](const auto& x, const auto& y ) {
255 return predicate(x.first, y.first);
256 });
257
258 std::vector<real_t<T>> eigenvalues_new;
259 eigenvalues_new.reserve(eigenvalues.size());
260 for(const auto& ev_index : ev_index_pairs) {
261 size_t k = ev_index.second;
262 eigenvalues_new.emplace_back(eigenvalues[k]);
263 }
264 eigenvalues = std::move(eigenvalues_new);
265
266 if(sort_eigenvector) {
267 std::vector<std::vector<T>> eigenvectors_new;
268 eigenvectors_new.reserve(eigenvalues.size());
269 for(const auto& ev_index : ev_index_pairs) {
270 size_t k = ev_index.second;
271 eigenvectors_new.push_back(std::move(eigenvectors[k]));
272 }
273 eigenvectors = std::move(eigenvectors_new);
274 }
275}
276
277
282template <typename T>
283inline constexpr int sig_decimal_digit() {
284 return (int)(std::numeric_limits<T>::digits *
285 log10(std::numeric_limits<T>::radix));
286}
287
288
289template <typename T>
290inline constexpr T minimum_effective_decimal() {
291 return pow(10, -sig_decimal_digit<T>());
292}
293
294
299template <typename T>
300T sgn(T val) {
301 if(val >= 0) {
302 return (T)1;
303 } else {
304 return (T)(-1);
305 }
306}
307
308
312template <typename T>
313std::string vectorToString(const std::vector<T>& vec, std::string delimiter = " ") {
314 std::stringstream ss;
315
316 for(const auto& elem : vec) {
317 ss << elem << delimiter;
318 }
319
320 /* Remove the last space */
321 std::string result = ss.str();
322 if(!result.empty()) {
323 result.pop_back();
324 }
325
326 return result;
327}
328
329}} /* namespace lambda_lanczos::util */
330
331#endif /* LAMBDA_LANCZOS_UTIL_H_ */
Definition: lambda_lanczos_util.hpp:59
MapValueIterable(const map_type &map)
Definition: lambda_lanczos_util.hpp:65
MapValueIterator< map_type > cend() const
Definition: lambda_lanczos_util.hpp:71
MapValueIterator< map_type > cbegin() const
Definition: lambda_lanczos_util.hpp:67
const map_type::const_iterator itr_cbegin
Definition: lambda_lanczos_util.hpp:61
const map_type::const_iterator itr_cend
Definition: lambda_lanczos_util.hpp:62
Iterator for a container of tuples to iterate over the I-th tuple elements.
Definition: lambda_lanczos_util.hpp:21
container_type::const_iterator iter
Definition: lambda_lanczos_util.hpp:23
bool operator!=(const TupleViewIterator &obj) const
Definition: lambda_lanczos_util.hpp:36
const std::tuple_element< I, typenamecontainer_type::value_type >::type & operator*() const
Definition: lambda_lanczos_util.hpp:28
TupleViewIterator operator++(int dummy)
Definition: lambda_lanczos_util.hpp:45
TupleViewIterator & operator++()
Definition: lambda_lanczos_util.hpp:40
TupleViewIterator(const typename container_type::const_iterator &iter)
Definition: lambda_lanczos_util.hpp:26
bool operator==(const TupleViewIterator &obj) const
Definition: lambda_lanczos_util.hpp:32
void normalize(std::vector< T > &vec)
Normalizes given vector.
Definition: lambda_lanczos_util.hpp:180
constexpr int sig_decimal_digit()
Returns the significant decimal digits of type T.
Definition: lambda_lanczos_util.hpp:283
void scalar_mul(T1 a, std::vector< T2 > &vec)
Multiplies each element of vec by a.
Definition: lambda_lanczos_util.hpp:170
real_t< T > norm(const std::vector< T > &vec)
Returns Euclidean norm of given vector.
Definition: lambda_lanczos_util.hpp:161
constexpr T minimum_effective_decimal()
Definition: lambda_lanczos_util.hpp:290
T typed_conj(const T &val)
Complex conjugate with type. This function returns the argument itself for real type,...
Definition: lambda_lanczos_util.hpp:135
void sort_eigenpairs(std::vector< real_t< T > > &eigenvalues, std::vector< std::vector< T > > &eigenvectors, bool sort_eigenvector, const std::function< bool(real_t< T >, real_t< T >)> predicate=std::less< real_t< T > >())
Sorts eigenvalues and eigenvectors with respect to given predicate.
Definition: lambda_lanczos_util.hpp:242
T sgn(T val)
Return the sign of given value.
Definition: lambda_lanczos_util.hpp:300
std::string vectorToString(const std::vector< T > &vec, std::string delimiter=" ")
Returns string representation of given vector.
Definition: lambda_lanczos_util.hpp:313
void initAsIdentity(std::vector< std::vector< T > > &a, size_t n)
Initializes the given matrix a to an n by n identity matrix.
Definition: lambda_lanczos_util.hpp:226
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
real_t< T > l1_norm(const std::vector< T > &vec)
Returns 1-norm of given vector.
Definition: lambda_lanczos_util.hpp:189
Definition: eigenpair_manager.hpp:10
static std::complex< T > invoke(const std::complex< T > val)
Definition: lambda_lanczos_util.hpp:123
Complex conjugate template.
Definition: lambda_lanczos_util.hpp:115
static T invoke(const T &val)
Definition: lambda_lanczos_util.hpp:116
T type
Definition: lambda_lanczos_util.hpp:88
Template class to map specific types. See real_t<T> for usage.
Definition: lambda_lanczos_util.hpp:82
T type
Definition: lambda_lanczos_util.hpp:83