2 #include "LinAlg/Matrix.hpp"
3 #include "Maths/Grid.hpp"
4 #include "Maths/Interpolator.hpp"
5 #include "Wavefunction/DiracSpinor.hpp"
46 std::size_t m_i0, m_stride;
51 std::shared_ptr<const Grid> m_rgrid;
52 std::vector<double> sub_r{};
57 RDMatrix(std::size_t i0, std::size_t stride, std::size_t size,
bool incl_g,
58 std::shared_ptr<const Grid> rgrid)
62 m_g_size(incl_g ? size : 0),
71 const auto &r = m_rgrid->r();
72 sub_r.reserve(m_size);
73 assert(m_i0 + m_stride * m_size <= r.size());
74 for (std::size_t i = 0; i < m_size; ++i) {
77 assert(m_i0 + m_stride * m_size <= r.size());
85 T &
ff(std::size_t i, std::size_t j) {
return m_ff(i, j); }
86 T &fg(std::size_t i, std::size_t j) {
return m_fg(i, j); }
87 T &gf(std::size_t i, std::size_t j) {
return m_gf(i, j); }
88 T &gg(std::size_t i, std::size_t j) {
return m_gg(i, j); }
89 const T
ff(std::size_t i, std::size_t j)
const {
return m_ff(i, j); }
90 const T fg(std::size_t i, std::size_t j)
const {
return m_fg(i, j); }
91 const T gf(std::size_t i, std::size_t j)
const {
return m_gf(i, j); }
92 const T gg(std::size_t i, std::size_t j)
const {
return m_gg(i, j); }
104 std::size_t size()
const {
return m_size; }
105 std::size_t g_size()
const {
return m_g_size; }
106 bool includes_g()
const {
return m_g_size == m_size; };
107 std::size_t i0()
const {
return m_i0; }
108 std::size_t stride()
const {
return m_stride; }
120 [[deprecated]]
void make_identity() {
128 [[deprecated]] RDMatrix<T> &plusIdent(T a = T{1.0}) {
203 RDMatrix<T> out(a.m_i0, a.m_stride, a.m_size, a.m_incl_g, a.m_rgrid);
209 out.
ff() = a.
ff() * b.
ff();
211 out.
ff() += a.fg() * b.gf();
212 out.fg() = a.
ff() * b.fg() + a.fg() * b.gg();
213 out.gf() = a.gf() * b.
ff() + a.gg() * b.gf();
214 out.gg() = a.gf() * b.fg() + a.gg() * b.gg();
240 out.ff().conj_in_place();
241 out.fg().conj_in_place();
242 out.gf().conj_in_place();
243 out.gg().conj_in_place();
251 out.fg() = m_fg.
real();
252 out.gf() = m_gf.
real();
253 out.gg() = m_gg.
real();
260 out.fg() = m_fg.
imag();
261 out.gf() = m_gf.
imag();
262 out.gg() = m_gg.
imag();
282 const auto &ai = m_ff;
283 const auto &b = m_fg;
284 const auto &c = m_gf;
285 const auto &d = m_gg;
286 const auto cai = c * ai;
288 const auto aib_dmcaib = ai * b * dmcaib;
289 m_ff += aib_dmcaib * cai;
290 m_fg = -1.0 * aib_dmcaib;
291 m_gf = -1.0 * dmcaib * cai;
299 return out.invert_in_place();
305 const auto dus = m_rgrid->du() * double(m_stride);
306 for (
auto i = 0ul; i < m_size; ++i) {
307 for (
auto j = 0ul; j < m_size; ++j) {
309 const auto dr = m_rgrid->drdu(sj) * dus;
314 for (
auto i = 0ul; i < m_size; ++i) {
315 for (
auto j = 0ul; j < m_size; ++j) {
317 const auto dr = m_rgrid->drdu(sj) * dus;
328 const auto dus = m_rgrid->du() * double(m_stride);
329 for (
auto i = 0ul; i < m_size; ++i) {
331 const auto dr = m_rgrid->drdu(si) * dus;
332 for (
auto j = 0ul; j < m_size; ++j) {
337 for (
auto i = 0ul; i < m_size; ++i) {
339 const auto dr = m_rgrid->drdu(si) * dus;
340 for (
auto j = 0ul; j < m_size; ++j) {
352 return out.drj_in_place();
357 return out.dri_in_place();
361 double dr(std::size_t sub_index)
const {
363 return m_rgrid->drdu(full_index) * m_rgrid->du() * double(m_stride);
369 return m_i0 + i * m_stride;
379 for (
auto i = 0ul; i < m_size; ++i) {
381 for (
auto j = 0ul; j < m_size; ++j) {
383 m_ff[i][j] += k * ket.f(si) * bra.f(sj);
388 for (
auto i = 0ul; i < m_size; ++i) {
390 for (
auto j = 0ul; j < m_size; ++j) {
393 m_fg[i][j] += k * ket.f(si) * bra.g(sj);
394 m_gf[i][j] += k * ket.g(si) * bra.f(sj);
395 m_gg[i][j] += k * ket.g(si) * bra.g(sj);
406 const auto &r = Fn.
grid().
r();
411 std::vector<double> f(m_size), g;
412 for (
auto i = 0ul; i < m_size; ++i) {
413 for (
auto j = 0ul; j < m_size; ++j) {
415 f[i] += m_ff(i, j) * Fn.
f(j_f);
420 for (
auto i = 0ul; i < m_size; ++i) {
421 for (
auto j = 0ul; j < m_size; ++j) {
423 f[i] += m_fg(i, j) * Fn.
g(j_f);
424 g[i] += (m_gf(i, j) * Fn.
f(j_f) + m_gg(i, j) * Fn.
g(j_f));
441 friend std::ostream &operator<<(std::ostream &os,
const RDMatrix<T> &a) {
457 template <
typename T>
460 equal(lhs.gf(), rhs.gf()) &&
equal(lhs.gg(), rhs.gg());
464 template <
typename T>
466 double xff = 0.0, xfg = 0.0, xgf = 0.0, xgg = 0.0;
467 for (
auto i = 0ul; i < a.size(); ++i) {
468 for (
auto j = 0ul; j < a.size(); ++j) {
469 if (std::abs(a.
ff(i, j)) > xff)
470 xff = std::abs(a.
ff(i, j));
471 if (a.g_size() != 0) {
472 if (std::abs(a.fg(i, j)) > xfg)
473 xfg = std::abs(a.fg(i, j));
474 if (std::abs(a.gf(i, j)) > xgf)
475 xgf = std::abs(a.gf(i, j));
476 if (std::abs(a.gg(i, j)) > xgg)
477 xgg = std::abs(a.gg(i, j));
481 return std::max({xff, xfg, xgf, xgg});
485 template <
typename T>
487 double xff = 0.0, xfg = 0.0, xgf = 0.0, xgg = 0.0;
488 for (
auto i = 0ul; i < a.size(); ++i) {
489 for (
auto j = 0ul; j < a.size(); ++j) {
490 if (std::abs(a.
ff(i, j) - b.
ff(i, j)) > xff)
491 xff = std::abs(a.
ff(i, j) - b.
ff(i, j));
492 if (a.g_size() != 0) {
493 if (std::abs(a.fg(i, j) - b.fg(i, j)) > xfg)
494 xfg = std::abs(a.fg(i, j) - b.fg(i, j));
495 if (std::abs(a.gf(i, j) - b.gf(i, j)) > xgf)
496 xgf = std::abs(a.gf(i, j) - b.gf(i, j));
497 if (std::abs(a.gg(i, j) - b.gg(i, j)) > xgg)
498 xgg = std::abs(a.gg(i, j) - b.gg(i, j));
502 return std::max({xff, xfg, xgf, xgg});
507 template <
typename T>
509 double xff = 0.0, xfg = 0.0, xgf = 0.0, xgg = 0.0;
510 for (
auto i = 0ul; i < a.size(); ++i) {
511 for (
auto j = 0ul; j < a.size(); ++j) {
513 std::abs((a.
ff(i, j) - b.
ff(i, j)) / (a.
ff(i, j) + b.
ff(i, j)));
516 if (a.g_size() != 0) {
518 std::abs((a.fg(i, j) - b.fg(i, j)) / (a.fg(i, j) + b.fg(i, j)));
520 std::abs((a.gf(i, j) - b.gf(i, j)) / (a.gf(i, j) + b.gf(i, j)));
522 std::abs((a.gg(i, j) - b.gg(i, j)) / (a.gg(i, j) + b.gg(i, j)));
532 return std::max({xff, xfg, xgf, xgg});
536 using GMatrix = RDMatrix<double>;
537 using ComplexGMatrix = RDMatrix<std::complex<double>>;
538 using ComplexDouble = std::complex<double>;
Stores radial Dirac spinor: F_nk = (f, g)
Definition: DiracSpinor.hpp:41
const Grid & grid() const
Resturns a const reference to the radial grid.
Definition: DiracSpinor.hpp:107
const std::vector< double > & f() const
Upper (large) radial component function, f.
Definition: DiracSpinor.hpp:117
const std::vector< double > & g() const
Lower (small) radial component function, g.
Definition: DiracSpinor.hpp:124
const std::vector< double > & r() const
Grid points, r.
Definition: Grid.hpp:75
Matrix< T > & make_identity()
Constructs a diagonal unit matrix (identity), in place; only for square.
Definition: Matrix.ipp:143
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 > & 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: RDMatrix.hpp:44
std::size_t index_to_fullgrid(std::size_t i) const
Converts an index on the sub-grid to the full grid.
Definition: RDMatrix.hpp:368
RDMatrix< double > imag() const
Returns imag part of complex matrix (changes type; returns a real matrix)
Definition: RDMatrix.hpp:257
friend RDMatrix< T > operator-(RDMatrix< T > lhs, const RDMatrix< T > &rhs)
Matrix adition +,-.
Definition: RDMatrix.hpp:165
RDMatrix< T > & operator-=(const RDMatrix< T > &rhs)
Matrix adition +,-.
Definition: RDMatrix.hpp:143
double dr(std::size_t sub_index) const
returns dr at position along sub grid
Definition: RDMatrix.hpp:361
RDMatrix< T > & operator+=(T aI)
Adition of identity: Matrix<T> += T : T assumed to be *Identity!
Definition: RDMatrix.hpp:175
RDMatrix< std::complex< double > > complex() const
Converts a real to complex matrix (changes type; returns a complex matrix)
Definition: RDMatrix.hpp:267
RDMatrix< T > & operator-=(T aI)
Adition of identity: Matrix<T> -= T : T assumed to be *Identity!
Definition: RDMatrix.hpp:181
RDMatrix< T > & dri_in_place()
Multiplies by dri: Q_ij -> Q_ij*dr_i, in place.
Definition: RDMatrix.hpp:327
void zero()
Sets all matrix elements to zero.
Definition: RDMatrix.hpp:112
friend RDMatrix< T > operator*(const T x, RDMatrix< T > rhs)
Scalar multiplication.
Definition: RDMatrix.hpp:170
friend RDMatrix< T > operator+(RDMatrix< T > M, T aI)
Adition of identity: Matrix<T> + T : T assumed to be *Identity!
Definition: RDMatrix.hpp:188
RDMatrix< T > drj() const
Multiplies by drj: Q_ij -> Q_ij*dr_j. Returns new matrix (orig unchanged)
Definition: RDMatrix.hpp:350
friend RDMatrix< T > operator+(RDMatrix< T > lhs, const RDMatrix< T > &rhs)
Matrix adition +,-.
Definition: RDMatrix.hpp:160
RDMatrix< T > & operator*=(const T x)
Scalar multiplication.
Definition: RDMatrix.hpp:151
T & ff(std::size_t i, std::size_t j)
direct access to matrix elements
Definition: RDMatrix.hpp:85
RDMatrix< T > & operator+=(const RDMatrix< T > &rhs)
Matrix adition +,-.
Definition: RDMatrix.hpp:135
RDMatrix< T > dri() const
Multiplies by dri: Q_ij -> Q_ij*dr_i. Returns new matrix (orig unchanged)
Definition: RDMatrix.hpp:355
void add(const DiracSpinor &ket, const DiracSpinor &bra, T k=T(1.0))
Adds k*|ket><bra| to matrix (used for building Green's functions)
Definition: RDMatrix.hpp:374
friend RDMatrix< T > operator-(RDMatrix< T > M, T aI)
Adition of identity: Matrix<T> - T : T assumed to be *Identity!
Definition: RDMatrix.hpp:192
RDMatrix< T > & invert_in_place()
Inversion (in place)
Definition: RDMatrix.hpp:279
RDMatrix< T > & mult_elements_by(const RDMatrix< T > &rhs)
Multiply elements (in place): Gij -> Gij*Bij.
Definition: RDMatrix.hpp:221
friend RDMatrix< T > operator*(const RDMatrix< T > &a, const RDMatrix< T > &b)
Matrix multplication: C=A*B := Cij = \sum_k Aik*Bkj. Note: integration measure not included: call ....
Definition: RDMatrix.hpp:200
RDMatrix< T > conj() const
Returns conjugate of matrix.
Definition: RDMatrix.hpp:238
const LinAlg::Matrix< T > & ff() const
direct access to matrix's
Definition: RDMatrix.hpp:95
RDMatrix< T > & drj_in_place()
Multiplies by drj: Q_ij -> Q_ij*dr_j, in place.
Definition: RDMatrix.hpp:304
DiracSpinor operator*(const DiracSpinor &Fn) const
Action of RDMatrix operator on DiracSpinor. Inludes Integration: G*F = Int[G(r,r')*F(r') dr'] = sum_j...
Definition: RDMatrix.hpp:404
RDMatrix< T > inverse() const
Returns inverse of matrix; original matrix unchanged.
Definition: RDMatrix.hpp:297
RDMatrix< double > real() const
Returns real part of complex matrix (changes type; returns a real matrix)
Definition: RDMatrix.hpp:248
friend RDMatrix< T > mult_elements(RDMatrix< T > lhs, const RDMatrix< T > &rhs)
Multiply elements (new matrix): Gij = Aij*Bij.
Definition: RDMatrix.hpp:229
std::vector< double > interpolate(const std::vector< double > &x_in, const std::vector< double > &y_in, const std::vector< double > &x_out, Method method=Method::cspline)
Performs interpolation using GSL (GNU Scientific Library)
Definition: Interpolator.hpp:162
Many-body perturbation theory.
Definition: CI_Integrals.hpp:9
bool equal(const RDMatrix< T > &lhs, const RDMatrix< T > &rhs)
Checks if two matrix's are equal (to within parts in 10^12)
Definition: RDMatrix.hpp:458
double max_epsilon(const RDMatrix< T > &a, const RDMatrix< T > &b)
returns maximum relative diference [aij-bij/(aij+bij)] (abs) between two matrices
Definition: RDMatrix.hpp:508
double max_delta(const RDMatrix< T > &a, const RDMatrix< T > &b)
returns maximum difference (abs) between two matrixs
Definition: RDMatrix.hpp:486
double max_element(const RDMatrix< T > &a)
returns maximum element (by abs)
Definition: RDMatrix.hpp:465