Orbiter 2022
Combinatorial Objects
surface_domain2.cpp
Go to the documentation of this file.
1/*
2 * surface_domain2.cpp
3 *
4 * Created on: Nov 3, 2019
5 * Author: anton
6 */
7
8
9
10#include "foundations.h"
11
12
13using namespace std;
14
15
16namespace orbiter {
17namespace layer1_foundations {
18namespace algebraic_geometry {
19
20
22 int *three_coeff, int *ten_coeff,
23 int verbose_level)
24{
25 int f_v = (verbose_level >= 1);
26 int i, j, a, b, c, idx, u;
27 int M[3];
28
29 if (f_v) {
30 cout << "surface_domain::multiply_conic_times_linear" << endl;
31 }
32
33
34 Int_vec_zero(ten_coeff, 10);
35 for (i = 0; i < 6; i++) {
36 a = six_coeff[i];
37 if (a == 0) {
38 continue;
39 }
40 for (j = 0; j < 3; j++) {
41 b = three_coeff[j];
42 if (b == 0) {
43 continue;
44 }
45 c = F->mult(a, b);
46
47 for (u = 0; u < 3; u++) {
48 M[u] = Poly2->get_monomial(i, u) + Poly1->get_monomial(j, u);
49 }
50 idx = Poly3->index_of_monomial(M);
51 if (idx >= 10) {
52 cout << "surface_domain::multiply_conic_times_linear "
53 "idx >= 10" << endl;
54 exit(1);
55 }
56 ten_coeff[idx] = F->add(ten_coeff[idx], c);
57 }
58 }
59
60
61 if (f_v) {
62 cout << "surface_domain::multiply_conic_times_linear done" << endl;
63 }
64}
65
67 int *three_coeff1, int *three_coeff2, int *three_coeff3,
68 int *ten_coeff, int verbose_level)
69{
70 int f_v = (verbose_level >= 1);
71 int i, j, k, a, b, c, d, idx, u;
72 int M[3];
73
74 if (f_v) {
75 cout << "surface_domain::multiply_linear_times_linear_times_linear" << endl;
76 }
77
78 Int_vec_zero(ten_coeff, 10);
79 for (i = 0; i < 3; i++) {
80 a = three_coeff1[i];
81 if (a == 0) {
82 continue;
83 }
84 for (j = 0; j < 3; j++) {
85 b = three_coeff2[j];
86 if (b == 0) {
87 continue;
88 }
89 for (k = 0; k < 3; k++) {
90 c = three_coeff3[k];
91 if (c == 0) {
92 continue;
93 }
94 d = F->mult3(a, b, c);
95 for (u = 0; u < 3; u++) {
96 M[u] = Poly1->get_monomial(i, u)
97 + Poly1->get_monomial(j, u)
98 + Poly1->get_monomial(k, u);
99 }
100 idx = Poly3->index_of_monomial(M);
101 if (idx >= 10) {
102 cout << "surface::multiply_linear_times_"
103 "linear_times_linear idx >= 10" << endl;
104 exit(1);
105 }
106 ten_coeff[idx] = F->add(ten_coeff[idx], d);
107 }
108 }
109 }
110
111
112 if (f_v) {
113 cout << "surface_domain::multiply_linear_times_linear_times_linear done" << endl;
114 }
115}
116
118 int *four_coeff1, int *four_coeff2, int *four_coeff3,
119 int *twenty_coeff, int verbose_level)
120{
121 int f_v = (verbose_level >= 1);
122 int i, j, k, a, b, c, d, idx, u;
123 int M[4];
124
125 if (f_v) {
126 cout << "surface_domain::multiply_linear_times_linear_times_linear_in_space" << endl;
127 }
128
129 Int_vec_zero(twenty_coeff, 20);
130 for (i = 0; i < 4; i++) {
131 a = four_coeff1[i];
132 if (a == 0) {
133 continue;
134 }
135 for (j = 0; j < 4; j++) {
136 b = four_coeff2[j];
137 if (b == 0) {
138 continue;
139 }
140 for (k = 0; k < 4; k++) {
141 c = four_coeff3[k];
142 if (c == 0) {
143 continue;
144 }
145 d = F->mult3(a, b, c);
146 for (u = 0; u < 4; u++) {
147 M[u] = Poly1_4->get_monomial(i, u)
148 + Poly1_4->get_monomial(j, u)
149 + Poly1_4->get_monomial(k, u);
150 }
151 idx = index_of_monomial(M);
152 if (idx >= 20) {
153 cout << "surface_domain::multiply_linear_times_linear_"
154 "times_linear_in_space idx >= 20" << endl;
155 exit(1);
156 }
157 twenty_coeff[idx] = F->add(twenty_coeff[idx], d);
158 }
159 }
160 }
161
162
163 if (f_v) {
164 cout << "surface_domain::multiply_linear_times_linear_times_linear_in_space done" << endl;
165 }
166}
167
169 int *input1, int *input2,
170 int *result, int verbose_level)
171{
172 int f_v = (verbose_level >= 1);
173 int i, j, a, b, c, idx, u;
174 int M[3];
175
176 if (f_v) {
177 cout << "surface_domain::multiply_Poly2_3_times_Poly2_3" << endl;
178 }
179
181 for (i = 0; i < Poly2->get_nb_monomials(); i++) {
182 a = input1[i];
183 if (a == 0) {
184 continue;
185 }
186 for (j = 0; j < Poly2->get_nb_monomials(); j++) {
187 b = input2[j];
188 if (b == 0) {
189 continue;
190 }
191 c = F->mult(a, b);
192
193 for (u = 0; u < 3; u++) {
194 M[u] = Poly2->get_monomial(i, u) + Poly2->get_monomial(j, u);
195 }
197 result[idx] = F->add(result[idx], c);
198 }
199 }
200
201
202 if (f_v) {
203 cout << "surface_domain::multiply_Poly2_3_times_Poly2_3 done" << endl;
204 }
205}
206
208 int *result, int verbose_level)
209{
210 int f_v = (verbose_level >= 1);
211 int i, j, a, b, c, idx, u;
212 int M[3];
213
214 if (f_v) {
215 cout << "surface_domain::multiply_Poly1_3_times_Poly3_3" << endl;
216 }
217
219 for (i = 0; i < Poly1->get_nb_monomials(); i++) {
220 a = input1[i];
221 if (a == 0) {
222 continue;
223 }
224 for (j = 0; j < Poly3->get_nb_monomials(); j++) {
225 b = input2[j];
226 if (b == 0) {
227 continue;
228 }
229 c = F->mult(a, b);
230 for (u = 0; u < 3; u++) {
231 M[u] = Poly1->get_monomial(i, u) + Poly3->get_monomial(j, u);
232 }
234 result[idx] = F->add(result[idx], c);
235 }
236 }
237
238 if (f_v) {
239 cout << "surface_domain::multiply_Poly1_3_times_Poly3_3 done" << endl;
240 }
241}
242
244 int *The_six_plane_equations, int *The_surface_equations,
245 int verbose_level)
246// The_six_plane_equations[24]
247// The_surface_equations[(q + 1) * 20]
248{
249 int f_v = (verbose_level >= 1);
250 int v[2];
251 int l;
252 int eqn_F[20];
253 int eqn_G[20];
254 int eqn_F2[20];
255 int eqn_G2[20];
256
257 if (f_v) {
258 cout << "surface_domain::create_equations_for_pencil_of_surfaces_from_trihedral_pair" << endl;
259 }
260
261
263 The_six_plane_equations + 0 * 4,
264 The_six_plane_equations + 1 * 4,
265 The_six_plane_equations + 2 * 4,
266 eqn_F, FALSE /* verbose_level */);
268 The_six_plane_equations + 3 * 4,
269 The_six_plane_equations + 4 * 4,
270 The_six_plane_equations + 5 * 4,
271 eqn_G, FALSE /* verbose_level */);
272
273
274 for (l = 0; l < q + 1; l++) {
275 F->PG_element_unrank_modified(v, 1, 2, l);
276
277 Int_vec_copy(eqn_F, eqn_F2, 20);
279 Int_vec_copy(eqn_G, eqn_G2, 20);
281 F->Linear_algebra->add_vector(eqn_F2, eqn_G2, The_surface_equations + l * 20, 20);
282 F->PG_element_normalize(The_surface_equations + l * 20, 1, 20);
283 }
284
285 if (f_v) {
286 cout << "surface_domain::create_equations_for_pencil_of_surfaces_from_trihedral_pair done" << endl;
287 }
288}
289
290
291
292
293long int surface_domain::plane_from_three_lines(long int *three_lines,
294 int verbose_level)
295{
296 int f_v = (verbose_level >= 1);
297 int Basis[6 * 4];
298 long int rk;
299
300 if (f_v) {
301 cout << "surface_domain::plane_from_three_lines" << endl;
302 }
303 unrank_lines(Basis, three_lines, 3);
304 rk = F->Linear_algebra->Gauss_easy(Basis, 6, 4);
305 if (rk != 3) {
306 cout << "surface_domain::plane_from_three_lines rk != 3" << endl;
307 exit(1);
308 }
309 rk = rank_plane(Basis);
310
311 if (f_v) {
312 cout << "surface_domain::plane_from_three_lines done" << endl;
313 }
314 return rk;
315}
316
317void surface_domain::Trihedral_pairs_to_planes(long int *Lines, long int *Planes_by_rank,
318 int verbose_level)
319// Planes_by_rank[nb_trihedral_pairs * 6]
320{
321 int f_v = (verbose_level >= 1);
322 int t, i, j;
323 long int rk;
324 long int lines_in_tritangent_plane[3];
325 long int three_lines[3];
327
328 if (f_v) {
329 cout << "surface_domain::Trihedral_pairs_to_planes" << endl;
330 }
331 for (t = 0; t < Schlaefli->nb_trihedral_pairs; t++) {
332 for (i = 0; i < 3; i++) {
333 for (j = 0; j < 3; j++) {
334 lines_in_tritangent_plane[j] = Schlaefli->Trihedral_pairs[t * 9 + i * 3 + j];
335 three_lines[j] = Lines[lines_in_tritangent_plane[j]];
336 }
337 rk = plane_from_three_lines(three_lines, 0 /* verbose_level */);
338 Planes_by_rank[t * 6 + i] = rk;
339 }
340 for (j = 0; j < 3; j++) {
341 for (i = 0; i < 3; i++) {
342 lines_in_tritangent_plane[i] = Schlaefli->Trihedral_pairs[t * 9 + i * 3 + j];
343 three_lines[i] = Lines[lines_in_tritangent_plane[i]];
344 }
345 rk = plane_from_three_lines(three_lines, 0 /* verbose_level */);
346 Planes_by_rank[t * 6 + 3 + j] = rk;
347 }
348 }
349 if (f_v) {
350 cout << "Trihedral_pairs_to_planes:" << endl;
352 Planes_by_rank, Schlaefli->nb_trihedral_pairs, 6, FALSE /* f_tex */);
353 }
354 if (f_v) {
355 cout << "surface_domain::Trihedral_pairs_to_planes done" << endl;
356 }
357}
358
359
360#if 0
361void surface_domain::compute_tritangent_planes_slow(long int *Lines,
362 long int *&Tritangent_planes, int &nb_tritangent_planes,
363 long int *&Unitangent_planes, int &nb_unitangent_planes,
364 long int *&Lines_in_tritangent_plane,
365 long int *&Line_in_unitangent_plane,
366 int verbose_level)
367{
368 int f_v = (verbose_level >= 1);
369 int *Inc_lines_planes;
370 int *The_plane_type;
371 int nb_planes;
372 int i, j, h, c;
373
374 if (f_v) {
375 cout << "surface_domain::compute_tritangent_planes_slow" << endl;
376 }
377 if (f_v) {
378 cout << "Lines=" << endl;
379 lint_vec_print(cout, Lines, 27);
380 cout << endl;
381 }
383 Inc_lines_planes, nb_planes, 0 /* verbose_level */);
384
385 The_plane_type = NEW_int(nb_planes);
386 int_vec_zero(The_plane_type, nb_planes);
387
388 for (j = 0; j < nb_planes; j++) {
389 for (i = 0; i < 27; i++) {
390 if (Inc_lines_planes[i * nb_planes + j]) {
391 The_plane_type[j]++;
392 }
393 }
394 }
395 tally Plane_type;
396
397 Plane_type.init(The_plane_type, nb_planes, FALSE, 0);
398 if (f_v) {
399 cout << "surface_domain::compute_tritangent_planes_slow The plane type is: ";
400 Plane_type.print_naked(TRUE);
401 cout << endl;
402 }
403
404
405 Plane_type.get_class_by_value_lint(Tritangent_planes,
406 nb_tritangent_planes, 3 /* value */, 0 /* verbose_level */);
407 if (f_v) {
408 cout << "surface_domain::compute_tritangent_planes_slow "
409 "The tritangent planes are: ";
410 lint_vec_print(cout, Tritangent_planes, nb_tritangent_planes);
411 cout << endl;
412 }
413 Lines_in_tritangent_plane = NEW_lint(nb_tritangent_planes * 3);
414 for (h = 0; h < nb_tritangent_planes; h++) {
415 j = Tritangent_planes[h];
416 c = 0;
417 for (i = 0; i < 27; i++) {
418 if (Inc_lines_planes[i * nb_planes + j]) {
419 Lines_in_tritangent_plane[h * 3 + c++] = i;
420 }
421 }
422 if (c != 3) {
423 cout << "surface_domain::compute_tritangent_planes_slow c != 3" << endl;
424 exit(1);
425 }
426 }
427
428
429 Plane_type.get_class_by_value_lint(Unitangent_planes,
430 nb_unitangent_planes, 1 /* value */, 0 /* verbose_level */);
431 if (f_v) {
432 cout << "surface_domain::compute_tritangent_planes_slow "
433 "The unitangent planes are: ";
434 lint_vec_print(cout, Unitangent_planes, nb_unitangent_planes);
435 cout << endl;
436 }
437 Line_in_unitangent_plane = NEW_lint(nb_unitangent_planes);
438 for (h = 0; h < nb_unitangent_planes; h++) {
439 j = Unitangent_planes[h];
440 c = 0;
441 for (i = 0; i < 27; i++) {
442 if (Inc_lines_planes[i * nb_planes + j]) {
443 Line_in_unitangent_plane[h * 1 + c++] = i;
444 }
445 }
446 if (c != 1) {
447 cout << "surface_domain::compute_tritangent_planes_slow c != 1" << endl;
448 exit(1);
449 }
450 }
451
452 FREE_int(Inc_lines_planes);
453 FREE_int(The_plane_type);
454
455 if (f_v) {
456 cout << "surface_domain::compute_tritangent_planes_slow done" << endl;
457 }
458}
459#endif
460
461
462
463
464
465void surface_domain::clebsch_cubics(int verbose_level)
466{
467 int f_v = (verbose_level >= 1);
468
469
470
471 if (f_v) {
472 cout << "surface_domain::clebsch_cubics" << endl;
473 }
474
476 cout << "surface::clebsch_cubics f_has_large_"
477 "polynomial_domains is FALSE" << endl;
478 exit(1);
479 }
480 int Monomial[27];
481
482 int i, j, idx;
483
485 Clebsch_P = NEW_pint(3 * 4);
486 Clebsch_P3 = NEW_pint(3 * 3);
487
489
490
491 for (i = 0; i < 3; i++) {
492 for (j = 0; j < 4; j++) {
493 Clebsch_P[i * 4 + j] =
494 Clebsch_Pij + (i * 4 + j) * nb_monomials2;
495 }
496 }
497 for (i = 0; i < 3; i++) {
498 for (j = 0; j < 3; j++) {
499 Clebsch_P3[i * 3 + j] =
500 Clebsch_Pij + (i * 4 + j) * nb_monomials2;
501 }
502 }
503 int coeffs[] = {
504 1, 15, 2, 11,
505 1, 16, 2, 12,
506 1, 17, 2, 13,
507 1, 18, 2, 14,
508 0, 3, 2, 19,
509 0, 4, 2, 20,
510 0, 5, 2, 21,
511 0, 6, 2, 22,
512 0, 23, 1, 7,
513 0, 24, 1, 8,
514 0, 25, 1, 9,
515 0, 26, 1, 10
516 };
517 int c0, c1;
518
519 if (f_v) {
520 cout << "surface_domain::clebsch_cubics "
521 "Setting up the matrix P:" << endl;
522 }
523 for (i = 0; i < 3; i++) {
524 for (j = 0; j < 4; j++) {
525 cout << "i=" << i << " j=" << j << endl;
526 Int_vec_zero(Monomial, 27);
527 c0 = coeffs[(i * 4 + j) * 4 + 0];
528 c1 = coeffs[(i * 4 + j) * 4 + 1];
529 Int_vec_zero(Monomial, 27);
530 Monomial[c0] = 1;
531 Monomial[c1] = 1;
532 idx = Poly2_27->index_of_monomial(Monomial);
533 Clebsch_P[i * 4 + j][idx] = 1;
534 c0 = coeffs[(i * 4 + j) * 4 + 2];
535 c1 = coeffs[(i * 4 + j) * 4 + 3];
536 Int_vec_zero(Monomial, 27);
537 Monomial[c0] = 1;
538 Monomial[c1] = 1;
539 idx = Poly2_27->index_of_monomial(Monomial);
540 Clebsch_P[i * 4 + j][idx] = 1;
541 }
542 }
543
544
545 if (f_v) {
546 cout << "surface_domain::clebsch_cubics the matrix "
547 "Clebsch_P is:" << endl;
548 }
549 for (i = 0; i < 3; i++) {
550 for (j = 0; j < 4; j++) {
551 cout << "Clebsch_P_" << i << "," << j << ":";
552 Poly2_27->print_equation(cout, Clebsch_P[i * 4 + j]);
553 cout << endl;
554 }
555 }
556
557 int *Cubics;
558 int *Adjugate;
559 int *Ad[3 * 3];
560 int *C[4];
561 int m1;
562
563
564 if (f_v) {
565 cout << "surface_domain::clebsch_cubics allocating cubics" << endl;
566 }
567
568 Cubics = NEW_int(4 * nb_monomials6);
569 Int_vec_zero(Cubics, 4 * nb_monomials6);
570
571 Adjugate = NEW_int(3 * 3 * nb_monomials4);
572 Int_vec_zero(Adjugate, 3 * 3 * nb_monomials4);
573
574 for (i = 0; i < 4; i++) {
575 C[i] = Cubics + i * nb_monomials6;
576 }
577 for (i = 0; i < 3; i++) {
578 for (j = 0; j < 3; j++) {
579 Ad[i * 3 + j] = Adjugate + (i * 3 + j) * nb_monomials4;
580 }
581 }
582
583 if (f_v) {
584 cout << "surface_domain::clebsch_cubics computing "
585 "C[3] = the determinant" << endl;
586 }
587 // compute C[3] as the negative of the determinant
588 // of the matrix of the first three columns:
589 //int_vec_zero(C[3], nb_monomials6);
590 m1 = F->negate(1);
592 Clebsch_P[1 * 4 + 1],
593 Clebsch_P[2 * 4 + 2], m1, C[3],
594 0 /* verbose_level*/);
596 Clebsch_P[1 * 4 + 2],
597 Clebsch_P[2 * 4 + 0], m1, C[3],
598 0 /* verbose_level*/);
600 Clebsch_P[1 * 4 + 0],
601 Clebsch_P[2 * 4 + 1], m1, C[3],
602 0 /* verbose_level*/);
604 Clebsch_P[1 * 4 + 1],
605 Clebsch_P[0 * 4 + 2], 1, C[3],
606 0 /* verbose_level*/);
608 Clebsch_P[1 * 4 + 2],
609 Clebsch_P[0 * 4 + 0], 1, C[3],
610 0 /* verbose_level*/);
612 Clebsch_P[1 * 4 + 0],
613 Clebsch_P[0 * 4 + 1], 1, C[3],
614 0 /* verbose_level*/);
615
616 int I[3];
617 int J[3];
618 int size_complement, scalar;
620
621 if (f_v) {
622 cout << "surface_domain::clebsch_cubics computing adjugate" << endl;
623 }
624 // compute adjugate:
625 for (i = 0; i < 3; i++) {
626 I[0] = i;
627 Combi.set_complement(I, 1, I + 1, size_complement, 3);
628 for (j = 0; j < 3; j++) {
629 J[0] = j;
630 Combi.set_complement(J, 1, J + 1, size_complement, 3);
631
632 if ((i + j) % 2) {
633 scalar = m1;
634 }
635 else {
636 scalar = 1;
637 }
638 minor22(Clebsch_P3, I[1], I[2], J[1], J[2], scalar,
639 Ad[j * 3 + i], 0 /* verbose_level */);
640 }
641 }
642
643 // multiply adjugate * last column:
644 if (f_v) {
645 cout << "surface_domain::clebsch_cubics multiply adjugate "
646 "times last column" << endl;
647 }
648
649 for (i = 0; i < 3; i++) {
650 for (j = 0; j < 3; j++) {
651 multiply42_and_add(Ad[i * 3 + j],
652 Clebsch_P[j * 4 + 3], C[i], 0 /* verbose_level */);
653 }
654 }
655
656 if (f_v) {
657 cout << "surface_domain::clebsch_cubics We have "
658 "computed the Clebsch cubics" << endl;
659 }
660
661
662 int Y[3];
663 int M24[24];
664 int h;
666
671 for (i = 0; i < 4; i++) {
672 for (j = 0; j < Poly3->get_nb_monomials(); j++) {
673 CC[i * Poly3->get_nb_monomials() + j] =
675 }
676 }
677 for (i = 0; i < Poly3->get_nb_monomials(); i++) {
679 for (j = 0; j < nb_monomials6; j++) {
680 if (Sorting.int_vec_compare(Y, Poly6_27->get_monomial_pointer(j), 3) == 0) {
682 idx = Poly3_24->index_of_monomial(M24);
683 for (h = 0; h < 4; h++) {
684 CC[h * Poly3->get_nb_monomials() + i][idx] =
685 F->add(CC[h * Poly3->get_nb_monomials() + i][idx], C[h][j]);
686 }
687 }
688 }
689 }
690
691 if (f_v) {
693 }
694
695 FREE_int(Cubics);
696 FREE_int(Adjugate);
697
698 if (f_v) {
699 cout << "surface_domain::clebsch_cubics done" << endl;
700 }
701}
702
703void surface_domain::multiply_222_27_and_add(int *M1, int *M2, int *M3,
704 int scalar, int *MM, int verbose_level)
705{
706 int f_v = (verbose_level >= 1);
707 int i, j, k, a, b, c, d, idx;
708 int M[27];
709
710 if (f_v) {
711 cout << "surface_domain::multiply_222_27_and_add" << endl;
712 }
713
715 cout << "surface_domain::multiply_222_27_and_add "
716 "f_has_large_polynomial_domains is FALSE" << endl;
717 exit(1);
718 }
719 //int_vec_zero(MM, nb_monomials6);
720 for (i = 0; i < nb_monomials2; i++) {
721 a = M1[i];
722 if (a == 0) {
723 continue;
724 }
725 for (j = 0; j < nb_monomials2; j++) {
726 b = M2[j];
727 if (b == 0) {
728 continue;
729 }
730 for (k = 0; k < nb_monomials2; k++) {
731 c = M3[k];
732 if (c == 0) {
733 continue;
734 }
735 d = F->mult3(a, b, c);
739 M, 27);
740 idx = Poly6_27->index_of_monomial(M);
741 if (idx >= nb_monomials6) {
742 cout << "surface_domain::multiply_222_27_and_add "
743 "idx >= nb_monomials6" << endl;
744 exit(1);
745 }
746 d = F->mult(scalar, d);
747 MM[idx] = F->add(MM[idx], d);
748 }
749 }
750 }
751
752
753 if (f_v) {
754 cout << "surface_domain::multiply_222_27_and_add done" << endl;
755 }
756}
757
758void surface_domain::minor22(int **P3, int i1, int i2, int j1, int j2,
759 int scalar, int *Ad, int verbose_level)
760{
761 int f_v = (verbose_level >= 1);
762 int i, j, a, b, d, idx;
763 int M[27];
764
765 if (f_v) {
766 cout << "surface_domain::minor22" << endl;
767 }
768
770 cout << "surface_domain::minor22 "
771 "f_has_large_polynomial_domains is FALSE" << endl;
772 exit(1);
773 }
775 for (i = 0; i < nb_monomials2; i++) {
776 a = P3[i1 * 3 + j1][i];
777 if (a == 0) {
778 continue;
779 }
780 for (j = 0; j < nb_monomials2; j++) {
781 b = P3[i2 * 3 + j2][j];
782 if (b == 0) {
783 continue;
784 }
785 d = F->mult(a, b);
788 M, 27);
789 idx = Poly4_27->index_of_monomial(M);
790 if (idx >= nb_monomials4) {
791 cout << "surface_domain::minor22 "
792 "idx >= nb_monomials4" << endl;
793 exit(1);
794 }
795 d = F->mult(scalar, d);
796 Ad[idx] = F->add(Ad[idx], d);
797 }
798 }
799 for (i = 0; i < nb_monomials2; i++) {
800 a = P3[i2 * 3 + j1][i];
801 if (a == 0) {
802 continue;
803 }
804 for (j = 0; j < nb_monomials2; j++) {
805 b = P3[i1 * 3 + j2][j];
806 if (b == 0) {
807 continue;
808 }
809 d = F->mult(a, b);
812 M, 27);
813 idx = Poly4_27->index_of_monomial(M);
814 if (idx >= nb_monomials4) {
815 cout << "surface_domain::minor22 "
816 "idx >= nb_monomials4" << endl;
817 exit(1);
818 }
819 d = F->mult(scalar, d);
820 d = F->negate(d);
821 Ad[idx] = F->add(Ad[idx], d);
822 }
823 }
824
825
826 if (f_v) {
827 cout << "surface_domain::minor22 done" << endl;
828 }
829}
830
832 int *MM, int verbose_level)
833{
834 int f_v = (verbose_level >= 1);
835 int i, j, a, b, d, idx;
836 int M[27];
837
838 if (f_v) {
839 cout << "surface_domain::multiply42_and_add" << endl;
840 }
841
843 cout << "surface_domain::multiply42_and_add "
844 "f_has_large_polynomial_domains is FALSE" << endl;
845 exit(1);
846 }
847 for (i = 0; i < nb_monomials4; i++) {
848 a = M1[i];
849 if (a == 0) {
850 continue;
851 }
852 for (j = 0; j < nb_monomials2; j++) {
853 b = M2[j];
854 if (b == 0) {
855 continue;
856 }
857 d = F->mult(a, b);
860 M, 27);
861 idx = Poly6_27->index_of_monomial(M);
862 if (idx >= nb_monomials6) {
863 cout << "surface_domain::multiply42_and_add "
864 "idx >= nb_monomials6" << endl;
865 exit(1);
866 }
867 MM[idx] = F->add(MM[idx], d);
868 }
869 }
870
871 if (f_v) {
872 cout << "surface_domain::multiply42_and_add done" << endl;
873 }
874}
875
876void surface_domain::prepare_system_from_FG(int *F_planes, int *G_planes,
877 int lambda, int *&system, int verbose_level)
878{
879 int f_v = (verbose_level >= 1);
880 int i, j;
881
882
883 if (f_v) {
884 cout << "surface_domain::prepare_system_from_FG" << endl;
885 }
886 system = NEW_int(3 * 4 * 3);
887 Int_vec_zero(system, 3 * 4 * 3);
888 for (i = 0; i < 3; i++) {
889 for (j = 0; j < 4; j++) {
890 int *p = system + (i * 4 + j) * 3;
891 if (i == 0) {
892 p[0] = 0;
893 p[1] = F->mult(lambda, G_planes[0 * 4 + j]);
894 p[2] = F_planes[2 * 4 + j];
895 }
896 else if (i == 1) {
897 p[0] = F_planes[0 * 4 + j];
898 p[1] = 0;
899 p[2] = G_planes[1 * 4 + j];
900 }
901 else if (i == 2) {
902 p[0] = G_planes[2 * 4 + j];
903 p[1] = F_planes[1 * 4 + j];
904 p[2] = 0;
905 }
906 }
907 }
908 if (f_v) {
909 cout << "surface_domain::prepare_system_from_FG done" << endl;
910 }
911}
912
913
914void surface_domain::compute_nine_lines(int *F_planes, int *G_planes,
915 long int *nine_lines, int verbose_level)
916{
917 int f_v = (verbose_level >= 1);
918 int i, j;
919 int Basis[16];
920
921 if (f_v) {
922 cout << "surface_domain::compute_nine_lines" << endl;
923 }
924 for (i = 0; i < 3; i++) {
925 for (j = 0; j < 3; j++) {
926 Int_vec_copy(F_planes + i * 4, Basis, 4);
927 Int_vec_copy(G_planes + j * 4, Basis + 4, 4);
928 F->Linear_algebra->RREF_and_kernel(4, 2, Basis, 0 /* verbose_level */);
929 nine_lines[i * 3 + j] = Gr->rank_lint_here(
930 Basis + 8, 0 /* verbose_level */);
931 }
932 }
933 if (f_v) {
934 cout << "The nine lines are: ";
935 Lint_vec_print(cout, nine_lines, 9);
936 cout << endl;
937 }
938 if (f_v) {
939 cout << "surface_domain::compute_nine_lines done" << endl;
940 }
941}
942
944 long int *F_planes_rank,
945 long int *G_planes_rank, long int *nine_lines, int verbose_level)
946{
947 int f_v = (verbose_level >= 1);
948 int i, j;
949 int F_planes[12];
950 int G_planes[12];
951 int Basis[16];
952
953 if (f_v) {
954 cout << "surface_domain::compute_nine_lines_by_dual_point_ranks" << endl;
955 }
956 for (i = 0; i < 3; i++) {
957 P->unrank_point(F_planes + i * 4, F_planes_rank[i]);
958 }
959 for (i = 0; i < 3; i++) {
960 P->unrank_point(G_planes + i * 4, G_planes_rank[i]);
961 }
962
963 for (i = 0; i < 3; i++) {
964 for (j = 0; j < 3; j++) {
965 Int_vec_copy(F_planes + i * 4, Basis, 4);
966 Int_vec_copy(G_planes + j * 4, Basis + 4, 4);
967 F->Linear_algebra->RREF_and_kernel(4, 2, Basis, 0 /* verbose_level */);
968 nine_lines[i * 3 + j] = Gr->rank_lint_here(
969 Basis + 8, 0 /* verbose_level */);
970 }
971 }
972 if (f_v) {
973 cout << "The nine lines are: ";
974 Lint_vec_print(cout, nine_lines, 9);
975 cout << endl;
976 }
977 if (f_v) {
978 cout << "surface_domain::compute_nine_lines_by_dual_point_ranks done" << endl;
979 }
980}
981
983 int *&f1, int *&f2, int *&f3, int verbose_level)
984{
985 int f_v = (verbose_level >= 1);
986
987 if (f_v) {
988 cout << "surface_domain::split_nice_equation" << endl;
989 }
990 int M[4];
991 int i, a, idx;
992
999
1000 for (i = 0; i < 20; i++) {
1001 a = nice_equation[i];
1002 if (a == 0) {
1003 continue;
1004 }
1006 if (M[0] == 3) {
1007 cout << "surface_domain::split_nice_equation the x_0^3 "
1008 "term is supposed to be zero" << endl;
1009 exit(1);
1010 }
1011 else if (M[0] == 2) {
1012 idx = Poly1->index_of_monomial(M + 1);
1013 f1[idx] = a;
1014 }
1015 else if (M[0] == 1) {
1016 idx = Poly2->index_of_monomial(M + 1);
1017 f2[idx] = a;
1018 }
1019 else if (M[0] == 0) {
1020 idx = Poly3->index_of_monomial(M + 1);
1021 f3[idx] = a;
1022 }
1023 }
1024 if (f_v) {
1025 cout << "surface_domain::split_nice_equation done" << endl;
1026 }
1027}
1028
1030 int *f1, int *f2, int *f3,
1031 int *&tangent_quadric, int verbose_level)
1032// 2*x_0*f_1 + f_2
1033{
1034 int f_v = (verbose_level >= 1);
1035
1036 if (f_v) {
1037 cout << "surface_domain::assemble_tangent_quadric" << endl;
1038 }
1039 int M[4];
1040 int i, a, idx, two;
1041
1042
1043 two = F->add(1, 1);
1044 tangent_quadric = NEW_int(Poly2_4->get_nb_monomials());
1045 Int_vec_zero(tangent_quadric, Poly2_4->get_nb_monomials());
1046
1047 for (i = 0; i < Poly1->get_nb_monomials(); i++) {
1048 a = f1[i];
1049 if (a == 0) {
1050 continue;
1051 }
1053 M[0] = 1;
1054 idx = Poly2_4->index_of_monomial(M);
1055 tangent_quadric[idx] = F->mult(two, a);
1056 }
1057
1058 for (i = 0; i < Poly2->get_nb_monomials(); i++) {
1059 a = f2[i];
1060 if (a == 0) {
1061 continue;
1062 }
1064 M[0] = 0;
1065 idx = Poly2_4->index_of_monomial(M);
1066 tangent_quadric[idx] = a;
1067 }
1068
1069 if (f_v) {
1070 cout << "surface_domain::assemble_tangent_quadric done" << endl;
1071 }
1072}
1073
1075 int tritangent_plane_idx,
1076 int &trihedral_pair_idx, int &position, int verbose_level)
1077{
1078 int f_v = (verbose_level >= 1);
1079 static int Table[] = {
1080 0, 2, // 0
1081 0, 5, // 1
1082 22, 0, // 2
1083 0, 1, // 3
1084 20, 0, // 4
1085 1, 1, // 5
1086 26, 0, //6
1087 5, 1, // 7
1088 32, 0, //8
1089 6, 1, //9
1090 0, 0, //10
1091 25, 0, // 11
1092 1, 0, // 12
1093 43, 0, //13
1094 2, 0, //14
1095 55, 0, // 15
1096 3, 0, // 16
1097 3, 3, //17
1098 4, 0, //18
1099 67, 0, // 19
1100 5, 0, // 20
1101 73, 0, // 21
1102 6, 0, // 22
1103 6, 3, // 23
1104 7, 0, // 24
1105 79, 0, // 25
1106 8, 0, // 26
1107 8, 3, // 27
1108 9, 0, // 28
1109 9, 3, // 29
1110 115, 0, // 30
1111 114, 0, // 31
1112 34, 2, // 32
1113 113, 0, // 33
1114 111, 0, // 34
1115 34, 5, // 35
1116 74, 2, // 36
1117 110, 0, // 37
1118 49, 2, // 38
1119 26, 5, // 39
1120 38, 5, // 40
1121 53, 5, // 41
1122 36, 5, // 42
1123 45, 5, // 43
1124 51, 5, // 44
1125 };
1126
1127 if (f_v) {
1128 cout << "surface_domain::tritangent_plane_to_trihedral_pair_and_position" << endl;
1129 }
1130 trihedral_pair_idx = Table[2 * tritangent_plane_idx + 0];
1131 position = Table[2 * tritangent_plane_idx + 1];
1132 if (f_v) {
1133 cout << "surface_domain::tritangent_plane_to_trihedral_pair_and_position done" << endl;
1134 }
1135}
1136
1138 long int *Arc6, int p1_idx, int p2_idx, int partition_rk,
1139 long int line1, long int line2,
1140 int *coeff20, long int *lines27,
1141 int verbose_level)
1142{
1143 int f_v = (verbose_level >= 1);
1144 long int arc[6];
1145 long int P1, P2;
1147
1148
1149 if (f_v) {
1150 cout << "surface_domain::do_arc_lifting_with_two_lines" << endl;
1151 cout << "Arc6: ";
1152 Lint_vec_print(cout, Arc6, 6);
1153 cout << endl;
1154 cout << "p1_idx=" << p1_idx << " p2_idx=" << p2_idx
1155 << " partition_rk=" << partition_rk
1156 << " line1=" << line1 << " line2=" << line2 << endl;
1157 }
1158
1159 P1 = Arc6[p1_idx];
1160 P2 = Arc6[p2_idx];
1161
1162 if (f_v) {
1163 cout << "surface_domain::do_arc_lifting_with_two_lines before "
1164 "Gg.rearrange_arc_for_lifting" << endl;
1165 }
1167 P1, P2, partition_rk, arc,
1168 verbose_level);
1169
1170 if (f_v) {
1171 cout << "surface_domain::do_arc_lifting_with_two_lines after "
1172 "Gg.rearrange_arc_for_lifting" << endl;
1173 cout << "arc: ";
1174 Lint_vec_print(cout, arc, 6);
1175 cout << endl;
1176 }
1177
1179
1181
1182
1183 if (f_v) {
1184 cout << "surface_domain::do_arc_lifting_with_two_lines before "
1185 "AL->create_surface" << endl;
1186 }
1187 AL->create_surface(this, arc, line1, line2, verbose_level);
1188 if (f_v) {
1189 cout << "surface_domain::do_arc_lifting_with_two_lines after "
1190 "AL->create_surface" << endl;
1191 cout << "equation: ";
1192 Int_vec_print(cout, AL->coeff, 20);
1193 cout << endl;
1194 cout << "lines: ";
1195 Lint_vec_print(cout, AL->lines27, 27);
1196 cout << endl;
1197 }
1198
1199 Int_vec_copy(AL->coeff, coeff20, 20);
1200 Lint_vec_copy(AL->lines27, lines27, 27);
1201
1202
1203 FREE_OBJECT(AL);
1204
1205
1206 if (f_v) {
1207 cout << "surface_domain::do_arc_lifting_with_two_lines done" << endl;
1208 }
1209}
1210
1212 long int *P6, long int *P6_local, int verbose_level)
1213{
1214 int f_v = (verbose_level >= 1);
1215
1216 if (f_v) {
1217 cout << "surface_domain::compute_local_coordinates_of_arc" << endl;
1218 }
1219
1220 int i;
1221 int v[4];
1222 int base_cols[3] = {0, 1, 2};
1223 int coefficients[3];
1224 int Basis_of_hyperplane[12] = { 1,0,0,0, 0,1,0,0, 0,0,1,0 };
1225
1226 for (i = 0; i < 6; i++) {
1227 if (f_v) {
1228 cout << "surface_domain::compute_local_coordinates_of_arc "
1229 "i=" << i << endl;
1230 }
1231 P->unrank_point(v, P6[i]);
1232 if (f_v) {
1233 cout << "surface_domain::compute_local_coordinates_of_arc "
1234 "which is ";
1235 Int_vec_print(cout, v, 4);
1236 cout << endl;
1237 }
1239 3, 4, Basis_of_hyperplane, base_cols,
1240 v, coefficients,
1241 0 /* verbose_level */);
1242 if (f_v) {
1243 cout << "surface_domain::compute_local_coordinates_of_arc "
1244 "local coefficients ";
1245 Int_vec_print(cout, coefficients, 3);
1246 cout << endl;
1247 }
1248 F->PG_element_rank_modified_lint(coefficients, 1, 3, P6_local[i]);
1249 }
1250 if (f_v) {
1251 cout << "surface_domain::compute_local_coordinates_of_arc" << endl;
1252 cout << "P6_local=" << endl;
1253 Lint_vec_print(cout, P6_local, 6);
1254 cout << endl;
1255 }
1256
1257 if (f_v) {
1258 cout << "surface_domain::compute_local_coordinates_of_arc done" << endl;
1259 }
1260}
1261
1262void surface_domain::compute_gradient(int *equation20, int *&gradient, int verbose_level)
1263{
1264 int f_v = (verbose_level >= 1);
1265 int i;
1266
1267 if (f_v) {
1268 cout << "surface_domain::compute_gradient" << endl;
1269 }
1270
1271
1272 if (f_v) {
1273 cout << "surface_domain::compute_gradient Poly2_4->get_nb_monomials() = " << Poly2_4->get_nb_monomials() << endl;
1274 }
1275
1276 gradient = NEW_int(4 * Poly2_4->get_nb_monomials());
1277
1278 for (i = 0; i < 4; i++) {
1279 if (f_v) {
1280 cout << "surface_domain::compute_gradient i=" << i << endl;
1281 }
1282 if (f_v) {
1283 cout << "surface_domain::compute_gradient eqn_in=";
1284 Int_vec_print(cout, equation20, 20);
1285 cout << " = " << endl;
1286 Poly3_4->print_equation(cout, equation20);
1287 cout << endl;
1288 }
1289 Partials[i].apply(equation20,
1290 gradient + i * Poly2_4->get_nb_monomials(),
1291 verbose_level - 2);
1292 if (f_v) {
1293 cout << "surface_domain::compute_gradient "
1294 "partial=";
1295 Int_vec_print(cout, gradient + i * Poly2_4->get_nb_monomials(),
1297 cout << " = ";
1298 Poly2_4->print_equation(cout,
1299 gradient + i * Poly2_4->get_nb_monomials());
1300 cout << endl;
1301 }
1302 }
1303
1304
1305 if (f_v) {
1306 cout << "surface_domain::compute_gradient done" << endl;
1307 }
1308}
1309
1310long int surface_domain::compute_tangent_plane(int *pt_coords, int *equation20, int verbose_level)
1311{
1312 int f_v = (verbose_level >= 1);
1313 int f_vv = (verbose_level >= 2);
1314 int nb_eqns = 4;
1315 int i;
1316 int w[4];
1317 int *gradient;
1318
1319 if (f_v) {
1320 cout << "surface_domain::compute_tangent_plane" << endl;
1321 }
1322 if (f_v) {
1323 cout << "surface_domain::compute_tangent_plane before compute_gradient" << endl;
1324 }
1325 compute_gradient(equation20, gradient, verbose_level - 2);
1326 if (f_v) {
1327 cout << "surface_domain::compute_tangent_plane after compute_gradient" << endl;
1328 }
1329
1330 for (i = 0; i < nb_eqns; i++) {
1331 if (f_vv) {
1332 cout << "surface_domain::compute_tangent_plane "
1333 "gradient i=" << i << " / " << nb_eqns << endl;
1334 }
1335 if (FALSE) {
1336 cout << "surface_domain::compute_tangent_plane "
1337 "gradient " << i << " = ";
1338 Int_vec_print(cout,
1339 gradient + i * Poly2_4->get_nb_monomials(),
1341 cout << endl;
1342 }
1344 gradient + i * Poly2_4->get_nb_monomials(), pt_coords);
1345 if (f_vv) {
1346 cout << "surface_domain::compute_tangent_plane "
1347 "value = " << w[i] << endl;
1348 }
1349 }
1350 for (i = 0; i < nb_eqns; i++) {
1351 if (w[i]) {
1352 break;
1353 }
1354 }
1355
1356 if (i == nb_eqns) {
1357 cout << "surface_domain::compute_tangent_plane the point is singular" << endl;
1358 exit(1);
1359 }
1360 long int plane_rk;
1361
1363 w /* eqn4 */,
1364 0 /* verbose_level*/);
1365
1366 FREE_int(gradient);
1367
1368 return plane_rk;
1369}
1370
1371
1372
1373}}}
1374
void create_surface(surface_domain *Surf, long int *Arc6, long int line1, long int line2, int verbose_level)
void prepare_system_from_FG(int *F_planes, int *G_planes, int lambda, int *&system, int verbose_level)
void multiply_Poly2_3_times_Poly2_3(int *input1, int *input2, int *result, int verbose_level)
void split_nice_equation(int *nice_equation, int *&f1, int *&f2, int *&f3, int verbose_level)
ring_theory::homogeneous_polynomial_domain * Poly4_x123
void multiply_222_27_and_add(int *M1, int *M2, int *M3, int scalar, int *MM, int verbose_level)
void multiply42_and_add(int *M1, int *M2, int *MM, int verbose_level)
void compute_nine_lines(int *F_planes, int *G_planes, long int *nine_lines, int verbose_level)
ring_theory::homogeneous_polynomial_domain * Poly1_4
void multiply_linear_times_linear_times_linear_in_space(int *four_coeff1, int *four_coeff2, int *four_coeff3, int *twenty_coeff, int verbose_level)
void minor22(int **P3, int i1, int i2, int j1, int j2, int scalar, int *Ad, int verbose_level)
ring_theory::homogeneous_polynomial_domain * Poly3_24
void Trihedral_pairs_to_planes(long int *Lines, long int *Planes_by_rank, int verbose_level)
ring_theory::homogeneous_polynomial_domain * Poly3_4
void compute_gradient(int *equation20, int *&gradient, int verbose_level)
void compute_local_coordinates_of_arc(long int *P6, long int *P6_local, int verbose_level)
long int compute_tangent_plane(int *pt_coords, int *equation20, int verbose_level)
long int plane_from_three_lines(long int *three_lines, int verbose_level)
void multiply_linear_times_linear_times_linear(int *three_coeff1, int *three_coeff2, int *three_coeff3, int *ten_coeff, int verbose_level)
ring_theory::homogeneous_polynomial_domain * Poly6_27
ring_theory::homogeneous_polynomial_domain * Poly2_4
void multiply_Poly1_3_times_Poly3_3(int *input1, int *input2, int *result, int verbose_level)
void do_arc_lifting_with_two_lines(long int *Arc6, int p1_idx, int p2_idx, int partition_rk, long int line1, long int line2, int *coeff20, long int *lines27, int verbose_level)
void tritangent_plane_to_trihedral_pair_and_position(int tritangent_plane_idx, int &trihedral_pair_idx, int &position, int verbose_level)
ring_theory::homogeneous_polynomial_domain * Poly2_27
ring_theory::homogeneous_polynomial_domain * Poly4_27
void compute_nine_lines_by_dual_point_ranks(long int *F_planes_rank, long int *G_planes_rank, long int *nine_lines, int verbose_level)
void create_equations_for_pencil_of_surfaces_from_trihedral_pair(int *The_six_plane_equations, int *The_surface_equations, int verbose_level)
void assemble_tangent_quadric(int *f1, int *f2, int *f3, int *&tangent_quadric, int verbose_level)
void multiply_conic_times_linear(int *six_coeff, int *three_coeff, int *ten_coeff, int verbose_level)
void set_complement(int *subset, int subset_size, int *complement, int &size_complement, int universal_set_size)
void add3(int *v1, int *v2, int *v3, int *w, int len)
Definition: int_vec.cpp:39
void add(int *v1, int *v2, int *w, int len)
Definition: int_vec.cpp:30
a collection of functions related to sorted vectors
void PG_element_unrank_modified(int *v, int stride, int len, int a)
void PG_element_rank_modified_lint(int *v, int stride, int len, long int &a)
various functions related to geometries
Definition: geometry.h:721
void rearrange_arc_for_lifting(long int *Arc6, long int P1, long int P2, int partition_rk, long int *arc, int verbose_level)
long int rank_lint_here(int *Mtx, int verbose_level)
Definition: grassmann.cpp:275
long int plane_rank_using_dual_coordinates_in_three_space(int *eqn4, int verbose_level)
void line_plane_incidence_matrix_restricted(long int *Lines, int nb_lines, int *&M, int &nb_planes, int verbose_level)
void reduce_mod_subspace_and_get_coefficient_vector(int k, int len, int *basis, int *base_cols, int *v, int *coefficients, int verbose_level)
int RREF_and_kernel(int n, int k, int *A, int verbose_level)
void print_lint_matrix_with_standard_labels(std::ostream &ost, long int *p, int m, int n, int f_tex)
void apply(int *eqn_in, int *eqn_out, int verbose_level)
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_pint(n)
Definition: foundations.h:627
#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 NEW_lint(n)
Definition: foundations.h:628
#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