ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Loading...
Searching...
No Matches
RadialMatrix.hpp
1#pragma once
2#include "LinAlg/Matrix.hpp"
3#include "Maths/Grid.hpp"
4#include "Maths/Interpolator.hpp"
5#include "Wavefunction/DiracSpinor.hpp"
6#include <cassert>
7#include <complex>
8#include <iostream>
9#include <type_traits>
10#include <vector>
11
12namespace MBPT {
13
26template <typename T>
28
29 std::size_t m_i0, m_stride;
30 std::size_t m_size;
31 LinAlg::Matrix<T> m_Rmatrix;
32 std::shared_ptr<const Grid> m_rgrid; // "full" grid
33 std::vector<double> sub_r{}; // sub grid (required for interpolation)
34
35public:
36 //============================================================================
37
38 RadialMatrix(std::size_t i0, std::size_t stride, std::size_t size,
39 std::shared_ptr<const Grid> rgrid)
40 : m_i0(i0),
41 m_stride(stride),
42 m_size(size),
43 m_Rmatrix(m_size),
44 m_rgrid(rgrid) {
45 //------------------
46 // create vector of r on sub-grid, used to interpolate values onto full
47 const auto &r = m_rgrid->r();
48 sub_r.reserve(m_size);
49 assert(m_i0 + m_stride * m_size <= r.size());
50 for (std::size_t i = 0; i < m_size; ++i) {
51 sub_r.push_back(r[index_to_fullgrid(i)]);
52 }
53 assert(m_i0 + m_stride * m_size <= r.size());
54 assert(sub_r[1] == r[index_to_fullgrid(1)]);
55 assert(sub_r[m_size - 1] == r[index_to_fullgrid(m_size - 1)]);
56 //------------------
57 }
58
59 //============================================================================
61
62 T &at(std::size_t i, std::size_t j) { return m_Rmatrix(i, j); }
63 T at(std::size_t i, std::size_t j) const { return m_Rmatrix(i, j); }
64
65 T &operator()(std::size_t i, std::size_t j) { return at(i, j); }
66 T operator()(std::size_t i, std::size_t j) const { return at(i, j); }
67
69 const LinAlg::Matrix<T> &Rmatrix() const { return m_Rmatrix; }
70 LinAlg::Matrix<T> &Rmatrix() { return m_Rmatrix; }
71
72 std::size_t size() const { return m_size; }
73 std::size_t i0() const { return m_i0; }
74 std::size_t stride() const { return m_stride; }
75
77 double r0() const { return sub_r.front(); }
79 double rmax() const { return sub_r.back(); }
80
82 double r(std::size_t sub_i) const { return sub_r.at(sub_i); }
83
85 double dr(std::size_t sub_i) const {
86 const auto full_index = index_to_fullgrid(sub_i);
87 return m_rgrid->drdu(sub_i) * m_rgrid->du() * double(m_stride);
88 }
89
91 std::size_t index_to_fullgrid(std::size_t i) const {
92 return m_i0 + i * m_stride;
93 }
94
95 //============================================================================
97 void zero() { m_Rmatrix.zero(); }
98
99 //============================================================================
102 m_Rmatrix += rhs.m_Rmatrix;
103 return *this;
104 }
107 m_Rmatrix -= rhs.m_Rmatrix;
108 return *this;
109 }
112 m_Rmatrix *= x;
113 return *this;
114 }
115
117 [[nodiscard]] friend RadialMatrix<T> operator+(RadialMatrix<T> lhs,
118 const RadialMatrix<T> &rhs) {
119 return lhs += rhs;
120 }
122 [[nodiscard]] friend RadialMatrix<T> operator-(RadialMatrix<T> lhs,
123 const RadialMatrix<T> &rhs) {
124 return lhs -= rhs;
125 }
127 [[nodiscard]] friend RadialMatrix<T> operator*(const T x,
128 RadialMatrix<T> rhs) {
129 return rhs *= x;
130 }
131
134 m_Rmatrix += aI;
135 return *this;
136 }
139 m_Rmatrix -= aI;
140 return *this;
141 }
142
144 [[nodiscard]] friend RadialMatrix<T> operator+(RadialMatrix<T> M, T aI) {
145 return (M += aI);
146 }
148 [[nodiscard]] friend RadialMatrix<T> operator-(RadialMatrix<T> M, T aI) {
149 return (M -= aI);
150 }
151
152 //============================================================================
155 m_Rmatrix.mult_elements_by(rhs.m_Rmatrix);
156 return *this;
157 }
158
160 [[nodiscard]] friend RadialMatrix<T>
162 lhs.mult_elements_by(rhs);
163 return lhs;
164 }
165
168 [[nodiscard]] friend RadialMatrix<T>
170 RadialMatrix<T> out(a.m_i0, a.m_stride, a.m_size, a.m_rgrid);
171 out.Rmatrix() = a.Rmatrix() * b.Rmatrix();
172 return out;
173 }
174
176 [[nodiscard]] friend RadialMatrix<T> operator*(const RadialMatrix<T> &a,
177 const RadialMatrix<T> &b) {
178 return matrix_multiply(a, b);
179 }
180
181 //============================================================================
182
184 [[nodiscard]] RadialMatrix<T> conj() const {
185 auto out = *this;
186 out.Rmatrix().conj_in_place();
187 return out;
188 }
189
192 m_Rmatrix.conj_in_place();
193 return *this;
194 }
195
197 [[nodiscard]] RadialMatrix<double> real() const {
198 RadialMatrix<double> out(m_i0, m_stride, m_size, m_rgrid);
199 out.Rmatrix() = m_Rmatrix.real();
200 return out;
201 }
202
204 [[nodiscard]] RadialMatrix<double> imag() const {
205 RadialMatrix<double> out(m_i0, m_stride, m_size, m_rgrid);
206 out.Rmatrix() = m_Rmatrix.imag();
207 return out;
208 }
209
212 RadialMatrix<std::complex<double>> out(m_i0, m_stride, m_size, m_rgrid);
213 out.Rmatrix() = m_Rmatrix.complex();
214 return out;
215 }
216
217 //============================================================================
220 m_Rmatrix.invert_in_place();
221 return *this;
222 }
224 [[nodiscard]] RadialMatrix<T> inverse() const {
225 auto out = *this; //
226 return out.invert_in_place();
227 }
228
229 //============================================================================
231 [[nodiscard]] RadialMatrix<T> transpose() const {
232 RadialMatrix<T> out(m_i0, m_stride, m_size, m_rgrid);
233 out.m_Rmatrix = m_Rmatrix.transpose();
234 return out;
235 }
236
237 //============================================================================
240 const auto dus = m_rgrid->du() * double(m_stride);
241 for (auto i = 0ul; i < m_size; ++i) {
242 for (auto j = 0ul; j < m_size; ++j) {
243 const auto sj = index_to_fullgrid(j);
244 const auto dr = m_rgrid->drdu(sj) * dus;
245 m_Rmatrix[i][j] *= dr;
246 }
247 }
248 return *this;
249 }
250
253 const auto dus = m_rgrid->du() * double(m_stride);
254 for (auto i = 0ul; i < m_size; ++i) {
255 const auto si = index_to_fullgrid(i);
256 const auto dr = m_rgrid->drdu(si) * dus;
257 for (auto j = 0ul; j < m_size; ++j) {
258 m_Rmatrix[i][j] *= dr;
259 }
260 }
261 return *this;
262 }
263
265 [[nodiscard]] RadialMatrix<T> drj() const {
266 auto out = *this;
267 return out.drj_in_place();
268 }
269
271 [[nodiscard]] RadialMatrix<T> dri() const {
272 auto out = *this;
273 return out.dri_in_place();
274 }
275};
276
277//==============================================================================
278
280template <typename T>
281bool equal(const RadialMatrix<T> &lhs, const RadialMatrix<T> &rhs) {
282 return LinAlg::equal(lhs.Rmatrix(), rhs.Rmatrix());
283}
284
286template <typename T>
287double max_element(const RadialMatrix<T> &a) {
288 double xmax = 0.0;
289 for (auto i = 0ul; i < a.size(); ++i) {
290 for (auto j = 0ul; j < a.size(); ++j) {
291 if (std::abs(a(i, j)) > xmax) {
292 xmax = std::abs(a(i, j));
293 }
294 }
295 }
296 return xmax;
297}
298
300template <typename T>
301double max_delta(const RadialMatrix<T> &a, const RadialMatrix<T> &b) {
302 double delta = 0.0;
303 for (auto i = 0ul; i < a.size(); ++i) {
304 for (auto j = 0ul; j < a.size(); ++j) {
305 if (std::abs(a.Rmatrix(i, j) - b.Rmatrix(i, j)) > delta) {
306 delta = std::abs(a.Rmatrix(i, j) - b.Rmatrix(i, j));
307 }
308 }
309 }
310 return delta;
311}
312
315template <typename T>
316double max_epsilon(const RadialMatrix<T> &a, const RadialMatrix<T> &b) {
317 double eps = 0.0;
318 for (auto i = 0ul; i < a.size(); ++i) {
319 for (auto j = 0ul; j < a.size(); ++j) {
320 const auto eps_temp = std::abs((a.Rmatrix(i, j) - b.Rmatrix(i, j)) /
321 (a.Rmatrix(i, j) + b.Rmatrix(i, j)));
322 if (eps_temp > eps)
323 eps = eps_temp;
324 }
325 }
326 return eps;
327}
328
329//==============================================================================
330
331using RMatrix = RadialMatrix<double>;
332using ComplexRMatrix = RadialMatrix<std::complex<double>>;
333
334} // namespace MBPT
Matrix class; row-major.
Definition Matrix.hpp:35
Matrix< T > & invert_in_place()
Inverts the matrix, in place. Uses GSL; via LU decomposition. Only works for double/complex<double>.
Definition Matrix.ipp:77
auto complex() const
Converts a real to complex matrix (changes type; returns a complex matrix)
Definition Matrix.ipp:205
auto imag() const
Returns imag part of complex matrix (changes type; returns a real matrix)
Definition Matrix.ipp:194
Matrix< T > & conj_in_place()
Conjugates matrix, in place.
Definition Matrix.ipp:174
Matrix< T > transpose() const
Returns transpose of matrix.
Definition Matrix.ipp:111
Matrix< T > & zero()
Sets all elements to zero, in place.
Definition Matrix.ipp:154
Matrix< T > & mult_elements_by(const Matrix< T > &a)
Muplitplies all the elements by those of matrix a, in place: M_ij *= a_ij.
Definition Matrix.ipp:270
auto real() const
Returns real part of complex matrix (changes type; returns a real matrix)
Definition Matrix.ipp:183
Definition RadialMatrix.hpp:27
RadialMatrix< T > transpose() const
Returns transpose of matrix; original matrix unchanged.
Definition RadialMatrix.hpp:231
RadialMatrix< T > & operator-=(const RadialMatrix< T > &rhs)
Matrix adition +,-.
Definition RadialMatrix.hpp:106
friend RadialMatrix< T > operator*(const RadialMatrix< T > &a, const RadialMatrix< T > &b)
Matrix multiplication: Gij = Aik*Bkj.
Definition RadialMatrix.hpp:176
friend RadialMatrix< T > mult_elements(RadialMatrix< T > lhs, const RadialMatrix< T > &rhs)
Multiply elements (new matrix): Gij = Aij*Bij.
Definition RadialMatrix.hpp:161
RadialMatrix< double > real() const
Returns real part of complex matrix (changes type; returns a real matrix)
Definition RadialMatrix.hpp:197
friend RadialMatrix< T > operator+(RadialMatrix< T > lhs, const RadialMatrix< T > &rhs)
Matrix adition +,-.
Definition RadialMatrix.hpp:117
friend RadialMatrix< T > matrix_multiply(const RadialMatrix< T > &a, const RadialMatrix< T > &b)
Matrix multiplication: Gij = Aik*Bkj Note: integration measure not included: call ....
Definition RadialMatrix.hpp:169
RadialMatrix< std::complex< double > > complex() const
Converts a real to complex matrix (changes type; returns a complex matrix)
Definition RadialMatrix.hpp:211
RadialMatrix< T > & operator+=(const RadialMatrix< T > &rhs)
Matrix adition +,-.
Definition RadialMatrix.hpp:101
RadialMatrix< T > & mult_elements_by(const RadialMatrix< T > &rhs)
Multiply coordinate elements (in place): Gij -> Gij*Bij.
Definition RadialMatrix.hpp:154
RadialMatrix< double > imag() const
Returns imag part of complex matrix (changes type; returns a real matrix)
Definition RadialMatrix.hpp:204
friend RadialMatrix< T > operator*(const T x, RadialMatrix< T > rhs)
Scalar multiplication.
Definition RadialMatrix.hpp:127
RadialMatrix< T > dri() const
Multiplies by dri: Q_ij -> Q_ij*dr_i. Returns new matrix (orig unchanged)
Definition RadialMatrix.hpp:271
RadialMatrix< T > & conj_in_place()
Conjuagtes current matrix, in place.
Definition RadialMatrix.hpp:191
double r0() const
First point along full grid for which subgrid is defined.
Definition RadialMatrix.hpp:77
double r(std::size_t sub_i) const
returns r at position sub_i along sub grid
Definition RadialMatrix.hpp:82
friend RadialMatrix< T > operator-(RadialMatrix< T > M, T aI)
Adition of identity: Matrix<T> - T : T assumed to be *Identity!
Definition RadialMatrix.hpp:148
double dr(std::size_t sub_i) const
returns dr at position along sub grid
Definition RadialMatrix.hpp:85
RadialMatrix< T > & operator*=(const T x)
Scalar multiplication.
Definition RadialMatrix.hpp:111
friend RadialMatrix< T > operator+(RadialMatrix< T > M, T aI)
Adition of identity: Matrix<T> + T : T assumed to be *Identity!
Definition RadialMatrix.hpp:144
double rmax() const
Last point along full grid for which subgrid is defined.
Definition RadialMatrix.hpp:79
std::size_t index_to_fullgrid(std::size_t i) const
Converts an index on the sub-grid to the full grid.
Definition RadialMatrix.hpp:91
void zero()
Sets the radial matrix to have all zero's.
Definition RadialMatrix.hpp:97
T & at(std::size_t i, std::size_t j)
direct access to matrix elements
Definition RadialMatrix.hpp:62
friend RadialMatrix< T > operator-(RadialMatrix< T > lhs, const RadialMatrix< T > &rhs)
Matrix adition +,-.
Definition RadialMatrix.hpp:122
RadialMatrix< T > & operator+=(T aI)
Adition of identity: Matrix<T> += T : T assumed to be *Identity!
Definition RadialMatrix.hpp:133
const LinAlg::Matrix< T > & Rmatrix() const
direct access to radial matrix
Definition RadialMatrix.hpp:69
RadialMatrix< T > & operator-=(T aI)
Adition of identity: Matrix<T> -= T : T assumed to be *Identity!
Definition RadialMatrix.hpp:138
RadialMatrix< T > & invert_in_place()
Inversion (in place)
Definition RadialMatrix.hpp:219
RadialMatrix< T > & drj_in_place()
Multiplies by drj: Q_ij -> Q_ij*dr_j, in place.
Definition RadialMatrix.hpp:239
RadialMatrix< T > conj() const
Returns conjugate of matrix.
Definition RadialMatrix.hpp:184
RadialMatrix< T > & dri_in_place()
Multiplies by dri: Q_ij -> Q_ij*dr_i, in place.
Definition RadialMatrix.hpp:252
RadialMatrix< T > drj() const
Multiplies by drj: Q_ij -> Q_ij*dr_j. Returns new matrix (orig unchanged)
Definition RadialMatrix.hpp:265
RadialMatrix< T > inverse() const
Returns inverse of matrix; original matrix unchanged.
Definition RadialMatrix.hpp:224
bool equal(const Matrix< T > &lhs, const Matrix< T > &rhs, T eps=myEps< T >())
Compares two matrices; returns true iff all elements compare relatively to better than eps.
Definition Matrix.ipp:381
Many-body perturbation theory.
Definition CI_Integrals.hpp:9
double max_element(const RadialMatrix< T > &a)
returns maximum element (by abs)
Definition RadialMatrix.hpp:287
bool equal(const RadialMatrix< T > &lhs, const RadialMatrix< T > &rhs)
Checks if two matrix's are equal (to within parts in 10^12)
Definition RadialMatrix.hpp:281
double max_delta(const RadialMatrix< T > &a, const RadialMatrix< T > &b)
returns maximum difference (abs) between two matrixs
Definition RadialMatrix.hpp:301
double max_epsilon(const RadialMatrix< T > &a, const RadialMatrix< T > &b)
returns maximum relative diference [aij-bij/(aij+bij)] (abs) between two matrices
Definition RadialMatrix.hpp:316