QMCPACK
MatrixOperators.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Bryan Clark, bclark@Princeton.edu, Princeton University
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
11 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #ifndef QMCPLUSPLUS_MATRIXOPERATORS_H
18 #define QMCPLUSPLUS_MATRIXOPERATORS_H
19 
20 #include "OhmmsPETE/OhmmsMatrix.h"
21 #include "OhmmsPETE/OhmmsVector.h"
22 #include "OhmmsPETE/TinyVector.h"
23 #include "OhmmsPETE/Tensor.h"
24 #include "CPU/BLAS.hpp"
25 #include "CPU/SIMD/algorithm.hpp"
26 
27 namespace qmcplusplus
28 {
29 namespace MatrixOperators
30 {
31 /** static function to perform C=AB for real matrices
32  *
33  * Call dgemm/zgemm/sgemm/cgemm via BLAS::gemm
34  */
35 template<typename T>
36 inline void product(const Matrix<T>& A, const Matrix<T>& B, Matrix<T>& C)
37 {
38  const char transa = 'N';
39  const char transb = 'N';
40  const T one(1.0);
41  const T zero(0.0);
42  BLAS::gemm(transa, transb, B.cols(), A.rows(), B.rows(), one, B.data(), B.cols(), A.data(), A.cols(), zero, C.data(),
43  C.cols());
44 }
45 
46 template<typename T>
47 inline void product_ABt(const Matrix<T>& A, const Matrix<T>& B, Matrix<T>& C)
48 {
49  const char transa = 't';
50  const char transb = 'n';
51  const T one(1.0);
52  const T zero(0.0);
53  BLAS::gemm(transa, transb, B.rows(), A.rows(), B.cols(), one, B.data(), B.cols(), A.data(), A.cols(), zero, C.data(),
54  C.cols());
55 }
56 
57 template<typename T>
58 inline void product_AtB(const Matrix<T>& A, const Matrix<T>& B, Matrix<T>& C)
59 {
60  const char transa = 'n';
61  const char transb = 't';
62  const T one(1.0);
63  const T zero(0.0);
64  BLAS::gemm(transa, transb, B.cols(), A.cols(), B.rows(), one, B.data(), B.cols(), A.data(), A.cols(), zero, C.data(),
65  C.cols());
66 }
67 
68 
69 inline void half_outerProduct(const Matrix<double>& M, const Vector<double>& B, int iat, Matrix<double>& C)
70 {
71  for (int i = 0; i < C.rows(); i++)
72  for (int j = 0; j < C.cols(); j++)
73  C(iat, i) += M(i, j) * B[j];
74  //for (int i=0; i<C.rows(); i++)
75  // C(iat,i)+=simd::dot(M[i],B.data(),C.cols());
76 }
77 
78 inline void other_half_outerProduct(const Matrix<double>& M, const Vector<double>& B, int iat, Matrix<double>& C)
79 {
80  for (int i = 0; i < C.rows(); i++)
81  for (int j = 0; j < C.cols(); j++)
82  C(i, iat) += M(i, j) * B[j];
83  //for (int i=0; i<C.rows(); i++)
84  // C(i,iat)+=simd::dot(M[i],B.data(),C.cols());
85 }
86 
87 inline double innerProduct(const Vector<double>& A, const Vector<double>& B)
88 {
89  double tot = 0.0;
90  for (int i = 0; i < A.size(); i++)
91  tot += A[i] * B[i];
92  return tot;
93  //return simd::dot(A.data(),B.data(),A.size());
94 }
95 
96 
97 template<typename T>
98 inline void transpose(Matrix<T>& A)
99 {
100  for (int i = 0; i < A.extent(0); i++)
101  for (int j = 0; j < i; j++)
102  std::swap(A(i, j), A(j, i));
103 }
104 
105 template<typename T>
106 inline void transpose(const Matrix<T>& A, Matrix<T>& B)
107 {
108  simd::transpose(A.data(), A.rows(), A.cols(), B.data(), B.rows(), B.cols());
109 }
110 
111 
112 /// C = A*diag(B)
113 template<typename T1, typename T2, typename T3>
114 inline void diag_product(const Matrix<T1>& A, const Vector<T2>& B, Matrix<T3>& C)
115 {
116  for (int i = 0; i < C.rows(); ++i)
117  for (int j = 0; j < C.cols(); ++j)
118  C(i, j) = A(i, j) * B[j];
119  //works?
120  //const int ccols = C.cols();
121  //const int ijmax = C.size();
122  //for (int ij=0; ij<ijmax; ++ij)
123  // C(ij)=A(ij)*B(ij%ccols);
124 }
125 
126 
127 /// C = diag(A)*B
128 template<typename T1, typename T2, typename T3>
129 inline void diag_product(const Vector<T1>& A, const Matrix<T2>& B, Matrix<T3>& C)
130 {
131  for (int i = 0; i < C.rows(); ++i)
132  for (int j = 0; j < C.cols(); ++j)
133  C(i, j) = A[i] * B(i, j);
134 
135 
136  //const int crows = C.rows();
137  //const int ccols = C.cols();
138  //for (int i=0,ijb=0; i<crows; ++i,ijb+=ccols)
139  //{
140  // const T1 a = A(i);
141  // for (int j=0; j<ccols; ++j)
142  // {
143  // int ij = ijb+j;
144  // C(ij)=a*B(ij);
145  // }
146  //}
147  //
148  //const int crows = C.rows();
149  //const int ijmax = C.size();
150  //for (int ij=0; ij<ijmax; ++ij)
151  // C(ij)=A(ij%crows)*B(ij);
152 }
153 
154 
155 /** static function to perform C=AB for complex matrices
156  *
157  * Call zgemm
158  */
159 inline void product(const Matrix<double>& A, const Matrix<std::complex<double>>& B, Matrix<double>& C)
160 {
161  std::cerr << " Undefined C=AB with real A and complex B " << std::endl;
162 }
163 
164 /** static function to perform y=Ax for generic matrix and vector
165  */
166 template<typename T>
167 inline void product(const Matrix<T>& A, const Vector<T>& x, Vector<T>& y)
168 {
169  const char transa = 'T';
170  const T one = 1.0;
171  const T zero = 0.0;
172  BLAS::gemv(transa, A.cols(), A.rows(), one, A.data(), A.cols(), x.data(), 1, zero, y.data(), 1);
173 }
174 
175 /** static function to perform y = A^t x for generic matrix and vector
176  */
177 template<typename T>
178 inline void product_Atx(const Matrix<T>& A, const Vector<T>& x, Vector<T>& y)
179 {
180  const char transa = 'N';
181  const T one = 1.0;
182  const T zero = 0.0;
183  BLAS::gemv(transa, A.cols(), A.rows(), one, A.data(), A.cols(), x.data(), 1, zero, y.data(), 1);
184 }
185 
186 /** static function to perform y=Ax for generic matrix and vector
187  */
188 template<typename T, unsigned D>
189 inline void product(const Matrix<T>& A, const TinyVector<T, D>* xvPtr, TinyVector<T, D>* restrict yptr)
190 {
191  const T one = 1.0;
192  const T zero = 0.0;
193  const char transa = 'N';
194  const char transb = 'N';
195  BLAS::gemm(transa, transb, D, A.rows(), A.cols(), one, xvPtr->begin(), D, A.data(), A.cols(), zero, yptr->begin(), D);
196 }
197 
198 template<typename T, unsigned D>
199 inline void product(const Matrix<T>& A, const Tensor<T, D>* xvPtr, Tensor<T, D>* restrict yptr)
200 {
201  const T one = 1.0;
202  const T zero = 0.0;
203  const char transa = 'N';
204  const char transb = 'N';
205  BLAS::gemm(transa, transb, D * D, A.rows(), A.cols(), one, xvPtr->begin(), D * D, A.data(), A.cols(), zero,
206  yptr->begin(), D * D);
207 }
208 
209 /** static function to perform y=Ax for generic matrix and vector
210  */
211 template<unsigned D>
212 inline void product(const Matrix<double>& A,
213  const Vector<TinyVector<double, D>>& x,
214  TinyVector<double, D>* restrict yptr)
215 {
216  const double one = 1.0;
217  const double zero = 0.0;
218  const char transa = 'N';
219  const char transb = 'N';
220  dgemm(transa, transb, D, A.rows(), x.size(), one, x.data()->begin(), D, A.data(), A.cols(), zero, yptr->begin(), D);
221 }
222 
223 /** static function to perform y=Ax for generic matrix and vector
224  */
225 template<unsigned D>
226 inline void product(const Matrix<std::complex<double>>& A,
227  const Vector<TinyVector<std::complex<double>, D>>& x,
228  TinyVector<std::complex<double>, D>* restrict yptr)
229 {
230  const char transa = 'N';
231  const char transb = 'N';
232  const std::complex<double> zone(1.0, 0.0);
233  const std::complex<double> zero(0.0, 0.0);
234  zgemm(transa, transb, D, A.rows(), x.size(), zone, x.data()->begin(), D, A.data(), A.cols(), zero, yptr->begin(), D);
235 }
236 
237 
238 /** static function to perform y=Ax for generic matrix and vector
239  */
240 inline void product(const Matrix<std::complex<double>>& A,
241  const Vector<std::complex<double>>& x,
242  std::complex<double>* restrict yptr)
243 {
244  const char transa = 'T';
245  const std::complex<double> zone(1.0, 0.0);
246  const std::complex<double> zero(0.0, 0.0);
247  zgemv(transa, A.cols(), A.rows(), zone, A.data(), A.cols(), x.data(), 1, zero, yptr, 1);
248 }
249 
250 /** static function to perform y=Ax for generic matrix and vector
251  */
252 inline void product(const Matrix<std::complex<double>>& A, const Vector<double>& x, std::complex<double>* restrict yptr)
253 {
254  const int n = A.rows();
255  const int m = A.cols();
256  const std::complex<double>* restrict aptr = A.data();
257  for (int i = 0, ij = 0; i < n; ++i)
258  {
259  std::complex<double> t = 0.0;
260  for (int j = 0; j < m; ++j, ++ij)
261  t += aptr[ij] * x[j];
262  yptr[i] = t;
263  }
264 }
265 
266 } // namespace MatrixOperators
267 
268 } // namespace qmcplusplus
269 #endif
void zgemm(const char &, const char &, const int &, const int &, const int &, const std::complex< double > &, const std::complex< double > *, const int &, const std::complex< double > *, const int &, const std::complex< double > &, std::complex< double > *, const int &)
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
double innerProduct(const Vector< double > &A, const Vector< double > &B)
void transpose(const T *restrict A, size_t m, size_t lda, TO *restrict B, size_t n, size_t ldb)
transpose of A(m,n) to B(n,m)
Definition: algorithm.hpp:97
void product_Atx(const Matrix< T > &A, const Vector< T > &x, Vector< T > &y)
static function to perform y = A^t x for generic matrix and vector
void dgemm(const char &, const char &, const int &, const int &, const int &, const double &, const double *, const int &, const double *, const int &, const double &, double *, const int &)
static void gemv(int n, int m, const double *restrict amat, const double *restrict x, double *restrict y)
Definition: BLAS.hpp:118
constexpr std::complex< double > zone
Definition: BLAS.hpp:52
void zgemv(const char &trans, const int &nr, const int &nc, const std::complex< double > &alpha, const std::complex< double > *amat, const int &lda, const std::complex< double > *bv, const int &incx, const std::complex< double > &beta, std::complex< double > *cv, const int &incy)
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
void product(const Matrix< T > &A, const Matrix< T > &B, Matrix< T > &C)
static function to perform C=AB for real matrices
void product_ABt(const Matrix< T > &A, const Matrix< T > &B, Matrix< T > &C)
Declaraton of Vector<T,Alloc> Manage memory through Alloc directly and allow referencing an existing ...
static void gemm(char Atrans, char Btrans, int M, int N, int K, double alpha, const double *A, int lda, const double *restrict B, int ldb, double beta, double *restrict C, int ldc)
Definition: BLAS.hpp:235
void transpose(Matrix< T > &A)
double B(double x, int k, int i, const std::vector< double > &t)
Type_t * begin()
Definition: Tensor.h:269
void other_half_outerProduct(const Matrix< double > &M, const Vector< double > &B, int iat, Matrix< double > &C)
SIMD version of functions in algorithm.
void product_AtB(const Matrix< T > &A, const Matrix< T > &B, Matrix< T > &C)
void half_outerProduct(const Matrix< double > &M, const Vector< double > &B, int iat, Matrix< double > &C)
void diag_product(const Matrix< T1 > &A, const Vector< T2 > &B, Matrix< T3 > &C)
C = A*diag(B)