lambda-lanczos 2.1.1
Loading...
Searching...
No Matches
linear_algebra_lapack.hpp
Go to the documentation of this file.
1#ifndef LAMBDA_LANCZOS_UTIL_LINEAR_ALGEBRA_LAPACK_H_
2#define LAMBDA_LANCZOS_UTIL_LINEAR_ALGEBRA_LAPACK_H_
3
4// clang-format off
5#include "macro.hpp" // This processes and defines certain macros
6// clang-format on
7
8#include <cassert>
9#include <cmath>
10#include <complex>
11#include <functional>
12#include <limits>
13#include <map>
14#include <numeric>
15#include <vector>
16
17#ifdef LAMBDA_LANCZOS_STDPAR_POLICY
18#include <execution>
19#endif
20
21#if defined(LAMBDA_LANCZOS_USE_LAPACK)
22#include <cblas.h>
23#include <lapacke.h>
24#elif defined(LAMBDA_LANCZOS_USE_MKL)
25#include <mkl.h>
26#endif
27
28#include "common.hpp"
29
30namespace lambda_lanczos {
31namespace util {
32
33inline float inner_prod(const std::vector<float>& v1, const std::vector<float>& v2) {
34 assert(v1.size() == v2.size());
35
36 lapack_int n = v1.size();
37 return cblas_sdot(n, v1.data(), 1, v2.data(), 1);
38}
39
40inline double inner_prod(const std::vector<double>& v1, const std::vector<double>& v2) {
41 assert(v1.size() == v2.size());
42
43 lapack_int n = v1.size();
44 return cblas_ddot(n, v1.data(), 1, v2.data(), 1);
45}
46
47inline std::complex<float> inner_prod(const std::vector<std::complex<float>>& v1,
48 const std::vector<std::complex<float>>& v2) {
49 assert(v1.size() == v2.size());
50
51 lapack_int n = v1.size();
52 std::complex<float> result;
53 cblas_cdotc_sub(n, v1.data(), 1, v2.data(), 1, &result);
54 return result;
55}
56
57inline std::complex<double> inner_prod(const std::vector<std::complex<double>>& v1,
58 const std::vector<std::complex<double>>& v2) {
59 assert(v1.size() == v2.size());
60
61 lapack_int n = v1.size();
62 std::complex<double> result;
63 cblas_zdotc_sub(n, v1.data(), 1, v2.data(), 1, &result);
64 return result;
65}
66
67inline float norm(const std::vector<float>& vec) {
68 return cblas_snrm2(vec.size(), vec.data(), 1);
69}
70
71inline double norm(const std::vector<double>& vec) {
72 return cblas_dnrm2(vec.size(), vec.data(), 1);
73}
74
75inline float norm(const std::vector<std::complex<float>>& vec) {
76 return cblas_scnrm2(vec.size(), vec.data(), 1);
77}
78
79inline double norm(const std::vector<std::complex<double>>& vec) {
80 return cblas_dznrm2(vec.size(), vec.data(), 1);
81}
82
83inline void scalar_mul(float a, std::vector<float>& vec) {
84 cblas_sscal(vec.size(), a, vec.data(), 1);
85}
86
87inline void scalar_mul(double a, std::vector<double>& vec) {
88 cblas_dscal(vec.size(), a, vec.data(), 1);
89}
90
91inline void scalar_mul(std::complex<float> a, std::vector<std::complex<float>>& vec) {
92 cblas_cscal(vec.size(), &a, vec.data(), 1);
93}
94
95inline void scalar_mul(std::complex<double> a, std::vector<std::complex<double>>& vec) {
96 cblas_zscal(vec.size(), &a, vec.data(), 1);
97}
98
99/* Special routine to multiply a real scalar to a complex vector */
100inline void scalar_mul(float a, std::vector<std::complex<float>>& vec) {
101 cblas_csscal(vec.size(), a, vec.data(), 1);
102}
103
104/* Special routine to multiply a real scalar to a complex vector */
105inline void scalar_mul(double a, std::vector<std::complex<double>>& vec) {
106 cblas_zdscal(vec.size(), a, vec.data(), 1);
107}
108
109template <typename T>
110inline void normalize(std::vector<T>& vec) {
111 scalar_mul(T(1) / norm(vec), vec);
112}
113
114inline float m_norm(const std::vector<float>& vec) {
115 return cblas_sasum(vec.size(), vec.data(), 1);
116}
117
118inline double m_norm(const std::vector<double>& vec) {
119 return cblas_dasum(vec.size(), vec.data(), 1);
120}
121
122inline float m_norm(const std::vector<std::complex<float>>& vec) {
123 return cblas_scasum(vec.size(), vec.data(), 1);
124}
125
126inline double m_norm(const std::vector<std::complex<double>>& vec) {
127 return cblas_dzasum(vec.size(), vec.data(), 1);
128}
129
130template <typename ForwardIterator>
131inline void schmidt_orth(std::vector<float>& uorth, ForwardIterator first, ForwardIterator last) {
132 const auto n = uorth.size();
133
134 for (auto iter = first; iter != last; ++iter) {
135 const auto& uk = *iter;
136 float alpha = -util::inner_prod(uk, uorth);
137 cblas_saxpy(n, alpha, uk.data(), 1, uorth.data(), 1);
138 }
139}
140
141template <typename ForwardIterator>
142inline void schmidt_orth(std::vector<double>& uorth, ForwardIterator first, ForwardIterator last) {
143 const auto n = uorth.size();
144
145 for (auto iter = first; iter != last; ++iter) {
146 const auto& uk = *iter;
147 double alpha = -util::inner_prod(uk, uorth);
148 cblas_daxpy(n, alpha, uk.data(), 1, uorth.data(), 1);
149 }
150}
151
152template <typename ForwardIterator>
153inline void schmidt_orth(std::vector<std::complex<float>>& uorth, ForwardIterator first, ForwardIterator last) {
154 const auto n = uorth.size();
155
156 for (auto iter = first; iter != last; ++iter) {
157 const auto& uk = *iter;
158 std::complex<float> alpha = -util::inner_prod(uk, uorth);
159 cblas_caxpy(n, &alpha, uk.data(), 1, uorth.data(), 1);
160 }
161}
162
163template <typename ForwardIterator>
164inline void schmidt_orth(std::vector<std::complex<double>>& uorth, ForwardIterator first, ForwardIterator last) {
165 const auto n = uorth.size();
166
167 for (auto iter = first; iter != last; ++iter) {
168 const auto& uk = *iter;
169 std::complex<double> alpha = -util::inner_prod(uk, uorth);
170 cblas_zaxpy(n, &alpha, uk.data(), 1, uorth.data(), 1);
171 }
172}
173
174template <typename T>
175void initAsIdentity(std::vector<std::vector<T>>& a, size_t n) {
176 a.resize(n);
177 for (size_t i = 0; i < n; ++i) {
178 a[i].resize(n);
179
180#ifdef LAMBDA_LANCZOS_STDPAR_POLICY
181 std::fill(LAMBDA_LANCZOS_STDPAR_POLICY, a[i].begin(), a[i].end(), T());
182#else
183 std::fill(a[i].begin(), a[i].end(), T());
184#endif
185
186 a[i][i] = 1.0;
187 }
188}
189
190} /* namespace util */
191} /* namespace lambda_lanczos */
192
193#endif /* LAMBDA_LANCZOS_UTIL_LINEAR_ALGEBRA_LAPACK_H_ */
Definition common.hpp:15
void normalize(std::vector< T > &vec)
Normalizes given vector.
Definition linear_algebra.hpp:78
void scalar_mul(T1 a, std::vector< T2 > &vec)
Multiplies each element of vec by a.
Definition linear_algebra.hpp:66
real_t< T > norm(const std::vector< T > &vec)
Returns Euclidean norm of given vector.
Definition linear_algebra.hpp:57
real_t< T > m_norm(const std::vector< T > &vec)
Returns Manhattan-like norm of given vector.
Definition linear_algebra.hpp:123
void initAsIdentity(std::vector< std::vector< T > > &a, size_t n)
Initializes the given matrix a to an n by n identity matrix.
Definition linear_algebra.hpp:150
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