Orbiter 2022
Combinatorial Objects
boolean_function_classify.cpp
Go to the documentation of this file.
1/*
2 * boolean_function_classify.cpp
3 *
4 * Created on: Nov 06, 2019
5 * Author: betten
6 */
7
8
9
10
11#include "orbiter.h"
12
13using namespace std;
14
15namespace orbiter {
16namespace layer5_applications {
17namespace apps_combinatorics {
18
19
20static void boolean_function_classify_print_function(int *poly, int sz, void *data);
21static void boolean_function_classify_reduction_function(int *poly, void *data);
22
23
25{
26 BF = NULL;
27 A = NULL;
28 nice_gens = NULL;
29 AonHPD = NULL;
30 SG = NULL;
31 A_affine = NULL;
32}
33
35{
36 if (A) {
38 }
39 if (nice_gens) {
41 }
42 if (AonHPD) {
44 }
45 if (SG) {
47 }
48 if (A_affine) {
50 }
51}
52
53
54
56{
57 int f_v = (verbose_level >= 1);
58
59 if (f_v) {
60 cout << "boolean_function_classify::init_group" << endl;
61 }
62
64
65 int degree = BF->n + 1;
66
68
69 if (f_v) {
70 cout << "boolean_function_classify::init_group "
71 "before init_projective_group" << endl;
72 }
73 A->init_projective_group(degree, BF->Fq,
74 FALSE /* f_semilinear */,
75 TRUE /* f_basis */, TRUE /* f_init_sims */,
77 verbose_level);
78
80 if (f_v) {
81 cout << "boolean_function_classify::init_group "
82 "before AonHPD->init" << endl;
83 }
84 AonHPD->init(A, &BF->Poly[BF->n], verbose_level);
85 if (f_v) {
86 cout << "boolean_function_classify::init_group "
87 "after AonHPD->init" << endl;
88 }
89
90
92
94
95 Mtx = A->get_matrix_group();
96
97 if (f_v) {
98 cout << "boolean_function_classify::init_group "
99 "before generators_for_parabolic_subgroup" << endl;
100 }
102 Mtx, degree - 1, verbose_level);
103 if (f_v) {
104 cout << "boolean_function_classify::init_group "
105 "after generators_for_parabolic_subgroup" << endl;
106 }
107
109
110 SG->group_order(go);
111 if (f_v) {
112 cout << "boolean_function_classify::init_group "
113 "go=" << go << endl;
114 }
115
116 if (f_v) {
117 cout << "boolean_function_classify::init_group "
118 "before A->restricted_action" << endl;
119 }
121 verbose_level);
122 if (f_v) {
123 cout << "boolean_function_classify::init_group "
124 "after A->restricted_action" << endl;
125 }
126
127 if (f_v) {
128 cout << "Generators in the induced action:" << endl;
130 cout, A_affine);
131 }
132
133
134#if 0
135 SG->init(A);
136 if (f_v) {
137 cout << "boolean_function::init_group "
138 "before init_transposed_group" << endl;
139 }
140 SG->init_transposed_group(SGt, verbose_level);
141 if (f_v) {
142 cout << "boolean_function::init_group "
143 "after init_transposed_group" << endl;
144 }
145#endif
146
147 if (f_v) {
148 cout << "boolean_function_classify::init_group done" << endl;
149 }
150}
151
152
154{
155 int f_v = (verbose_level >= 1);
156 int *poly;
157 int i, j;
159 int nb_sol = 0;
160 int nb_orbits = 0;
161 uint32_t h;
165 vector<int> orbit_first;
166 vector<int> orbit_length;
167
168 vector<vector<int> > Bent_function_table;
169 vector<vector<int> > Equation_table;
170
171 std::multimap<uint32_t, int> Hashing;
172 // we store the pair (hash, idx)
173 // where hash is the hash value of the set and idx is the
174 // index in the table Sets where the set is stored.
175 //
176 // we use a multimap because the hash values are not unique
177 // it happens that two sets have the same hash value.
178 // map cannot handle that.
179
180
181 if (f_v) {
182 cout << "boolean_function_classify::search_for_bent_functions" << endl;
183 }
184
185
186
187 poly = NEW_int(BF->Poly[BF->n].get_nb_monomials());
188
189 a.create(0, __FILE__, __LINE__);
190 while (D.is_less_than(a, *BF->NN)) {
191
192 Gg.AG_element_unrank_longinteger(2, BF->f, 1, BF->Q, a);
193 //Gg.AG_element_unrank(2, f, 1, Q, a);
194 cout << a << " / " << BF->NN << " : ";
195 Int_vec_print(cout, BF->f, BF->Q);
196 //cout << endl;
197
198 BF->raise(BF->f, BF->F);
199
201
202 cout << " : ";
203 Int_vec_print(cout, BF->T, BF->Q);
204
205 if (BF->is_bent(BF->T)) {
206 cout << " is bent " << nb_sol;
207 nb_sol++;
208
209 h = Data.int_vec_hash(BF->f, BF->Q);
210
211 map<uint32_t, int>::iterator itr, itr1, itr2;
212 int pos, f_found;
213
214 itr1 = Hashing.lower_bound(h);
215 itr2 = Hashing.upper_bound(h);
216 f_found = FALSE;
217 for (itr = itr1; itr != itr2; ++itr) {
218 pos = itr->second;
219 for (j = 0; j < BF->Q; j++) {
220 if (BF->f[j] != Bent_function_table[pos][j]) {
221 break;
222 }
223 }
224 if (j == BF->Q) {
225 f_found = TRUE;
226 break;
227 }
228 }
229
230
231 if (!f_found) {
232
233 cout << " NEW orbit " << nb_orbits << endl;
234
235 BF->compute_polynomial_representation(BF->f, poly, 0 /*verbose_level*/);
236 cout << " : ";
237 BF->Poly[BF->n].print_equation(cout, poly);
238 cout << " : ";
239 //evaluate_projectively(poly, f_proj);
240 BF->evaluate(poly, BF->f_proj);
241 Int_vec_print(cout, BF->f_proj, BF->Q);
242 cout << endl;
243
245
247
249 Orb->print_function = boolean_function_classify_print_function;
250 Orb->print_function_data = this;
251
252 Orb->f_has_reduction = TRUE;
253 Orb->reduction_function = boolean_function_classify_reduction_function;
254 Orb->reduction_function_data = this;
255
256 cout << "orbit " << nb_orbits << ", computing orbit of bent function:" << endl;
257 Orb->init(A, BF->Fq,
258 AonHPD,
259 SG /* A->Strong_gens*/, poly,
260 0 /*verbose_level*/);
261 cout << "found an orbit of length " << Orb->used_length << endl;
262
263 groups::strong_generators *Stab_gens;
264
265 cout << "orbit " << nb_orbits << ", computing stabilizer:" << endl;
266 Stab_gens = Orb->stabilizer_orbit_rep(
267 go, verbose_level);
268 Stab_gens->print_generators_tex(cout);
269
270 orbit_first.push_back(Bent_function_table.size());
271 orbit_length.push_back(Orb->used_length);
272
273 int *coeff;
274
275 for (i = 0; i < Orb->used_length; i++) {
276 coeff = Orb->Equations[i] + 1;
277 BF->evaluate(coeff, BF->f_proj);
278 vector<int> v;
279 for (j = 0; j < BF->Q; j++) {
280 v.push_back(BF->f_proj[j]);
281 }
282 vector<int> w;
283 for (j = 0; j < BF->Poly[BF->n].get_nb_monomials(); j++) {
284 w.push_back(Orb->Equations[i][1 + j]);
285 }
286
287 h = Data.int_vec_hash(BF->f_proj, BF->Q);
288 Hashing.insert(pair<uint32_t, int>(h, Bent_function_table.size()));
289
290 Bent_function_table.push_back(v);
291 Equation_table.push_back(w);
292 }
293
294 //int idx = 3;
295 int idx = 0;
296
297 if (BF->n == 4) {
298 if (nb_orbits == 0) {
299 idx = 12;
300 }
301 else if (nb_orbits == 1) {
302 idx = 180;
303 }
304 }
305
306 if (Orb->used_length > idx) {
307 cout << "orbit " << nb_orbits << ", computing stabilizer of element " << idx << endl;
308
309 coeff = Orb->Equations[idx] + 1;
310 BF->evaluate(coeff, BF->f_proj);
311 cout << "orbit " << nb_orbits << ", function: ";
312 Int_vec_print(cout, BF->f_proj, BF->Q);
313 cout << endl;
314 cout << "orbit " << nb_orbits << ", equation: ";
315 Int_vec_print(cout, coeff, BF->Poly[BF->n].get_nb_monomials());
316 cout << endl;
317
318 groups::strong_generators *Stab_gens_clean;
319
320
321 Stab_gens_clean = Orb->stabilizer_any_point(
322 go, idx,
323 verbose_level);
324 Stab_gens_clean->print_generators_tex(cout);
325 cout << "orbit " << nb_orbits << ", induced action:" << endl;
326 Stab_gens_clean->print_with_given_action(
327 cout, A_affine);
328
329 FREE_OBJECT(Stab_gens_clean);
330 }
331
332 FREE_OBJECT(Stab_gens);
333 FREE_OBJECT(Orb);
334
335 nb_orbits++;
336
337 }
338 else {
339 cout << "The bent function has been found earlier already" << endl;
340 }
341 }
342 else {
343 cout << endl;
344 }
345 a.increment();
346 cout << "after increment: a=" << a << endl;
347 }
348 cout << "We found " << nb_sol << " bent functions" << endl;
349 cout << "We have " << Bent_function_table.size() << " bent functions in the table" << endl;
350 cout << "They fall into " << orbit_first.size() << " orbits:" << endl;
351
352 int fst, len, t;
353
354 for (h = 0; h < orbit_first.size(); h++) {
355 fst = orbit_first[h];
356 len = orbit_length[h];
357 cout << "Orbit " << h << " / " << orbit_first.size() << " has length " << len << ":" << endl;
358 for (t = 0; t < len; t++) {
359 i = fst + t;
360 cout << i << " : " << t << " / " << len << " : ";
361 for (j = 0; j < BF->Q; j++) {
362 BF->f[j] = Bent_function_table[i][j];
363 }
364 for (j = 0; j < BF->Poly[BF->n].get_nb_monomials(); j++) {
365 poly[j] = Equation_table[i][j];
366 }
367
368 Int_vec_copy(BF->f, BF->f2, BF->Q);
369 Gg.AG_element_rank_longinteger(2, BF->f2, 1, BF->Q, a);
370
371 Int_vec_print(cout, BF->f, BF->Q);
372 cout << " : " << a << " : ";
373 Int_vec_print(cout, poly, BF->Poly[BF->n].get_nb_monomials());
374 cout << " : ";
375 BF->Poly[BF->n].print_equation(cout, poly);
376 cout << endl;
377 }
378 }
379#if 0
380 for (i = 0; i < Bent_function_table.size(); i++) {
381 cout << i << " : ";
382 for (j = 0; j < Q; j++) {
383 f[j] = Bent_function_table[i][j];
384 }
385 for (j = 0; j < Poly[n].get_nb_monomials(); j++) {
386 poly[j] = Equation_table[i][j];
387 }
388 int_vec_print(cout, f, Q);
389 cout << " : ";
390 int_vec_print(cout, poly, Poly[n].get_nb_monomials());
391 cout << " : ";
392 Poly[n].print_equation(cout, poly);
393 cout << endl;
394 }
395#endif
396
397
398
399 for (h = 0; h < orbit_first.size(); h++) {
400 cout << "orbit " << h << " / " << orbit_first.size() << " has length " << orbit_length[h] << endl;
401 }
402
403 FREE_int(poly);
404
405 if (f_v) {
406 cout << "boolean_function_classify::search_for_bent_functions done" << endl;
407 }
408}
409
410
411
412static void boolean_function_classify_print_function(int *poly, int sz, void *data)
413{
417
418 BFC->BF->evaluate(poly + 1, BFC->BF->f_proj);
419 Int_vec_copy(BFC->BF->f_proj, BFC->BF->f_proj2, BFC->BF->Q);
420 Gg.AG_element_rank_longinteger(2, BFC->BF->f_proj2, 1, BFC->BF->Q, a);
421
422 cout << " : ";
423 Int_vec_print(cout, BFC->BF->f_proj, BFC->BF->Q);
424 cout << " : rk=" << a;
425
426}
427
428static void boolean_function_classify_reduction_function(int *poly, void *data)
429{
430 boolean_function_classify *BFC = (boolean_function_classify *) data;
431
432 if (BFC->BF->dim_kernel) {
433 int i, i1, i2;
434 int a, ma;
435
436 for (i = 0; i < BFC->BF->dim_kernel; i++) {
437 i1 = BFC->BF->Kernel[i * 2 + 0];
438 i2 = BFC->BF->Kernel[i * 2 + 1];
439 a = poly[i1];
440 if (a) {
441 ma = BFC->BF->Fq->negate(a);
442 poly[i1] = 0;
443 poly[i2] = BFC->BF->Fq->add(poly[i2], ma);
444 }
445
446 }
447 }
448#if 0
449 // c_0 = c_4:
450 a = poly[0];
451 if (a) {
452 ma = BFC->Fq->negate(a);
453 poly[0] = 0;
454 poly[4] = BFC->Fq->add(poly[4], ma);
455 }
456 // c_1 = c_5:
457 a = poly[1];
458 if (a) {
459 ma = BFC->Fq->negate(a);
460 poly[1] = 0;
461 poly[5] = BFC->Fq->add(poly[5], ma);
462 }
463#endif
464 //BFC->evaluate(poly + 1, BFC->f_proj);
465 //int_vec_print(cout, BFC->f_proj, BFC->Q);
466
467}
468
469
470
471}}}
472
473
ring_theory::homogeneous_polynomial_domain * Poly
Definition: combinatorics.h:43
void compute_polynomial_representation(int *func, int *coeff, int verbose_level)
a catch-all container class for everything related to data structures
various functions related to geometries
Definition: geometry.h:721
void AG_element_rank_longinteger(int q, int *v, int stride, int len, ring_theory::longinteger_object &a)
void AG_element_unrank_longinteger(int q, int *v, int stride, int len, ring_theory::longinteger_object &a)
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
int is_less_than(longinteger_object &a, longinteger_object &b)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
a permutation group in a fixed action.
Definition: actions.h:99
action * restricted_action(long int *points, int nb_points, int verbose_level)
void init_projective_group(int n, field_theory::finite_field *F, int f_semilinear, int f_basis, int f_init_sims, data_structures_groups::vector_ge *&nice_gens, int verbose_level)
groups::matrix_group * get_matrix_group()
Definition: action.cpp:2986
a matrix group over a finite field in projective, vector space or affine action
Definition: groups.h:318
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
void generators_for_parabolic_subgroup(actions::action *A_PGL_n_q, matrix_group *Mtx, int k, int verbose_level)
void print_with_given_action(std::ostream &ost, actions::action *A2)
void init_transposed_group(strong_generators *SG, int verbose_level)
void group_order(ring_theory::longinteger_object &go)
induced action on the set of homogeneous polynomials over a finite field
void init(actions::action *A, ring_theory::homogeneous_polynomial_domain *HPD, int verbose_level)
orbit of homogeneous equations using a Schreier tree
Definition: orbits.h:30
groups::strong_generators * stabilizer_orbit_rep(ring_theory::longinteger_object &full_group_order, int verbose_level)
void(* print_function)(int *object, int sz, void *print_function_data)
Definition: orbits.h:49
groups::strong_generators * stabilizer_any_point(ring_theory::longinteger_object &full_group_order, int idx, int verbose_level)
void(* reduction_function)(int *object, void *reduction_function_data)
Definition: orbits.h:53
void init(actions::action *A, field_theory::finite_field *F, induced_actions::action_on_homogeneous_polynomials *AonHPD, groups::strong_generators *SG, int *coeff_in, int verbose_level)
void init_group(combinatorics::boolean_function_domain *BF, int verbose_level)
induced_actions::action_on_homogeneous_polynomials * AonHPD
#define FREE_int(p)
Definition: foundations.h:640
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
the orbiter library for the classification of combinatorial objects