Orbiter 2022
Combinatorial Objects
surface_domain_lines.cpp
Go to the documentation of this file.
1// surface_domain_lines.cpp
2//
3// Anton Betten
4//
5// moved here from surface.cpp: Dec 26, 2018
6//
7//
8//
9//
10
11#include "foundations.h"
12
13
14using namespace std;
15
16
17namespace orbiter {
18namespace layer1_foundations {
19namespace algebraic_geometry {
20
21
22
23void surface_domain::init_Schlaefli(int verbose_level)
24{
25 int f_v = (verbose_level >= 1);
26
27 if (f_v) {
28 cout << "surface_domain::init_Schlaefli" << endl;
29 }
30
32
33 Schlaefli->init(this, verbose_level);
34
35
36 if (f_v) {
37 cout << "surface_domain::init_Schlaefli done" << endl;
38 }
39}
40
41
42
43void surface_domain::unrank_line(int *v, long int rk)
44{
45 Gr->unrank_lint_here(v, rk, 0 /* verbose_level */);
46}
47
48void surface_domain::unrank_lines(int *v, long int *Rk, int nb)
49{
50 int i;
51
52 for (i = 0; i < nb; i++) {
53 Gr->unrank_lint_here(v + i * 8, Rk[i], 0 /* verbose_level */);
54 }
55}
56
58{
59 long int rk;
60
61 rk = Gr->rank_lint_here(v, 0 /* verbose_level */);
62 return rk;
63}
64
66 int len, long int *S,
67 int *coeff, int verbose_level)
68{
69 int f_v = (verbose_level >= 1);
70 int r;
71 int *System;
72 int nb_rows;
73
74 if (f_v) {
75 cout << "surface_domain::build_cubic_surface_from_lines" << endl;
76 }
77
78 if (f_v) {
79 cout << "surface_domain::build_cubic_surface_from_lines before create_system" << endl;
80 }
81 create_system(len, S, System, nb_rows, verbose_level);
82 if (f_v) {
83 cout << "surface_domain::build_cubic_surface_from_lines after create_system" << endl;
84 }
85
86
87 int base_cols[20];
88
89 if (f_v) {
90 cout << "surface_domain::build_cubic_surface_from_lines before F->Gauss_simple" << endl;
91 }
92 r = F->Linear_algebra->Gauss_simple(System, nb_rows, nb_monomials,
93 base_cols, 0 /* verbose_level */);
94 if (f_v) {
95 cout << "surface_domain::build_cubic_surface_from_lines after F->Gauss_simple" << endl;
96 }
97
98 if (FALSE) {
99 cout << "surface_domain::create_system "
100 "The system in RREF:" << endl;
102 }
103 if (f_v) {
104 cout << "surface_domain::create_system "
105 "The system has rank " << r << endl;
106 }
107
108
109 if (r != nb_monomials - 1) {
110 cout << "surface_domain::build_cubic_surface_from_lines "
111 "r != nb_monomials - 1" << endl;
112 cout << "r=" << r << endl;
113 exit(1);
114 }
115
116 int kernel_m, kernel_n;
117
118 if (f_v) {
119 cout << "surface_domain::build_cubic_surface_from_lines before F->matrix_get_kernel" << endl;
120 }
121 F->Linear_algebra->matrix_get_kernel(System, r, nb_monomials, base_cols, r,
122 kernel_m, kernel_n, coeff, 0 /* verbose_level */);
123 if (f_v) {
124 cout << "surface_domain::build_cubic_surface_from_lines after F->matrix_get_kernel" << endl;
125 }
126
127 FREE_int(System);
128
129 //cout << "kernel_m=" << kernel_m << endl;
130 //cout << "kernel_n=" << kernel_n << endl;
131 if (f_v) {
132 cout << "surface_domain::build_cubic_surface_from_lines done" << endl;
133 }
134}
135
136int surface_domain::rank_of_system(int len, long int *S,
137 int verbose_level)
138{
139 int f_v = (verbose_level >= 1);
140 int *System;
141 int nb_rows;
142 int r;
143
144 if (f_v) {
145 cout << "surface_domain::rank_of_system" << endl;
146 }
147 create_system(len, S, System, nb_rows, verbose_level);
148
149
150 int base_cols[20];
151
152 r = F->Linear_algebra->Gauss_simple(System, nb_rows, nb_monomials,
153 base_cols, 0 /* verbose_level */);
154
155
156 FREE_int(System);
157
158 if (f_v) {
159 cout << "surface_domain::rank_of_system done" << endl;
160 }
161
162 return r;
163}
164
165void surface_domain::create_system(int len, long int *S,
166 int *&System, int &nb_rows, int verbose_level)
167{
168 //verbose_level = 1;
169 int f_v = (verbose_level >= 1);
170 long int a;
171 int i, j;
172
173 if (f_v) {
174 cout << "surface_domain::create_system" << endl;
175 }
176 if (f_v) {
177 cout << "surface_domain::create_system len = " << len << endl;
178 }
179
180 vector<long int> Pts;
181 long int *pts_on_line;
182 int *Pt_coords;
183
184
185 pts_on_line = NEW_lint(P->k);
186 //nb_pts = 0;
187 for (i = 0; i < len; i++) {
188 a = S[i];
189
190 if (P->Implementation->Lines) {
191 for (j = 0; j < P->k; j++) {
192 Pts.push_back(P->Implementation->Lines[a * P->k + j]);
193 //pt_list[nb_pts++] = P->Lines[a * P->k + j];
194 }
195 }
196 else {
197 if (f_v) {
198 cout << "surface_domain::create_system before P->create_points_on_line" << endl;
199 }
201 pts_on_line, //pt_list + nb_pts,
202 0 /* verbose_level */);
203 if (f_v) {
204 cout << "surface_domain::create_system after P->create_points_on_line" << endl;
205 }
206 //nb_pts += P->k;
207 for (j = 0; j < P->k; j++) {
208 Pts.push_back(pts_on_line[j]);
209 }
210 }
211 }
212 FREE_lint(pts_on_line);
213
214#if 0
215 if (nb_pts > max_pts) {
216 cout << "surface_domain::create_system "
217 "nb_pts > max_pts" << endl;
218 exit(1);
219 }
220 if (FALSE) {
221 cout << "surface_domain::create_system list of "
222 "covered points by lines:" << endl;
223 lint_matrix_print(pt_list, len, P->k);
224 }
225#endif
226
227 if (f_v) {
228 cout << "surface_domain::create_system list of "
229 "covered points by lines has been created" << endl;
230 }
231
232
233 nb_rows = Pts.size();
234
235 if (f_v) {
236 cout << "surface_domain::create_system nb_rows = " << nb_rows << endl;
237 cout << "surface_domain::create_system n = " << n << endl;
238 }
239 Pt_coords = NEW_int(nb_rows * n);
240
241 for (i = 0; i < nb_rows; i++) {
242 unrank_point(Pt_coords + i * n, Pts[i]);
243 }
244
245 if (f_v && FALSE) {
246 cout << "surface_domain::create_system list of "
247 "covered points in coordinates:" << endl;
249 }
250
251 if (f_v) {
252 cout << "surface_domain::create_system nb_rows = " << nb_rows << endl;
253 }
254
255 System = NEW_int(nb_rows * nb_monomials);
256
257 for (i = 0; i < nb_rows; i++) {
258 for (j = 0; j < nb_monomials; j++) {
259 System[i * nb_monomials + j] = Poly3_4->evaluate_monomial(j, Pt_coords + i * n);
260 }
261 }
262 FREE_int(Pt_coords);
263
264
265 if (f_v) {
266 cout << "surface_domain::create_system "
267 "The system has been created" << endl;
268 }
269 if (f_v && FALSE) {
270 cout << "surface_domain::create_system "
271 "The system:" << endl;
273 }
274
275 if (f_v) {
276 cout << "surface_domain::create_system done" << endl;
277 }
278}
279
281 long int *Lines, int nb_lines,
282 long int *&Intersection_pt,
283 int verbose_level)
284{
285 int f_v = (verbose_level >= 1);
286 int j1, j2, a1, a2, pt;
287
288 if (f_v) {
289 cout << "surface_domain::compute_intersection_points" << endl;
290 }
291 Intersection_pt = NEW_lint(nb_lines * nb_lines);
292 orbiter_kernel_system::Orbiter->Lint_vec->mone(Intersection_pt, nb_lines * nb_lines);
293 for (j1 = 0; j1 < nb_lines; j1++) {
294 a1 = Lines[j1];
295 for (j2 = j1 + 1; j2 < nb_lines; j2++) {
296 a2 = Lines[j2];
297 if (Adj[j1 * nb_lines + j2]) {
298 pt = P->intersection_of_two_lines(a1, a2);
299 Intersection_pt[j1 * nb_lines + j2] = pt;
300 Intersection_pt[j2 * nb_lines + j1] = pt;
301 }
302 }
303 }
304 if (f_v) {
305 cout << "surface_domain::compute_intersection_points done" << endl;
306 }
307}
308
310 long int *Points, int nb_points,
311 long int *Lines, int nb_lines,
312 int *&Intersection_pt, int *&Intersection_pt_idx,
313 int verbose_level)
314{
315 int f_v = (verbose_level >= 1);
316 int j1, j2;
317 long int a1, a2, pt;
318 int idx;
320
321 if (f_v) {
322 cout << "surface_domain::compute_intersection_points_and_indices" << endl;
323 }
324 Intersection_pt = NEW_int(nb_lines * nb_lines);
325 Intersection_pt_idx = NEW_int(nb_lines * nb_lines);
326 orbiter_kernel_system::Orbiter->Int_vec->mone(Intersection_pt, nb_lines * nb_lines);
327 for (j1 = 0; j1 < nb_lines; j1++) {
328 a1 = Lines[j1];
329 for (j2 = j1 + 1; j2 < nb_lines; j2++) {
330 a2 = Lines[j2];
331 if (Adj[j1 * nb_lines + j2]) {
332 pt = P->intersection_of_two_lines(a1, a2);
333 if (!Sorting.lint_vec_search(Points, nb_points,
334 pt, idx, 0)) {
335 cout << "surface_domain::compute_intersection_points_and_indices "
336 "cannot find point in Points" << endl;
337 cout << "Points:";
338 Lint_vec_print_fully(cout, Points, nb_points);
339 cout << endl;
340 cout << "j1=" << j1 << endl;
341 cout << "j2=" << j2 << endl;
342 cout << "a1=" << a1 << endl;
343 cout << "a2=" << a2 << endl;
344 cout << "pt=" << pt << endl;
345 exit(1);
346 }
347 Intersection_pt[j1 * nb_lines + j2] = pt;
348 Intersection_pt[j2 * nb_lines + j1] = pt;
349 Intersection_pt_idx[j1 * nb_lines + j2] = idx;
350 Intersection_pt_idx[j2 * nb_lines + j1] = idx;
351 }
352 }
353 }
354 if (f_v) {
355 cout << "surface_domain::compute_intersection_points_and_indices done" << endl;
356 }
357}
358
360 long int *lines_meet3, long int *lines_skew3,
361 long int *&lines, int &nb_lines,
362 int verbose_level)
363{
364 int f_v = (verbose_level >= 1);
365 long int o_rank[6];
366 int i, j;
367 long int *perp;
368 int perp_sz;
369
370 if (f_v) {
371 cout << "surface_domain::lines_meet3_and_skew3" << endl;
372 cout << "The three lines we will meet are ";
373 Lint_vec_print(cout, lines_meet3, 3);
374 cout << endl;
375 cout << "The three lines we will be skew to are ";
376 Lint_vec_print(cout, lines_skew3, 3);
377 cout << endl;
378 }
379 for (i = 0; i < 3; i++) {
380 o_rank[i] = Klein->line_to_point_on_quadric(
381 lines_meet3[i], 0 /* verbose_level*/);
382 }
383 for (i = 0; i < 3; i++) {
384 o_rank[3 + i] = Klein->line_to_point_on_quadric(
385 lines_skew3[i], 0 /* verbose_level*/);
386 }
387
388 O->perp_of_k_points(o_rank, 3, perp, perp_sz, verbose_level);
389
390 lines = NEW_lint(perp_sz);
391 nb_lines = 0;
392 for (i = 0; i < perp_sz; i++) {
393 for (j = 0; j < 3; j++) {
395 o_rank[3 + j]) == 0) {
396 break;
397 }
398 }
399 if (j == 3) {
400 lines[nb_lines++] = perp[i];
401 }
402 }
403
404 FREE_lint(perp);
405
406 for (i = 0; i < nb_lines; i++) {
407 lines[i] = Klein->point_on_quadric_to_line(lines[i], 0 /* verbose_level*/);
408 }
409
410 if (f_v) {
411 cout << "surface_domain::lines_meet3_and_skew3 done" << endl;
412 }
413}
414
415void surface_domain::perp_of_three_lines(long int *three_lines,
416 long int *&perp, int &perp_sz, int verbose_level)
417{
418 int f_v = (verbose_level >= 1);
419 long int o_rank[3];
420 int i;
421
422 if (f_v) {
423 cout << "surface_domain::perp_of_three_lines" << endl;
424 cout << "The three lines are ";
425 Lint_vec_print(cout, three_lines, 3);
426 cout << endl;
427 }
428 for (i = 0; i < 3; i++) {
429 o_rank[i] = Klein->line_to_point_on_quadric(
430 three_lines[i], 0 /* verbose_level*/);
431 }
432 O->perp_of_k_points(o_rank, 3, perp, perp_sz, verbose_level);
433
434 for (i = 0; i < perp_sz; i++) {
436 perp[i], 0 /* verbose_level*/);
437 }
438
439 if (f_v) {
440 cout << "surface_domain::perp_of_three_lines done" << endl;
441 }
442}
443
445
453 long int *four_lines, long int *trans12,
454 int &perp_sz, int verbose_level)
455{
456 int f_v = (verbose_level >= 1);
457 long int o_rank[4];
458 int i;
459 long int *Perp;
460 int ret = TRUE;
461
462 if (f_v) {
463 cout << "surface_domain::perp_of_four_lines" << endl;
464 cout << "The four lines are ";
465 Lint_vec_print(cout, four_lines, 4);
466 cout << endl;
467 }
468 for (i = 0; i < 4; i++) {
469 o_rank[i] = Klein->line_to_point_on_quadric(
470 four_lines[i], 0 /* verbose_level*/);
471 }
472 //Perp = NEW_int(O->alpha * (O->q + 1));
473 O->perp_of_k_points(o_rank, 4, Perp, perp_sz, verbose_level);
474 if (perp_sz != 2) {
475 if (f_v) {
476 cout << "perp_sz = " << perp_sz << " != 2" << endl;
477 }
478 ret = FALSE;
479 goto finish;
480 }
481
482 trans12[0] = Klein->point_on_quadric_to_line(Perp[0], 0 /* verbose_level*/);
483 trans12[1] = Klein->point_on_quadric_to_line(Perp[1], 0 /* verbose_level*/);
484
485finish:
486 FREE_lint(Perp);
487 if (f_v) {
488 cout << "surface_domain::perp_of_four_lines done" << endl;
489 }
490 return ret;
491}
492
494 long int *four_lines,
495 int verbose_level)
496{
497 int f_v = (verbose_level >= 1);
498 long int o_rank[4];
499 int *coords;
500 int i;
501 long int rk;
502
503 if (f_v) {
504 cout << "surface_domain::rank_of_four_lines_on_Klein_quadric" << endl;
505 cout << "The four lines are ";
506 Lint_vec_print(cout, four_lines, 4);
507 cout << endl;
508 }
509 for (i = 0; i < 4; i++) {
510 o_rank[i] = Klein->line_to_point_on_quadric(
511 four_lines[i], 0 /* verbose_level*/);
512 }
513
514 coords = NEW_int(4 * 6);
515 for (i = 0; i < 4; i++) {
516 O->unrank_point(coords + i * 6, 1,
517 o_rank[i], 0 /* verbose_level */);
518 }
519 rk = F->Linear_algebra->Gauss_easy(coords, 4, 6);
520 FREE_int(coords);
521 if (f_v) {
522 cout << "surface_domain::rank_of_four_lines_on_Klein_quadric done" << endl;
523 }
524 return rk;
525}
526
528
534 long int *five_pts, long int *double_six,
535 int verbose_level)
536{
537 int f_v = (verbose_level >= 1);
538 long int o_rank[12];
539 int i, j;
540 int ret = TRUE;
541
542 if (f_v) {
543 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal" << endl;
544 cout << "The five lines are ";
545 Lint_vec_print(cout, five_pts, 5);
546 cout << endl;
547 }
548 for (i = 0; i < 5; i++) {
549 o_rank[i] = Klein->line_to_point_on_quadric(
550 five_pts[i], 0 /* verbose_level*/);
551 }
552 for (i = 0; i < 5; i++) {
553 for (j = i + 1; j < 5; j++) {
555 o_rank[i], o_rank[j]) == 0) {
556 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal two of the given lines "
557 "intersect, error" << endl;
558 exit(1);
559 }
560 }
561 }
562 if (f_v) {
563 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal" << endl;
564 cout << "The five lines as orthogonal points are ";
565 Lint_vec_print(cout, o_rank, 5);
566 cout << endl;
567 }
568
569 int nb_subsets;
570 int subset[4];
571 long int pts[4];
572 int rk;
573 long int **Perp;
574 int *Perp_sz;
575 long int lines[2];
576 long int opposites[5];
577 long int transversal = 0;
579
580 nb_subsets = Combi.int_n_choose_k(5, 4);
581 Perp = NEW_plint(nb_subsets);
582 Perp_sz = NEW_int(nb_subsets);
583 if (f_v) {
584 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal computing perp of 4-subsets" << endl;
585 }
586 for (rk = 0; rk < nb_subsets; rk++) {
587 Combi.unrank_k_subset(rk, subset, 5, 4);
588 for (i = 0; i < 4; i++) {
589 pts[i] = o_rank[subset[i]];
590 }
591
592 if (f_v) {
593 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal subset " << rk << " / " << nb_subsets << " : " << endl;
594 }
595 O->perp_of_k_points(pts, 4,
596 Perp[rk], Perp_sz[rk], 0/*verbose_level - 1*/);
597 if (FALSE) {
598 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal the perp of the subset ";
599 Int_vec_print(cout, subset, 4);
600 cout << " has size " << Perp_sz[rk] << " : ";
601 Lint_vec_print(cout, Perp[rk], Perp_sz[rk]);
602 cout << endl;
603 }
604 if (Perp_sz[rk] != 2) {
605 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal "
606 "Perp_opp_sz != 2, something is wrong" << endl;
607 cout << "subset " << rk << " / " << nb_subsets << endl;
608 exit(1);
609 ret = FALSE;
610 nb_subsets = rk + 1;
611 goto finish;
612 }
613 if (rk == 0) {
614 Lint_vec_copy(Perp[rk], lines, 2);
615 }
616 else if (rk == 1) {
617 if (lines[0] == Perp[rk][0]) {
618 transversal = lines[0];
619 opposites[0] = lines[1];
620 opposites[1] = Perp[rk][1];
621 }
622 else if (lines[0] == Perp[rk][1]) {
623 transversal = lines[0];
624 opposites[0] = lines[1];
625 opposites[1] = Perp[rk][0];
626 }
627 else if (lines[1] == Perp[rk][0]) {
628 transversal = lines[1];
629 opposites[0] = lines[0];
630 opposites[1] = Perp[rk][1];
631 }
632 else if (lines[1] == Perp[rk][1]) {
633 transversal = lines[1];
634 opposites[0] = lines[0];
635 opposites[1] = Perp[rk][0];
636 }
637 }
638 else {
639 if (transversal == Perp[rk][0]) {
640 opposites[rk] = Perp[rk][1];
641 }
642 else {
643 opposites[rk] = Perp[rk][0];
644 }
645 }
646 }
647 if (FALSE) {
648 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal" << endl;
649 cout << "opposites ";
650 Lint_vec_print(cout, opposites, 5);
651 cout << endl;
652 }
653
654 o_rank[11] = transversal;
655 for (i = 0; i < 5; i++) {
656 o_rank[10 - i] = opposites[i];
657 }
658
659 long int *Perp_opp;
660 int Perp_opp_sz;
661 long int transversal_opp;
662
663 //Perp_opp = NEW_int(O->alpha * (O->q + 1));
664 if (f_v) {
665 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal before O->perp_of_k_points" << endl;
666 }
667 O->perp_of_k_points(opposites, 4, Perp_opp, Perp_opp_sz,
668 0/*verbose_level - 1*/);
669 if (f_v) {
670 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal after O->perp_of_k_points" << endl;
671 }
672 if (FALSE) {
673 cout << "the perp of the opposite subset ";
674 Lint_vec_print(cout, opposites, 4);
675 cout << " has size " << Perp_opp_sz << ":";
676 Lint_vec_print(cout, Perp_opp, Perp_opp_sz);
677 cout << endl;
678 }
679 if (Perp_opp_sz != 2) {
680 ret = FALSE;
681 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal Perp_opp_sz != 2, "
682 "something is wrong" << endl;
683 exit(1);
684 FREE_lint(Perp_opp);
685 goto finish;
686 }
687
688 transversal_opp = -1;
689 if (Perp_opp[0] == o_rank[0]) {
690 transversal_opp = Perp_opp[1];
691 }
692 else if (Perp_opp[1] == o_rank[0]) {
693 transversal_opp = Perp_opp[0];
694 }
695 else {
696 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal something is wrong "
697 "with Perp_opp" << endl;
698 exit(1);
699 }
700
701 o_rank[5] = transversal_opp;
702
703 if (f_v) {
704 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal" << endl;
705 cout << "o_rank ";
706 Lint_vec_print(cout, o_rank, 12);
707 cout << endl;
708 }
709
710 for (i = 0; i < 12; i++) {
711 double_six[i] = Klein->point_on_quadric_to_line(o_rank[i], 0 /* verbose_level*/);
712 }
713 if (f_v) {
714 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal" << endl;
715 cout << "double_six ";
716 Lint_vec_print(cout, double_six, 12);
717 cout << endl;
718 }
719
720
721
722 if (f_v) {
723 for (i = 0; i < 12; i++) {
724 for (j = 0; j < 12; j++) {
726 o_rank[i], o_rank[j]) == 0) {
727 cout << "1";
728 }
729 else {
730 cout << "0";
731 }
732 }
733 cout << endl;
734 }
735 }
736
737
738 FREE_lint(Perp_opp);
739
740finish:
741 for (i = 0; i < nb_subsets; i++) {
742 FREE_lint(Perp[i]);
743 }
744 FREE_plint(Perp);
745 FREE_int(Perp_sz);
746
747 if (f_v) {
748 cout << "surface_domain::create_double_six_from_five_lines_with_a_common_transversal done" << endl;
749 }
750 return ret;
751}
752
754
761 long int *single_six,
762 long int *double_six, int verbose_level)
763{
764 int f_v = (verbose_level >= 1);
765 long int o_rank[12];
766 int i, j;
767 int ret = FALSE;
770
771 if (f_v) {
772 cout << "surface_domain::create_double_six_from_six_disjoint_lines" << endl;
773 }
774 for (i = 0; i < 6; i++) {
775 o_rank[i] = Klein->line_to_point_on_quadric(single_six[i], 0 /* verbose_level*/);
776 }
777
778 for (i = 0; i < 6; i++) {
779 for (j = i + 1; j < 6; j++) {
781 o_rank[i], o_rank[j]) == 0) {
782 cout << "two of the given lines intersect, error" << endl;
783 exit(1);
784 }
785 }
786 }
787
788
789 // compute the perp on the Klein quadric of each of the 6 given lines:
790 long int **Perp_without_pt;
791 int perp_sz = 0;
792 int sz;
793
794 sz = O->alpha * q;
795 Perp_without_pt = NEW_plint(6);
796 for (i = 0; i < 6; i++) {
797 Perp_without_pt[i] = NEW_lint(sz);
798 O->perp(o_rank[i], Perp_without_pt[i], perp_sz,
799 0 /* verbose_level */);
800 if (perp_sz != sz) {
801 cout << "perp_sz != sz" << endl;
802 exit(1);
803 }
804 }
805
806 if (f_v) {
807 cout << "perp_sz=" << perp_sz << endl;
808 for (i = 0; i < 6; i++) {
809 Lint_vec_print(cout, Perp_without_pt[i], perp_sz);
810 cout << endl;
811 }
812 }
813
814
815 // compute the intersection of all perps, five at a time:
816
817 long int **I2;
818 int *I2_sz;
819 long int **I3;
820 int *I3_sz;
821 long int **I4;
822 int *I4_sz;
823 long int **I5;
824 int *I5_sz;
825 long int six2, six3, six4, six5, rk, rk2;
826 int subset[6];
827
828 six2 = Combi.int_n_choose_k(6, 2);
829 I2 = NEW_plint(six2);
830 I2_sz = NEW_int(six2);
831 for (rk = 0; rk < six2; rk++) {
832 Combi.unrank_k_subset(rk, subset, 6, 2);
833 Sorting.vec_intersect(
834 Perp_without_pt[subset[0]],
835 perp_sz,
836 Perp_without_pt[subset[1]],
837 perp_sz,
838 I2[rk], I2_sz[rk]);
839 if (f_v) {
840 cout << "Perp_" << subset[0] << " \\cap Perp_" << subset[1]
841 << " of size " << I2_sz[rk] << " = ";
842 Lint_vec_print(cout, I2[rk], I2_sz[rk]);
843 cout << endl;
844 }
845 }
846 six3 = Combi.int_n_choose_k(6, 3);
847 I3 = NEW_plint(six3);
848 I3_sz = NEW_int(six3);
849 for (rk = 0; rk < six3; rk++) {
850 Combi.unrank_k_subset(rk, subset, 6, 3);
851 rk2 = Combi.rank_k_subset(subset, 6, 2);
852 Combi.unrank_k_subset(rk, subset, 6, 3);
853 Sorting.vec_intersect(I2[rk2], I2_sz[rk2],
854 Perp_without_pt[subset[2]],
855 perp_sz,
856 I3[rk], I3_sz[rk]);
857 if (f_v) {
858 cout << "Perp_" << subset[0] << " \\cap Perp_" << subset[1]
859 << " \\cap Perp_" << subset[2] << " of size "
860 << I3_sz[rk] << " = ";
861 Lint_vec_print(cout, I3[rk], I3_sz[rk]);
862 cout << endl;
863 }
864 }
865
866 six4 = Combi.int_n_choose_k(6, 4);
867 I4 = NEW_plint(six4);
868 I4_sz = NEW_int(six4);
869 for (rk = 0; rk < six4; rk++) {
870 Combi.unrank_k_subset(rk, subset, 6, 4);
871 rk2 = Combi.rank_k_subset(subset, 6, 3);
872 Combi.unrank_k_subset(rk, subset, 6, 4);
873 Sorting.vec_intersect(I3[rk2], I3_sz[rk2],
874 Perp_without_pt[subset[3]], perp_sz,
875 I4[rk], I4_sz[rk]);
876 if (f_v) {
877 cout << rk << " / " << six4 << " : Perp_" << subset[0]
878 << " \\cap Perp_" << subset[1] << " \\cap Perp_"
879 << subset[2] << " \\cap Perp_" << subset[3]
880 << " of size " << I4_sz[rk] << " = ";
881 Lint_vec_print(cout, I4[rk], I4_sz[rk]);
882 cout << endl;
883 }
884 }
885
886 six5 = Combi.int_n_choose_k(6, 5);
887 I5 = NEW_plint(six5);
888 I5_sz = NEW_int(six5);
889 for (rk = 0; rk < six5; rk++) {
890 Combi.unrank_k_subset(rk, subset, 6, 5);
891 rk2 = Combi.rank_k_subset(subset, 6, 4);
892 Combi.unrank_k_subset(rk, subset, 6, 5);
893 Sorting.vec_intersect(I4[rk2], I4_sz[rk2],
894 Perp_without_pt[subset[4]], perp_sz,
895 I5[rk], I5_sz[rk]);
896 if (f_v) {
897 cout << rk << " / " << six5 << " : Perp_" << subset[0]
898 << " \\cap Perp_" << subset[1] << " \\cap Perp_"
899 << subset[2] << " \\cap Perp_" << subset[3]
900 << " \\cap Perp_" << subset[4] << " of size "
901 << I5_sz[rk] << " = ";
902 Lint_vec_print(cout, I5[rk], I5_sz[rk]);
903 cout << endl;
904 }
905
906 if (I5_sz[rk] != 1) {
907 cout << "surface_domain::create_double_six I5_sz[rk] != 1" << endl;
908 ret = FALSE;
909 goto free_it;
910 }
911 }
912 for (i = 0; i < 6; i++) {
913 o_rank[6 + i] = I5[6 - 1 - i][0];
914 }
915 for (i = 0; i < 12; i++) {
916 double_six[i] = Klein->point_on_quadric_to_line(o_rank[i], 0 /* verbose_level*/);
917 }
918
919 ret = TRUE;
920free_it:
921 for (i = 0; i < 6; i++) {
922 FREE_lint(Perp_without_pt[i]);
923 }
924 FREE_plint(Perp_without_pt);
925 //free_pint_all(Perp_without_pt, 6);
926
927
928
929 for (i = 0; i < six2; i++) {
930 FREE_lint(I2[i]);
931 }
932 FREE_plint(I2);
933 //free_pint_all(I2, six2);
934
935 FREE_int(I2_sz);
936
937
938 for (i = 0; i < six3; i++) {
939 FREE_lint(I3[i]);
940 }
941 FREE_plint(I3);
942 //free_pint_all(I3, six3);
943
944 FREE_int(I3_sz);
945
946
947 for (i = 0; i < six4; i++) {
948 FREE_lint(I4[i]);
949 }
950 FREE_plint(I4);
951
952 //free_pint_all(I4, six4);
953
954 FREE_int(I4_sz);
955
956
957 for (i = 0; i < six5; i++) {
958 FREE_lint(I5[i]);
959 }
960 FREE_plint(I5);
961
962 //free_pint_all(I5, six5);
963
964 FREE_int(I5_sz);
965
966
967 if (f_v) {
968 cout << "surface_domain::create_double_six_from_six_disjoint_lines done" << endl;
969 }
970 return ret;
971}
972
974
981 long int *double_six,
982 long int *fifteen_other_lines, int verbose_level)
983{
984 int f_v = (verbose_level >= 1);
985
986 if (f_v) {
987 cout << "surface_domain::create_the_fifteen_other_lines" << endl;
988 }
989 long int *Planes;
990 long int *Lines;
991 int h, k3;
992 int i, j;
993
994 Planes = NEW_lint(30);
995 if (f_v) {
996 cout << "creating the 30 planes:" << endl;
997 }
998 for (h = 0; h < 30; h++) {
999 i = Schlaefli->Labels->Sets[h * 2 + 0];
1000 j = Schlaefli->Labels->Sets[h * 2 + 1];
1001 Gr->unrank_lint_here(Basis0, double_six[i],
1002 0/* verbose_level*/);
1003 Gr->unrank_lint_here(Basis0 + 8, double_six[j],
1004 0/* verbose_level*/);
1005 if (F->Linear_algebra->Gauss_easy(Basis0, 4, 4) != 3) {
1006 cout << "the rank is not 3" << endl;
1007 exit(1);
1008 }
1009 Planes[h] = Gr3->rank_lint_here(Basis0,
1010 0/* verbose_level*/);
1011 if (f_v) {
1012 cout << "plane " << h << " / " << 30
1013 << " has rank " << Planes[h] << " and basis ";
1014 Int_vec_print(cout, Basis0, 12);
1015 cout << endl;
1016 }
1017 }
1018 Lines = NEW_lint(15);
1019 if (f_v) {
1020 cout << "creating the 15 lines:" << endl;
1021 }
1022 for (h = 0; h < 15; h++) {
1023 i = Schlaefli->Labels->Sets2[h * 2 + 0];
1024 j = Schlaefli->Labels->Sets2[h * 2 + 1];
1025 Gr3->unrank_lint_here(Basis1, Planes[i],
1026 0/* verbose_level*/);
1027 Gr3->unrank_lint_here(Basis2, Planes[j],
1028 0/* verbose_level*/);
1030 k3, Basis0, 0 /* verbose_level */);
1031 if (k3 != 2) {
1032 cout << "the rank is not 2" << endl;
1033 exit(1);
1034 }
1035 Lines[h] = Gr->rank_lint_here(Basis0,
1036 0/* verbose_level*/);
1037 for (i = 0; i < 2; i++) {
1039 Basis0 + i * 4, 1, 4);
1040 }
1041 if (f_v) {
1042 cout << "line " << h << " / " << 15
1043 << " has rank " << Lines[h]
1044 << " and basis ";
1045 Int_vec_print(cout, Basis0, 8);
1046 cout << endl;
1047 }
1048 }
1049
1050 Lint_vec_copy(Lines, fifteen_other_lines, 15);
1051
1052
1053 FREE_lint(Planes);
1054 FREE_lint(Lines);
1055
1056 if (f_v) {
1057 cout << "surface_domain::create_the_fifteen_other_lines done" << endl;
1058 }
1059
1060}
1061
1062
1064
1069int surface_domain::test_double_six_property(long int *S12, int verbose_level)
1070{
1071 int f_v = (verbose_level >= 1);
1072 int i, j;
1073 int expect;
1074 int f_fail = FALSE;
1075
1076 if (f_v) {
1077 cout << "surface_domain::test_double_six_property" << endl;
1078 }
1079
1080 int *Adj;
1081
1083 Adj, S12, 12, 0 /*verbose_level*/);
1084
1085
1086 for (i = 0; i < 12; i++) {
1087 for (j = i + 1; j < 12; j++) {
1088 if (i < 6 && j < 6) {
1089 expect = 0;
1090 }
1091 else if (i >= 6 && j >= 6) {
1092 expect = 0;
1093 }
1094 else if (i < 6 && j >= 6) {
1095 if (i == j - 6) {
1096 expect = 0;
1097 }
1098 else {
1099 expect = 1;
1100 }
1101 }
1102 if (Adj[i * 12 + j] != expect) {
1103 cout << "surface_domain::test_double_six_property double six property is "
1104 "violated for " << Schlaefli->Labels->Line_label[i] << " and " << Schlaefli->Labels->Line_label[j] << endl;
1105 f_fail = TRUE;
1106 }
1107 }
1108 }
1109
1110 FREE_int(Adj);
1111
1112 if (f_v) {
1113 cout << "surface_domain::test_double_six_property done" << endl;
1114 }
1115 if (f_fail) {
1116 return FALSE;
1117 }
1118 else {
1119 return TRUE;
1120 }
1121}
1122
1124
1132 int *&Adj, long int *S, int n, int verbose_level)
1133{
1134 int f_v = (verbose_level >= 1);
1135 int i, j;
1136 long int *o_rank;
1137
1138 if (f_v) {
1139 cout << "surface_domain::compute_adjacency_matrix_of_line_intersection_graph" << endl;
1140 }
1141
1142#if 0
1143 if (n > 27) {
1144 cout << "surface_domain::compute_adjacency_matrix_of_line_intersection_graph n > 27" << endl;
1145 exit(1);
1146 }
1147#endif
1148
1149 o_rank = NEW_lint(n);
1150 for (i = 0; i < n; i++) {
1151 o_rank[i] = Klein->line_to_point_on_quadric(S[i], 0 /* verbose_level*/);
1152 }
1153
1154 Adj = NEW_int(n * n);
1155 Int_vec_zero(Adj, n * n);
1156 for (i = 0; i < n; i++) {
1157 for (j = i + 1; j < n; j++) {
1159 o_rank[i], o_rank[j]) == 0) {
1160 Adj[i * n + j] = 1;
1161 Adj[j * n + i] = 1;
1162 }
1163 }
1164 }
1165 FREE_lint(o_rank);
1166 if (f_v) {
1167 cout << "surface_domain::compute_adjacency_matrix_of_line_intersection_graph done" << endl;
1168 }
1169}
1170
1172
1179 int *&Adj, long int *S, int n, int verbose_level)
1180{
1181 int f_v = (verbose_level >= 1);
1182 int i, j;
1183 long int *o_rank;
1184
1185 if (f_v) {
1186 cout << "surface_domain::compute_adjacency_matrix_of_line_disjointness_graph" << endl;
1187 }
1188
1189#if 0
1190 if (n > 27) {
1191 cout << "surface_domain::compute_adjacency_matrix_of_line_disjointness_graph n > 27" << endl;
1192 exit(1);
1193 }
1194#endif
1195
1196 o_rank = NEW_lint(n);
1197 for (i = 0; i < n; i++) {
1198 o_rank[i] = Klein->line_to_point_on_quadric(S[i], 0 /* verbose_level*/);
1199 }
1200
1201 Adj = NEW_int(n * n);
1202 Int_vec_zero(Adj, n * n);
1203 for (i = 0; i < n; i++) {
1204 for (j = i + 1; j < n; j++) {
1206 o_rank[i], o_rank[j]) != 0) {
1207 Adj[i * n + j] = 1;
1208 Adj[j * n + i] = 1;
1209 }
1210 }
1211 }
1212 FREE_lint(o_rank);
1213 if (f_v) {
1214 cout << "surface_domain::compute_adjacency_matrix_of_line_disjointness_graph done" << endl;
1215 }
1216}
1217
1219 long int *Pts_on_surface, int nb_points_on_surface,
1220 long int *Lines, int nb_lines,
1221 data_structures::set_of_sets *&pts_on_lines,
1222 int *&f_is_on_line,
1223 int verbose_level)
1224{
1225 int f_v = (verbose_level >= 1);
1226 int i, j, l, r;
1227 int *Surf_pt_coords;
1228 int Basis[8];
1229 int Mtx[12];
1230
1231 if (f_v) {
1232 cout << "surface_domain::compute_points_on_lines" << endl;
1233 }
1234 f_is_on_line = NEW_int(nb_points_on_surface);
1235 Int_vec_zero(f_is_on_line, nb_points_on_surface);
1236
1238 pts_on_lines->init_basic_constant_size(nb_points_on_surface,
1239 nb_lines, q + 1, 0 /* verbose_level */);
1240 Surf_pt_coords = NEW_int(nb_points_on_surface * 4);
1241 for (i = 0; i < nb_points_on_surface; i++) {
1242 P->unrank_point(Surf_pt_coords + i * 4, Pts_on_surface[i]);
1243 }
1244
1245 orbiter_kernel_system::Orbiter->Lint_vec->zero(pts_on_lines->Set_size, nb_lines);
1246 for (i = 0; i < nb_lines; i++) {
1247 l = Lines[i];
1248 P->unrank_line(Basis, l);
1249 //cout << "Line " << i << " basis=";
1250 //int_vec_print(cout, Basis, 8);
1251 //cout << " : ";
1252 for (j = 0; j < nb_points_on_surface; j++) {
1253 Int_vec_copy(Basis, Mtx, 8);
1254 Int_vec_copy(Surf_pt_coords + j * 4, Mtx + 8, 4);
1255 r = F->Linear_algebra->Gauss_easy(Mtx, 3, 4);
1256 if (r == 2) {
1257 pts_on_lines->add_element(i, j);
1258 f_is_on_line[j] = TRUE;
1259 //cout << j << " ";
1260 }
1261 }
1262 //cout << endl;
1263 }
1264 //cout << "the surface points on the set of " << nb_lines
1265 //<< " lines are:" << endl;
1266 //pts_on_lines->print_table();
1267
1268 FREE_int(Surf_pt_coords);
1269 if (f_v) {
1270 cout << "surface_domain::compute_points_on_lines done" << endl;
1271 }
1272}
1273
1275 long int *&Rk, int &nb_subsets,
1276 long int *lines, int sz, int verbose_level)
1277{
1278 int f_v = (verbose_level >= 1);
1279 int subset[4];
1280 long int four_lines[4];
1281 int i, rk;
1282 int ret = TRUE;
1284
1285 if (f_v) {
1286 cout << "surface_domain::compute_rank_of_any_four" << endl;
1287 }
1288 nb_subsets = Combi.int_n_choose_k(sz, 4);
1289 Rk = NEW_lint(nb_subsets);
1290 for (rk = 0; rk < nb_subsets; rk++) {
1291 Combi.unrank_k_subset(rk, subset, sz, 4);
1292 for (i = 0; i < 4; i++) {
1293 four_lines[i] = lines[subset[i]];
1294 }
1295
1296 if (f_v) {
1297 cout << "testing subset " << rk << " / "
1298 << nb_subsets << " : " << endl;
1299 }
1300
1302 four_lines, 0 /* verbose_level */);
1303 if (Rk[rk] < 4) {
1304 ret = FALSE;
1305 }
1306 }
1307 if (f_v) {
1308 cout << "Ranks:" << endl;
1309 Lint_vec_print(cout, Rk, nb_subsets);
1310 cout << endl;
1311 }
1312 if (f_v) {
1313 cout << "surface_domain::compute_rank_of_any_four done" << endl;
1314 }
1315 return ret;
1316}
1317
1319 int *given_double_six,
1320 long int *New_lines,
1321 int verbose_level)
1322{
1323 int f_v = (verbose_level >= 1);
1324 int *Adj;
1325 int nb_lines = 27;
1326 int i, j, h;
1327
1328 if (f_v) {
1329 cout << "surface_domain::rearrange_lines_according_to_a_given_double_six" << endl;
1330 }
1331 if (f_v) {
1332 cout << "surface_domain::rearrange_lines_according_to_a_given_double_six "
1333 "before compute_adjacency_matrix_of_line_intersection_graph" << endl;
1334 }
1336 Lines, nb_lines, 0 /* verbose_level */);
1337
1338 for (i = 0; i < 12; i++) {
1339 New_lines[i] = Lines[given_double_six[i]];
1340 }
1341
1342
1343 h = 0;
1344 for (i = 0; i < 6; i++) {
1345 for (j = i + 1; j < 6; j++, h++) {
1346 New_lines[12 + h] = compute_cij(New_lines /* double_six */, i, j,
1347 0 /* verbose_level */);
1348 }
1349 }
1350 if (f_v) {
1351 cout << "New_lines:";
1352 Lint_vec_print(cout, New_lines, 27);
1353 cout << endl;
1354 }
1355
1356
1357
1358 if (f_v) {
1359 cout << "surface_domain::rearrange_lines_according_to_a_given_double_six done" << endl;
1360 }
1361}
1362
1364
1369 int verbose_level)
1370{
1371 int f_v = (verbose_level >= 1);
1372 int *Adj;
1373 int nb_lines = 27;
1374 long int New_lines[27];
1375
1376 if (f_v) {
1377 cout << "surface_domain::rearrange_lines_according_to_double_six" << endl;
1378 }
1379 if (f_v) {
1380 cout << "surface_domain::rearrange_lines_according_to_double_six "
1381 "before compute_adjacency_matrix_of_line_"
1382 "intersection_graph" << endl;
1383 }
1385 Lines, nb_lines, 0 /* verbose_level */);
1386
1387
1388 data_structures::set_of_sets *line_intersections;
1389 int *Starter_Table;
1390 int nb_starter;
1391
1392 line_intersections = NEW_OBJECT(data_structures::set_of_sets);
1393
1394 if (f_v) {
1395 cout << "surface_domain::rearrange_lines_according_to_double_six "
1396 "before line_intersections->init_from_adjacency_matrix"
1397 << endl;
1398 }
1399 line_intersections->init_from_adjacency_matrix(nb_lines, Adj,
1400 0 /* verbose_level */);
1401
1402 if (f_v) {
1403 cout << "surface_domain::rearrange_lines_according_to_double_six "
1404 "before list_starter_configurations" << endl;
1405 }
1406 list_starter_configurations(Lines, nb_lines,
1407 line_intersections, Starter_Table, nb_starter,
1408 0 /*verbose_level */);
1409
1410 int l, line_idx, subset_idx;
1411
1412 if (nb_starter == 0) {
1413 cout << "surface_domain::rearrange_lines_according_to_double_six "
1414 "nb_starter == 0" << endl;
1415 exit(1);
1416 }
1417 l = 0;
1418 line_idx = Starter_Table[l * 2 + 0];
1419 subset_idx = Starter_Table[l * 2 + 1];
1420
1421 if (f_v) {
1422 cout << "surface_domain::rearrange_lines_according_to_double_six "
1423 "before rearrange_lines_according_to_starter_"
1424 "configuration" << endl;
1425 }
1427 Lines, New_lines,
1428 line_idx, subset_idx, Adj,
1429 line_intersections, 0 /*verbose_level*/);
1430
1431 Lint_vec_copy(New_lines, Lines, 27);
1432
1433 FREE_int(Adj);
1434 FREE_int(Starter_Table);
1435 FREE_OBJECT(line_intersections);
1436 if (f_v) {
1437 cout << "surface_domain::rearrange_lines_according_"
1438 "to_double_six done" << endl;
1439 }
1440}
1441
1443 long int *Lines, long int *New_lines,
1444 int line_idx, int subset_idx, int *Adj,
1445 data_structures::set_of_sets *line_intersections,
1446 int verbose_level)
1447{
1448 int f_v = (verbose_level >= 1);
1449 long int S3[6];
1450 int i, idx;
1451 int nb_lines = 27;
1453
1454
1455 if (f_v) {
1456 cout << "surface_domain::rearrange_lines_according_to_starter_configuration" << endl;
1457 }
1458
1459 create_starter_configuration(line_idx, subset_idx,
1460 line_intersections, Lines, S3, 0 /* verbose_level */);
1461
1462
1463 if (f_v) {
1464 cout << "line_intersections:" << endl;
1465 line_intersections->print_table();
1466 }
1467
1468 int Line_idx[27];
1469 for (i = 0; i < 6; i++) {
1470 if (!Sorting.lint_vec_search_linear(Lines, nb_lines, S3[i], idx)) {
1471 cout << "could not find the line" << endl;
1472 exit(1);
1473 }
1474 Line_idx[i] = idx;
1475 }
1476
1477 if (f_v) {
1478 cout << "The 5+1 lines are ";
1479 Int_vec_print(cout, Line_idx, 6);
1480 cout << endl;
1481 }
1482
1483 Line_idx[11] = Line_idx[5];
1484 Line_idx[5] = 0;
1485 Lint_vec_zero(New_lines, 27);
1486 Lint_vec_copy(S3, New_lines, 5);
1487 New_lines[11] = S3[5];
1488
1489 if (f_v) {
1490 cout << "computing b_j:" << endl;
1491 }
1492 for (i = 0; i < 5; i++) {
1493 int four_lines[4];
1494
1495 if (f_v) {
1496 cout << i << " / " << 5 << ":" << endl;
1497 }
1498
1499 Int_vec_copy(Line_idx, four_lines, i);
1500 Int_vec_copy(Line_idx + i + 1, four_lines + i, 5 - i - 1);
1501 if (f_v) {
1502 cout << "four_lines=";
1503 Int_vec_print(cout, four_lines, 4);
1504 cout << endl;
1505 }
1506
1507 Line_idx[6 + i] = intersection_of_four_lines_but_not_b6(
1508 Adj, four_lines, Line_idx[11], verbose_level);
1509 if (f_v) {
1510 cout << "b_" << i + 1 << " = "
1511 << Line_idx[6 + i] << endl;
1512 }
1513 }
1514
1515 int five_lines_idx[5];
1516 Int_vec_copy(Line_idx + 6, five_lines_idx, 5);
1517 Line_idx[5] = intersection_of_five_lines(Adj,
1518 five_lines_idx, verbose_level);
1519 if (f_v) {
1520 cout << "a_" << i + 1 << " = "
1521 << Line_idx[5] << endl;
1522 }
1523
1524
1525 long int double_six[12];
1526 int h, j;
1527
1528 for (i = 0; i < 12; i++) {
1529 double_six[i] = Lines[Line_idx[i]];
1530 }
1531 Lint_vec_copy(double_six, New_lines, 12);
1532
1533 h = 0;
1534 for (i = 0; i < 6; i++) {
1535 for (j = i + 1; j < 6; j++, h++) {
1536 New_lines[12 + h] = compute_cij(
1537 double_six, i, j,
1538 0 /* verbose_level */);
1539 }
1540 }
1541 if (f_v) {
1542 cout << "New_lines:";
1543 Lint_vec_print(cout, New_lines, 27);
1544 cout << endl;
1545 }
1546
1547 if (f_v) {
1548 cout << "surface_domain::rearrange_lines_according_to_starter_configuration done" << endl;
1549 }
1550}
1551
1553 int *four_lines_idx, int b6, int verbose_level)
1554{
1555 int f_v = (verbose_level >= 1);
1556 int a, i, j;
1557
1558 if (f_v) {
1559 cout << "surface_domain::intersection_of_four_lines_but_not_b6" << endl;
1560 }
1561 for (i = 0; i < 27; i++) {
1562 if (i == b6) {
1563 continue;
1564 }
1565 for (j = 0; j < 4; j++) {
1566 if (Adj[i * 27 + four_lines_idx[j]] == 0) {
1567 break;
1568 }
1569 }
1570 if (j == 4) {
1571 a = i;
1572 break;
1573 }
1574 }
1575 if (i == 27) {
1576 cout << "surface_domain::intersection_of_four_lines_but_not_b6 could not find the line" << endl;
1577 exit(1);
1578 }
1579
1580 if (f_v) {
1581 cout << "surface_domain::intersection_of_four_lines_but_not_b6 done" << endl;
1582 }
1583 return a;
1584}
1585
1587 int *five_lines_idx, int verbose_level)
1588{
1589 int f_v = (verbose_level >= 1);
1590 int a, i, j;
1591
1592 if (f_v) {
1593 cout << "surface_domain::intersection_of_five_lines" << endl;
1594 }
1595 for (i = 0; i < 27; i++) {
1596 for (j = 0; j < 5; j++) {
1597 if (Adj[i * 27 + five_lines_idx[j]] == 0) {
1598 break;
1599 }
1600 }
1601 if (j == 5) {
1602 a = i;
1603 break;
1604 }
1605 }
1606 if (i == 27) {
1607 cout << "surface_domain::intersection_of_five_lines "
1608 "could not find the line" << endl;
1609 exit(1);
1610 }
1611
1612 if (f_v) {
1613 cout << "surface_domain::intersection_of_five_lines done" << endl;
1614 }
1615 return a;
1616}
1617
1619 long int *Lines,
1620 long int *New_lines, long int *double_six, int verbose_level)
1621{
1622 int f_v = (verbose_level >= 1);
1623 int i, j, h;
1624
1625
1626 if (f_v) {
1627 cout << "surface_domain::rearrange_lines_according_to_a_given_double_six" << endl;
1628 }
1629 for (i = 0; i < 12; i++) {
1630 New_lines[i] = Lines[double_six[i]];
1631 }
1632 h = 0;
1633 for (i = 0; i < 6; i++) {
1634 for (j = i + 1; j < 6; j++, h++) {
1635 New_lines[12 + h] = compute_cij(
1636 New_lines /*double_six */, i, j, 0 /* verbose_level */);
1637 }
1638 }
1639 if (f_v) {
1640 cout << "New_lines:";
1641 Lint_vec_print(cout, New_lines, 27);
1642 cout << endl;
1643 }
1644
1645 if (f_v) {
1646 cout << "surface_domain::rearrange_lines_according_to_a_given_double_six done" << endl;
1647 }
1648}
1649
1651 int *The_plane_equations,
1652 long int *Lines27, int verbose_level)
1653{
1654 int f_v = (verbose_level >= 1);
1655 int line_idx, plane1, plane2;
1656 int Basis[16];
1657
1658 if (f_v) {
1659 cout << "surface_domain::create_lines_from_plane_equations" << endl;
1660 }
1661
1662 for (line_idx = 0; line_idx < 27; line_idx++) {
1664 line_idx, plane1, plane2, 0 /* verbose_level */);
1665 Int_vec_copy(The_plane_equations + plane1 * 4, Basis, 4);
1666 Int_vec_copy(The_plane_equations + plane2 * 4, Basis + 4, 4);
1667 F->Linear_algebra->perp_standard(4, 2, Basis, 0 /* verbose_level */);
1668 Lines27[line_idx] = rank_line(Basis + 8);
1669 }
1670
1671 if (f_v) {
1672 cout << "surface_domain::create_lines_from_plane_equations done" << endl;
1673 }
1674}
1675
1676
1677
1679 long int *double_six, long int *fifteen_lines,
1680 int verbose_level)
1681{
1682 int f_v = (verbose_level >= 1);
1683 int f_vv = (verbose_level >= 2);
1684 int i, j, h;
1685
1686 if (f_v) {
1687 cout << "surface_domain::create_remaining_fifteen_lines" << endl;
1688 }
1689 h = 0;
1690 for (i = 0; i < 6; i++) {
1691 for (j = i + 1; j < 6; j++) {
1692 if (f_vv) {
1693 cout << "surface_domain::create_remaining_fifteen_lines "
1694 "creating line c_ij where i=" << i
1695 << " j=" << j << ":" << endl;
1696 }
1697 fifteen_lines[h++] = compute_cij(double_six, i, j, 0 /*verbose_level*/);
1698 }
1699 }
1700 if (f_v) {
1701 cout << "surface_domain::create_remaining_fifteen_lines done" << endl;
1702 }
1703}
1704
1706
1710long int surface_domain::compute_cij(long int *double_six,
1711 int i, int j, int verbose_level)
1712{
1713 int f_v = (verbose_level >= 1);
1714 long int ai, aj, bi, bj;
1715 int Basis1[16];
1716 int Basis2[16];
1717 int K1[16];
1718 int K2[16];
1719 int K[16];
1720 int base_cols1[4];
1721 int base_cols2[4];
1722 int kernel_m, kernel_n;
1723 long int cij;
1724
1725 if (f_v) {
1726 cout << "surface_domain::compute_cij" << endl;
1727 }
1728 ai = double_six[i];
1729 aj = double_six[j];
1730 bi = double_six[6 + i];
1731 bj = double_six[6 + j];
1732 Gr->unrank_lint_here(Basis1, ai, 0 /* verbose_level */);
1733 Gr->unrank_lint_here(Basis1 + 2 * 4, bj, 0 /* verbose_level */);
1734 Gr->unrank_lint_here(Basis2, aj, 0 /* verbose_level */);
1735 Gr->unrank_lint_here(Basis2 + 2 * 4, bi, 0 /* verbose_level */);
1736 if (F->Linear_algebra->Gauss_simple(Basis1, 4, 4, base_cols1,
1737 0 /* verbose_level */) != 3) {
1738 cout << "The rank of Basis1 is not 3" << endl;
1739 exit(1);
1740 }
1741 if (F->Linear_algebra->Gauss_simple(Basis2, 4, 4, base_cols2,
1742 0 /* verbose_level */) != 3) {
1743 cout << "The rank of Basis2 is not 3" << endl;
1744 exit(1);
1745 }
1746 if (f_v) {
1747 cout << "surface_domain::compute_cij before matrix_get_"
1748 "kernel Basis1" << endl;
1749 }
1750 F->Linear_algebra->matrix_get_kernel(Basis1, 3, 4, base_cols1, 3,
1751 kernel_m, kernel_n, K1, 0 /* verbose_level */);
1752 if (kernel_m != 4) {
1753 cout << "surface_domain::compute_cij kernel_m != 4 "
1754 "when computing K1" << endl;
1755 exit(1);
1756 }
1757 if (kernel_n != 1) {
1758 cout << "surface_domain::compute_cij kernel_1 != 1 "
1759 "when computing K1" << endl;
1760 exit(1);
1761 }
1762 for (j = 0; j < kernel_n; j++) {
1763 for (i = 0; i < 4; i++) {
1764 K[j * 4 + i] = K1[i * kernel_n + j];
1765 }
1766 }
1767 if (f_v) {
1768 cout << "surface_domain::compute_cij before matrix_"
1769 "get_kernel Basis2" << endl;
1770 }
1771 F->Linear_algebra->matrix_get_kernel(Basis2, 3, 4, base_cols2, 3,
1772 kernel_m, kernel_n, K2, 0 /* verbose_level */);
1773 if (kernel_m != 4) {
1774 cout << "surface_domain::compute_cij kernel_m != 4 "
1775 "when computing K2" << endl;
1776 exit(1);
1777 }
1778 if (kernel_n != 1) {
1779 cout << "surface_domain::compute_cij kernel_1 != 1 "
1780 "when computing K2" << endl;
1781 exit(1);
1782 }
1783 for (j = 0; j < kernel_n; j++) {
1784 for (i = 0; i < 4; i++) {
1785 K[(1 + j) * 4 + i] = K2[i * kernel_n + j];
1786 }
1787 }
1788 if (F->Linear_algebra->Gauss_simple(K, 2, 4, base_cols1,
1789 0 /* verbose_level */) != 2) {
1790 cout << "The rank of K is not 2" << endl;
1791 exit(1);
1792 }
1793 if (f_v) {
1794 cout << "surface_domain::compute_cij before "
1795 "matrix_get_kernel K" << endl;
1796 }
1797 F->Linear_algebra->matrix_get_kernel(K, 2, 4, base_cols1, 2,
1798 kernel_m, kernel_n, K1, 0 /* verbose_level */);
1799 if (kernel_m != 4) {
1800 cout << "surface_domain::compute_cij kernel_m != 4 "
1801 "when computing final kernel" << endl;
1802 exit(1);
1803 }
1804 if (kernel_n != 2) {
1805 cout << "surface_domain::compute_cij kernel_n != 2 "
1806 "when computing final kernel" << endl;
1807 exit(1);
1808 }
1809 for (j = 0; j < kernel_n; j++) {
1810 for (i = 0; i < n; i++) {
1811 Basis1[j * n + i] = K1[i * kernel_n + j];
1812 }
1813 }
1814 cij = Gr->rank_lint_here(Basis1, 0 /* verbose_level */);
1815 if (f_v) {
1816 cout << "surface_domain::compute_cij done" << endl;
1817 }
1818 return cij;
1819}
1820
1822 long int *&Trans, int &nb_subsets,
1823 long int *lines, int sz,
1824 int verbose_level)
1825{
1826 int f_v = (verbose_level >= 1);
1827 long int trans12[2];
1828 int subset[4];
1829 long int four_lines[4];
1830 int i, rk, perp_sz;
1831 int ret = TRUE;
1833
1834 if (f_v) {
1835 cout << "surface_domain::compute_transversals_of_any_four" << endl;
1836 }
1837 nb_subsets = Combi.int_n_choose_k(sz, 4);
1838 Trans = NEW_lint(nb_subsets * 2);
1839 for (rk = 0; rk < nb_subsets; rk++) {
1840 Combi.unrank_k_subset(rk, subset, sz, 4);
1841 for (i = 0; i < 4; i++) {
1842 four_lines[i] = lines[subset[i]];
1843 }
1844
1845 if (f_v) {
1846 cout << "testing subset " << rk << " / "
1847 << nb_subsets << " : " << endl;
1848 }
1849 if (!perp_of_four_lines(four_lines, trans12,
1850 perp_sz, 0 /*verbose_level*/)) {
1851
1852 if (f_v) {
1853 cout << "The 4-subset does not lead "
1854 "to two transversal lines: ";
1855 Int_vec_print(cout, subset, 4);
1856 cout << " = ";
1857 Lint_vec_print(cout, four_lines, 4);
1858 cout << " perp_sz=" << perp_sz << endl;
1859 }
1860 ret = FALSE;
1861 //break;
1862 trans12[0] = -1;
1863 trans12[1] = -1;
1864 }
1865 Lint_vec_copy(trans12, Trans + rk * 2, 2);
1866 }
1867 if (f_v) {
1868 cout << "Transversals:" << endl;
1869 Lint_matrix_print(Trans, nb_subsets, 2);
1870 }
1871 if (f_v) {
1872 cout << "surface_domain::compute_transversals_of_any_four done" << endl;
1873 }
1874 return ret;
1875}
1876
1878{
1879 if (strcmp(p, "a1") == 0) {
1880 return 0;
1881 }
1882 else if (strcmp(p, "a2") == 0) {
1883 return 1;
1884 }
1885 else if (strcmp(p, "a3") == 0) {
1886 return 2;
1887 }
1888 else if (strcmp(p, "a4") == 0) {
1889 return 3;
1890 }
1891 else if (strcmp(p, "a5") == 0) {
1892 return 4;
1893 }
1894 else if (strcmp(p, "a6") == 0) {
1895 return 5;
1896 }
1897 else if (strcmp(p, "b1") == 0) {
1898 return 6;
1899 }
1900 else if (strcmp(p, "b2") == 0) {
1901 return 7;
1902 }
1903 else if (strcmp(p, "b3") == 0) {
1904 return 8;
1905 }
1906 else if (strcmp(p, "b4") == 0) {
1907 return 9;
1908 }
1909 else if (strcmp(p, "b5") == 0) {
1910 return 10;
1911 }
1912 else if (strcmp(p, "b6") == 0) {
1913 return 11;
1914 }
1915 else if (strcmp(p, "c12") == 0) {
1916 return 12;
1917 }
1918 else if (strcmp(p, "c13") == 0) {
1919 return 13;
1920 }
1921 else if (strcmp(p, "c14") == 0) {
1922 return 14;
1923 }
1924 else if (strcmp(p, "c15") == 0) {
1925 return 15;
1926 }
1927 else if (strcmp(p, "c16") == 0) {
1928 return 16;
1929 }
1930 else if (strcmp(p, "c23") == 0) {
1931 return 17;
1932 }
1933 else if (strcmp(p, "c24") == 0) {
1934 return 18;
1935 }
1936 else if (strcmp(p, "c25") == 0) {
1937 return 19;
1938 }
1939 else if (strcmp(p, "c26") == 0) {
1940 return 20;
1941 }
1942 else if (strcmp(p, "c34") == 0) {
1943 return 21;
1944 }
1945 else if (strcmp(p, "c35") == 0) {
1946 return 22;
1947 }
1948 else if (strcmp(p, "c36") == 0) {
1949 return 23;
1950 }
1951 else if (strcmp(p, "c45") == 0) {
1952 return 24;
1953 }
1954 else if (strcmp(p, "c46") == 0) {
1955 return 25;
1956 }
1957 else if (strcmp(p, "c56") == 0) {
1958 return 26;
1959 }
1960 else {
1961 cout << "surface_domain::read_schlaefli_label unknown schlaefli label: " << p << endl;
1962 exit(1);
1963 }
1964}
1965
1966void surface_domain::read_string_of_schlaefli_labels(std::string &str, int *&v, int &sz, int verbose_level)
1967{
1968 int f_v = (verbose_level >= 1);
1970 char **argv;
1971 int i;
1972
1973 if (f_v) {
1974 cout << "surface_domain::read_string_of_schlaefli_labels" << endl;
1975 }
1976
1977 ST.chop_string_comma_separated(str.c_str(), sz, argv);
1978
1979 if (f_v) {
1980 cout << "surface_domain::read_string_of_schlaefli_labels reading:" << endl;
1981 for (i = 0; i < sz; i++) {
1982 cout << i << " : " << argv[i] << endl;
1983 }
1984 }
1985
1986 v = NEW_int(sz);
1987 for (i = 0; i < sz; i++) {
1988 v[i] = read_schlaefli_label(argv[i]);
1989 }
1990
1991
1992 if (f_v) {
1993 cout << "surface_domain::read_string_of_schlaefli_labels done" << endl;
1994 }
1995}
1996
1997}}}
1998
1999
schlaefli labeling of objects in cubic surfaces with 27 lines
void find_tritangent_planes_intersecting_in_a_line(int line_idx, int &plane1, int &plane2, int verbose_level)
Definition: schlaefli.cpp:266
void init(surface_domain *Surf, int verbose_level)
Definition: schlaefli.cpp:156
int compute_rank_of_any_four(long int *&Rk, int &nb_subsets, long int *lines, int sz, int verbose_level)
int intersection_of_four_lines_but_not_b6(int *Adj, int *four_lines_idx, int b6, int verbose_level)
int compute_transversals_of_any_four(long int *&Trans, int &nb_subsets, long int *lines, int sz, int verbose_level)
void read_string_of_schlaefli_labels(std::string &str, int *&v, int &sz, int verbose_level)
void compute_points_on_lines(long int *Pts_on_surface, int nb_points_on_surface, long int *Lines, int nb_lines, data_structures::set_of_sets *&pts_on_lines, int *&f_is_on_line, int verbose_level)
int rank_of_four_lines_on_Klein_quadric(long int *four_lines, int verbose_level)
int test_double_six_property(long int *S12, int verbose_level)
Given a set of lines in S12[12], test the double six property.
void compute_intersection_points_and_indices(int *Adj, long int *Points, int nb_points, long int *Lines, int nb_lines, int *&Intersection_pt, int *&Intersection_pt_idx, int verbose_level)
void lines_meet3_and_skew3(long int *lines_meet3, long int *lines_skew3, long int *&lines, int &nb_lines, int verbose_level)
int create_double_six_from_five_lines_with_a_common_transversal(long int *five_pts, long int *double_six, int verbose_level)
Given a five-plus-one five_pts[5], complete the double-six.
void create_the_fifteen_other_lines(long int *double_six, long int *fifteen_other_lines, int verbose_level)
Given a double six in double_six[12], compute the 15 remaining lines cij.
void rearrange_lines_according_to_double_six(long int *Lines, int verbose_level)
Picks a double six and rearranges the lines accordingly.
ring_theory::homogeneous_polynomial_domain * Poly3_4
void list_starter_configurations(long int *Lines, int nb_lines, data_structures::set_of_sets *line_intersections, int *&Table, int &N, int verbose_level)
void compute_intersection_points(int *Adj, long int *Lines, int nb_lines, long int *&Intersection_pt, int verbose_level)
void create_lines_from_plane_equations(int *The_plane_equations, long int *Lines, int verbose_level)
void perp_of_three_lines(long int *three_lines, long int *&perp, int &perp_sz, int verbose_level)
void rearrange_lines_according_to_starter_configuration(long int *Lines, long int *New_lines, int line_idx, int subset_idx, int *Adj, data_structures::set_of_sets *line_intersections, int verbose_level)
void compute_adjacency_matrix_of_line_intersection_graph(int *&Adj, long int *S, int n, int verbose_level)
Given a set of lines in S[n], compute the associated line intersection graph.
void create_starter_configuration(int line_idx, int subset_idx, data_structures::set_of_sets *line_neighbors, long int *Lines, long int *S, int verbose_level)
int perp_of_four_lines(long int *four_lines, long int *trans12, int &perp_sz, int verbose_level)
Given four general lines in four_lines[4], complete the two transversal lines.
void create_remaining_fifteen_lines(long int *double_six, long int *fifteen_lines, int verbose_level)
int create_double_six_from_six_disjoint_lines(long int *single_six, long int *double_six, int verbose_level)
Given a single six in single_six[6], compute the other 6 lines in a double-six.
void build_cubic_surface_from_lines(int len, long int *S, int *coeff, int verbose_level)
void create_system(int len, long int *S, int *&System, int &nb_rows, int verbose_level)
void rearrange_lines_according_to_a_given_double_six(long int *Lines, int *given_double_six, long int *New_lines, int verbose_level)
void compute_adjacency_matrix_of_line_disjointness_graph(int *&Adj, long int *S, int n, int verbose_level)
Given a set of lines in S[n], compute the associated disjointness graph.
long int compute_cij(long int *double_six, int i, int j, int verbose_level)
Computes cij, given a double six.
int intersection_of_five_lines(int *Adj, int *five_lines_idx, int verbose_level)
void init_basic_constant_size(int underlying_set_size, int nb_sets, int constant_size, int verbose_level)
void init_from_adjacency_matrix(int n, int *Adj, int verbose_level)
Definition: set_of_sets.cpp:87
a collection of functions related to sorted vectors
int lint_vec_search_linear(long int *v, int len, long int a, int &idx)
Definition: sorting.cpp:699
void vec_intersect(long int *v1, int len1, long int *v2, int len2, long int *&v3, int &len3)
Definition: sorting.cpp:741
int lint_vec_search(long int *v, int len, long int a, int &idx, int verbose_level)
Definition: sorting.cpp:1157
functions related to strings and character arrays
void chop_string_comma_separated(const char *str, int &argc, char **&argv)
long int rank_lint_here(int *Mtx, int verbose_level)
Definition: grassmann.cpp:275
void unrank_lint_here(int *Mtx, long int rk, int verbose_level)
Definition: grassmann.cpp:269
long int line_to_point_on_quadric(long int line_rk, int verbose_level)
long int point_on_quadric_to_line(long int point_rk, int verbose_level)
void create_points_on_line(long int line_rk, long int *line, int verbose_level)
projective_space_implementation * Implementation
Definition: geometry.h:1940
int perp_standard(int n, int k, int *A, int verbose_level)
int Gauss_simple(int *A, int m, int n, int *base_cols, int verbose_level)
void matrix_get_kernel(int *M, int m, int n, int *base_cols, int nb_base_cols, int &kernel_m, int &kernel_n, int *kernel, int verbose_level)
int intersect_subspaces(int n, int k1, int *A, int k2, int *B, int &k3, int *intersection, int verbose_level)
void unrank_point(int *v, int stride, long int rk, int verbose_level)
void perp_of_k_points(long int *pts, int nb_pts, long int *&Perp, int &sz, int verbose_level)
void perp(long int pt, long int *Perp_without_pt, int &sz, int verbose_level)
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define Lint_matrix_print(A, B, C)
Definition: foundations.h:708
#define NEW_plint(n)
Definition: foundations.h:629
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define FREE_plint(p)
Definition: foundations.h:643
#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 TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define Lint_vec_zero(A, B)
Definition: foundations.h:714
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define Lint_vec_print_fully(A, B, C)
Definition: foundations.h:688
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects