Orbiter 2022
Combinatorial Objects
generators_symplectic_group.cpp
Go to the documentation of this file.
1// generators_symplectic_group.cpp
2//
3// Anton Betten
4// March 29, 2016
5
6#include "foundations.h"
7
8
9using namespace std;
10
11
12namespace orbiter {
13namespace layer1_foundations {
14namespace algebra {
15
16
17
19{
20 null();
21}
22
24{
25 freeself();
26}
27
29{
30 nb_candidates = NULL;
31 cur_candidate = NULL;
32 candidates = NULL;
33 Mtx = NULL;
34 v = NULL;
35 v2 = NULL;
36 w = NULL;
37 Points = NULL;
38 nb_gens = 0;
39 Data = NULL;
40 transversal_length = NULL;
41}
42
44{
45 int i;
46
47 if (nb_candidates) {
49 }
50 if (cur_candidate) {
52 }
53 if (candidates) {
54 for (i = 0; i < n + 1; i++) {
56 }
58 }
59 if (Mtx) {
61 }
62 if (v) {
63 FREE_int(v);
64 }
65 if (v2) {
66 FREE_int(v2);
67 }
68 if (w) {
69 FREE_int(w);
70 }
71 if (Points) {
73 }
74 if (Data) {
76 }
79 }
80 null();
81}
82
84 int n, int verbose_level)
85{
86 int f_v = (verbose_level >= 1);
87 int i;
90
91 if (f_v) {
92 cout << "generators_symplectic_group::init" << endl;
93 }
96 if (ODD(n)) {
97 cout << "generators_symplectic_group::init "
98 "n must be even" << endl;
99 exit(1);
100 }
101 n_half = n >> 1;
102 q = F->q;
103 qn = NT.i_power_j(q, n);
104 nb_candidates = NEW_int(n + 1);
106 candidates = NEW_pint(n + 1);
107 for (i = 0; i < n + 1; i++) {
108 candidates[i] = NEW_int(qn);
109 }
110
111 Mtx = NEW_int(n * n);
112 v = NEW_int(n);
113 v2 = NEW_int(n);
114 w = NEW_int(n);
115 Points = NEW_int(qn * n);
116 for (i = 0; i < qn; i++) {
117 Gg.AG_element_unrank(q, Points + i * n, 1, n, i);
118 }
119
120 create_first_candidate_set(verbose_level);
121
122 if (f_v) {
123 cout << "first candidate set has size "
124 << nb_candidates[0] << endl;
125 }
126
127 //backtrack_search(0 /* depth */, verbose_level);
128
129
130
131 int first_moved = n;
132 int nb;
133
134 nb_gens = 0;
135 first_moved = n;
137 for (i = 0; i < n; i++) {
138 transversal_length[i] = 1;
139 }
141 transversal_length, first_moved, 0, verbose_level);
142
143 if (f_v) {
144 cout << "We found " << nb_gens << " strong generators" << endl;
145 cout << "transversal_length = ";
147 cout << endl;
148 cout << "group order: ";
149
151
153 cout << endl;
154 }
155
156 Data = NEW_int(nb_gens * n * n);
157
158 nb = 0;
159 first_moved = n;
160 get_strong_generators(Data, nb, first_moved, 0, verbose_level);
161
162 if (nb != nb_gens) {
163 cout << "nb != nb_gens" << endl;
164 exit(1);
165 }
166
167 if (f_v) {
168 cout << "The strong generators are:" << endl;
169 for (i = 0; i < nb_gens; i++) {
170 cout << "generator " << i << " / " << nb_gens << ":" << endl;
171 Int_matrix_print(Data + i * n * n, n, n);
172 }
173 }
174
175
176 if (f_v) {
177 cout << "generators_symplectic_group::init done" << endl;
178 }
179}
180
182 int *transversal_length, int &first_moved, int depth,
183 int verbose_level)
184{
185 //int f_v = (verbose_level >= 1);
186 int a;
187
188 if (depth == n) {
189 //cout << "solution " << nb << endl;
190 //int_matrix_print(Mtx, n, n);
191 if (first_moved < n) {
192 transversal_length[first_moved]++;
193 }
194 nb++;
195 return FALSE;
196 }
197 for (cur_candidate[depth] = 0;
198 cur_candidate[depth] < nb_candidates[depth];
199 cur_candidate[depth]++) {
200 if (cur_candidate[depth] && depth < first_moved) {
201 first_moved = depth;
202 }
203 a = candidates[depth][cur_candidate[depth]];
204 if (FALSE) {
205 cout << "depth " << depth << " " << cur_candidate[depth]
206 << " / " << nb_candidates[depth] << " which is " << a << endl;
207 }
208 Int_vec_copy(Points + a * n, Mtx + depth * n, n);
209 create_next_candidate_set(depth, 0 /* verbose_level */);
210
212 first_moved, depth + 1, verbose_level)
213 && depth > first_moved) {
214 return FALSE;
215 }
216 }
217 return TRUE;
218}
219
221 int &nb, int &first_moved, int depth, int verbose_level)
222{
223 //int f_v = (verbose_level >= 1);
224 int a;
225
226 if (depth == n) {
227 //cout << "solution " << nb << endl;
228 //int_matrix_print(Mtx, n, n);
229 Int_vec_copy(Mtx, Data + nb * n * n, n * n);
230 nb++;
231 return FALSE;
232 }
233 for (cur_candidate[depth] = 0;
234 cur_candidate[depth] < nb_candidates[depth];
235 cur_candidate[depth]++) {
236 if (cur_candidate[depth] && depth < first_moved) {
237 first_moved = depth;
238 }
239 a = candidates[depth][cur_candidate[depth]];
240 if (FALSE) {
241 cout << "depth " << depth << " " << cur_candidate[depth]
242 << " / " << nb_candidates[depth] << " which is " << a << endl;
243 }
244 Int_vec_copy(Points + a * n, Mtx + depth * n, n);
245 create_next_candidate_set(depth, 0 /* verbose_level */);
246
247 if (!get_strong_generators(Data, nb, first_moved,
248 depth + 1, verbose_level) && depth > first_moved) {
249 return FALSE;
250 }
251 }
252 return TRUE;
253}
254
256 int verbose_level)
257{
258 int f_v = (verbose_level >= 1);
259 int i, nb;
260
261 if (f_v) {
262 cout << "generators_symplectic_group::create_first_candidate_set" << endl;
263 }
264 nb = 0;
265 // skip over the zero vector:
266 for (i = 1; i < qn; i++) {
267 candidates[0][nb++] = i;
268 }
269 nb_candidates[0] = nb;
270
271 if (f_v) {
272 cout << "generators_symplectic_group::create_first_candidate_set done" << endl;
273 }
274}
275
277 int level, int verbose_level)
278{
279 int f_v = (verbose_level >= 1);
280 int i, ai, nb;
281
282 if (f_v) {
283 cout << "generators_symplectic_group::create_next_"
284 "candidate_set level=" << level << endl;
285 }
286 nb = 0;
287
288 if (EVEN(level)) {
289
290 Int_vec_copy(Mtx + level * n, v, n);
291
292 for (i = 0; i < nb_candidates[level]; i++) {
293 ai = candidates[level][i];
294 Int_vec_copy(Points + ai * n, w, n);
295 if (dot_product(v, w) == 1) {
296 candidates[level + 1][nb++] = ai;
297 }
298 }
299 }
300 else {
301
302 Int_vec_copy(Mtx + (level - 1) * n, v, n);
303 Int_vec_copy(Mtx + level * n, v2, n);
304
305 for (i = 0; i < nb_candidates[level - 1]; i++) {
306 ai = candidates[level - 1][i];
307 Int_vec_copy(Points + ai * n, w, n);
308 if (dot_product(v, w) == 0 && dot_product(v2, w) == 0) {
309 candidates[level + 1][nb++] = ai;
310 }
311 }
312 }
313 nb_candidates[level + 1] = nb;
314
315 if (f_v) {
316 cout << "generators_symplectic_group::create_next_"
317 "candidate_set done, found " << nb_candidates[level + 1]
318 << " candidates at level " << level + 1 << endl;
319 }
320}
321
322
324{
325 int c;
326 int i;
327
328 c = 0;
329 for (i = 0; i < n_half; i++) {
330 c = F->add(c, F->mult(u1[2 * i + 0], u2[2 * i + 1]));
331 c = F->add(c, F->negate(F->mult(u1[2 * i + 1], u2[2 * i + 0])));
332 }
333 return c;
334}
335
336}}}
337
338
int get_strong_generators(int *Data, int &nb, int &first_moved, int depth, int verbose_level)
void init(field_theory::finite_field *F, int n, int verbose_level)
int count_strong_generators(int &nb, int *transversal_length, int &first_moved, int depth, int verbose_level)
various functions related to geometries
Definition: geometry.h:721
void AG_element_unrank(int q, int *v, int stride, int len, long int a)
void print_longinteger_after_multiplying(std::ostream &ost, int *factors, int len)
#define FREE_int(p)
Definition: foundations.h:640
#define NEW_pint(n)
Definition: foundations.h:627
#define NEW_int(n)
Definition: foundations.h:625
#define Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define EVEN(x)
Definition: foundations.h:221
#define ODD(x)
Definition: foundations.h:222
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_pint(p)
Definition: foundations.h:641
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
the orbiter library for the classification of combinatorial objects