LIBINT  2.1.0-stable
deriv_iter.h
1 /*
2  * This file is a part of Libint.
3  * Copyright (C) 2004-2014 Edward F. Valeev
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see http://www.gnu.org/licenses/.
17  *
18  */
19 
20 #ifndef _libint2_src_bin_libint_deriviter_h_
21 #define _libint2_src_bin_libint_deriviter_h_
22 
23 #include <numeric>
24 #include <string>
25 #include <stdexcept>
26 
27 namespace libint2 {
28 
30  template <unsigned int NCenters>
32  public:
33  DerivIndexIterator(unsigned int deriv_order) : deriv_order_(deriv_order) {
34  assert(NCenters != 0);
35  std::fill(deriv_index_, deriv_index_+NCenters*3, 0u);
36  deriv_index_[0] = deriv_order_;
37  }
38 
39  unsigned int range_rank() const {
40  unsigned int result = 1;
41  for(unsigned int d=1; d<=deriv_order_; ++d) {
42  result *= (NCenters*3+d-1); result /= d;
43  }
44  return result;
45  }
46 
47  unsigned int value(unsigned int i) const {
48  assert(i < NCenters*3);
49  return deriv_index_[i];
50  }
51 
52  const unsigned int* values() const {
53  return deriv_index_;
54  }
55 
57  bool last() const {
58  return last(const_cast<unsigned int*>(deriv_index_), NCenters*3);
59  }
61  void next() {
62  next(deriv_index_, NCenters*3);
63  }
64 
65  private:
66  unsigned int deriv_order_;
67  unsigned int deriv_index_[NCenters*3];
68 
69  static void
70  first(unsigned int* deriv_index, unsigned int n) {
71  assert(n != 0);
72  const unsigned int deriv_order = std::accumulate(deriv_index, deriv_index+n, 0u);
73  std::fill(deriv_index, deriv_index+n, 0u);
74  deriv_index[0] = deriv_order;
75  }
76  static bool
77  last(unsigned int* deriv_index, unsigned int n) {
78  const unsigned int deriv_order = std::accumulate(deriv_index, deriv_index+n, 0u);
79  return deriv_index[n-1] == deriv_order;
80  }
81  static void
82  next(unsigned int* deriv_index, unsigned int n) {
83  if (n == 1) return;
84  if (last(deriv_index+1, n-1)) {
85  assert(deriv_index[0]!=0u);
86  --deriv_index[0];
87  ++deriv_index[1];
88  first(deriv_index+1, n-1);
89  }
90  else
91  next(deriv_index+1, n-1);
92  }
93  };
94 }
95 
96 #endif /* header guard */
Iterates over unique derivative indices.
Definition: deriv_iter.h:31
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:23
void next()
will throw if last() == true
Definition: deriv_iter.h:61