MPQC  3.0.0-alpha
sigma3.hpp
1 #ifndef MPQC_CI_SIGMA3_HPP
2 #define MPQC_CI_SIGMA3_HPP
3 
4 #include "mpqc/ci/ci.hpp"
5 #include "mpqc/ci/string.hpp"
6 #include "mpqc/ci/subspace.hpp"
7 
8 #include "mpqc/utility/timer.hpp"
9 #include "mpqc/range.hpp"
10 #include "mpqc/math/matrix.hpp"
11 #include "mpqc/omp.hpp"
12 
13 #include "mpqc/array.hpp"
14 #include "mpqc/array/functions.hpp"
15 
16 #include <boost/type_traits/is_same.hpp>
17 
18 namespace mpqc {
19 namespace ci {
20 
22  struct Excitation {
23  float sgn;
24  int integral;
25  int I;
26  int J;
27  };
28 
29  // inline bool operator<(const Excitation &a, const Excitation &b) {
30  // // sort by I or by J if I's are the same
31  // return ((a.I != b.I) ? (a.I < b.I) : (a.J < b.J));
32  // }
33 
34  inline std::ostream& operator<<(std::ostream &os, const Excitation &r) {
35  os << r.I << " -> " << r.J
36  << ", phase = " << r.sgn
37  << ", ij = " << r.integral;
38  return os;
39  }
40 
43  template<class CI, class Spin>
44  void append(const CI &ci,
45  const String &I, const Subspace<Spin> &S,
46  std::vector<Excitation> &V) {
47  // this particular traversal is used to generate semi-ordered list
48  int idx = (int)ci.template strings<Spin>()[I];
49  size_t i = I.size();
50  while (i--) {
51  if (!I[i]) continue; // empty orbital
52  for (size_t j = 0; j < I.size(); ++j) {
53  if (I[j] && (i != j)) continue; // not an empty orbital
54  String J = I.swap(i, j);
55  if (!ci.test(J)) continue;
56  int jdx = (int)ci.template strings<Spin>()[J];
57  if (!S.test(jdx)) continue; // string not in S
58  Excitation t;
59  t.sgn = (float)sgn(I, i, j);
60  t.integral = (int)index(i,j);
61  t.I = idx;
62  t.J = jdx;
63  V.push_back(t);
64  }
65  }
66  }
67 
69  template<class Spin>
70  struct Excitations {
71  template<class CI>
72  Excitations(const CI &ci, const Subspace<Spin> &I, const Subspace<Spin> &J)
73  : I_(I), J_(J)
74  {
75  BOOST_FOREACH (int i, I) {
76  append(ci, ci.template strings<Spin>()[i], J, data_);
77  }
78  }
79  typedef std::vector<Excitation>::const_iterator const_iterator;
80  const_iterator begin() const { return data_.begin(); }
81  const_iterator end() const { return data_.end(); }
82  size_t size() const { return data_.size(); }
83  const Excitation& operator[](int i) const { return data_.at(i); }
84  const Subspace<Spin>& I() const { return this->I_; }
85  const Subspace<Spin>& J() const { return this->J_; }
86  private:
87  std::vector<Excitation> data_;
88  Subspace<Spin> I_, J_;
89  };
90 
91 #define MPQC_CI_SIGMA3_NAIVE
92 #ifdef MPQC_CI_SIGMA3_NAIVE
93 
95  void sigma3(const Excitations<Alpha> &alpha, const Excitations<Beta> &beta,
96  const Matrix &V, const Matrix &C, Matrix &S) {
97  // beta->beta excitations
98  BOOST_FOREACH (auto b, beta) {
99  // alpha->alpha excitations
100  BOOST_FOREACH (auto a, alpha) {
101  int Ia = a.I;
102  int Ja = a.J;
103  int Ib = b.I;
104  int Jb = b.J;
105  double c = C(Ja - *alpha.J().begin(), Jb - *beta.J().begin());
106  double s = a.sgn*b.sgn*V(a.integral,b.integral)*c;
107  S(Ia - *alpha.I().begin(), Ib - *beta.I().begin()) += s;
108  }
109  }
110  }
111 
112 #else // MPQC_CI_SIGMA3_NAIVE
113 
115  void sigma3(int n, double phase,
116  const double * RESTRICT v,
117  const double * RESTRICT c,
118  double * RESTRICT s) {
119  for (int i = 0; i < n; ++i) {
120  s[i] += phase*c[i]*v[i];
121  }
122  }
123 
125  template<class V, class C, class S>
126  void sigma3(int n, double phase, const V &v, const C &c, S &s) {
127  sigma3(n, phase, v.data(), c.data(), s.data());
128  // for (int i = 0; i < n; ++i) {
129  // s[i] += phase*c[i]*v[i];
130  // }
131  }
132 
140  template<class SpinA, class SpinB>
141  void sigma3(const Excitations<SpinA> &A, const Excitations<SpinB> &B,
142  const Matrix &V, const Matrix &C, Matrix &S) {
143  static_assert(!boost::is_same<SpinA,SpinB>::value, "spins must not be the same");
144  const int BLOCK = 128;
145  mpqc::Matrix c, v;
146  mpqc::Vector s;
147  std::vector<int> Ia;
148  // iterate over A excitations in blocks
149  for (int ba = 0; ba < A.size(); ba += BLOCK) {
150  int na = std::min<int>(A.size() - ba, BLOCK);
151  c.resize(na, C.cols());
152  v.resize(na, V.cols());
153  Ia.clear();
155  for (int a = 0; a < na; ++a) {
156  auto aa = A[a+ba];
157  c.row(a) = C.row(aa.J - *A.J().begin());
158  v.row(a) = V.col(aa.integral);
159  v.row(a) *= aa.sgn;
160  Ia.push_back(aa.I - *A.I().begin()); // record Ia index
161  }
162  s = mpqc::Vector::Zero(na);
163  for (auto b = B.begin(); b != B.end(); ++b) {
164  int Ib = b->I - *B.I().begin();
165  int Jb = b->J - *B.J().begin();
166  // vectorized s += sgn(Ib,Jb)*v*c
167  sigma3(na, b->sgn, v.col(b->integral), c.col(Jb), s);
168  // next iteration updates same Ib
169  if ((b+1) != B.end() && (b+1)->I == (b)->I) continue;
170  // scatter
171  //mutex.lock();
172  for (int a = 0; a < Ia.size(); ++a) {
173  S(Ia[a], Ib) += s(a);
174  s(a) = 0;
175  }
176  //mutex.unlock();
177  }
178  }
179  }
180 
181 #endif // MPQC_CI_SIGMA3_NAIVE
182 
183 }
184 }
185 
186 #endif /* MPQC_CI_SIGMA3_HPP */
187 
mpqc::ci::Excitation::integral
int integral
replacement parity, -1 or 1
Definition: sigma3.hpp:24
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
mpqc::ci::Excitation
One-particle excitation from string I to string J, {sign, ij, I, J}.
Definition: sigma3.hpp:22
mpqc::ci::Excitation::J
int J
ref.
Definition: sigma3.hpp:26
mpqc::matrix
Matrix class derived from Eigen::Matrix with additional MPQC integration.
Definition: matrix.hpp:21
mpqc::Matrix
matrix< double > Matrix
Convience double matrix type.
Definition: matrix.hpp:170
mpqc::ci::CI
CI class template.
Definition: ci.hpp:71
mpqc::ci::Subspace
A range of a space where all objects in the subspace range are assumed to have the same space rank.
Definition: subspace.hpp:51
mpqc::operator<<
void operator<<(Array< T > A, const V &v)
Write to Array from a generic vector V.
Definition: array.hpp:191
mpqc::ci::Excitations
Vector of single particle excitations from I to J subspace.
Definition: sigma3.hpp:70
mpqc::vector
Vector class derived from Eigen::Matrix with additional MPQC integration.
Definition: matrix.hpp:133
mpqc::ci::Excitation::I
int I
integral index, (i**2+i)/2 + j
Definition: sigma3.hpp:25

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.