6#ifndef INVERSE_MATRIX_HPP
7#define INVERSE_MATRIX_HPP
19template <
typename Tdata>
28 using_syev(threshold_condition_number);
33template <
typename Tdata>
37 LapackConnector::potrf(
'U', A.shape[0], A.ptr(), A.shape[0], info);
39 throw std::range_error(
"info=" + std::to_string(info) +
"\n" + std::string(__FILE__) +
" line "
40 + std::to_string(__LINE__));
42 LapackConnector::potri(
'U', A.shape[0], A.ptr(), A.shape[0], info);
44 throw std::range_error(
"info=" + std::to_string(info) +
"\n" + std::string(__FILE__) +
" line "
45 + std::to_string(__LINE__));
63 static constexpr char gemm_trans =
'T';
72 static void syev(RI::Tensor<std::complex<double>>& A,
value_type* w,
int& info)
76 static constexpr char gemm_trans =
'C';
89 static constexpr char gemm_trans =
'T';
98 static void syev(RI::Tensor<std::complex<float>>& A,
value_type* w,
int& info)
102 static constexpr char gemm_trans =
'C';
109 using val_t =
typename traits::value_type;
112 std::vector<val_t> eigen_value(A.shape[0]);
114 traits::syev(A, eigen_value.data(), info);
116 throw std::range_error(
"info=" + std::to_string(info) +
"\n" + std::string(__FILE__) +
" line "
117 + std::to_string(__LINE__));
119 val_t eigen_value_max = 0;
120 for (
const val_t& val: eigen_value)
121 eigen_value_max = std::max(val, eigen_value_max);
123 const double threshold = eigen_value_max * threshold_condition_number;
125 typename traits::matrix_type eA(A.shape[0], A.shape[1]);
128 for (
int i = 0;
i != A.shape[0]; ++
i)
133 sqrt(1.0 / eigen_value[
i]),
134 A.ptr() +
i * A.shape[1],
143 BlasConnector::gemm(traits::gemm_trans,
'N', eA.nc, eA.nc, ie, 1, eA.c, eA.nc, eA.c, eA.nc, 0, A.ptr(), A.shape[1]);
169template <
typename Tdata>
172 assert(m.shape.size() == 2);
173 assert(m.shape[0] == m.shape[1]);
177template <
typename Tdata>
180 const size_t N0 = ms.size();
182 const size_t N1 = ms[0].size();
184 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
185 assert(ms[Im0].size() == N1);
187 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
188 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
189 assert(ms[Im0][Im1].shape.size() == 2);
191 std::vector<size_t> n0(N0);
192 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
193 n0[Im0] = ms[Im0][0].shape[0];
194 std::vector<size_t> n1(N1);
195 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
196 n1[Im1] = ms[0][Im1].shape[1];
198 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
199 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
200 assert((ms[Im0][Im1].shape[0] == n0[Im0]) && (ms[Im0][Im1].shape[1] == n1[Im1]));
202 const size_t n_all = std::accumulate(n0.begin(), n0.end(), 0);
203 assert(n_all == std::accumulate(n1.begin(), n1.end(), 0));
204 this->A = RI::Tensor<Tdata>({n_all, n_all});
206 std::vector<size_t> n0_partial(N0 + 1);
207 std::partial_sum(n0.begin(), n0.end(), n0_partial.begin() + 1);
208 std::vector<size_t> n1_partial(N1 + 1);
209 std::partial_sum(n1.begin(), n1.end(), n1_partial.begin() + 1);
211 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
212 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
214 const RI::Tensor<Tdata>& m_tmp = ms.at(Im0).at(Im1);
215 for (
size_t im0 = 0; im0 < m_tmp.shape[0]; ++im0)
216 for (
size_t im1 = 0; im1 < m_tmp.shape[1]; ++im1)
217 this->A(im0 + n0_partial[Im0], im1 + n1_partial[Im1]) = m_tmp(im0, im1);
221template <
typename Tdata>
224 return this->A.copy();
227template <
typename Tdata>
229 const std::vector<size_t>& n1)
const
231 assert(std::accumulate(n0.begin(), n0.end(), 0) == this->A.shape[0]);
232 assert(std::accumulate(n1.begin(), n1.end(), 0) == this->A.shape[1]);
234 const size_t N0 = n0.size();
235 const size_t N1 = n1.size();
237 std::vector<size_t> n0_partial(N0 + 1);
238 std::partial_sum(n0.begin(), n0.end(), n0_partial.begin() + 1);
239 std::vector<size_t> n1_partial(N1 + 1);
240 std::partial_sum(n1.begin(), n1.end(), n1_partial.begin() + 1);
242 std::vector<std::vector<RI::Tensor<Tdata>>> ms(N0, std::vector<RI::Tensor<Tdata>>(N1));
243 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
244 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
246 RI::Tensor<Tdata>& m_tmp = ms[Im0][Im1] = RI::Tensor<Tdata>({n0[Im0], n1[Im1]});
247 for (
size_t im0 = 0; im0 < n0[Im0]; ++im0)
248 for (
size_t im1 = 0; im1 < n1[Im1]; ++im1)
249 m_tmp(im0, im1) = this->A(im0 + n0_partial[Im0], im1 + n1_partial[Im1]);
254template <
typename Tdata>
257 for (
size_t i0 = 0; i0 < A.shape[0]; ++i0)
258 for (
size_t i1 = 0; i1 < i0; ++i1)
259 A(i0, i1) = A(i1, i0);
const std::complex< double > i
Definition cal_pLpR.cpp:46
static void axpy(const int n, const float alpha, const float *X, const int incX, float *Y, const int incY, base_device::AbacusDevice_t device_type=base_device::AbacusDevice_t::CpuDevice)
Definition blas_connector_vector.cpp:18
static void gemm(const char transa, const char transb, const int m, const int n, const int k, const float alpha, const float *a, const int lda, const float *b, const int ldb, const float beta, float *c, const int ldc, base_device::AbacusDevice_t device_type=base_device::AbacusDevice_t::CpuDevice)
Definition blas_connector_matrix.cpp:26
Method
Definition Inverse_Matrix.h:18
void using_potrf()
Definition Inverse_Matrix.hpp:34
void copy_down_triangle()
Definition Inverse_Matrix.hpp:255
void input(const RI::Tensor< Tdata > &m)
Definition Inverse_Matrix.hpp:170
RI::Tensor< Tdata > output() const
Definition Inverse_Matrix.hpp:222
void using_syev(const double &threshold_condition_number)
Definition Inverse_Matrix.hpp:106
void cal_inverse(const Method &method, const double &threshold_condition_number=0.)
Definition Inverse_Matrix.hpp:20
Definition complexmatrix.h:13
std::complex< double > complex
Definition diago_cusolver.cpp:15
This is a wrapper of some LAPACK routines. Row-Major version.
void tensor_syev(char jobz, char uplo, RI::Tensor< T > &a, RI::Global_Func::To_Real_t< T > *w, int &info)
#define threshold
Definition sph_bessel_recursive_test.cpp:4
static void syev(RI::Tensor< double > &A, value_type *w, int &info)
Definition Inverse_Matrix.hpp:59
double value_type
Definition Inverse_Matrix.hpp:58
static void syev(RI::Tensor< float > &A, value_type *w, int &info)
Definition Inverse_Matrix.hpp:85
float value_type
Definition Inverse_Matrix.hpp:84
static void syev(RI::Tensor< std::complex< double > > &A, value_type *w, int &info)
Definition Inverse_Matrix.hpp:72
double value_type
Definition Inverse_Matrix.hpp:71
static void syev(RI::Tensor< std::complex< float > > &A, value_type *w, int &info)
Definition Inverse_Matrix.hpp:98
float value_type
Definition Inverse_Matrix.hpp:97
Definition Inverse_Matrix.hpp:51