21 #ifndef _libint2_include_libint2_util_intpartiter_h_ 22 #define _libint2_include_libint2_util_intpartiter_h_ 31 #include <type_traits> 38 constexpr
auto size(
const C& c) -> decltype(c.size()) {
42 template <
class T, std::
size_t N>
43 constexpr std::size_t size(
const T (&array)[N]) noexcept {
49 template <
typename T,
size_t N>
51 template <
typename T,
size_t N>
56 template <
typename T,
typename A>
57 void resize(std::vector<T,A>& x, std::size_t n) {
71 template <
typename Sequence,
72 typename =
typename std::enable_if<std::numeric_limits<
73 typename Sequence::value_type>::is_integer>::type>
76 typedef const Sequence& value_type;
77 typedef typename Sequence::value_type integer_type;
78 typedef typename std::make_unsigned<integer_type>::type unsigned_integer_type;
79 typedef typename Sequence::size_type size_type;
83 template <
typename Seq = Sequence>
85 unsigned_integer_type n,
90 std::fill(std::begin(partition_), std::end(partition_), integer_type(0));
101 detail::resize(partition_, k);
102 std::fill(std::begin(partition_), std::end(partition_), integer_type(0));
109 const auto partition_size = detail::size(partition_);
110 for (intmax_t d = 1; d <= n_; ++d) {
111 result *= (partition_size + d - 1);
117 value_type operator*()
const {
return partition_; }
119 const Sequence* operator->()
const {
return &partition_; }
122 operator bool()
const {
return this->
last(); }
125 bool last()
const {
return last(&partition_[0], detail::size(partition_)); }
129 void next() {
next(&partition_[0], detail::size(partition_)); }
132 template <
typename Seq>
133 static intmax_t
rank(
const Seq& part) {
134 auto k = detail::size(part);
135 decltype(k) count = 0;
137 auto part_i = part[0];
138 for (decltype(k) i = 0; i != k;) {
142 intmax_t contrib_i = 1;
143 for (decltype(count) c = 0; c != count; ++c) {
144 contrib_i *= (i + c);
161 static void first(integer_type* partition, size_type size) {
164 std::accumulate(partition, partition + size, unsigned_integer_type(0));
165 std::fill(partition, partition + size, integer_type(0));
168 static bool last(
const integer_type* partition, size_type size) {
170 const auto n = std::accumulate(partition, partition + size, 0u);
171 return partition[size - 1] == n;
173 static void next(integer_type* partition, size_type size) {
175 if (size == 1)
return;
176 if (
last(partition + 1, size - 1)) {
177 assert(partition[0] != 0u);
180 first(partition + 1, size - 1);
182 next(partition + 1, size - 1);
intmax_t range_size() const
Definition: intpart_iter.h:107
static intmax_t rank(const Seq &part)
returns the rank (index) of partition part in the partition range
Definition: intpart_iter.h:133
bool last() const
Definition: intpart_iter.h:125
void next()
update to the next partition in the range
Definition: intpart_iter.h:129
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
Iterates over all partitions of a non-negative integer into nonnegative integers in reverse lexicog...
Definition: intpart_iter.h:74
FixedOrderedIntegerPartitionIterator(unsigned_integer_type n, typename std::enable_if< detail::has_static_size< Seq >::value >::type *=nullptr)
Definition: intpart_iter.h:84
Definition: intpart_iter.h:48
FixedOrderedIntegerPartitionIterator(unsigned_integer_type n, size_type k)
Definition: intpart_iter.h:96