2#include "LinAlg/Matrix.hpp"
3#include "Maths/Grid.hpp"
4#include "Maths/Interpolator.hpp"
5#include "RadialMatrix.hpp"
6#include "Wavefunction/DiracSpinor.hpp"
59 std::size_t m_i0, m_stride;
64 std::shared_ptr<const Grid> m_rgrid;
65 std::vector<double> sub_r{};
84 bool incl_g, std::shared_ptr<const Grid> rgrid)
88 m_g_size(incl_g ?
size : 0),
97 const auto &r = m_rgrid->r();
98 sub_r.reserve(m_size);
101 for (std::size_t i = 0; i < m_size; ++i) {
111 T &
ff(std::size_t i, std::size_t j) {
return m_ff(i, j); }
112 T &fg(std::size_t i, std::size_t j) {
return m_fg(i, j); }
113 T &gf(std::size_t i, std::size_t j) {
return m_gf(i, j); }
114 T &gg(std::size_t i, std::size_t j) {
return m_gg(i, j); }
115 const T
ff(std::size_t i, std::size_t j)
const {
return m_ff(i, j); }
116 const T fg(std::size_t i, std::size_t j)
const {
return m_fg(i, j); }
117 const T gf(std::size_t i, std::size_t j)
const {
return m_gf(i, j); }
118 const T gg(std::size_t i, std::size_t j)
const {
return m_gg(i, j); }
140 assert(mu < 2 && nu < 2);
141 if (mu == 0 && nu == 0)
143 if (mu == 0 && nu == 1)
145 if (mu == 1 && nu == 0)
147 if (mu == 1 && nu == 1)
149 assert(
false &&
"SpinorMatrix::sp: mu, nu must be 0 or 1");
155 assert(mu < 2 && nu < 2);
156 if (mu == 0 && nu == 0)
158 if (mu == 0 && nu == 1)
160 if (mu == 1 && nu == 0)
162 if (mu == 1 && nu == 1)
164 assert(
false &&
"SpinorMatrix::sp: mu, nu must be 0 or 1");
169 std::size_t
size()
const {
return m_size; }
171 std::size_t
g_size()
const {
return m_g_size; }
175 std::size_t
i0()
const {
return m_i0; }
177 std::size_t
stride()
const {
return m_stride; }
207 m_fg.
resize(m_size, m_size);
208 m_gf.
resize(m_size, m_size);
209 m_gg.
resize(m_size, m_size);
312 SpinorMatrix<T> out(a.m_i0, a.m_stride, a.m_size, a.m_incl_g || b.m_incl_g,
319 out.
ff() = a.
ff() * b.
ff();
320 if (a.m_incl_g && b.m_incl_g) {
321 out.
ff() += a.fg() * b.gf();
322 out.fg() = a.
ff() * b.fg() + a.fg() * b.gg();
323 out.gf() = a.gf() * b.
ff() + a.gg() * b.gf();
324 out.gg() = a.gf() * b.fg() + a.gg() * b.gg();
325 }
else if (a.m_incl_g) {
327 out.gf() = a.gf() * b.
ff();
328 }
else if (b.m_incl_g) {
330 out.fg() = a.
ff() * b.fg();
339 if (this->m_incl_g) {
364 if (this->m_incl_g) {
391 out.ff().conj_in_place();
392 out.fg().conj_in_place();
393 out.gf().conj_in_place();
394 out.gg().conj_in_place();
401 out.fg() = m_fg.
real();
402 out.gf() = m_gf.
real();
403 out.gg() = m_gg.
real();
410 out.fg() = m_fg.
imag();
411 out.gf() = m_gf.
imag();
412 out.gg() = m_gg.
imag();
431 const auto &ai = m_ff;
432 const auto &b = m_fg;
433 const auto &c = m_gf;
434 const auto &d = m_gg;
435 const auto cai = c * ai;
437 const auto aib_dmcaib = ai * b * dmcaib;
438 m_ff += aib_dmcaib * cai;
439 m_fg = -1.0 * aib_dmcaib;
440 m_gf = -1.0 * dmcaib * cai;
448 return out.invert_in_place();
454 const auto dus = m_rgrid->du() * double(m_stride);
455 for (
auto i = 0ul; i < m_size; ++i) {
456 for (
auto j = 0ul; j < m_size; ++j) {
458 const auto dr = m_rgrid->drdu(sj) * dus;
463 for (
auto i = 0ul; i < m_size; ++i) {
464 for (
auto j = 0ul; j < m_size; ++j) {
466 const auto dr = m_rgrid->drdu(sj) * dus;
477 const auto dus = m_rgrid->du() * double(m_stride);
478 for (
auto i = 0ul; i < m_size; ++i) {
480 const auto dr = m_rgrid->drdu(si) * dus;
481 for (
auto j = 0ul; j < m_size; ++j) {
486 for (
auto i = 0ul; i < m_size; ++i) {
488 const auto dr = m_rgrid->drdu(si) * dus;
489 for (
auto j = 0ul; j < m_size; ++j) {
501 return out.drj_in_place();
506 return out.dri_in_place();
510 double dr(std::size_t sub_index)
const {
512 return m_rgrid->drdu(full_index) * m_rgrid->du() * double(m_stride);
518 return m_i0 + i * m_stride;
528 for (
auto i = 0ul; i < m_size; ++i) {
530 for (
auto j = 0ul; j < m_size; ++j) {
532 m_ff[i][j] += k * ket.f(si) * bra.f(sj);
537 for (
auto i = 0ul; i < m_size; ++i) {
539 for (
auto j = 0ul; j < m_size; ++j) {
542 m_fg[i][j] += k * ket.f(si) * bra.g(sj);
543 m_gf[i][j] += k * ket.g(si) * bra.f(sj);
544 m_gg[i][j] += k * ket.g(si) * bra.g(sj);
564 const auto &r = Fn.
grid().
r();
566 std::vector<double> f(m_size), g;
567 for (
auto i = 0ul; i < m_size; ++i) {
568 for (
auto j = 0ul; j < m_size; ++j) {
570 f[i] += m_ff(i, j) * Fn.
f(j_f);
575 for (
auto i = 0ul; i < m_size; ++i) {
576 for (
auto j = 0ul; j < m_size; ++j) {
578 f[i] += m_fg(i, j) * Fn.
g(j_f);
579 g[i] += (m_gf(i, j) * Fn.
f(j_f) + m_gg(i, j) * Fn.
g(j_f));
595 friend std::ostream &operator<<(std::ostream &os,
const SpinorMatrix<T> &a) {
614 equal(lhs.gf(), rhs.gf()) &&
equal(lhs.gg(), rhs.gg());
620 double xff = 0.0, xfg = 0.0, xgf = 0.0, xgg = 0.0;
621 for (
auto i = 0ul; i < a.
size(); ++i) {
622 for (
auto j = 0ul; j < a.
size(); ++j) {
623 if (std::abs(a.
ff(i, j)) > xff)
624 xff = std::abs(a.
ff(i, j));
626 if (std::abs(a.fg(i, j)) > xfg)
627 xfg = std::abs(a.fg(i, j));
628 if (std::abs(a.gf(i, j)) > xgf)
629 xgf = std::abs(a.gf(i, j));
630 if (std::abs(a.gg(i, j)) > xgg)
631 xgg = std::abs(a.gg(i, j));
635 return std::max({xff, xfg, xgf, xgg});
650 double xff = 0.0, xfg = 0.0, xgf = 0.0, xgg = 0.0;
651 for (
auto i = 0ul; i < a.
size(); ++i) {
652 for (
auto j = 0ul; j < a.
size(); ++j) {
653 if (std::abs(a.
ff(i, j) - b.
ff(i, j)) > xff)
654 xff = std::abs(a.
ff(i, j) - b.
ff(i, j));
656 if (std::abs(a.fg(i, j) - b.fg(i, j)) > xfg)
657 xfg = std::abs(a.fg(i, j) - b.fg(i, j));
658 if (std::abs(a.gf(i, j) - b.gf(i, j)) > xgf)
659 xgf = std::abs(a.gf(i, j) - b.gf(i, j));
660 if (std::abs(a.gg(i, j) - b.gg(i, j)) > xgg)
661 xgg = std::abs(a.gg(i, j) - b.gg(i, j));
665 return std::max({xff, xfg, xgf, xgg});
681 double xff = 0.0, xfg = 0.0, xgf = 0.0, xgg = 0.0;
682 for (
auto i = 0ul; i < a.
size(); ++i) {
683 for (
auto j = 0ul; j < a.
size(); ++j) {
685 std::abs((a.
ff(i, j) - b.
ff(i, j)) / (a.
ff(i, j) + b.
ff(i, j)));
690 std::abs((a.fg(i, j) - b.fg(i, j)) / (a.fg(i, j) + b.fg(i, j)));
692 std::abs((a.gf(i, j) - b.gf(i, j)) / (a.gf(i, j) + b.gf(i, j)));
694 std::abs((a.gg(i, j) - b.gg(i, j)) / (a.gg(i, j) + b.gg(i, j)));
704 return std::max({xff, xfg, xgf, xgg});
708using GMatrix = SpinorMatrix<double>;
709using ComplexGMatrix = SpinorMatrix<std::complex<double>>;
710using ComplexDouble = std::complex<double>;
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:55
const std::vector< double > & f() const
Upper (large) radial component function, f.
Definition DiracSpinor.hpp:180
const Grid & grid() const
Returns a const reference to the radial grid.
Definition DiracSpinor.hpp:166
const std::vector< double > & g() const
Lower (small) radial component function, g.
Definition DiracSpinor.hpp:187
const std::vector< double > & r() const
Full grid vector r.
Definition Grid.hpp:131
Row-major dense matrix with arithmetic and linear algebra support.
Definition Matrix.hpp:208
Matrix< T > & invert_in_place()
Inverts the matrix in place.
Definition Matrix.ipp:54
auto complex() const
Converts a real to complex matrix (changes type; returns a complex matrix)
Definition Matrix.ipp:188
auto imag() const
Returns imag part of complex matrix (changes type; returns a real matrix)
Definition Matrix.ipp:177
Matrix< T > & zero()
Sets all elements to zero, in place.
Definition Matrix.ipp:137
Matrix< T > & mult_elements_by(const Matrix< T > &a)
Elementwise multiply in place: M_ij *= a_ij.
Definition Matrix.ipp:268
auto real() const
Returns real part of complex matrix (changes type; returns a real matrix)
Definition Matrix.ipp:166
void resize(std::size_t rows, std::size_t cols)
Resizes matrix to new dimension; all values reset to default.
Definition Matrix.hpp:265
Radial matrix: stored on a sub-grid (defined by i0, stride, size).
Definition RadialMatrix.hpp:26
const LinAlg::Matrix< T > & Rmatrix() const
direct access to radial matrix
Definition RadialMatrix.hpp:83
Radial Dirac spinor matrix.
Definition SpinorMatrix.hpp:57
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 SpinorMatrix.hpp:523
SpinorMatrix< T > & operator-=(T aI)
Addition of identity: Matrix<T> -= T : T assumed to be *Identity!
Definition SpinorMatrix.hpp:279
friend SpinorMatrix< T > mult_elements(SpinorMatrix< T > lhs, const SpinorMatrix< T > &rhs)
Multiply elements (new matrix): Gij = Aij*Bij.
Definition SpinorMatrix.hpp:355
SpinorMatrix< std::complex< double > > complex() const
Converts a real to complex matrix (changes type; returns a complex matrix)
Definition SpinorMatrix.hpp:416
SpinorMatrix< T > & create_g()
Creates g parts of spinor matrix - will have value 0.
Definition SpinorMatrix.hpp:204
SpinorMatrix(std::size_t i0, std::size_t stride, std::size_t size, bool incl_g, std::shared_ptr< const Grid > rgrid)
Constructs a zero matrix on the given radial sub-grid.
Definition SpinorMatrix.hpp:83
T & ff(std::size_t i, std::size_t j)
direct access to matrix elements
Definition SpinorMatrix.hpp:111
friend SpinorMatrix< T > operator+(SpinorMatrix< T > M, T aI)
Addition of identity: Matrix<T> + T : T assumed to be *Identity!
Definition SpinorMatrix.hpp:286
SpinorMatrix< T > drj() const
Multiplies by drj: Q_ij -> Q_ij*dr_j. Returns new matrix (orig unchanged)
Definition SpinorMatrix.hpp:499
SpinorMatrix< T > & drj_in_place()
Multiplies by drj: Q_ij -> Q_ij*dr_j, in place.
Definition SpinorMatrix.hpp:453
std::size_t g_size() const
Dimension of the g blocks: size(), or 0 if g parts are not included.
Definition SpinorMatrix.hpp:171
SpinorMatrix< T > & operator*=(const T x)
Scalar multiplication.
Definition SpinorMatrix.hpp:248
SpinorMatrix< T > & dri_in_place()
Multiplies by dri: Q_ij -> Q_ij*dr_i, in place.
Definition SpinorMatrix.hpp:476
std::size_t stride() const
Sub-grid stride: every stride-th point of the full grid.
Definition SpinorMatrix.hpp:177
friend SpinorMatrix< T > mult_elements(SpinorMatrix< T > lhs, const RadialMatrix< T > &rhs)
Multiply elements (new matrix): Gij = Aij*Bij.
Definition SpinorMatrix.hpp:374
const LinAlg::Matrix< T > & ff() const
direct access to matrices
Definition SpinorMatrix.hpp:121
LinAlg::Matrix< T > & sp(std::size_t mu, std::size_t nu)
Spinor block by index: 0 = f, 1 = g.
Definition SpinorMatrix.hpp:139
friend SpinorMatrix< T > operator*(const T x, SpinorMatrix< T > rhs)
Scalar multiplication.
Definition SpinorMatrix.hpp:267
SpinorMatrix< T > & operator-=(const SpinorMatrix< T > &rhs)
Matrix addition +,- (see operator+= for matrices without g parts)
Definition SpinorMatrix.hpp:235
const LinAlg::Matrix< T > & sp(std::size_t mu, std::size_t nu) const
Spinor block by index: 0 = f, 1 = g (const)
Definition SpinorMatrix.hpp:154
bool includes_g() const
True if g parts (fg, gf, gg) are included.
Definition SpinorMatrix.hpp:173
SpinorMatrix< T > & operator+=(T aI)
Addition of identity: Matrix<T> += T : T assumed to be *Identity!
Definition SpinorMatrix.hpp:273
std::size_t size() const
Number of sub-grid points (dimension of each block)
Definition SpinorMatrix.hpp:169
SpinorMatrix< double > imag() const
Returns imag part of complex matrix (changes type; returns a real matrix)
Definition SpinorMatrix.hpp:407
void zero()
Sets all matrix elements to zero.
Definition SpinorMatrix.hpp:181
SpinorMatrix< T > dri() const
Multiplies by dri: Q_ij -> Q_ij*dr_i. Returns new matrix (orig unchanged)
Definition SpinorMatrix.hpp:504
SpinorMatrix< T > & mult_elements_by(const SpinorMatrix< T > &rhs)
Multiply elements (in place): Gij -> Gij*Bij.
Definition SpinorMatrix.hpp:337
DiracSpinor operator*(const DiracSpinor &Fn) const
Action of SpinorMatrix operator on DiracSpinor.
Definition SpinorMatrix.hpp:562
SpinorMatrix< T > & drop_g()
Kills g parts of spinor matrix, in place!
Definition SpinorMatrix.hpp:190
SpinorMatrix< T > & operator+=(const SpinorMatrix< T > &rhs)
Matrix addition +,-.
Definition SpinorMatrix.hpp:222
SpinorMatrix< T > & invert_in_place()
Inversion (in place)
Definition SpinorMatrix.hpp:428
friend SpinorMatrix< T > mult_elements(const RadialMatrix< T > &rhs, SpinorMatrix< T > lhs)
Multiply elements (new matrix): Gij = Aij*Bij.
Definition SpinorMatrix.hpp:380
std::size_t index_to_fullgrid(std::size_t i) const
Converts an index on the sub-grid to the full grid.
Definition SpinorMatrix.hpp:517
friend SpinorMatrix< T > operator-(SpinorMatrix< T > M, T aI)
Addition of identity: Matrix<T> - T : T assumed to be *Identity!
Definition SpinorMatrix.hpp:290
double dr(std::size_t sub_index) const
returns dr at position along sub grid
Definition SpinorMatrix.hpp:510
friend SpinorMatrix< T > operator*(const SpinorMatrix< T > &a, const SpinorMatrix< T > &b)
Matrix multiplication.
Definition SpinorMatrix.hpp:309
SpinorMatrix< double > real() const
Returns real part of complex matrix (changes type; returns a real matrix)
Definition SpinorMatrix.hpp:398
friend SpinorMatrix< T > operator+(SpinorMatrix< T > lhs, const SpinorMatrix< T > &rhs)
Matrix addition +,-.
Definition SpinorMatrix.hpp:257
std::size_t i0() const
Full-grid index of the first sub-grid point.
Definition SpinorMatrix.hpp:175
SpinorMatrix< T > inverse() const
Returns inverse of matrix; original matrix unchanged.
Definition SpinorMatrix.hpp:446
SpinorMatrix< T > & mult_elements_by(const RadialMatrix< T > &rhs)
Multiply elements (in place): Gij -> Gij*Bij.
Definition SpinorMatrix.hpp:362
SpinorMatrix< T > conj() const
Returns conjugate of matrix.
Definition SpinorMatrix.hpp:389
friend SpinorMatrix< T > operator-(SpinorMatrix< T > lhs, const SpinorMatrix< T > &rhs)
Matrix addition +,-.
Definition SpinorMatrix.hpp:262
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)
Convenience wrapper: interpolates y_in(x_in) and evaluates at x_out.
Definition Interpolator.hpp:154
Many-body perturbation theory.
Definition MatrixElements.hpp:12
double max_element(const RadialMatrix< T > &a)
returns maximum element (by abs)
Definition RadialMatrix.hpp:307
bool equal(const RadialMatrix< T > &lhs, const RadialMatrix< T > &rhs)
Checks if two matrices are equal (to within parts in 10^12)
Definition RadialMatrix.hpp:301
double max_delta(const RadialMatrix< T > &a, const RadialMatrix< T > &b)
returns maximum difference (abs) between two matrices
Definition RadialMatrix.hpp:321
double max_epsilon(const RadialMatrix< T > &a, const RadialMatrix< T > &b)
returns maximum relative difference, |(aij-bij)/(aij+bij)|, of two matrices
Definition RadialMatrix.hpp:335