HPCombi
High Performance Combinatorics in C++ using vector instructions v1.0.3
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
22
23#ifndef HPCOMBI_VECT_GENERIC_HPP_
24#define HPCOMBI_VECT_GENERIC_HPP_
25
26#include <algorithm> // for max, min, shuffle, sort
27#include <array> // for array
28#include <cassert> // for assert
29#include <cstddef> // for size_t
30#include <cstdint> // for uint64_t, int8_t, int64_t
31#include <functional> // for hash
32#include <initializer_list> // for initializer_list
33#include <iomanip> // for operator<<, setw
34#include <memory> // for hash
35#include <ostream> // for operator<<, basic_ostream
36#include <random> // for mt19937, random_devide
37#include <type_traits> // for is_trivial
38
39#include "debug.hpp" // for HPCOMBI_ASSERT
40
41namespace HPCombi {
42
43template <size_t Size, typename Expo = uint8_t>
44std::array<Expo, Size> sorted_vect(std::array<Expo, Size> v) {
45 std::sort(v.begin(), v.end());
46 return v;
47}
48
56template <size_t Size, typename Expo = uint8_t> struct VectGeneric {
57 static constexpr size_t size() { return Size; }
58 using array = std::array<Expo, Size>;
60
61 VectGeneric() = default;
62
63 VectGeneric(const array &_v) : v(_v) {} // NOLINT
64 VectGeneric(std::initializer_list<Expo> il, Expo def = 0) {
65 HPCOMBI_ASSERT(il.size() <= Size);
66 std::copy(il.begin(), il.end(), v.begin());
67 std::fill(v.begin() + il.size(), v.end(), def);
68 }
69
70 Expo operator[](uint64_t i) const { return v[i]; }
71 Expo &operator[](uint64_t i) { return v[i]; }
72
73 size_t first_diff(const VectGeneric &u, size_t bound = Size) const {
74 for (size_t i = 0; i < bound; i++)
75 if (v[i] != u[i])
76 return i;
77 return Size;
78 }
79
80 size_t last_diff(const VectGeneric &u, size_t bound = Size) const {
81 while (bound != 0) {
82 --bound;
83 if (u[bound] != v[bound])
84 return bound;
85 }
86 return Size;
87 }
88
89 using value_type = Expo;
90 using iterator = typename array::iterator;
91 using const_iterator = typename array::const_iterator;
92 iterator begin() { return v.begin(); }
93 iterator end() { return v.end(); }
94 const_iterator begin() const { return v.begin(); }
95 const_iterator end() const { return v.end(); }
96
97 bool operator==(const VectGeneric &u) const {
98 return first_diff(u) == Size;
99 }
100 bool operator!=(const VectGeneric &u) const {
101 return first_diff(u) != Size;
102 }
103
104 bool operator<(const VectGeneric &u) const {
105 uint64_t diff = first_diff(u);
106 return (diff != Size) && v[diff] < u[diff];
107 }
108
109 int8_t less_partial(const VectGeneric &u, int k) const {
110 uint64_t diff = first_diff(u, k);
111 return (diff == Size) ? 0 : int8_t(v[diff]) - int8_t(u[diff]);
112 }
113
116 for (uint64_t i = 0; i < Size; i++) {
117 if (u[i] < Size)
118 res[i] = v[u[i]];
119 }
120 return res;
121 }
122
123 void sort() { std::sort(v.begin(), v.end()); }
124
125 bool is_sorted() const {
126 for (uint64_t i = 1; i < Size; i++)
127 if (v[i - 1] < v[i])
128 return false;
129 return true;
130 }
131
133 static std::random_device rd;
134 static std::mt19937 g(rd());
135
137 std::shuffle(res.begin(), res.end(), g);
138 return res;
139 }
140
141 uint64_t first_non_zero(size_t bound = Size) const {
142 for (uint64_t i = 0; i < bound; i++)
143 if (v[i] != 0)
144 return i;
145 return Size;
146 }
147 uint64_t first_zero(size_t bound = Size) const {
148 for (uint64_t i = 0; i < bound; i++)
149 if (v[i] == 0)
150 return i;
151 return Size;
152 }
153 uint64_t last_non_zero(size_t bound = Size) const {
154 for (int64_t i = bound - 1; i >= 0; i--)
155 if (v[i] != 0)
156 return i;
157 return Size;
158 }
159 uint64_t last_zero(size_t bound = Size) const {
160 for (int64_t i = bound - 1; i >= 0; i--)
161 if (v[i] == 0)
162 return i;
163 return Size;
164 }
165
166 bool is_permutation(const size_t k = Size) const {
167 auto temp = v;
168 std::sort(temp.begin(), temp.end());
169 for (uint64_t i = 0; i < Size; i++)
170 if (temp[i] != i)
171 return false;
172 for (uint64_t i = k; i < Size; i++)
173 if (v[i] != i)
174 return false;
175 return true;
176 }
177
178 uint64_t horiz_sum() const noexcept {
179 Expo res = 0;
180 for (uint64_t i = 0; i < Size; i++)
181 res += v[i];
182 return res;
183 }
184
185 VectGeneric partial_sums() const noexcept {
186 auto res = *this;
187 for (uint64_t i = 1; i < Size; i++)
188 res[i] += res[i - 1];
189 return res;
190 }
191
193 for (uint64_t i = 1; i < Size; i++)
194 v[i] += v[i - 1];
195 }
196
197 Expo horiz_max() const {
198 Expo res = v[0];
199 for (uint64_t i = 1; i < Size; i++)
200 res = std::max(res, v[i]);
201 return res;
202 }
203
205 for (uint64_t i = 1; i < Size; i++)
206 v[i] = std::max(v[i], v[i - 1]);
207 }
208
209 Expo horiz_min() const {
210 Expo res = v[0];
211 for (uint64_t i = 1; i < Size; i++)
212 res = std::min(res, v[i]);
213 return res;
214 }
215
217 for (uint64_t i = 1; i < Size; i++)
218 v[i] = std::min(v[i], v[i - 1]);
219 }
220
223 for (size_t i = 0; i < Size; i++)
224 if (v[i] < Size)
225 res[v[i]]++;
226 return res;
227 }
228};
229
230static_assert(std::is_trivial<VectGeneric<12>>(),
231 "VectGeneric is not a trivial class !");
232
233} // namespace HPCombi
234
235namespace std {
236
237template <size_t Size, typename Expo>
238std::ostream &operator<<(std::ostream &stream,
240 stream << "{" << std::setw(2) << unsigned(v[0]);
241 for (unsigned i = 1; i < Size; ++i)
242 stream << "," << std::setw(2) << unsigned(v[i]);
243 stream << "}";
244 return stream;
245}
246
249template <size_t Size, typename Expo>
250struct hash<HPCombi::VectGeneric<Size, Expo>> {
252 size_t h = 0;
253 for (size_t i = 0; i < Size; i++)
254 h = hash<Expo>()(ar[i]) + (h << 6) + (h << 16) - h;
255 return h;
256 }
257};
258
259} // namespace std
260
261#endif // HPCOMBI_VECT_GENERIC_HPP_
defines the macro HPCOMBI_ASSERT
#define HPCOMBI_ASSERT(x)
Definition debug.hpp:31
std::array< std::tuple< uint16_t, uint16_t, std::array< uint16_t, gens.size()> >, 65536 > res
Definition image.cpp:66
Definition bmat16.hpp:39
std::array< Expo, Size > sorted_vect(std::array< Expo, Size > v)
Definition vect_generic.hpp:44
Definition bmat16_impl.hpp:362
std::ostream & operator<<(std::ostream &os, HPCombi::BMat16 const &bm)
Definition bmat16_impl.hpp:365
VectGeneric is to Vect16 what PermGeneric is to Perm16; see PermGeneric.
Definition vect_generic.hpp:56
const_iterator end() const
Definition vect_generic.hpp:95
bool operator<(const VectGeneric &u) const
Definition vect_generic.hpp:104
Expo value_type
Definition vect_generic.hpp:89
bool operator==(const VectGeneric &u) const
Definition vect_generic.hpp:97
int8_t less_partial(const VectGeneric &u, int k) const
Definition vect_generic.hpp:109
uint64_t last_zero(size_t bound=Size) const
Definition vect_generic.hpp:159
Expo & operator[](uint64_t i)
Definition vect_generic.hpp:71
void sort()
Definition vect_generic.hpp:123
array v
Definition vect_generic.hpp:59
uint64_t last_non_zero(size_t bound=Size) const
Definition vect_generic.hpp:153
uint64_t first_zero(size_t bound=Size) const
Definition vect_generic.hpp:147
uint64_t first_non_zero(size_t bound=Size) const
Definition vect_generic.hpp:141
static VectGeneric random()
Definition vect_generic.hpp:132
bool is_sorted() const
Definition vect_generic.hpp:125
bool is_permutation(const size_t k=Size) const
Definition vect_generic.hpp:166
typename array::iterator iterator
Definition vect_generic.hpp:90
VectGeneric permuted(const VectGeneric &u) const
Definition vect_generic.hpp:114
static constexpr size_t size()
Definition vect_generic.hpp:57
uint64_t horiz_sum() const noexcept
Definition vect_generic.hpp:178
size_t first_diff(const VectGeneric &u, size_t bound=Size) const
Definition vect_generic.hpp:73
typename array::const_iterator const_iterator
Definition vect_generic.hpp:91
void partial_min_inplace()
Definition vect_generic.hpp:216
iterator begin()
Definition vect_generic.hpp:92
VectGeneric(const array &_v)
Definition vect_generic.hpp:63
iterator end()
Definition vect_generic.hpp:93
void partial_sums_inplace()
Definition vect_generic.hpp:192
size_t last_diff(const VectGeneric &u, size_t bound=Size) const
Definition vect_generic.hpp:80
void partial_max_inplace()
Definition vect_generic.hpp:204
Expo horiz_min() const
Definition vect_generic.hpp:209
std::array< Expo, Size > array
Definition vect_generic.hpp:58
const_iterator begin() const
Definition vect_generic.hpp:94
VectGeneric eval() const
Definition vect_generic.hpp:221
bool operator!=(const VectGeneric &u) const
Definition vect_generic.hpp:100
VectGeneric partial_sums() const noexcept
Definition vect_generic.hpp:185
Expo operator[](uint64_t i) const
Definition vect_generic.hpp:70
VectGeneric(std::initializer_list< Expo > il, Expo def=0)
Definition vect_generic.hpp:64
Expo horiz_max() const
Definition vect_generic.hpp:197
size_t operator()(const HPCombi::VectGeneric< Size, Expo > &ar) const
Definition vect_generic.hpp:251