QMCPACK
makeRngSpdMatrix.hpp
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) 2021 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
8 //
9 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include <type_traits>
13 #include "Platforms/CPU/BLAS.hpp"
15 #include "OhmmsPETE/OhmmsMatrix.h"
19 
20 namespace qmcplusplus
21 {
22 
23 /** Get the right type for rng in case of complex T.
24  * Probably a more elegant way to do this especially in c++17
25  */
26 template<typename T>
27 using RngValueType = typename std::disjunction<OnTypesEqual<T, float, float>,
28  OnTypesEqual<T, double, double>,
29  OnTypesEqual<T, std::complex<float>, float>,
30  OnTypesEqual<T, std::complex<double>, double>,
32 
33 namespace testing
34 {
35 
36 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, void>::type>
38 {
39  int n = mat_spd.rows();
40  Matrix<T> mat_a;
41  mat_a.resize(n, n);
42  rng.fillBufferRng(mat_a.data(), mat_a.size());
43  Matrix<T> mat_a_t(mat_a);
44  Matrix<T> mat_c;
45  mat_c.resize(n, n);
46  Matrix<T> mat_u;
47  mat_u.resize(n, n);
48  Matrix<T> mat_v;
49  mat_v.resize(n, n);
50  Matrix<T> mat_diag;
51  mat_diag.resize(n, n);
52  mat_diag = 0.0;
53  std::vector<T> singular_values(n);
54  std::vector<T> work_vec(5 * n);
55  int info;
56  const char trans = 't';
57  const char notrans = 'n';
58  const char all = 'a';
59  BLAS::gemm(trans, notrans, n, n, n, 1.0, mat_a.data(), n, mat_a_t.data(), n, 0.0, mat_c.data(), n);
60  LAPACK::gesvd(all, all, n, n, mat_c.data(), n, singular_values.data(), mat_u.data(), n, mat_v.data(), n,
61  work_vec.data(), work_vec.size(), info);
62  if (info == 0)
63  {
64  for (int i = 0; i < n; ++i)
65  mat_diag(i, i) = rng();
66  mat_diag += 1.0;
67  // reuse mat_a_t for this intermediate resutls
68  BLAS::gemm(notrans, notrans, n, n, n, 1.0, mat_u.data(), n, mat_diag.data(), n, 0.0, mat_a_t.data(), n);
69  // then reuse mat_u
70  BLAS::gemm(notrans, notrans, n, n, n, 1.0, mat_a_t.data(), n, mat_v.data(), n, 0.0, mat_u.data(), n);
71  }
72  simd::transpose(mat_u.data(), n, mat_u.cols(), mat_spd.data(), n, n);
73 }
74 
75 template<typename T, IsComplex<T> = true>
77 {
78  int n = mat_spd.rows();
79  Matrix<T> mat_a;
80  mat_a.resize(n, n);
81  rng.fillBufferRng(mat_a.data(), mat_a.size());
82  Matrix<T> mat_a_t(mat_a);
83  Matrix<T> mat_c;
84  mat_c.resize(n, n);
85  Matrix<T> mat_u;
86  mat_u.resize(n, n);
87  Matrix<T> mat_v;
88  mat_v.resize(n, n);
89  Matrix<T> mat_diag;
90  mat_diag.resize(n, n);
91  mat_diag = 0.0;
92  std::vector<typename T::value_type> singular_values(n);
93  std::vector<T> work_vec(5 * n);
94  std::vector<typename T::value_type> real_work_vec(5 * n);
95  int info;
96  const char trans = 't';
97  const char notrans = 'n';
98  const char all = 'a';
99  BLAS::gemm(trans, notrans, n, n, n, 1.0, mat_a.data(), n, mat_a_t.data(), n, 0.0, mat_c.data(), n);
100  LAPACK::gesvd(all, all, n, n, mat_c.data(), n, singular_values.data(), mat_u.data(), n, mat_v.data(), n,
101  work_vec.data(), work_vec.size(), real_work_vec.data(), info);
102  if (info == 0)
103  {
104  for (int i = 0; i < n; ++i)
105  mat_diag(i, i) = rng();
106  mat_diag += 1.0;
107  // reuse mat_a_t for this intermediate resutls
108  BLAS::gemm(notrans, notrans, n, n, n, 1.0, mat_u.data(), n, mat_diag.data(), n, 0.0, mat_a_t.data(), n);
109  // then reuse mat_u
110  BLAS::gemm(notrans, notrans, n, n, n, 1.0, mat_a_t.data(), n, mat_v.data(), n, 0.0, mat_u.data(), n);
111  }
112  simd::transpose(mat_u.data(), n, mat_u.cols(), mat_spd.data(), n, n);
113 }
114 
115 /** Functor to provide scope for rng when making SpdMatrix for testing.
116  */
117 template<typename T>
119 {
120 public:
121  void operator()(Matrix<T>& mat_spd) { makeRngSpdMatrix(rng, mat_spd); }
122 
123 private:
125 };
126 
127 /** make a random Vector
128  */
129 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, void>::type>
131 {
132  int n = vec.size();
133  rng.fillBufferRng(vec.data(), vec.size());
134 }
135 
136 /** Functor to provide scope for rng when making SpdMatrix for testing.
137  */
138 template<typename T>
140 {
141 public:
142  void operator()(Vector<T>& vec) { makeRngSpdMatrix(rng, vec); }
143 
144 private:
146 };
147 
148 extern template class MakeRngSpdMatrix<double>;
149 extern template class MakeRngSpdMatrix<float>;
150 extern template class MakeRngSpdMatrix<std::complex<double>>;
151 extern template class MakeRngSpdMatrix<std::complex<float>>;
152 
153 } // namespace testing
154 } // namespace qmcplusplus
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
testing::RandomForTest< RngValueType< T > > rng
Get a known sequence of random numbers for testing.
Definition: RandomForTest.h:31
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 resize(size_type n, size_type m)
Resize the container.
Definition: OhmmsMatrix.h:99
size_type cols() const
Definition: OhmmsMatrix.h:78
Functor to provide scope for rng when making SpdMatrix for testing.
size_type size() const
Definition: OhmmsMatrix.h:76
void makeRngSpdMatrix(testing::RandomForTest< RngValueType< T >> &rng, Matrix< T > &mat_spd)
size_type size() const
return the current size
Definition: OhmmsVector.h:162
static void gesvd(const char &jobu, const char &jobvt, const int &m, const int &n, float *a, const int &lda, float *s, float *u, const int &ldu, float *vt, const int &ldvt, float *work, const int &lwork, int &info)
Definition: BLAS.hpp:520
void makeRngVector(testing::RandomForTest< RngValueType< T >> &rng, Vector< T > &vec)
make a random Vector
size_type rows() const
Definition: OhmmsMatrix.h:77
typename std::disjunction< OnTypesEqual< T, float, float >, OnTypesEqual< T, double, double >, OnTypesEqual< T, std::complex< float >, float >, OnTypesEqual< T, std::complex< double >, double >, default_type< void > >::type RngValueType
Get the right type for rng in case of complex T.
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
SIMD version of functions in algorithm.
testing::RandomForTest< RngValueType< T > > rng
Functor to provide scope for rng when making SpdMatrix for testing.