21#ifndef _libint2_include_libint2_util_intpartiter_h_
22#define _libint2_include_libint2_util_intpartiter_h_
38constexpr auto size(
const C& c) ->
decltype(c.size()) {
42template <
class T, std::
size_t N>
43constexpr std::size_t size(
const T (&array)[N])
noexcept {
48struct has_static_size;
49template <
typename T,
size_t N>
51template <
typename T,
size_t N>
56template <
typename T,
typename A>
57void resize(std::vector<T,A>& x, std::size_t n) {
71template <
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;
82 template <
typename Seq = Sequence>
84 unsigned_integer_type n,
89 std::fill(std::begin(partition_), std::end(partition_), integer_type(0));
100 detail::resize(partition_, k);
101 std::fill(std::begin(partition_), std::end(partition_), integer_type(0));
108 const auto partition_size = detail::size(partition_);
109 for (intmax_t d = 1; d <= n_; ++d) {
110 result *= (partition_size + d - 1);
116 value_type operator*()
const {
return partition_; }
118 const Sequence* operator->()
const {
return &partition_; }
121 operator bool()
const {
return this->
last(); }
124 bool last()
const {
return last(&partition_[0], detail::size(partition_)); }
128 void next() {
next(&partition_[0], detail::size(partition_)); }
131 template <
typename Seq>
132 static intmax_t
rank(
const Seq& part) {
133 auto k = detail::size(part);
134 decltype(k) count = 0;
136 auto part_i = part[0];
137 for (
decltype(k) i = 0; i != k;) {
141 intmax_t contrib_i = 1;
142 for (
decltype(count) c = 0; c != count; ++c) {
143 contrib_i *= (i + c);
160 static void first(integer_type* partition, size_type size) {
163 std::accumulate(partition, partition + size, unsigned_integer_type(0));
164 std::fill(partition, partition + size, integer_type(0));
167 static bool last(
const integer_type* partition, size_type size) {
169 const auto n = std::accumulate(partition, partition + size, 0u);
170 return partition[size - 1] == n;
172 static void next(integer_type* partition, size_type size) {
174 if (size == 1)
return;
175 if (
last(partition + 1, size - 1)) {
176 assert(partition[0] != 0u);
179 first(partition + 1, size - 1);
181 next(partition + 1, size - 1);
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
void next()
update to the next partition in the range
Definition: intpart_iter.h:128
FixedOrderedIntegerPartitionIterator(unsigned_integer_type n, size_type k)
Definition: intpart_iter.h:95
FixedOrderedIntegerPartitionIterator(unsigned_integer_type n, typename std::enable_if< detail::has_static_size< Seq >::value >::type *=nullptr)
Definition: intpart_iter.h:83
bool last() const
Definition: intpart_iter.h:124
static intmax_t rank(const Seq &part)
returns the rank (index) of partition part in the partition range
Definition: intpart_iter.h:132
intmax_t range_size() const
Definition: intpart_iter.h:106
Definition: intpart_iter.h:54