dejavu
Fast probabilistic symmetry detection.
Loading...
Searching...
No Matches
utility.h
Go to the documentation of this file.
1// Copyright 2024 Markus Anders
2// This file is part of dejavu 2.0.
3// See LICENSE for extended copyright information.
4
5#include <iostream>
6#include <algorithm>
7#include <random>
8#include <unordered_map>
9#include <unordered_set>
10#include <fstream>
11#include <set>
12#include <cstring>
13#include <queue>
14#include <memory>
15#include <chrono>
16#include <iomanip>
17#include <functional>
18
19#ifndef DEJAVU_UTILITY_H
20#define DEJAVU_UTILITY_H
21
22#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
23 #define OS_WINDOWS
24#endif
25
26#if __APPLE__
27 #define OS_MAC
28#endif
29
30#if __linux__
31 #define OS_LINUX
32#endif
33
34#define PRINT_NO_NEWLINE(str) std::cout << str << std::flush;
35#define PRINT(str) std::cout << str << std::endl;
36
37#ifdef DEJDEBUG
38#define dej_assert(expr) (assert(expr))
39#else
40#define dej_assert(expr) (void)0
41#endif
42
43#if ((defined(_MSVC_LANG) && _MSVC_LANG > 201402L) || __cplusplus > 201402L)
44#define dej_nodiscard [[nodiscard]]
45#else
46#define dej_nodiscard
47#endif
48
49// use these options to prevent dejavu from using certain C++ language features
50// #define dej_nolambda
51// #define dej_nothreadlocal
52
53
60static inline unsigned int hash(unsigned int x) {
61 x = ((x >> 16) ^ x) * 0x45d9f3b;
62 x = ((x >> 16) ^ x) * 0x45d9f3b;
63 x = (x >> 16) ^ x;
64 return x;
65}
66
74static inline unsigned long add_to_hash(unsigned long hash, const int d) {
75 const unsigned long ho = hash & 0xff00000000000000; // extract high-order 8 bits from hash
76 hash = hash << 8; // shift hash left by 5 bits
77 hash = hash ^ (ho >> 56); // move the highorder 5 bits to the low-order
78 hash = hash ^ d; // XOR into hash
79
80 return hash;
81}
82
89static inline bool file_exists(const std::string& name) {
90 std::ifstream f(name.c_str());
91 return f.good();
92}
93
94typedef void type_dejavu_hook(int, const int*, int, const int*);
95typedef std::function<void(int, const int*, int, const int*)> dejavu_hook;
96
97namespace dejavu {
98
105 bool true_random = false;
106 std::mt19937 pseudo_random_device;
107 std::random_device true_random_device;
108 public:
115 random_source(bool set_true_random, int set_seed) {
116 true_random = set_true_random;
117 pseudo_random_device.seed(set_seed);
118 }
119
125 return true_random?static_cast<int>(true_random_device()&INT32_MAX):
126 static_cast<int>(pseudo_random_device()&INT32_MAX);
127 }
128 };
129
139 public:
140 long double mantissa = 1.0;
142 int exponent = 0;
145 friend bool operator<(const big_number& l, const big_number& r)
146 {
147 return (l.exponent < r.exponent) || (l.exponent == r.exponent && l.mantissa+0.01 < r.mantissa);
148 }
149
150 friend bool operator==(const big_number& l, const big_number& r)
151 {
152 return (l.exponent == r.exponent) && (l.mantissa > r.mantissa-0.01) && (l.mantissa < r.mantissa+0.01);
153 }
154
155 void set(long double set_mantissa, int set_exponent) {
156 mantissa = set_mantissa;
157 exponent = set_exponent;
158 }
159
165 void multiply(int number) {
166 multiply(number, 0);
167 }
168
174 void multiply(big_number number) {
175 multiply(number.mantissa, number.exponent);
176 }
177
178
186 void multiply(long double other_mantissa, int other_exponent) {
187 if(std::fpclassify(other_mantissa) == FP_INFINITE || std::fpclassify(other_mantissa) == FP_NAN) {
188 return;
189 }
190 while (other_mantissa >= 10.0) {
191 exponent += 1;
192 other_mantissa = other_mantissa / 10;
193 }
194 exponent += other_exponent;
195 mantissa *= other_mantissa;
196 man_to_exp();
197 }
198
199 private:
200 void man_to_exp() {
201 if(std::fpclassify(mantissa) == FP_INFINITE || std::fpclassify(mantissa) == FP_NAN) {
202 return;
203 }
204 while(mantissa >= 10.0) {
205 exponent += 1;
206 mantissa = mantissa / 10;
207 }
208 }
209 };
210
211 inline std::ostream& operator<<(std::ostream& out, big_number number) {
212 return out << number.mantissa << "*10^" << number.exponent;
213 }
214
218 static void progress_print_split() {
219 PRINT("\r______________________________________________________________");
220 }
221
225 static void progress_print_header() {
226 progress_print_split();
227 PRINT(std::setw(11) << std::left <<"T (ms)" << std::setw(11) << "delta(ms)" << std::setw(12) << "proc"
228 << std::setw(16) << "p1" << std::setw(16) << "p2");
229 progress_print_split();
230 }
231
238 std::chrono::high_resolution_clock::time_point first;
239 std::chrono::high_resolution_clock::time_point previous;
240 public:
241
242 bool h_silent = false;
243
245 first = std::chrono::high_resolution_clock::now();
246 previous = first;
247 }
248
249 void print_header() const {
250 if(h_silent) return;
251 progress_print_header();
252 }
253
254 void print_split() const {
255 if(h_silent) return;
256 progress_print_split();
257 }
258
259 void print(const std::string& str) const {
260 if(h_silent) return;
261 PRINT("\r" << str);
262 }
263
264 void timer_print(const std::string& proc, const std::string& p1, const std::string& p2) {
265 if(h_silent) return;
266 auto now = std::chrono::high_resolution_clock::now();
267 PRINT("\r" << std::fixed << std::setprecision(2) << std::setw(11) << std::left
268 << (std::chrono::duration_cast<std::chrono::nanoseconds>(now - first).count()) / 1000000.0
269 << std::setw(11)
270 << (std::chrono::duration_cast<std::chrono::nanoseconds>(now - previous).count()) / 1000000.0
271 << std::setw(12) << proc << std::setw(16) << p1 << std::setw(16) << p2);
272 previous = now;
273 }
274
275 void timer_split() {
276 previous = std::chrono::high_resolution_clock::now();
277 }
278
279 void timer_print(const std::string& proc, const int p1, const int p2) {
280 if(h_silent) return;
281 auto now = std::chrono::high_resolution_clock::now();
282 PRINT("\r" << std::fixed << std::setprecision(2) << std::setw(11) << std::left
283 << (std::chrono::duration_cast<std::chrono::nanoseconds>(now - first).count()) / 1000000.0
284 << std::setw(11)
285 << (std::chrono::duration_cast<std::chrono::nanoseconds>(now - previous).count()) / 1000000.0
286 << std::setw(12) << proc << std::setw(16) << p1 << std::setw(16) << p2);
287 previous = now;
288 }
289
290 void timer_print(const std::string& proc, const int p1, const double p2) {
291 if(h_silent) return;
292 auto now = std::chrono::high_resolution_clock::now();
293 PRINT("\r" << std::fixed << std::setprecision(2) << std::setw(11) << std::left
294 << (std::chrono::duration_cast<std::chrono::nanoseconds>(now - first).count()) / 1000000.0
295 << std::setw(11)
296 << (std::chrono::duration_cast<std::chrono::nanoseconds>(now - previous).count()) / 1000000.0
297 << std::setw(12) << proc << std::setw(16) << p1 << std::setw(16) << p2);
298 previous = now;
299 }
300
301 void progress_current_method(const std::string& print) const {
302 if(h_silent) return;
303 PRINT_NO_NEWLINE("\r>" << print);
304 }
305 void progress_current_method(const std::string& method_name, const std::string& var1, double var1_val,
306 const std::string& var2, double var2_val) const {
307 if(h_silent) return;
308 PRINT_NO_NEWLINE("\r>" << method_name << " " << var1 << "=" << var1_val << ", " << var2 << "=" << var2_val);
309 }
310 void progress_current_method(const std::string& method_name, const std::string& var1, int var1_val,
311 const std::string& var2, int var2_val,
312 const std::string& var3, double var3_val) const {
313 if(h_silent) return;
314 PRINT_NO_NEWLINE("\r>" << method_name << " " << var1 << "=" << var1_val << ", " << var2 << "=" << var2_val
315 << ", " << var3 << "=" << var3_val);
316 }
317
318 void progress_current_method(const std::string& method_name, const std::string& var1, double var1_val,
319 const std::string& var2, int var2_val,
320 const std::string& var3, int var3_val,
321 const std::string& var4, int var4_val) const {
322 if(h_silent) return;
323 PRINT_NO_NEWLINE("\r>" << method_name << " " << var1 << "=" << var1_val << ", " << var2 << "=" << var2_val
324 << ", " << var3 << "=" << var3_val << ", " << var4 << "=" << var4_val);
325 }
326 };
327}
328
329#endif //DEJAVU_UTILITY_H
Stores big numbers.
Definition: utility.h:138
long double mantissa
Definition: utility.h:140
void multiply(big_number number)
Definition: utility.h:174
friend bool operator==(const big_number &l, const big_number &r)
Definition: utility.h:150
friend bool operator<(const big_number &l, const big_number &r)
Definition: utility.h:145
void set(long double set_mantissa, int set_exponent)
Definition: utility.h:155
void multiply(long double other_mantissa, int other_exponent)
Definition: utility.h:186
void multiply(int number)
Definition: utility.h:165
Random number generation.
Definition: utility.h:104
random_source(bool set_true_random, int set_seed)
Definition: utility.h:115
Prints information to the console.
Definition: utility.h:237
void timer_split()
Definition: utility.h:275
void print_split() const
Definition: utility.h:254
void print(const std::string &str) const
Definition: utility.h:259
void progress_current_method(const std::string &method_name, const std::string &var1, int var1_val, const std::string &var2, int var2_val, const std::string &var3, double var3_val) const
Definition: utility.h:310
void progress_current_method(const std::string &method_name, const std::string &var1, double var1_val, const std::string &var2, double var2_val) const
Definition: utility.h:305
void timer_print(const std::string &proc, const std::string &p1, const std::string &p2)
Definition: utility.h:264
void timer_print(const std::string &proc, const int p1, const int p2)
Definition: utility.h:279
void timer_print(const std::string &proc, const int p1, const double p2)
Definition: utility.h:290
void print_header() const
Definition: utility.h:249
void progress_current_method(const std::string &method_name, const std::string &var1, double var1_val, const std::string &var2, int var2_val, const std::string &var3, int var3_val, const std::string &var4, int var4_val) const
Definition: utility.h:318
void progress_current_method(const std::string &print) const
Definition: utility.h:301
Definition: bfs.h:10
std::ostream & operator<<(std::ostream &out, big_number number)
Definition: utility.h:211
void type_dejavu_hook(int, const int *, int, const int *)
Definition: utility.h:94
#define PRINT_NO_NEWLINE(str)
Definition: utility.h:34
std::function< void(int, const int *, int, const int *)> dejavu_hook
Definition: utility.h:95
#define PRINT(str)
Definition: utility.h:35