42std::vector<std::vector<Factor_> >
combine_factors(std::size_t n,
const std::vector<const Factor_*>& factors, Combined_* combined) {
43 auto nfac = factors.size();
44 auto output = sanisizer::create<std::vector<std::vector<Factor_> > >(nfac);
48 std::fill_n(combined, n, 0);
58 Combination(std::size_t i) : index(i) {}
67 auto cmp = [&](
const Combination& left,
const Combination& right) ->
bool {
68 for (
auto curf : factors) {
69 if (curf[left.index] < curf[right.index]) {
71 }
else if (curf[left.index] > curf[right.index]) {
78 auto eq = [&](
const Combination& left,
const Combination& right) ->
bool {
79 for (
auto curf : factors) {
80 if (curf[left.index] != curf[right.index]) {
87 std::map<Combination, Combined_,
decltype(cmp)> mapping(std::move(cmp));
88 for (
decltype(n) i = 0; i < n; ++i) {
89 Combination current(i);
90 auto mIt = mapping.find(current);
91 if (mIt == mapping.end() || !eq(mIt->first, current)) {
92 Combined_ alt = mapping.size();
93 mapping.insert(mIt, std::make_pair(current, alt));
96 combined[i] = mIt->second;
100 return std::vector<std::pair<Combination, Combined_> >(mapping.begin(), mapping.end());
104 auto nuniq = unique.size();
105 for (
auto& ofac : output) {
108 auto remapping = sanisizer::create<std::vector<Combined_> >(nuniq);
109 for (
decltype(nuniq) u = 0; u < nuniq; ++u) {
110 auto ix = unique[u].first.index;
111 for (
decltype(nfac) f = 0; f < nfac; ++f) {
112 output[f].push_back(factors[f][ix]);
114 remapping[unique[u].second] = u;
118 for (
decltype(n) i = 0; i < n; ++i) {
119 combined[i] = remapping[combined[i]];
148std::vector<std::vector<Factor_> >
combine_factors_unused(std::size_t n,
const std::vector<std::pair<const Factor_*, Number_> >& factors, Combined_* combined) {
149 auto nfac = factors.size();
150 auto output = sanisizer::create<std::vector<std::vector<Factor_> > >(nfac);
154 std::fill_n(combined, n, 0);
158 output[0].resize(factors[0].second);
159 std::iota(output[0].begin(), output[0].end(),
static_cast<Combined_
>(0));
160 std::copy_n(factors[0].first, n, combined);
165 std::copy_n(factors[nfac - 1].first, n, combined);
166 Combined_ ncombos = factors[nfac - 1].second;
167 for (
decltype(nfac) f = nfac - 1; f > 0; --f) {
168 const auto& finfo = factors[f - 1];
169 auto next_ncombos = sanisizer::product<Combined_>(ncombos, finfo.second);
170 auto ff = finfo.first;
171 for (
decltype(n) i = 0; i < n; ++i) {
172 combined[i] += ncombos * ff[i];
174 ncombos = next_ncombos;
177 sanisizer::cast<
decltype(output[0].size())>(ncombos);
178 Combined_ outer_repeats = ncombos;
179 Combined_ inner_repeats = 1;
180 for (
decltype(nfac) f = nfac; f > 0; --f) {
181 auto& out = output[f - 1];
182 out.reserve(ncombos);
184 const auto& finfo = factors[f - 1];
185 Combined_ initial_size = inner_repeats * finfo.second;
186 out.resize(initial_size);
188 if (inner_repeats == 1) {
189 std::iota(out.begin(), out.end(),
static_cast<Combined_
>(0));
191 auto oIt = out.begin();
192 for (Number_ l = 0; l < finfo.second; ++l) {
193 std::fill_n(oIt, inner_repeats, l);
194 oIt += inner_repeats;
197 inner_repeats = initial_size;
199 outer_repeats /= finfo.second;
200 for (Combined_ r = 1; r < outer_repeats; ++r) {
201 out.insert(out.end(), out.begin(), out.begin() + initial_size);
std::vector< std::vector< Factor_ > > combine_factors_unused(std::size_t n, const std::vector< std::pair< const Factor_ *, Number_ > > &factors, Combined_ *combined)
Definition combine_factors.hpp:148
std::vector< std::vector< Factor_ > > combine_factors(std::size_t n, const std::vector< const Factor_ * > &factors, Combined_ *combined)
Definition combine_factors.hpp:42