6#ifndef INVERSE_MATRIX_HPP
7#define INVERSE_MATRIX_HPP
15template <
typename Tdata>
24 using_syev(threshold_condition_number);
29template <
typename Tdata>
33 LapackConnector::potrf(
'U', A.shape[0], A.ptr(), A.shape[0], info);
35 throw std::range_error(
"info=" + std::to_string(info) +
"\n" + std::string(__FILE__) +
" line "
36 + std::to_string(__LINE__));
38 LapackConnector::potri(
'U', A.shape[0], A.ptr(), A.shape[0], info);
40 throw std::range_error(
"info=" + std::to_string(info) +
"\n" + std::string(__FILE__) +
" line "
41 + std::to_string(__LINE__));
59 static constexpr char gemm_trans =
'T';
68 static void syev(RI::Tensor<std::complex<double>>& A,
value_type* w,
int& info)
72 static constexpr char gemm_trans =
'C';
85 static constexpr char gemm_trans =
'T';
94 static void syev(RI::Tensor<std::complex<float>>& A,
value_type* w,
int& info)
98 static constexpr char gemm_trans =
'C';
105 using val_t =
typename traits::value_type;
108 std::vector<val_t> eigen_value(A.shape[0]);
110 traits::syev(A, eigen_value.data(), info);
112 throw std::range_error(
"info=" + std::to_string(info) +
"\n" + std::string(__FILE__) +
" line "
113 + std::to_string(__LINE__));
115 val_t eigen_value_max = 0;
116 for (
const val_t& val: eigen_value)
117 eigen_value_max = std::max(val, eigen_value_max);
119 const double threshold = eigen_value_max * threshold_condition_number;
121 typename traits::matrix_type eA(A.shape[0], A.shape[1]);
124 for (
int i = 0; i != A.shape[0]; ++i)
129 sqrt(1.0 / eigen_value[i]),
130 A.ptr() + i * A.shape[1],
139 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]);
165template <
typename Tdata>
168 assert(m.shape.size() == 2);
169 assert(m.shape[0] == m.shape[1]);
173template <
typename Tdata>
176 const size_t N0 = ms.size();
178 const size_t N1 = ms[0].size();
180 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
181 assert(ms[Im0].size() == N1);
183 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
184 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
185 assert(ms[Im0][Im1].shape.size() == 2);
187 std::vector<size_t> n0(N0);
188 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
189 n0[Im0] = ms[Im0][0].shape[0];
190 std::vector<size_t> n1(N1);
191 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
192 n1[Im1] = ms[0][Im1].shape[1];
194 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
195 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
196 assert((ms[Im0][Im1].shape[0] == n0[Im0]) && (ms[Im0][Im1].shape[1] == n1[Im1]));
198 const size_t n_all = std::accumulate(n0.begin(), n0.end(), 0);
199 assert(n_all == std::accumulate(n1.begin(), n1.end(), 0));
200 this->A = RI::Tensor<Tdata>({n_all, n_all});
202 std::vector<size_t> n0_partial(N0 + 1);
203 std::partial_sum(n0.begin(), n0.end(), n0_partial.begin() + 1);
204 std::vector<size_t> n1_partial(N1 + 1);
205 std::partial_sum(n1.begin(), n1.end(), n1_partial.begin() + 1);
207 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
208 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
210 const RI::Tensor<Tdata>& m_tmp = ms.at(Im0).at(Im1);
211 for (
size_t im0 = 0; im0 < m_tmp.shape[0]; ++im0)
212 for (
size_t im1 = 0; im1 < m_tmp.shape[1]; ++im1)
213 this->A(im0 + n0_partial[Im0], im1 + n1_partial[Im1]) = m_tmp(im0, im1);
217template <
typename Tdata>
220 return this->A.copy();
223template <
typename Tdata>
225 const std::vector<size_t>& n1)
const
227 assert(std::accumulate(n0.begin(), n0.end(), 0) == this->A.shape[0]);
228 assert(std::accumulate(n1.begin(), n1.end(), 0) == this->A.shape[1]);
230 const size_t N0 = n0.size();
231 const size_t N1 = n1.size();
233 std::vector<size_t> n0_partial(N0 + 1);
234 std::partial_sum(n0.begin(), n0.end(), n0_partial.begin() + 1);
235 std::vector<size_t> n1_partial(N1 + 1);
236 std::partial_sum(n1.begin(), n1.end(), n1_partial.begin() + 1);
238 std::vector<std::vector<RI::Tensor<Tdata>>> ms(N0, std::vector<RI::Tensor<Tdata>>(N1));
239 for (
size_t Im0 = 0; Im0 < N0; ++Im0)
240 for (
size_t Im1 = 0; Im1 < N1; ++Im1)
242 RI::Tensor<Tdata>& m_tmp = ms[Im0][Im1] = RI::Tensor<Tdata>({n0[Im0], n1[Im1]});
243 for (
size_t im0 = 0; im0 < n0[Im0]; ++im0)
244 for (
size_t im1 = 0; im1 < n1[Im1]; ++im1)
245 m_tmp(im0, im1) = this->A(im0 + n0_partial[Im0], im1 + n1_partial[Im1]);
250template <
typename Tdata>
253 for (
size_t i0 = 0; i0 < A.shape[0]; ++i0)
254 for (
size_t i1 = 0; i1 < i0; ++i1)
255 A(i0, i1) = A(i1, i0);
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:21
Method
Definition Inverse_Matrix.h:18
void using_potrf()
Definition Inverse_Matrix.hpp:30
void copy_down_triangle()
Definition Inverse_Matrix.hpp:251
void input(const RI::Tensor< Tdata > &m)
Definition Inverse_Matrix.hpp:166
RI::Tensor< Tdata > output() const
Definition Inverse_Matrix.hpp:218
void using_syev(const double &threshold_condition_number)
Definition Inverse_Matrix.hpp:102
void cal_inverse(const Method &method, const double &threshold_condition_number=0.)
Definition Inverse_Matrix.hpp:16
Definition complexmatrix.h:14
std::complex< double > complex
Definition diago_cusolver.cpp:13
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:55
double value_type
Definition Inverse_Matrix.hpp:54
static void syev(RI::Tensor< float > &A, value_type *w, int &info)
Definition Inverse_Matrix.hpp:81
float value_type
Definition Inverse_Matrix.hpp:80
static void syev(RI::Tensor< std::complex< double > > &A, value_type *w, int &info)
Definition Inverse_Matrix.hpp:68
double value_type
Definition Inverse_Matrix.hpp:67
static void syev(RI::Tensor< std::complex< float > > &A, value_type *w, int &info)
Definition Inverse_Matrix.hpp:94
float value_type
Definition Inverse_Matrix.hpp:93
Definition Inverse_Matrix.hpp:47