HPCombi
High Performance Combinatorics in C++ using vector instructions v1.0.0
Loading...
Searching...
No Matches
vect_generic.hpp
Go to the documentation of this file.
1//****************************************************************************//
2// Copyright (C) 2016-2024 Florent Hivert <Florent.Hivert@lisn.fr>, //
3// //
4// This file is part of HP-Combi <https://github.com/libsemigroups/HPCombi> //
5// //
6// HP-Combi is free software: you can redistribute it and/or modify it //
7// under the terms of the GNU General Public License as published by the //
8// Free Software Foundation, either version 3 of the License, or //
9// (at your option) any later version. //
10// //
11// HP-Combi is distributed in the hope that it will be useful, but WITHOUT //
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //
13// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License //
14// for more details. //
15// //
16// You should have received a copy of the GNU General Public License along //
17// with HP-Combi. If not, see <https://www.gnu.org/licenses/>. //
18//****************************************************************************//
19
20#ifndef HPCOMBI_VECT_GENERIC_HPP_
21#define HPCOMBI_VECT_GENERIC_HPP_
22
23#include <algorithm> // for max, min, shuffle, sort
24#include <array> // for array
25#include <cassert> // for assert
26#include <cstddef> // for size_t
27#include <cstdint> // for uint64_t, int8_t, int64_t
28#include <functional> // for hash
29#include <initializer_list> // for initializer_list
30#include <iomanip> // for operator<<, setw
31#include <memory> // for hash
32#include <ostream> // for operator<<, basic_ostream
33#include <random> // for mt19937, random_devide
34#include <type_traits> // for is_trivial
35
36#include "debug.hpp" // for HPCOMBI_ASSERT
37
38namespace HPCombi {
39
40template <size_t Size, typename Expo = uint8_t>
41std::array<Expo, Size> sorted_vect(std::array<Expo, Size> v) {
42 std::sort(v.begin(), v.end());
43 return v;
44}
45
48template <size_t Size, typename Expo = uint8_t> struct VectGeneric {
49 static constexpr size_t size() { return Size; }
50 using array = std::array<Expo, Size>;
52
53 VectGeneric() = default;
54
55 VectGeneric(const array &_v) : v(_v) {} // NOLINT
56 VectGeneric(std::initializer_list<Expo> il, Expo def = 0) {
57 HPCOMBI_ASSERT(il.size() <= Size);
58 std::copy(il.begin(), il.end(), v.begin());
59 std::fill(v.begin() + il.size(), v.end(), def);
60 }
61
62 Expo operator[](uint64_t i) const { return v[i]; }
63 Expo &operator[](uint64_t i) { return v[i]; }
64
65 size_t first_diff(const VectGeneric &u, size_t bound = Size) const {
66 for (size_t i = 0; i < bound; i++)
67 if (v[i] != u[i])
68 return i;
69 return Size;
70 }
71
72 size_t last_diff(const VectGeneric &u, size_t bound = Size) const {
73 while (bound != 0) {
74 --bound;
75 if (u[bound] != v[bound])
76 return bound;
77 }
78 return Size;
79 }
80
81 using value_type = Expo;
82 using iterator = typename array::iterator;
83 using const_iterator = typename array::const_iterator;
84 iterator begin() { return v.begin(); }
85 iterator end() { return v.end(); }
86 const_iterator begin() const { return v.begin(); }
87 const_iterator end() const { return v.end(); }
88
89 bool operator==(const VectGeneric &u) const {
90 return first_diff(u) == Size;
91 }
92 bool operator!=(const VectGeneric &u) const {
93 return first_diff(u) != Size;
94 }
95
96 bool operator<(const VectGeneric &u) const {
97 uint64_t diff = first_diff(u);
98 return (diff != Size) && v[diff] < u[diff];
99 }
100
101 int8_t less_partial(const VectGeneric &u, int k) const {
102 uint64_t diff = first_diff(u, k);
103 return (diff == Size) ? 0 : int8_t(v[diff]) - int8_t(u[diff]);
104 }
105
108 for (uint64_t i = 0; i < Size; i++) {
109 if (u[i] < Size)
110 res[i] = v[u[i]];
111 }
112 return res;
113 }
114
115 void sort() { std::sort(v.begin(), v.end()); }
116
117 bool is_sorted() const {
118 for (uint64_t i = 1; i < Size; i++)
119 if (v[i - 1] < v[i])
120 return false;
121 return true;
122 }
123
125 static std::random_device rd;
126 static std::mt19937 g(rd());
127
129 std::shuffle(res.begin(), res.end(), g);
130 return res;
131 }
132
133 uint64_t first_non_zero(size_t bound = Size) const {
134 for (uint64_t i = 0; i < bound; i++)
135 if (v[i] != 0)
136 return i;
137 return Size;
138 }
139 uint64_t first_zero(size_t bound = Size) const {
140 for (uint64_t i = 0; i < bound; i++)
141 if (v[i] == 0)
142 return i;
143 return Size;
144 }
145 uint64_t last_non_zero(size_t bound = Size) const {
146 for (int64_t i = bound - 1; i >= 0; i--)
147 if (v[i] != 0)
148 return i;
149 return Size;
150 }
151 uint64_t last_zero(size_t bound = Size) const {
152 for (int64_t i = bound - 1; i >= 0; i--)
153 if (v[i] == 0)
154 return i;
155 return Size;
156 }
157
158 bool is_permutation(const size_t k = Size) const {
159 auto temp = v;
160 std::sort(temp.begin(), temp.end());
161 for (uint64_t i = 0; i < Size; i++)
162 if (temp[i] != i)
163 return false;
164 for (uint64_t i = k; i < Size; i++)
165 if (v[i] != i)
166 return false;
167 return true;
168 }
169
170 uint64_t horiz_sum() const noexcept {
171 Expo res = 0;
172 for (uint64_t i = 0; i < Size; i++)
173 res += v[i];
174 return res;
175 }
176
177 VectGeneric partial_sums() const noexcept {
178 auto res = *this;
179 for (uint64_t i = 1; i < Size; i++)
180 res[i] += res[i - 1];
181 return res;
182 }
183
185 for (uint64_t i = 1; i < Size; i++)
186 v[i] += v[i - 1];
187 }
188
189 Expo horiz_max() const {
190 Expo res = v[0];
191 for (uint64_t i = 1; i < Size; i++)
192 res = std::max(res, v[i]);
193 return res;
194 }
195
197 for (uint64_t i = 1; i < Size; i++)
198 v[i] = std::max(v[i], v[i - 1]);
199 }
200
201 Expo horiz_min() const {
202 Expo res = v[0];
203 for (uint64_t i = 1; i < Size; i++)
204 res = std::min(res, v[i]);
205 return res;
206 }
207
209 for (uint64_t i = 1; i < Size; i++)
210 v[i] = std::min(v[i], v[i - 1]);
211 }
212
215 for (size_t i = 0; i < Size; i++)
216 if (v[i] < Size)
217 res[v[i]]++;
218 return res;
219 }
220};
221
222static_assert(std::is_trivial<VectGeneric<12>>(),
223 "VectGeneric is not a trivial class !");
224
225} // namespace HPCombi
226
227namespace std {
228
229template <size_t Size, typename Expo>
230std::ostream &operator<<(std::ostream &stream,
232 stream << "{" << std::setw(2) << unsigned(v[0]);
233 for (unsigned i = 1; i < Size; ++i)
234 stream << "," << std::setw(2) << unsigned(v[i]);
235 stream << "}";
236 return stream;
237}
238
239template <size_t Size, typename Expo>
240struct hash<HPCombi::VectGeneric<Size, Expo>> {
242 size_t h = 0;
243 for (size_t i = 0; i < Size; i++)
244 h = hash<Expo>()(ar[i]) + (h << 6) + (h << 16) - h;
245 return h;
246 }
247};
248
249} // namespace std
250
251#endif // HPCOMBI_VECT_GENERIC_HPP_
#define HPCOMBI_ASSERT(x)
Definition debug.hpp:28
std::array< std::tuple< uint16_t, uint16_t, std::array< uint16_t, gens.size()> >, 65536 > res
Definition image.cpp:66
Definition bmat8.hpp:41
std::array< Expo, Size > sorted_vect(std::array< Expo, Size > v)
Definition vect_generic.hpp:41
Definition bmat8.hpp:364
std::ostream & operator<<(std::ostream &os, HPCombi::BMat8 const &bm)
Definition bmat8_impl.hpp:508
A generic class for combinatorial integer vectors.
Definition vect_generic.hpp:48
const_iterator end() const
Definition vect_generic.hpp:87
bool operator<(const VectGeneric &u) const
Definition vect_generic.hpp:96
Expo value_type
Definition vect_generic.hpp:81
bool operator==(const VectGeneric &u) const
Definition vect_generic.hpp:89
int8_t less_partial(const VectGeneric &u, int k) const
Definition vect_generic.hpp:101
uint64_t last_zero(size_t bound=Size) const
Definition vect_generic.hpp:151
Expo & operator[](uint64_t i)
Definition vect_generic.hpp:63
void sort()
Definition vect_generic.hpp:115
array v
Definition vect_generic.hpp:51
uint64_t last_non_zero(size_t bound=Size) const
Definition vect_generic.hpp:145
uint64_t first_zero(size_t bound=Size) const
Definition vect_generic.hpp:139
uint64_t first_non_zero(size_t bound=Size) const
Definition vect_generic.hpp:133
static VectGeneric random()
Definition vect_generic.hpp:124
bool is_sorted() const
Definition vect_generic.hpp:117
bool is_permutation(const size_t k=Size) const
Definition vect_generic.hpp:158
typename array::iterator iterator
Definition vect_generic.hpp:82
VectGeneric permuted(const VectGeneric &u) const
Definition vect_generic.hpp:106
static constexpr size_t size()
Definition vect_generic.hpp:49
uint64_t horiz_sum() const noexcept
Definition vect_generic.hpp:170
size_t first_diff(const VectGeneric &u, size_t bound=Size) const
Definition vect_generic.hpp:65
typename array::const_iterator const_iterator
Definition vect_generic.hpp:83
void partial_min_inplace()
Definition vect_generic.hpp:208
iterator begin()
Definition vect_generic.hpp:84
VectGeneric(const array &_v)
Definition vect_generic.hpp:55
iterator end()
Definition vect_generic.hpp:85
void partial_sums_inplace()
Definition vect_generic.hpp:184
size_t last_diff(const VectGeneric &u, size_t bound=Size) const
Definition vect_generic.hpp:72
void partial_max_inplace()
Definition vect_generic.hpp:196
Expo horiz_min() const
Definition vect_generic.hpp:201
std::array< Expo, Size > array
Definition vect_generic.hpp:50
const_iterator begin() const
Definition vect_generic.hpp:86
VectGeneric eval() const
Definition vect_generic.hpp:213
bool operator!=(const VectGeneric &u) const
Definition vect_generic.hpp:92
VectGeneric partial_sums() const noexcept
Definition vect_generic.hpp:177
Expo operator[](uint64_t i) const
Definition vect_generic.hpp:62
VectGeneric(std::initializer_list< Expo > il, Expo def=0)
Definition vect_generic.hpp:56
Expo horiz_max() const
Definition vect_generic.hpp:189
size_t operator()(const HPCombi::VectGeneric< Size, Expo > &ar) const
Definition vect_generic.hpp:241