Orbiter 2022
Combinatorial Objects
upstep_work_subspace_action.cpp
Go to the documentation of this file.
1// upstep_work_subspace_action.cpp
2//
3// Anton Betten
4// March 10, 2010
5// moved here: June 28, 2014
6
7
9#include "discreta/discreta.h"
12
13using namespace std;
14
15namespace orbiter {
16namespace layer4_classification {
17namespace poset_classification {
18
19
21// This routine is called from upstep_work::init_extension_node
22// It computes coset_table.
23// It is testing a set of size 'size'.
24// The newly added point is in gen->S[size - 1]
25// The extension is initiated from node 'prev'
26// and from extension 'prev_ex'
27// The node 'prev' is at depth 'size' - 1
28// returns FALSE if the set is not canonical
29// (provided f_indicate_not_canonicals is TRUE)
30{
31 //if (prev == 1) verbose_level += 20;
32
33 int f_v = (verbose_level >= 1);
34 int f_vv = (verbose_level >= 5);
35 int f_vvv = (verbose_level >= 6);
36 //int f_v4 = (verbose_level >= 7);
37 int f_v5 = (verbose_level >= 8);
38 groups::schreier up_orbit;
40 int *aut;
42 int final_node, final_ex;
43
44 //wreath_product *W;
47 {
50 {
51 actions::action A_on_hyperplanes;
52 int big_n, n, k, rk, degree, idx;
53 int *ambient_space; // [n * big_n]
54 int *base_change_matrix; // [n * n]
55 int *base_cols; // [n]
56 int *embedding; // [n]
57 int *changed_space; // [n * big_n]
58
60
61
62 O_cur->store_set(gen, size - 1);
63 // stores a set of size 'size' to gen->S
64 if (f_v) {
66 cout << "upstep_work::upstep_subspace_action "
67 "upstep in subspace action for set ";
69 cout << " verbose_level=" << verbose_level;
70 cout << " f_indicate_not_canonicals="
72 //cout << endl;
73 }
74
75 if (!gen->get_A2()->f_is_linear) {
76 cout << "upstep_work::upstep_subspace_action "
77 "action is not linear" << endl;
78 exit(1);
79 }
80#if 0
81 if (gen->get_A2()->type_G == matrix_group_t) {
82 M = gen->get_A2()->G.matrix_grp;
83 F = M->GFq;
84 }
85 else {
86 action *sub = gen->get_A2()->subaction;
87 if (sub->type_G == wreath_product_t) {
88 W = sub->G.wreath_product_group;
89 F = W->F;
90 }
91 else {
92 M = sub->G.matrix_grp;
93 F = M->GFq;
94 }
95 }
96#else
97 M = gen->get_A2()->get_matrix_group();
98 F = M->GFq;
99#endif
100
101
102
103#if 1
106 // we need the small field because we work
107 // in the large vector space over the small field.
108 }
109#endif
110 big_n = gen->get_VS()->dimension;
111 n = size;
112 k = size - 1;
113 if (f_vv) {
114 cout << "big_n=" << big_n << endl;
115 cout << "n=" << n << endl;
116 cout << "k=" << k << endl;
117 }
118 ambient_space = NEW_int(n * big_n);
119 base_change_matrix = NEW_int(n * n);
120 base_cols = NEW_int(n);
121 embedding = NEW_int(n);
122 changed_space = NEW_int(n * big_n);
123
124 gen->unrank_basis(ambient_space, gen->get_S(), n);
125
126 if (f_vv) {
127 cout << "upstep_work::upstep_subspace_action "
128 "ambient space:" << endl;
129
130 Int_vec_print_integer_matrix_width(cout, ambient_space,
131 n, big_n, big_n, F->log10_of_q);
132
133 cout << "setting up grassmannian n=" << n
134 << " k=" << k << " q=" << F->q << endl;
135 }
136 G.init(n, k, F, 0 /*verbose_level - 1*/);
137 if (f_vv) {
138 cout << "upstep_work::upstep_subspace_action "
139 "grassmann initialized" << endl;
140 cout << "upstep_work::upstep_subspace_action "
141 "setting up action_on_grassmannian:" << endl;
142 }
143 AG->init(*gen->get_A2(), &G, verbose_level - 2);
144 if (f_vv) {
145 cout << "upstep_work::upstep_subspace_action "
146 "after AG.init" << endl;
147 }
148 AG->init_embedding(big_n, ambient_space, verbose_level - 8);
149 if (f_vv) {
150 cout << "upstep_work::upstep_subspace_action "
151 "after AG.init_embedding, big_n=" << big_n << endl;
152 }
153
154 if (f_vv) {
155 cout << "upstep_work::upstep_subspace_action "
156 "AG->GE->degree = " << AG->GE->degree << endl;
157 cout << "upstep_work::upstep_subspace_action "
158 "before induced_action_on_grassmannian" << endl;
159 }
160
161
162 A_on_hyperplanes.induced_action_on_grassmannian(
163 gen->get_A2(),
164 AG,
165 FALSE /* f_induce_action*/,
166 NULL /*sims *old_G*/,
167 verbose_level - 3);
168 if (f_vv) {
169 cout << "upstep_work::upstep_subspace_action "
170 "after A_on_hyperplanes->induced_action_on_grassmannian"
171 << endl;
172 }
173 degree = A_on_hyperplanes.degree;
174 if (f_vv) {
175 cout << "upstep_work::upstep_subspace_action "
176 "The action on hyperplanes has degree = "
177 << degree << endl;
178 }
179 if (degree != AG->GE->degree) {
180 cout << "upstep_work::upstep_subspace_action "
181 "degree != AG->GE->degree" << endl;
182 exit(1);
183 }
184
185 up_orbit.init(&A_on_hyperplanes, verbose_level - 2);
186 up_orbit.init_generators(*H->SG, verbose_level - 2);
187 if (f_vvv) {
188 cout << "upstep_work::upstep_subspace_action "
189 "generators for H:" << endl;
191
192#if 1
193 cout << "generators in the action on hyperplanes:" << endl;
195 cout,
196 &A_on_hyperplanes,
197 verbose_level - 2);
198#endif
199
200 }
201 if (f_vv) {
202 cout << "upstep_work::upstep_subspace_action "
203 "computing initial orbits of hyperplane action:"
204 << endl;
205 }
206 up_orbit.compute_point_orbit(
207 0 /* the initial hyperplane */,
208 verbose_level);
209 // computes the orbits of the group H
210 // up_orbit will be extended as soon
211 // as n e w automorphisms are found
212 if (f_vv) {
213 cout << "upstep_work::upstep_subspace_action "
214 "computing initial orbits of hyperplane action done"
215 << endl;
216 }
217 if (f_vv) {
218 cout << "upstep_work::upstep_subspace_action "
219 "the initial orbits on hyperplanes are:" << endl;
220 up_orbit.print_and_list_orbits(cout);
221 }
222
223 if (f_vv) {
224 cout << "upstep_work::upstep_subspace_action "
225 "initializing union_find:" << endl;
226 }
227 UF.init(&A_on_hyperplanes, verbose_level - 8);
228 UF.add_generators(H->SG, 0 /*verbose_level - 8 */);
229 if (f_vv) {
230 cout << "upstep_work::upstep_subspace_action "
231 "initializing union_find done" << endl;
232 }
233 if (f_vvv) {
234 UF.print();
235 }
236
237 if (f_vv) {
238 cout << "upstep_work::upstep_subspace_action "
239 "we will now loop over the " << degree
240 << " cosets of the hyperplane stabilizer:" << endl;
241 }
242
244 nb_cosets = degree;
246
247 for (coset = 0; coset < degree; coset++) {
248
249 if (f_vv) {
251 cout << " upstep_work::upstep_subspace_action coset "
252 << coset << " / " << degree << endl;
253 }
254 idx = UF.ancestor(coset);
255 if (idx < coset) {
256 //gen->nb_times_trace_was_saved++;
257 if (f_vv) {
258 cout << "upstep_work::upstep_subspace_action coset "
259 << coset << " / " << degree << " is at " << idx
260 << " which has already been done, "
261 "so we save one trace" << endl;
262 }
263 continue;
264 }
265#if 0
266 idx = up_orbit.orbit_inv[coset];
267 if (idx < up_orbit.orbit_len[0]) {
268 if (f_v) {
269 cout << "upstep_work::upstep_subspace_action "
270 "coset " << coset << " is at " << idx
271 << " which is part of the current orbit, "
272 "so we save one trace" << endl;
273 }
274 continue;
275 }
276#endif
277
278 // for all the previous (=old) points
279 if (f_vv) {
281 cout << endl;
282 }
283 if (f_vvv) {
284 cout << "upstep_work::upstep_subspace_action "
285 "unranking " << coset << ":" << endl;
286 }
287 G.unrank_lint(coset, 0 /*verbose_level - 5*/);
288 Int_vec_copy(G.M, base_change_matrix, k * n);
289
290 if (f_vvv) {
291 cout << "upstep_work::upstep_subspace_action "
292 "base_change_matrix (hyperplane part) for coset "
293 << coset << ":" << endl;
295 base_change_matrix,
296 k, n, n, F->log10_of_q);
297 }
299 k, n,
300 base_change_matrix,
301 base_cols,
302 embedding,
303 0/*verbose_level*/);
304 if (rk != k) {
305 cout << "rk != k" << endl;
306 exit(1);
307 }
308 if (f_v5) {
309 cout << "upstep_work::upstep_subspace_action base_cols:";
310 Int_vec_print(cout, base_cols, rk);
311 cout << " embedding:";
312 Int_vec_print(cout, embedding, n - rk);
313 cout << endl;
314 }
315
316 // fill the matrix up and make it invertible:
317 Int_vec_zero(base_change_matrix + (n - 1) * n, n);
318 base_change_matrix[(n - 1) * n + embedding[0]] = 1;
319
320 if (f_v5) {
321 cout << "upstep_work::upstep_subspace_action "
322 "extended base_change_matrix (hyperplane part) "
323 "for coset " << coset << ":" << endl;
325 base_change_matrix,
326 n, n, n, F->log10_of_q);
327 }
328 if (f_v5) {
329 cout << "upstep_work::upstep_subspace_action "
330 "AG->GE->M:" << endl;
332 AG->GE->M, n, big_n, big_n, F->log10_of_q);
333 }
334
335
336 // now base_change_matrix is invertible
338 base_change_matrix, base_cols, embedding,
339 0/*verbose_level*/);
340 if (rk != n) {
341 cout << "upstep_work::upstep_subspace_action "
342 "rk != n" << endl;
343 exit(1);
344 }
346 base_change_matrix,
347 AG->GE->M,
348 changed_space,
349 n, n, big_n,
350 0 /* verbose_level */);
351 if (f_v5) {
352 cout << "upstep_work::upstep_subspace_action "
353 "changed_space for coset " << coset << ":" << endl;
355 changed_space,
356 n, big_n, big_n, F->log10_of_q);
357 }
358
359 // initialize set[0] for the tracing
360 // (keep gen->S as it is):
361 gen->rank_basis(changed_space, gen->get_set_i(0), n);
362
363 if (f_vvv) {
364 cout << "upstep_work::upstep_subspace_action "
365 "changed_space for coset " << coset
366 << " as rank vector: ";
367 Lint_vec_print(cout, gen->get_set_i(0), n);
368 cout << endl;
369 }
370
371
372 // initialize transporter[0] for the tracing
374
375
376 if (f_vv) {
378 cout << "upstep_work::upstep_subspace_action exchanged set: ";
380 cout << endl;
381 cout << "upstep_work::upstep_subspace_action "
382 "calling recognize" << endl;
383 }
384
385#if 0
386 if (prev == 1 && prev_ex == 1) {
387 verbose_level += 20;
388 }
389#endif
390
391 int nb_times_image_of_called0 = gen->get_A()->ptr->nb_times_image_of_called;
392 int nb_times_mult_called0 = gen->get_A()->ptr->nb_times_mult_called;
393 int nb_times_invert_called0 = gen->get_A()->ptr->nb_times_invert_called;
394 int nb_times_retrieve_called0 = gen->get_A()->ptr->nb_times_retrieve_called;
395
396
397 if (f_vv) {
399 cout << " upstep_work::upstep_subspace_action coset "
400 << coset << " / " << degree
401 << " before recognize " << endl;
402 }
403
404 r = recognize(
405 final_node, final_ex,
406 TRUE /* f_tolerant */,
407 verbose_level - 1);
408 // upstep_work_trace.cpp
409 // gen->set[0] is the set we want to trace
410 // gen->transporter->ith(0) is the identity
411
412
413 if (f_vv) {
415 cout << " upstep_work::upstep_subspace_action coset "
416 << coset << " / " << degree
417 << " after recognize " << endl;
418 }
419
420
426 gen->get_A()->ptr->nb_times_image_of_called - nb_times_image_of_called0;
428 gen->get_A()->ptr->nb_times_mult_called - nb_times_mult_called0;
430 gen->get_A()->ptr->nb_times_invert_called - nb_times_invert_called0;
432 gen->get_A()->ptr->nb_times_retrieve_called - nb_times_retrieve_called0;
434
435 if (f_v) {
437 cout << "upstep_work::upstep_subspace_action calling "
438 "find_automorphism returns "
439 << trace_result_as_text(r) << endl;
440 }
441
442
443 if (r == found_automorphism) {
444 aut = gen->get_transporter()->ith(size);
445 if (f_v) {
447 cout << "upstep_work::upstep_subspace_action "
448 "found automorphism in coset " << coset << endl;
449 if (coset > 0 &&
450 TRUE /*gen->f_allowed_to_show_group_elements*/
451 && f_v) {
452 gen->get_A()->element_print_quick(aut, cout);
453 cout << endl;
454#if 0
455 cout << "in the action " << gen->A2->label
456 << ":" << endl;
457 gen->A2->element_print_as_permutation(aut, cout);
458#endif
459 cout << "in the action "
460 << A_on_hyperplanes.label
461 << " on the hyperplanes:" << endl;
463 aut,
464 cout, 0/*verbose_level - 5*/);
465 }
466 }
467#if 0
468 if (A_on_hyperplanes.element_image_of(coset,
469 aut, FALSE) != 0) {
470 cout << "upstep_work::upstep_subspace_action fatal: "
471 "automorphism does not map " << coset
472 << " to 0 as it should" << endl;
473 exit(1);
474 }
475#endif
476
477 UF.add_generator(aut, 0 /*verbose_level - 5*/);
478 up_orbit.extend_orbit(aut, verbose_level - 8);
479 if (f_vv) {
480 cout << "upstep_work::upstep_subspace_action "
481 "n e w orbit length upstep = "
482 << up_orbit.orbit_len[0] << endl;
483 }
484 }
485 else if (r == not_canonical) {
487 if (f_vvv) {
488 cout << "upstep_work::upstep_subspace_action "
489 "not canonical" << endl;
490 }
491 return FALSE;
492 }
493 cout << "upstep_work::upstep_subspace_action: "
494 "recognize returns not_canonical, "
495 "this should not happen" << endl;
496 exit(1);
497 }
498 else if (r == no_result_extension_not_found) {
499 if (f_vvv) {
500 cout << "upstep_work::upstep_subspace_action "
501 "no_result_extension_not_found" << endl;
502 }
503 cout << "upstep_work::upstep_subspace_action "
504 "fatal: no_result_extension_not_found" << endl;
505 exit(1);
506 }
507 else if (r == no_result_fusion_node_installed) {
508 if (f_vvv) {
509 cout << "upstep_work::upstep_subspace_action "
510 "no_result_fusion_node_installed" << endl;
511 }
512 }
514 if (f_vvv) {
515 cout << "upstep_work::upstep_subspace_action "
516 "no_result_fusion_node_already_installed" << endl;
517 }
518 }
519 } // next coset
520
521
522 if (f_v) {
524 cout << "upstep_work::upstep_subspace_action "
525 "upstep orbit length for set ";
527 cout << " is " << up_orbit.orbit_len[0] << endl;
528 }
529
530 if (f_vv) {
531 cout << "upstep_work::upstep_subspace_action "
532 "the final orbits on hyperplanes are:" << endl;
533 up_orbit.print_and_list_orbits(cout);
534 }
535
536
537
540 int *tl_extension = NEW_int(gen->get_A()->base_len());
541 int f_OK;
542 int f_tolerant = FALSE;
543
544#if 0
545 if (cur == 26) {
546 cout << "upstep_work::upstep_subspace_action "
547 "node " << cur << ":" << endl;
548 }
549#endif
550 if (f_vv) {
551 cout << "upstep_work::upstep_subspace_action "
552 "before H->S->transitive_extension_tolerant"
553 << endl;
554 }
556 up_orbit, SG_extension,
557 tl_extension,
558 f_tolerant,
559 0 /*verbose_level - 8*/);
560 if (f_vv) {
561 cout << "upstep_work::upstep_subspace_action "
562 "after H->S->transitive_extension_tolerant"
563 << endl;
564 }
565 if (!f_OK) {
566 cout << "upstep_work::upstep_subspace_action "
567 "overshooting the group order" << endl;
568 }
570 H->init_strong_generators(SG_extension, tl_extension, verbose_level - 2);
571
572
573 FREE_int(tl_extension);
574 }
575
576 FREE_int(ambient_space);
577 FREE_int(base_change_matrix);
578 FREE_int(base_cols);
579 FREE_int(embedding);
580 FREE_int(changed_space);
581
582 if (f_vv) {
583 cout << "upstep_work::upstep_subspace_action "
584 "before freeing A_on_hyperplanes" << endl;
585 }
586 } // end A_on_hyperplanes
587
588 FREE_OBJECT(AG);
589
590 if (f_vv) {
591 cout << "upstep_work::upstep_subspace_action "
592 "before freeing the rest" << endl;
593 }
594 }
595 if (f_v) {
596 cout << "upstep_work::upstep_subspace_action done" << endl;
597 }
598 return TRUE;
599}
600
601}}}
602
603
604
to rank and unrank subspaces of a fixed dimension in F_q^n
Definition: geometry.h:892
int base_cols_and_embedding(int m, int n, int *A, int *base_cols, int *embedding, int verbose_level)
void mult_matrix_matrix(int *A, int *B, int *C, int m, int n, int o, int verbose_level)
a permutation group in a fixed action.
Definition: actions.h:99
void element_print_quick(void *elt, std::ostream &ost)
Definition: action_cb.cpp:353
void element_print_as_permutation_verbose(void *elt, std::ostream &ost, int verbose_level)
Definition: action_cb.cpp:428
void element_one(void *elt, int verbose_level)
Definition: action_cb.cpp:224
action * induced_action_on_grassmannian(int k, int verbose_level)
groups::matrix_group * get_matrix_group()
Definition: action.cpp:2986
long int element_image_of(long int a, void *elt, int verbose_level)
Definition: action_cb.cpp:198
void init_strong_generators(vector_ge &SG, int *tl, int verbose_level)
void print_strong_generators(std::ostream &ost, int f_print_as_permutation)
void print_strong_generators_with_different_action_verbose(std::ostream &ost, actions::action *A2, int verbose_level)
a union find data structure (used in the poset classification algorithm)
void init(actions::action *A, int verbose_level)
Definition: union_find.cpp:41
void add_generators(vector_ge *gens, int verbose_level)
Definition: union_find.cpp:123
a matrix group over a finite field in projective, vector space or affine action
Definition: groups.h:318
Schreier trees for orbits of groups on points.
Definition: groups.h:839
void extend_orbit(int *elt, int verbose_level)
Definition: schreier.cpp:901
void init_generators(data_structures_groups::vector_ge &generators, int verbose_level)
Definition: schreier.cpp:373
void compute_point_orbit(int pt, int verbose_level)
Definition: schreier.cpp:1256
void init(actions::action *A, int verbose_level)
Definition: schreier.cpp:308
int transitive_extension_tolerant(schreier &O, data_structures_groups::vector_ge &SG, int *tl, int f_tolerant, int verbose_level)
induced action on the grassmannian (subspaces of a fixed dimension of a vectors space)
void init_embedding(int big_n, int *ambient_space, int verbose_level)
void init(actions::action &A, geometry::grassmann *G, int verbose_level)
trace_result recognize(int &final_node, int &final_ex, int f_tolerant, int verbose_level)
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define Int_vec_print_integer_matrix_width(A, B, C, D, E, F)
Definition: foundations.h:691
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#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
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects
a helper class for the poset classification algorithm to build up a coset transversal for the automor...
int coset
int node
int type
int nb_times_invert_called
int nb_times_mult_called
int ex
int nb_times_retrieve_called
int nb_times_image_of_called
induced_actions::action_by_subfield_structure * SubfieldStructure