ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
Inverse_Matrix.hpp
Go to the documentation of this file.
1//=======================
2// AUTHOR : Peize Lin
3// DATE : 2022-08-17
4//=======================
5
6#ifndef INVERSE_MATRIX_HPP
7#define INVERSE_MATRIX_HPP
8
9#include "Inverse_Matrix.h"
11
12#include <cassert>
13
14template<typename Tdata>
16{
17 switch(method)
18 {
19 case Method::potrf: using_potrf(); break;
20// case Method::syev: using_syev(1E-6); break;
21 }
22}
23
24template<typename Tdata>
26{
27 int info;
28 LapackConnector::potrf('U', A.shape[0], A.ptr(), A.shape[0], info);
29 if(info)
30 throw std::range_error("info="+std::to_string(info)+"\n"+std::string(__FILE__)+" line "+std::to_string(__LINE__));
31
32 LapackConnector::potri('U', A.shape[0], A.ptr(), A.shape[0], info);
33 if(info)
34 throw std::range_error("info="+std::to_string(info)+"\n"+std::string(__FILE__)+" line "+std::to_string(__LINE__));
35
36 copy_down_triangle();
37}
38
39/*
40void Inverse_Matrix::using_syev( const double &threshold_condition_number )
41{
42 std::vector<double> eigen_value(A.nr);
43 LapackConnector::dsyev('V','U',A,eigen_value.data(),info);
44
45 double eigen_value_max = 0;
46 for( const double &ie : eigen_value )
47 eigen_value_max = std::max( ie, eigen_value_max );
48 const double threshold = eigen_value_max * threshold_condition_number;
49
50 ModuleBase::matrix eA( A.nr, A.nc );
51 int ie=0;
52 for( int i=0; i!=A.nr; ++i )
53 if( eigen_value[i] > threshold )
54 {
55 BlasConnector::axpy( A.nc, sqrt(1.0/eigen_value[i]), A.c+i*A.nc,1, eA.c+ie*eA.nc,1 );
56 ++ie;
57 }
58 BlasConnector::gemm( 'T','N', eA.nc,eA.nc,ie, 1, eA.c,eA.nc, eA.c,eA.nc, 0, A.c,A.nc );
59}
60*/
61
62template<typename Tdata>
63void Inverse_Matrix<Tdata>::input( const RI::Tensor<Tdata> &m )
64{
65 assert(m.shape.size()==2);
66 assert(m.shape[0]==m.shape[1]);
67 this->A = m.copy();
68}
69
70
71template<typename Tdata>
72void Inverse_Matrix<Tdata>::input(const std::vector<std::vector<RI::Tensor<Tdata>>> &ms)
73{
74 const size_t N0 = ms.size();
75 assert(N0>0);
76 const size_t N1 = ms[0].size();
77 assert(N1>0);
78 for(size_t Im0=0; Im0<N0; ++Im0)
79 assert(ms[Im0].size()==N1);
80
81 for(size_t Im0=0; Im0<N0; ++Im0)
82 for(size_t Im1=0; Im1<N1; ++Im1)
83 assert(ms[Im0][Im1].shape.size()==2);
84
85 std::vector<size_t> n0(N0);
86 for(size_t Im0=0; Im0<N0; ++Im0)
87 n0[Im0] = ms[Im0][0].shape[0];
88 std::vector<size_t> n1(N1);
89 for(size_t Im1=0; Im1<N1; ++Im1)
90 n1[Im1] = ms[0][Im1].shape[1];
91
92 for(size_t Im0=0; Im0<N0; ++Im0)
93 for(size_t Im1=0; Im1<N1; ++Im1)
94 assert((ms[Im0][Im1].shape[0]==n0[Im0]) && (ms[Im0][Im1].shape[1]==n1[Im1]));
95
96 const size_t n_all = std::accumulate(n0.begin(), n0.end(), 0);
97 assert(n_all == std::accumulate(n1.begin(), n1.end(), 0));
98 this->A = RI::Tensor<Tdata>({n_all, n_all});
99
100 std::vector<size_t> n0_partial(N0+1);
101 std::partial_sum(n0.begin(), n0.end(), n0_partial.begin()+1);
102 std::vector<size_t> n1_partial(N1+1);
103 std::partial_sum(n1.begin(), n1.end(), n1_partial.begin()+1);
104
105 for(size_t Im0=0; Im0<N0; ++Im0)
106 for(size_t Im1=0; Im1<N1; ++Im1)
107 {
108 const RI::Tensor<Tdata> &m_tmp = ms.at(Im0).at(Im1);
109 for(size_t im0=0; im0<m_tmp.shape[0]; ++im0)
110 for(size_t im1=0; im1<m_tmp.shape[1]; ++im1)
111 this->A(im0+n0_partial[Im0], im1+n1_partial[Im1]) = m_tmp(im0,im1);
112 }
113}
114
115
116template<typename Tdata>
117RI::Tensor<Tdata> Inverse_Matrix<Tdata>::output() const
118{
119 return this->A.copy();
120}
121
122
123template<typename Tdata>
124std::vector<std::vector<RI::Tensor<Tdata>>>
125Inverse_Matrix<Tdata>::output(const std::vector<size_t> &n0, const std::vector<size_t> &n1) const
126{
127 assert( std::accumulate(n0.begin(), n0.end(), 0) == this->A.shape[0] );
128 assert( std::accumulate(n1.begin(), n1.end(), 0) == this->A.shape[1] );
129
130 const size_t N0 = n0.size();
131 const size_t N1 = n1.size();
132
133 std::vector<size_t> n0_partial(N0+1);
134 std::partial_sum(n0.begin(), n0.end(), n0_partial.begin()+1);
135 std::vector<size_t> n1_partial(N1+1);
136 std::partial_sum(n1.begin(), n1.end(), n1_partial.begin()+1);
137
138 std::vector<std::vector<RI::Tensor<Tdata>>> ms(N0, std::vector<RI::Tensor<Tdata>>(N1));
139 for(size_t Im0=0; Im0<N0; ++Im0)
140 for(size_t Im1=0; Im1<N1; ++Im1)
141 {
142 RI::Tensor<Tdata> &m_tmp = ms[Im0][Im1] = RI::Tensor<Tdata>({n0[Im0], n1[Im1]});
143 for(size_t im0=0; im0<n0[Im0]; ++im0)
144 for(size_t im1=0; im1<n1[Im1]; ++im1)
145 m_tmp(im0,im1) = this->A(im0+n0_partial[Im0], im1+n1_partial[Im1]);
146 }
147 return ms;
148}
149
150
151template<typename Tdata>
153{
154 for( size_t i0=0; i0<A.shape[0]; ++i0 )
155 for( size_t i1=0; i1<i0; ++i1 )
156 A(i0,i1) = A(i1,i0);
157}
158
159#endif
Method
Definition Inverse_Matrix.h:15
void using_potrf()
Definition Inverse_Matrix.hpp:25
void cal_inverse(const Method &method)
Definition Inverse_Matrix.hpp:15
void copy_down_triangle()
Definition Inverse_Matrix.hpp:152
void input(const RI::Tensor< Tdata > &m)
Definition Inverse_Matrix.hpp:63
RI::Tensor< Tdata > output() const
Definition Inverse_Matrix.hpp:117
static void potrf(const char &uplo, const int &n, float *const A, const int &lda, int &info)
Definition lapack_connector.h:374
static void potri(const char &uplo, const int &n, float *const A, const int &lda, int &info)
Definition lapack_connector.h:401