40std::vector<std::vector<Factor_> >
combine_factors(
size_t n,
const std::vector<const Factor_*>& factors, Combined_* combined) {
41 size_t nfac = factors.size();
42 std::vector<std::vector<Factor_> > output(nfac);
46 std::fill_n(combined, n, 0);
56 Combination(
size_t i) : index(i) {}
65 auto cmp = [&](
const Combination& left,
const Combination& right) ->
bool {
66 for (
auto curf : factors) {
67 if (curf[left.index] < curf[right.index]) {
69 }
else if (curf[left.index] > curf[right.index]) {
76 auto eq = [&](
const Combination& left,
const Combination& right) ->
bool {
77 for (
auto curf : factors) {
78 if (curf[left.index] != curf[right.index]) {
85 std::map<Combination, Combined_,
decltype(cmp)> mapping(std::move(cmp));
86 for (
size_t i = 0; i < n; ++i) {
87 Combination current(i);
88 auto mIt = mapping.find(current);
89 if (mIt == mapping.end() || !eq(mIt->first, current)) {
90 Combined_ alt = mapping.size();
91 mapping.insert(mIt, std::make_pair(current, alt));
94 combined[i] = mIt->second;
98 return std::vector<std::pair<Combination, Combined_> >(mapping.begin(), mapping.end());
102 size_t nuniq = unique.size();
103 for (
auto& ofac : output) {
106 std::vector<Combined_> remapping(nuniq);
107 for (
size_t u = 0; u < nuniq; ++u) {
108 auto ix = unique[u].first.index;
109 for (
size_t f = 0; f < nfac; ++f) {
110 output[f].push_back(factors[f][ix]);
112 remapping[unique[u].second] = u;
116 for (
size_t i = 0; i < n; ++i) {
117 combined[i] = remapping[combined[i]];
146std::vector<std::vector<Factor_> >
combine_factors_unused(
size_t n,
const std::vector<std::pair<const Factor_*, Number_> >& factors, Combined_* combined) {
147 size_t nfac = factors.size();
148 std::vector<std::vector<Factor_> > output(nfac);
152 std::fill_n(combined, n, 0);
156 output[0].resize(factors[0].second);
157 std::iota(output[0].begin(), output[0].end(),
static_cast<Combined_
>(0));
158 std::copy_n(factors[0].first, n, combined);
163 std::copy_n(factors[nfac - 1].first, n, combined);
164 Combined_ mult = factors[nfac - 1].second;
165 for (
size_t f = nfac - 1; f > 0; --f) {
166 const auto& finfo = factors[f - 1];
167 auto ff = finfo.first;
168 for (
size_t i = 0; i < n; ++i) {
169 combined[i] += mult * ff[i];
171 mult *= finfo.second;
175 Combined_ outer_repeats = mult;
176 Combined_ inner_repeats = 1;
177 for (
size_t f = nfac; f > 0; --f) {
178 auto& out = output[f - 1];
179 out.reserve(ncombos);
181 const auto& finfo = factors[f - 1];
182 size_t initial_size = inner_repeats * finfo.second;
183 out.resize(initial_size);
185 if (inner_repeats == 1) {
186 std::iota(out.begin(), out.end(),
static_cast<Combined_
>(0));
188 auto oIt = out.begin();
189 for (Number_ l = 0; l < finfo.second; ++l) {
190 std::fill_n(oIt, inner_repeats, l);
191 oIt += inner_repeats;
194 inner_repeats = initial_size;
196 outer_repeats /= finfo.second;
197 for (Combined_ r = 1; r < outer_repeats; ++r) {
198 out.insert(out.end(), out.begin(), out.begin() + initial_size);
std::vector< std::vector< Factor_ > > combine_factors_unused(size_t n, const std::vector< std::pair< const Factor_ *, Number_ > > &factors, Combined_ *combined)
Definition combine_factors.hpp:146
std::vector< std::vector< Factor_ > > combine_factors(size_t n, const std::vector< const Factor_ * > &factors, Combined_ *combined)
Definition combine_factors.hpp:40