1 #ifndef MPQC_CI_SIGMA3_HPP
2 #define MPQC_CI_SIGMA3_HPP
4 #include "mpqc/ci/ci.hpp"
5 #include "mpqc/ci/string.hpp"
6 #include "mpqc/ci/subspace.hpp"
8 #include "mpqc/utility/timer.hpp"
9 #include "mpqc/range.hpp"
10 #include "mpqc/math/matrix.hpp"
11 #include "mpqc/omp.hpp"
13 #include "mpqc/array.hpp"
14 #include "mpqc/array/functions.hpp"
16 #include <boost/type_traits/is_same.hpp>
35 os << r.
I <<
" -> " << r.
J
36 <<
", phase = " << r.sgn
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) {
48 int idx = (int)ci.template strings<Spin>()[I];
52 for (
size_t j = 0; j < I.size(); ++j) {
53 if (I[j] && (i != j))
continue;
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;
59 t.sgn = (float)sgn(I, i, j);
60 t.integral = (int)index(i,j);
75 BOOST_FOREACH (
int i, I) {
76 append(ci, ci.template strings<Spin>()[i], J, data_);
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); }
87 std::vector<Excitation> data_;
91 #define MPQC_CI_SIGMA3_NAIVE
92 #ifdef MPQC_CI_SIGMA3_NAIVE
98 BOOST_FOREACH (
auto b, beta) {
100 BOOST_FOREACH (
auto a, alpha) {
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;
112 #else // MPQC_CI_SIGMA3_NAIVE
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];
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());
140 template<
class SpinA,
class SpinB>
141 void sigma3(
const Excitations<SpinA> &A,
const Excitations<SpinB> &B,
143 static_assert(!boost::is_same<SpinA,SpinB>::value,
"spins must not be the same");
144 const int BLOCK = 128;
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());
155 for (
int a = 0; a < na; ++a) {
157 c.row(a) = C.row(aa.J - *A.J().begin());
158 v.row(a) = V.col(aa.integral);
160 Ia.push_back(aa.I - *A.I().begin());
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();
167 sigma3(na, b->sgn, v.col(b->integral), c.col(Jb), s);
169 if ((b+1) != B.end() && (b+1)->I == (b)->I)
continue;
172 for (
int a = 0; a < Ia.size(); ++a) {
173 S(Ia[a], Ib) += s(a);
181 #endif // MPQC_CI_SIGMA3_NAIVE