Orbiter 2022
Combinatorial Objects
homogeneous_polynomial_domain.cpp
Go to the documentation of this file.
1// homogeneous_polynomial_domain.cpp
2//
3// Anton Betten
4//
5// September 9, 2016
6
7
8
9#include "foundations.h"
10
11
12using namespace std;
13
14
15namespace orbiter {
16namespace layer1_foundations {
17namespace ring_theory {
18
19
20static int homogeneous_polynomial_domain_compare_monomial_with(void *data,
21 int i, void *data2, void *extra_data);
22static int homogeneous_polynomial_domain_compare_monomial(void *data,
23 int i, int j, void *extra_data);
24static void homogeneous_polynomial_domain_swap_monomial(void *data,
25 int i, int j, void *extra_data);
26#if 0
27static void HPD_callback_print_function(
28 std::stringstream &ost, void *data, void *callback_data);
29static void HPD_callback_print_function2(
30 std::stringstream &ost, void *data, void *callback_data);
31#endif
32
33
34
36{
37 Monomial_ordering_type = t_LEX;
38 F = NULL;
39 nb_monomials = 0;
40 Monomials = NULL;
41 symbols = NULL;
42 symbols_latex = NULL;
43 monomial_symbols = NULL;
44 monomial_symbols_latex = NULL;
45 monomial_symbols_easy = NULL;
46 Variables = NULL;
47 nb_affine = 0;
48 Affine = NULL;
49 v = NULL;
50 Affine_to_monomial = NULL;
51 coeff2 = NULL;
52 coeff3 = NULL;
53 coeff4 = NULL;
54 factors = NULL;
55 my_affine = NULL;
56 P = NULL;
57 base_cols = NULL;
58 type1 = NULL;
59 type2 = NULL;
60
61
62 q = 0;
63 nb_variables = 0;
64 degree = 0;
65
66
67 //null();
68}
69
71{
72 freeself();
73}
74
76{
77 int i;
78
79 if (v) {
80 FREE_int(v);
81 }
82 if (Monomials) {
83 FREE_int(Monomials);
84 }
85 if (symbols) {
86 delete [] symbols;
87 }
88 if (symbols_latex) {
89 delete [] symbols_latex;
90 }
91 if (monomial_symbols) {
92 for (i = 0; i < nb_monomials; i++) {
93 FREE_char(monomial_symbols[i]);
94 }
95 FREE_pchar(monomial_symbols);
96 }
97 if (monomial_symbols_latex) {
98 for (i = 0; i < nb_monomials; i++) {
99 FREE_char(monomial_symbols_latex[i]);
100 }
101 FREE_pchar(monomial_symbols_latex);
102 }
103 if (monomial_symbols_easy) {
104 for (i = 0; i < nb_monomials; i++) {
105 FREE_char(monomial_symbols_easy[i]);
106 }
107 FREE_pchar(monomial_symbols_easy);
108 }
109 if (Variables) {
110 FREE_int(Variables);
111 }
112 if (Affine) {
113 FREE_int(Affine);
114 }
115 if (Affine_to_monomial) {
116 FREE_int(Affine_to_monomial);
117 }
118 if (coeff2) {
119 FREE_int(coeff2);
120 }
121 if (coeff3) {
122 FREE_int(coeff3);
123 }
124 if (coeff4) {
125 FREE_int(coeff4);
126 }
127 if (factors) {
128 FREE_int(factors);
129 }
130 if (my_affine) {
131 FREE_int(my_affine);
132 }
133 if (P) {
134 FREE_OBJECT(P);
135 }
136 if (base_cols) {
137 FREE_int(base_cols);
138 }
139 if (type1) {
140 FREE_int(type1);
141 }
142 if (type2) {
143 FREE_int(type2);
144 }
145 null();
146}
147
149{
150}
151
153 int nb_vars, int degree, int f_init_incidence_structure,
154 monomial_ordering_type Monomial_ordering_type,
155 int verbose_level)
156{
157 int f_v = (verbose_level >= 1);
158 int m;
159
160 if (f_v) {
161 cout << "homogeneous_polynomial_domain::init" << endl;
162 }
163 homogeneous_polynomial_domain::F = F;
164 q = F->q;
167 homogeneous_polynomial_domain::Monomial_ordering_type = Monomial_ordering_type;
168
170 type1 = NEW_int(degree + 1);
171 type2 = NEW_int(degree + 1);
172
173 if (f_v) {
174 cout << "homogeneous_polynomial_domain::init before make_monomials" << endl;
175 }
176 make_monomials(Monomial_ordering_type, 0 /*verbose_level*/);
177 if (f_v) {
178 cout << "homogeneous_polynomial_domain::init after make_monomials" << endl;
179 }
180
181 m = MAXIMUM(nb_monomials, degree + 1);
182 // substitute_semilinear needs [nb_monomials]
183 // substitute_line needs [degree + 1]
184
185 coeff2 = NEW_int(m);
186 coeff3 = NEW_int(m);
187 coeff4 = NEW_int(m);
188 factors = NEW_int(degree);
189
190 my_affine = NEW_int(degree);
191
192
193
195 if (f_v) {
196 cout << "homogeneous_polynomial_domain::init before P->projective_space_init" << endl;
197 }
199 f_init_incidence_structure,
200 verbose_level);
201 if (f_v) {
202 cout << "homogeneous_polynomial_domain::init after P->projective_space_init" << endl;
203 }
204 base_cols = NEW_int(nb_monomials);
205
206 if (f_v) {
207 cout << "homogeneous_polynomial_domain::init done" << endl;
208 }
209
210}
211
213{
214 return nb_monomials;
215}
216
218{
219 return P;
220}
221
223{
224 return F;
225}
226
228{
229 if (j > nb_variables) {
230 cout << "homogeneous_polynomial_domain::get_monomial j > nb_variables" << endl;
231 exit(1);
232 }
233 return Monomials[i * nb_variables + j];
234}
235
237{
238 return monomial_symbols_easy[i];
239}
240
242{
243 return Monomials + i * nb_variables;
244}
245
246int homogeneous_polynomial_domain::evaluate_monomial(int idx_of_monomial, int *coords)
247{
248 int r;
249
251 Monomials + idx_of_monomial * nb_variables,
252 coords, nb_variables);
253 return r;
254}
255
257 const char *symbol_mask, const char *symbol_mask_latex,
258 int verbose_level)
259{
260 int i; //, l;
261 char label[1000];
262
263 if (symbols) {
264 delete [] symbols;
265 }
266 if (symbols_latex) {
267 delete [] symbols_latex;
268 }
269 symbols = new string [nb_variables];
270 symbols_latex = new string [nb_variables];
271 for (i = 0; i < nb_variables; i++) {
272 snprintf(label, 1000, symbol_mask, i + symbol_offset);
273 symbols[i].assign(label);
274 }
275 for (i = 0; i < nb_variables; i++) {
276 snprintf(label, 1000, symbol_mask_latex, i + symbol_offset);
277 symbols_latex[i].assign(label);
278 }
279}
280
282 int from, int len,
283 const char *symbol_mask, const char *symbol_mask_latex,
284 int verbose_level)
285{
286 int i, j; //, l;
287 char label[1000];
288
289 for (j = 0; j < len; j++) {
290 i = from + j;
291 snprintf(label, 1000, symbol_mask, i + symbol_offset);
292 symbols[i].assign(label);
293 }
294 for (j = 0; j < len; j++) {
295 i = from + j;
296 snprintf(label, 1000, symbol_mask_latex, i + symbol_offset);
297 symbols_latex[i].assign(label);
298 }
299
300}
301
303 monomial_ordering_type Monomial_ordering_type,
304 int verbose_level)
305{
306 int f_v = (verbose_level >= 1);
307 int i, j, a, h, idx, t;
311
312 if (f_v) {
313 cout << "homogeneous_polynomial_domain::make_monomials" << endl;
314 }
315
316 nb_monomials = Combi.int_n_choose_k(nb_variables + degree - 1, nb_variables - 1);
317
319
321
322 D->open(1, nb_variables);
324 D->RHSi(0) = degree;
325 D->type[0] = t_EQ;
326 D->set_x_min_constant(0);
328 D->f_has_sum = TRUE;
329 D->sum = degree;
330
331 if (f_v) {
332 cout << "homogeneous_polynomial_domain::make_monomials before D->solve_all_betten" << endl;
333 }
334 D->solve_all_betten(0 /* verbose_level */);
335 if (f_v) {
336 cout << "homogeneous_polynomial_domain::make_monomials after D->solve_all_betten" << endl;
337 }
338
339 if (f_v) {
340 cout << "homogeneous_polynomial_domain::make_monomials "
341 "We found " << D->_resultanz << " monomials" << endl;
342 }
343
344 int nb_sol;
345
346 D->get_solutions_full_length(Monomials, nb_sol, 0 /* verbose_level */);
347 if (f_v) {
348 cout << "There are " << nb_sol << " monomials." << endl;
349
350 if (nb_sol < 100) {
351 Int_matrix_print(Monomials, nb_sol, nb_variables);
352 }
353 else {
354 cout << "too many to print" << endl;
355 }
356 }
357
358 if (nb_sol != nb_monomials) {
359 cout << "homogeneous_polynomial_domain::make_monomials "
360 "nb_sol != nb_monomials" << endl;
361 cout << "nb_sol=" << nb_sol << endl;
362 cout << "nb_monomials=" << nb_monomials << endl;
363 exit(1);
364 }
365
366 FREE_OBJECT(D);
367
368 if (Monomial_ordering_type == t_PART) {
369
370 if (f_v) {
371 cout << "homogeneous_polynomial_domain::make_monomials rearranging by partition type:" << endl;
372 }
374
375 }
376
377 if (f_v) {
378 cout << "After rearranging by type:" << endl;
379 if (nb_monomials < 100) {
380 Int_matrix_print(Monomials, nb_monomials, nb_variables);
381 }
382 else {
383 cout << "too many to print" << endl;
384 }
385 }
386
387 char label[1000];
388 int l;
389
390 symbols = new string[nb_variables];
391 for (i = 0; i < nb_variables; i++) {
392
393
394 if (TRUE) {
395 label[0] = 'X';
396 label[1] = '0' + i;
397 label[2] = 0;
398 }
399 else {
400 label[0] = 'A' + i;
401 label[1] = 0;
402 }
403 symbols[i].assign(label);
404 }
405 symbols_latex = new string[nb_variables];
406 for (i = 0; i < nb_variables; i++) {
407
408 //int l;
409
410 if (TRUE) {
411 label[0] = 'X';
412 label[1] = '_';
413 label[2] = '0' + i;
414 label[3] = 0;
415 }
416 else {
417 label[0] = 'A' + i;
418 label[1] = 0;
419 }
420 symbols_latex[i].assign(label);
421 }
422
423 int f_first = FALSE;
424
425 monomial_symbols = NEW_pchar(nb_monomials);
426 for (i = 0; i < nb_monomials; i++) {
427 label[0] = 0;
428 f_first = TRUE;
429 for (j = 0; j < nb_variables; j++) {
430 a = Monomials[i * nb_variables + j];
431 if (a) {
432 if (!f_first) {
433 strcat(label, "*");
434 }
435 else {
436 f_first = FALSE;
437 }
438 strcat(label, symbols[j].c_str());
439 if (a > 1) {
440 sprintf(label + strlen(label), "^%d", a);
441 }
442 }
443 }
444 l = strlen(label);
445 monomial_symbols[i] = NEW_char(l + 1);
446 strcpy(monomial_symbols[i], label);
447 }
448
449 monomial_symbols_latex = NEW_pchar(nb_monomials);
450 for (i = 0; i < nb_monomials; i++) {
451 label[0] = 0;
452 for (j = 0; j < nb_variables; j++) {
453 a = Monomials[i * nb_variables + j];
454 if (a) {
455 strcat(label, symbols_latex[j].c_str());
456 if (a > 1) {
457 if (a >= 10) {
458 sprintf(label + strlen(label), "^{%d}", a);
459 }
460 else {
461 sprintf(label + strlen(label), "^%d", a);
462 }
463 }
464 }
465 }
466 l = strlen(label);
467 monomial_symbols_latex[i] = NEW_char(l + 1);
468 strcpy(monomial_symbols_latex[i], label);
469 }
470
471 Variables = NEW_int(nb_monomials * degree);
472 for (i = 0; i < nb_monomials; i++) {
473 h = 0;
474 for (j = 0; j < nb_variables; j++) {
475 a = Monomials[i * nb_variables + j];
476 for (t = 0; t < a; t++) {
477 Variables[i * degree + h] = j;
478 h++;
479 }
480 }
481 if (h != degree) {
482 cout << "homogeneous_polynomial_domain::make_monomials "
483 "h != degree" << endl;
484 exit(1);
485 }
486 }
487
488
489 monomial_symbols_easy = NEW_pchar(nb_monomials);
490 for (i = 0; i < nb_monomials; i++) {
491 label[0] = 'X';
492 label[1] = 0;
493 for (j = 0; j < degree; j++) {
494 a = Variables[i * degree + j];
495 sprintf(label + strlen(label), "%d", a);
496 }
497 l = strlen(label);
498 monomial_symbols_easy[i] = NEW_char(l + 1);
499 strcpy(monomial_symbols_easy[i], label);
500 }
501
502
503 if (f_v) {
504 cout << "homogeneous_polynomial_domain::make_monomials the "
505 "variable lists are:" << endl;
506 if (nb_monomials < 100) {
507 for (i = 0; i < nb_monomials; i++) {
508 cout << i << " : " << monomial_symbols[i] << " : ";
509 Int_vec_print(cout, Variables + i * degree, degree);
510 cout << endl;
511 }
512 }
513 else {
514 cout << "too many to print" << endl;
515 }
516 }
517
518
519
520
521 nb_affine = NT.i_power_j(nb_variables, degree);
522
523 if (nb_affine < ONE_MILLION) {
524 Affine = NEW_int(nb_affine * degree);
525 if (f_v) {
526 cout << "homogeneous_polynomial_domain::make_monomials "
527 "Affine, nb_affine=" << nb_affine << endl;
528 }
529 for (h = 0; h < nb_affine; h++) {
530 Gg.AG_element_unrank(nb_variables /* q */, Affine + h * degree, 1, degree, h);
531 }
532 if (FALSE) {
533 cout << "homogeneous_polynomial_domain::make_monomials "
534 "Affine" << endl;
535 Int_matrix_print(Affine, nb_affine, degree);
536 }
537 Affine_to_monomial = NEW_int(nb_affine);
538 for (i = 0; i < nb_affine; i++) {
539 if (i > 0 && (i & ((1 << 20) - 1)) == 0) {
540 cout << "homogeneous_polynomial_domain::make_monomials "
541 "i = " << i << " / " << nb_affine << endl;
542 }
544 for (j = 0; j < degree; j++) {
545 a = Affine[i * degree + j];
546 v[a]++;
547 }
548 idx = index_of_monomial(v);
549 Affine_to_monomial[i] = idx;
550 }
551 }
552 else {
553 cout << "homogeneous_polynomial_domain::make_monomials "
554 "nb_affine is too big, skipping Affine_to_monomial" << endl;
555 Affine = NULL;
556 Affine_to_monomial = NULL;
557 }
558
559 if (FALSE) {
560 cout << "homogeneous_polynomial_domain::make_monomials "
561 "Affine : idx:" << endl;
562 for (i = 0; i < nb_affine; i++) {
563 cout << i << " : ";
564 Int_vec_print(cout, Affine + i * degree, degree);
565 cout << " : " << Affine_to_monomial[i] << endl;
566 }
567 }
568
569
570 if (f_v) {
571 cout << "homogeneous_polynomial_domain::make_monomials done" << endl;
572 }
573}
574
576 int verbose_level)
577{
578 int f_v = (verbose_level >= 1);
580
581 if (f_v) {
582 cout << "homogeneous_polynomial_domain::rearrange_monomials_by_partition_type" << endl;
583 }
584
585 Sorting.Heapsort_general(Monomials, nb_monomials,
586 homogeneous_polynomial_domain_compare_monomial,
587 homogeneous_polynomial_domain_swap_monomial,
588 this);
589
590
591 if (f_v) {
592 cout << "homogeneous_polynomial_domain::rearrange_monomials_by_partition_type done" << endl;
593 }
594}
595
597{
599
600#if 0
601 int i, j;
602
603 for (i = 0; i < nb_monomials; i++) {
604 for (j = 0; j < n; j++) {
605 if (v[j] != Monomials[i * n + j]) {
606 break;
607 }
608 }
609 if (j == n) {
610 return i;
611 }
612 }
613#endif
614 int idx;
615
616 if (!Sorting.search_general(Monomials, nb_monomials, v, idx,
617 homogeneous_polynomial_domain_compare_monomial_with,
618 this /* extra_data */, 0 /* verbose_level */)) {
619
620 cout << "homogeneous_polynomial_domain::index_of_monomial "
621 "Did not find the monomial v=";
622 Int_vec_print(cout, v, nb_variables);
623 cout << endl;
624 cout << "Monomials:" << endl;
625 //int_matrix_print(Monomials, nb_monomials, n);
626 int i;
627 for (i = 0; i < nb_monomials; i++) {
628 cout << setw(3) << i << " : ";
629 Int_vec_print(cout, Monomials + i * nb_variables, nb_variables);
630 cout << endl;
631 }
632 cout << "homogeneous_polynomial_domain::index_of_monomial "
633 "Did not find the monomial v=";
634 Int_vec_print(cout, v, nb_variables);
635 cout << endl;
636 Sorting.search_general(Monomials, nb_monomials, v, idx,
637 homogeneous_polynomial_domain_compare_monomial_with,
638 this /* extra_data */, 3);
639 exit(1);
640 }
641 return idx;
642}
643
645 int *&Kernel, int &dim_kernel, int verbose_level)
646{
647 int f_v = (verbose_level >= 1);
648 int i, j, h, a, b, c, idx, f_kernel;
649 int *mon;
650
651 if (f_v) {
652 cout << "homogeneous_polynomial_domain::affine_evaluation_kernel" << endl;
653 }
654 dim_kernel = 0;
655 mon = NEW_int(nb_variables);
656 for (i = 0; i < nb_monomials; i++) {
657 Int_vec_copy(Monomials + i * nb_variables, mon, nb_variables);
658 f_kernel = FALSE;
659 for (j = 0; j < nb_variables - 1; j++) {
660 a = mon[j];
661 if (a >= q) {
662 b = a % (q - 1);
663 if (b == 0) {
664 b += (q - 1);
665 }
666 c = a - b;
667 mon[j] = b;
668 mon[nb_variables - 1] += c;
669 f_kernel = TRUE;
670 }
671 }
672 if (f_kernel) {
673 if (f_v) {
674 cout << "homogeneous_polynomial_domain::affine_evaluation_kernel monomial ";
675 Int_vec_print(cout, Monomials + i * nb_variables, nb_variables);
676 cout << " = ";
677 Int_vec_print(cout, mon, nb_variables);
678 cout << endl;
679 }
680 dim_kernel++;
681 }
682 }
683 if (f_v) {
684 cout << "homogeneous_polynomial_domain::affine_evaluation_kernel dim_kernel = " << dim_kernel << endl;
685 }
686 Kernel = NEW_int(dim_kernel * 2);
687 h = 0;
688 for (i = 0; i < nb_monomials; i++) {
689 Int_vec_copy(Monomials + i * nb_variables, mon, nb_variables);
690 f_kernel = FALSE;
691 for (j = 0; j < nb_variables - 1; j++) {
692 a = mon[j];
693 if (a >= q) {
694 b = a % (q - 1);
695 if (b == 0) {
696 b += (q - 1);
697 }
698 c = a - b;
699 mon[j] = b;
700 mon[nb_variables - 1] += c;
701 f_kernel = TRUE;
702 }
703 }
704 if (f_kernel) {
705 if (f_v) {
706 cout << "homogeneous_polynomial_domain::affine_evaluation_kernel monomial ";
707 Int_vec_print(cout, Monomials + i * nb_variables, nb_variables);
708 cout << " = ";
709 Int_vec_print(cout, mon, nb_variables);
710 cout << endl;
711 }
712 idx = index_of_monomial(mon);
713 Kernel[h * 2 + 0] = i;
714 Kernel[h * 2 + 1] = idx;
715 h++;
716 }
717 }
718 FREE_int(mon);
719 if (f_v) {
720 cout << "homogeneous_polynomial_domain::affine_evaluation_kernel done" << endl;
721 }
722}
723
724void homogeneous_polynomial_domain::print_monomial(ostream &ost, int i)
725{
726 int j, a, f_first = TRUE;
727
728 for (j = 0; j < nb_variables; j++) {
729 a = Monomials[i * nb_variables + j];
730 if (a == 0) {
731 continue;
732 }
733 if (!f_first) {
734 ost << "*";
735 }
736 else {
737 f_first = FALSE;
738 }
739 ost << symbols[j];
740 if (a > 1) {
741 ost << "^" << a;
742 }
743 }
744}
745
746void homogeneous_polynomial_domain::print_monomial(ostream &ost, int *mon)
747{
748 int j, a, f_first = TRUE;
749
750 for (j = 0; j < nb_variables; j++) {
751 a = mon[j];
752 if (a == 0) {
753 continue;
754 }
755 if (!f_first) {
756 ost << "*";
757 }
758 else {
759 f_first = FALSE;
760 }
761 ost << symbols[j];
762 if (a > 1) {
763 ost << "^" << a;
764 }
765 }
766}
767
769{
770 int j, a;
771
772 for (j = 0; j < nb_variables; j++) {
773 a = mon[j];
774 if (a == 0) {
775 continue;
776 }
777 ost << symbols_latex[j];
778 if (a >= 10) {
779 ost << "^{" << a << "}";
780 }
781 else if (a > 1) {
782 ost << "^" << a;
783 }
784 }
785}
786
788{
789 int *mon;
790
791 mon = Monomials + i * nb_variables;
792 print_monomial_latex(ost, mon);
793}
794
796{
797 int j, a;
798
799 for (j = 0; j < nb_variables; j++) {
800 a = mon[j];
801 if (a == 0) {
802 continue;
803 }
804 s.append(symbols_latex[j]);
805
806 char str[1000];
807
808
809 if (a >= 10) {
810 sprintf(str, "^{%d}", a);
811 }
812 else if (a > 1) {
813 sprintf(str, "^%d", a);
814 }
815 s.append(str);
816 }
817}
818
820{
821 int *mon;
822
823 mon = Monomials + i * nb_variables;
824 print_monomial_latex(s, mon);
825}
826
827
828void homogeneous_polynomial_domain::print_monomial_str(std::stringstream &ost, int i)
829{
830 int j, a, f_first = TRUE;
831
832 for (j = 0; j < nb_variables; j++) {
833 a = Monomials[i * nb_variables + j];
834 if (a == 0) {
835 continue;
836 }
837 if (!f_first) {
838 ost << "*";
839 }
840 else {
841 f_first = FALSE;
842 }
843 ost << symbols[j];
844 if (a > 1) {
845 ost << "^" << a;
846 }
847 }
848}
849
850
852{
853 int j, a;
854
855 for (j = 0; j < nb_variables; j++) {
856 a = Monomials[i * nb_variables + j];
857 if (a == 0) {
858 continue;
859 }
860 ost << symbols_latex[j];
861 if (a > 1) {
862 ost << "^" << a;
863 }
864 }
865}
866
867void homogeneous_polynomial_domain::print_equation(std::ostream &ost, int *coeffs)
868{
869 int i, c;
870 int f_first = TRUE;
871
872 //cout << "homogeneous_polynomial_domain::print_equation" << endl;
873 for (i = 0; i < nb_monomials; i++) {
874 c = coeffs[i];
875 if (c == 0) {
876 continue;
877 }
878 if (f_first) {
879 f_first = FALSE;
880 }
881 else {
882 ost << " + ";
883 }
884 if (c > 1) {
885 F->print_element(ost, c);
886 //ost << c;
887 }
888 print_monomial(ost, i);
889 }
890}
891
893{
894
895 Int_vec_print_fully(cout, coeffs, nb_monomials);
896}
897
898
899void homogeneous_polynomial_domain::print_equation_tex(std::ostream &ost, int *coeffs)
900{
901 int i, c;
902 int f_first = TRUE;
903
904
905 for (i = 0; i < nb_monomials; i++) {
906 c = coeffs[i];
907 if (c == 0) {
908 continue;
909 }
910 if (f_first) {
911 f_first = FALSE;
912 }
913 else {
914 ost << " + ";
915 }
916 if (c > 1) {
917 F->print_element(ost, c);
918 //ost << c;
919 }
920 print_monomial_latex(ost, i);
921 }
922}
923
925{
926 int i, c;
927 int f_first = TRUE;
928
929
930 for (i = 0; i < nb_monomials; i++) {
931 c = coeffs[i];
932 if (c == 0) {
933 continue;
934 }
935 if (f_first) {
936 f_first = FALSE;
937 }
938 else {
939 ost << " + ";
940 }
941 if (c > 1) {
942 //F->print_element(ost, c);
943 ost << c;
944 }
945 print_monomial(ost, i);
946 }
947}
948
949void homogeneous_polynomial_domain::print_equation_lint(std::ostream &ost, long int *coeffs)
950{
951 int i, c;
952 int f_first = TRUE;
953
954
955 for (i = 0; i < nb_monomials; i++) {
956 c = coeffs[i];
957 if (c == 0) {
958 continue;
959 }
960 if (f_first) {
961 f_first = FALSE;
962 }
963 else {
964 ost << " + ";
965 }
966 if (c > 1) {
967 F->print_element(ost, c);
968 //ost << c;
969 }
970 print_monomial(ost, i);
971 }
972}
973
974void homogeneous_polynomial_domain::print_equation_lint_tex(std::ostream &ost, long int *coeffs)
975{
976 int i, c;
977 int f_first = TRUE;
978
979
980 for (i = 0; i < nb_monomials; i++) {
981 c = coeffs[i];
982 if (c == 0) {
983 continue;
984 }
985 if (f_first) {
986 f_first = FALSE;
987 }
988 else {
989 ost << " + ";
990 }
991 if (c > 1) {
992 F->print_element(ost, c);
993 //ost << c;
994 }
995 print_monomial_latex(ost, i);
996 }
997}
998
999void homogeneous_polynomial_domain::print_equation_str(std::stringstream &ost, int *coeffs)
1000{
1001 int i, c;
1002 int f_first = TRUE;
1003
1004
1005 for (i = 0; i < nb_monomials; i++) {
1006 c = coeffs[i];
1007 if (c == 0) {
1008 continue;
1009 }
1010 if (f_first) {
1011 f_first = FALSE;
1012 }
1013 else {
1014 ost << "+";
1015 }
1016 if (c > 1) {
1017 F->print_element_str(ost, c);
1018 //ost << c;
1019 }
1020 print_monomial_str(ost, i);
1021 }
1022}
1023
1025 std::ostream &ost, int *coeffs, int nb_terms_per_line,
1026 const char *new_line_text)
1027{
1028 int i, c, cnt = 0;
1029 int f_first = TRUE;
1030
1031
1032 for (i = 0; i < nb_monomials; i++) {
1033 c = coeffs[i];
1034 if (c == 0) {
1035 continue;
1036 }
1037
1038 if ((cnt % nb_terms_per_line) == 0 && cnt) {
1039 ost << new_line_text;
1040 }
1041
1042
1043 if (f_first) {
1044 f_first = FALSE;
1045 }
1046 else {
1047 ost << " + ";
1048 }
1049 if (c > 1) {
1050 F->print_element(ost, c);
1051 //ost << c;
1052 }
1053 print_monomial_latex(ost, i);
1054 cnt++;
1055 }
1056}
1057
1059 ostream &ost, long int *coeffs, int nb_terms_per_line,
1060 const char *new_line_text)
1061{
1062 int i, c, cnt = 0;
1063 int f_first = TRUE;
1064
1065
1066 for (i = 0; i < nb_monomials; i++) {
1067 c = coeffs[i];
1068 if (c == 0) {
1069 continue;
1070 }
1071
1072 if ((cnt % nb_terms_per_line) == 0 && cnt) {
1073 ost << new_line_text;
1074 }
1075
1076
1077 if (f_first) {
1078 f_first = FALSE;
1079 }
1080 else {
1081 ost << " + ";
1082 }
1083 if (c > 1) {
1084 F->print_element(ost, c);
1085 //ost << c;
1086 }
1087 print_monomial_latex(ost, i);
1088 cnt++;
1089 }
1090}
1091
1093 long int *Pts, int &nb_pts, int verbose_level)
1094{
1095 int f_v = (verbose_level >= 1);
1096 int rk, a, i;
1097
1098 if (f_v) {
1099 cout << "homogeneous_polynomial_domain::algebraic_set "
1100 "P->N_points=" << P->N_points << endl;
1101 }
1102 nb_pts = 0;
1103 for (rk = 0; rk < P->N_points; rk++) {
1104 unrank_point(v, rk);
1105 for (i = 0; i < nb_eqns; i++) {
1106 a = evaluate_at_a_point(Eqns + i * nb_monomials, v);
1107 if (a) {
1108 break;
1109 }
1110 }
1111 if (i == nb_eqns) {
1112 Pts[nb_pts++] = rk;
1113 }
1114 }
1115
1116 if (f_v) {
1117 cout << "homogeneous_polynomial_domain::algebraic_set "
1118 "done" << endl;
1119 }
1120}
1121
1122void homogeneous_polynomial_domain::polynomial_function(int *coeff, int *f, int verbose_level)
1123{
1124 int f_v = (verbose_level >= 1);
1125 int rk, a;
1126
1127 if (f_v) {
1128 cout << "homogeneous_polynomial_domain::polynomial_function "
1129 "P->N_points=" << P->N_points << endl;
1130 }
1131 for (rk = 0; rk < P->N_points; rk++) {
1132 unrank_point(v, rk);
1133 a = evaluate_at_a_point(coeff, v);
1134 f[rk] = a;
1135 }
1136}
1137
1139 std::vector<long int> &Pts,
1140 int verbose_level)
1141{
1142 int f_v = (verbose_level >= 1);
1143 int f_vv = FALSE; //(verbose_level >= 2);
1144 long int rk;
1145 int a;
1146
1147 if (f_v) {
1148 cout << "homogeneous_polynomial_domain::enumerate_points" << endl;
1149 }
1150 if (f_vv) {
1151 cout << "homogeneous_polynomial_domain::enumerate_points P->N_points=" << P->N_points << endl;
1152 cout << "homogeneous_polynomial_domain::enumerate_points coeff=" << endl;
1153 Int_vec_print(cout, coeff, nb_monomials);
1154 cout << endl;
1155#if 0
1157 coeff, 8 /* nb_terms_per_line*/,
1158 "\\\\\n");
1159 cout << endl;
1160#endif
1161 }
1162 //nb_pts = 0;
1163 for (rk = 0; rk < P->N_points; rk++) {
1164 unrank_point(v, rk);
1165 a = evaluate_at_a_point(coeff, v);
1166 if (f_vv) {
1167 cout << "homogeneous_polynomial_domain::enumerate_points point " << rk << " / " << P->N_points << " :";
1168 Int_vec_print(cout, v, nb_variables);
1169 cout << " evaluates to " << a << endl;
1170 }
1171 if (a == 0) {
1172 Pts.push_back(rk);
1173 }
1174 }
1175
1176 if (f_v) {
1177 cout << "homogeneous_polynomial_domain::enumerate_points "
1178 "done" << endl;
1179 }
1180}
1181
1183 long int *&Pts, int &nb_pts, int verbose_level)
1184{
1185 int f_v = (verbose_level >= 1);
1186
1187 if (f_v) {
1188 cout << "homogeneous_polynomial_domain::enumerate_points_lint" << endl;
1189 }
1190
1191 vector<long int> Points;
1192
1193 if (f_v) {
1194 cout << "homogeneous_polynomial_domain::enumerate_points_lint before "
1195 "enumerate_points" << endl;
1196 }
1197 enumerate_points(coeff, Points, verbose_level - 1);
1198
1199 if (f_v) {
1200 cout << "homogeneous_polynomial_domain::enumerate_points_lint after "
1201 "enumerate_points" << endl;
1202 }
1203 if (f_v) {
1204 cout << "homogeneous_polynomial_domain::enumerate_points_lint The object "
1205 "has " << Points.size() << " points" << endl;
1206 }
1207 int i;
1208
1209 nb_pts = Points.size();
1210 Pts = NEW_lint(nb_pts);
1211 for (i = 0; i < nb_pts; i++) {
1212 Pts[i] = Points[i];
1213 }
1214
1215
1216 if (f_v) {
1217 cout << "homogeneous_polynomial_domain::enumerate_points_lint done" << endl;
1218 }
1219}
1220
1221
1223 std::vector<long int> &Pts,
1224 int verbose_level)
1225{
1226 int f_v = (verbose_level >= 1);
1227 int f_vv = (verbose_level >= 2);
1228 long int rk;
1229 int a;
1230
1231 if (f_v) {
1232 cout << "homogeneous_polynomial_domain::enumerate_points_zariski_open_set" << endl;
1233 }
1234 if (f_vv) {
1235 cout << "homogeneous_polynomial_domain::enumerate_points_zariski_open_set "
1236 "P->N_points=" << P->N_points << endl;
1238 coeff, 8 /* nb_terms_per_line*/,
1239 "\\\\\n");
1240 cout << endl;
1241 }
1242 for (rk = 0; rk < P->N_points; rk++) {
1243 unrank_point(v, rk);
1244 a = evaluate_at_a_point(coeff, v);
1245 if (a) {
1246 Pts.push_back(rk);
1247 }
1248 }
1249
1250 if (f_v) {
1251 cout << "homogeneous_polynomial_domain::enumerate_points_zariski_open_set "
1252 "done" << endl;
1253 }
1254}
1255
1257 int *coeff, int pt)
1258{
1259 int a;
1260
1261 unrank_point(v, pt);
1262 a = evaluate_at_a_point(coeff, v);
1263 return a;
1264}
1265
1267 int *coeff, int *pt_vec)
1268{
1269 int i, a, b, c;
1270
1271 a = 0;
1272 for (i = 0; i < nb_monomials; i++) {
1273 if (coeff[i] == 0) {
1274 continue;
1275 }
1276 b = F->Linear_algebra->evaluate_monomial(Monomials + i * nb_variables, pt_vec, nb_variables);
1277 c = F->mult(coeff[i], b);
1278 a = F->add(a, c);
1279 }
1280 return a;
1281}
1282
1284 int *coeff_in, int *coeff_out,
1285 int *Mtx_inv, int verbose_level)
1286{
1287 int f_v = (verbose_level >= 1);
1288
1289 if (f_v) {
1290 cout << "homogeneous_polynomial_domain::substitute_linear" << endl;
1291 }
1292
1293 substitute_semilinear(coeff_in, coeff_out,
1294 FALSE /* f_semilinear */, 0 /* frob_power */,
1295 Mtx_inv, verbose_level);
1296 if (f_v) {
1297 cout << "homogeneous_polynomial_domain::substitute_linear "
1298 "done" << endl;
1299 }
1300}
1301
1303 int *coeff_in, int *coeff_out,
1304 int f_semilinear, int frob_power, int *Mtx_inv,
1305 int verbose_level)
1306// applies frob_power field automorphisms and then performs substitution
1307{
1308 int f_v = (verbose_level >= 1);
1309 int a, b, c, i, j, idx;
1310 int *A;
1311 int *V;
1313
1314 if (f_v) {
1315 cout << "homogeneous_polynomial_domain::substitute_semilinear" << endl;
1316 }
1317
1318
1319 if (f_semilinear) {
1320 F->frobenius_power_vec_to_vec(coeff_in, coeff4, nb_monomials, frob_power);
1321 }
1322 else {
1323 Int_vec_copy(coeff_in, coeff4, nb_monomials);
1324 }
1325
1326
1327 Int_vec_zero(coeff3, nb_monomials);
1328 for (i = 0; i < nb_monomials; i++) {
1329 c = coeff4[i];
1330 if (c == 0) {
1331 continue;
1332 }
1333
1334#if 0
1335 cout << "homogeneous_polynomial_domain::substitute_semilinear monomial " << c << " * ";
1336 print_monomial(cout, i);
1337 cout << endl;
1338#endif
1339
1340 V = Variables + i * degree;
1341 // a list of the indices of the variables
1342 // which appear in the monomial
1343 // (possibly with repeats)
1344 // Example: the monomial x_0^3 becomes 0,0,0
1345
1346#if 0
1347 cout << "variables: ";
1348 int_vec_print(cout, V, degree);
1349 cout << endl;
1350
1351 cout << "Mtx:" << endl;
1352 int_matrix_print(Mtx_inv, n, n);
1353#endif
1354
1355 Int_vec_zero(coeff2, nb_monomials);
1356 for (a = 0; a < nb_affine; a++) {
1357 if (Affine) {
1358 A = Affine + a * degree;
1359 }
1360 else {
1361 A = my_affine;
1362 Gg.AG_element_unrank(nb_variables /* q */, my_affine, 1, degree, a);
1363 // sequence of length degree over the alphabet 0,...,n-1.
1364 }
1365 for (j = 0; j < degree; j++) {
1366 //factors[j] = Mtx_inv[V[j] * n + A[j]];
1367 factors[j] = Mtx_inv[A[j] * nb_variables + V[j]];
1368 }
1369
1370 b = F->product_n(factors, degree);
1371 if (Affine_to_monomial) {
1372 idx = Affine_to_monomial[a];
1373 }
1374 else {
1376 for (j = 0; j < degree; j++) {
1377 a = Affine[i * degree + j];
1378 v[a]++;
1379 }
1380 idx = index_of_monomial(v);
1381 }
1382
1383#if 0
1384 cout << "affine " << a << " / " << nb_affine << " : ";
1385 int_vec_print(cout, A, 3);
1386 cout << " factors ";
1387 int_vec_print(cout, factors, 3);
1388 cout << " b=" << b << " idx=" << idx << endl;
1389#endif
1390 coeff2[idx] = F->add(coeff2[idx], b);
1391 }
1392 for (j = 0; j < nb_monomials; j++) {
1393 coeff2[j] = F->mult(coeff2[j], c);
1394 }
1395
1396#if 0
1397 cout << "homogeneous_polynomial_domain::substitute_semilinear "
1398 "monomial " << c << " * ";
1399 print_monomial(cout, i);
1400 cout << " yields:" << endl;
1401 int_vec_print(cout, coeff2, nb_monomials);
1402 cout << endl;
1403#endif
1404
1405 for (j = 0; j < nb_monomials; j++) {
1406 coeff3[j] = F->add(coeff2[j], coeff3[j]);
1407 }
1408 }
1409#if 0
1410 cout << "homogeneous_polynomial_domain::substitute_semilinear "
1411 "input:" << endl;
1412 int_vec_print(cout, coeff_in, nb_monomials);
1413 cout << endl;
1414 cout << "homogeneous_polynomial_domain::substitute_semilinear "
1415 "output:" << endl;
1416 int_vec_print(cout, coeff3, nb_monomials);
1417 cout << endl;
1418#endif
1419
1420
1421
1422
1423
1424 Int_vec_copy(coeff3, coeff_out, nb_monomials);
1425 if (f_v) {
1426 cout << "homogeneous_polynomial_domain::substitute_semilinear "
1427 "done" << endl;
1428 }
1429}
1430
1432 int *coeff_in, int *coeff_out,
1433 int *Pt1_coeff, int *Pt2_coeff,
1434 int verbose_level)
1435// coeff_in[nb_monomials], coeff_out[degree + 1]
1436{
1437 int f_v = (verbose_level >= 1);
1438 int rk, b, c, i, j, idx;
1439 int *A;
1440 int *V;
1441 int *Mtx;
1442 int my_nb_affine, wt;
1445
1446
1447 if (f_v) {
1448 cout << "homogeneous_polynomial_domain::substitute_line" << endl;
1449 }
1450
1451 my_nb_affine = NT.i_power_j(2, degree);
1452
1453 Mtx = NEW_int(nb_variables * 2);
1454
1455 for (i = 0; i < nb_variables; i++) {
1456 Mtx[i * 2 + 0] = Pt1_coeff[i];
1457 Mtx[i * 2 + 1] = Pt2_coeff[i];
1458 }
1459
1460 Int_vec_copy(coeff_in, coeff4, nb_monomials);
1461
1462
1463 Int_vec_zero(coeff3, degree + 1);
1464
1465 for (i = 0; i < nb_monomials; i++) {
1466 c = coeff4[i];
1467 if (c == 0) {
1468 continue;
1469 }
1470
1471#if 0
1472 cout << "homogeneous_polynomial_domain::substitute_line monomial " << c << " * ";
1473 print_monomial(cout, i);
1474 cout << endl;
1475#endif
1476
1477 V = Variables + i * degree;
1478 // a list of the indices of the variables
1479 // which appear in the monomial
1480 // (possibly with repeats)
1481 // Example: the monomial x_0^3 becomes 0,0,0
1482
1483#if 0
1484 cout << "variables: ";
1485 int_vec_print(cout, V, degree);
1486 cout << endl;
1487
1488 cout << "Mtx:" << endl;
1489 int_matrix_print(Mtx, n, 2);
1490#endif
1491
1492 Int_vec_zero(coeff2, degree + 1);
1493 for (rk = 0; rk < my_nb_affine; rk++) {
1494
1495 A = my_affine;
1496 Gg.AG_element_unrank(2 /* q */, my_affine, 1, degree, rk);
1497 // sequence of length degree over the alphabet 0,1.
1498
1499 wt = 0;
1500 for (j = 0; j < degree; j++) {
1501 if (my_affine[j]) {
1502 wt++;
1503 }
1504 }
1505 for (j = 0; j < degree; j++) {
1506 //factors[j] = Mtx_inv[V[j] * n + A[j]];
1507 factors[j] = Mtx[V[j] * 2 + A[j]];
1508 }
1509
1510 b = F->product_n(factors, degree);
1511
1512#if 0
1513 if (Affine_to_monomial) {
1514 idx = Affine_to_monomial[a];
1515 }
1516 else {
1517 int_vec_zero(v, n);
1518 for (j = 0; j < degree; j++) {
1519 a = Affine[i * degree + j];
1520 v[a]++;
1521 }
1522 idx = index_of_monomial(v);
1523 }
1524#else
1525 idx = wt;
1526#endif
1527
1528#if 0
1529 cout << "affine " << a << " / " << nb_affine << " : ";
1530 int_vec_print(cout, A, 3);
1531 cout << " factors ";
1532 int_vec_print(cout, factors, 3);
1533 cout << " b=" << b << " idx=" << idx << endl;
1534#endif
1535 coeff2[idx] = F->add(coeff2[idx], b);
1536 }
1537 for (j = 0; j <= degree; j++) {
1538 coeff2[j] = F->mult(coeff2[j], c);
1539 }
1540
1541#if 0
1542 cout << "homogeneous_polynomial_domain::substitute_line "
1543 "monomial " << c << " * ";
1544 print_monomial(cout, i);
1545 cout << " yields:" << endl;
1546 int_vec_print(cout, coeff2, nb_monomials);
1547 cout << endl;
1548#endif
1549
1550 for (j = 0; j <= degree; j++) {
1551 coeff3[j] = F->add(coeff2[j], coeff3[j]);
1552 }
1553 }
1554#if 0
1555 cout << "homogeneous_polynomial_domain::substitute_line "
1556 "input:" << endl;
1557 int_vec_print(cout, coeff_in, nb_monomials);
1558 cout << endl;
1559 cout << "homogeneous_polynomial_domain::substitute_line "
1560 "output:" << endl;
1561 int_vec_print(cout, coeff3, nb_monomials);
1562 cout << endl;
1563#endif
1564
1565
1566
1567
1568
1569 Int_vec_copy(coeff3, coeff_out, degree + 1);
1570
1571 FREE_int(Mtx);
1572
1573 if (f_v) {
1574 cout << "homogeneous_polynomial_domain::substitute_line "
1575 "done" << endl;
1576 }
1577}
1578
1580 int *coeff_in, int scalar, int *coeff_out,
1581 int verbose_level)
1582{
1583 int f_v = (verbose_level >= 1);
1584 int i, a, c;
1585
1586 if (f_v) {
1587 cout << "homogeneous_polynomial_domain::multiply_by_scalar" << endl;
1588 }
1589
1590 Int_vec_zero(coeff_out, nb_monomials);
1591 for (i = 0; i < nb_monomials; i++) {
1592 a = coeff_in[i];
1593 if (a == 0) {
1594 continue;
1595 }
1596 if (f_v) {
1597 cout << "coeff_in[" << i << "] = " << a << endl;
1598 }
1599 c = F->mult(a, scalar);
1600 coeff_out[i] = c;
1601 }
1602
1603 if (f_v) {
1604 cout << "homogeneous_polynomial_domain::multiply_by_scalar done" << endl;
1605 }
1606}
1607
1608
1610 int *coeff1, int *coeff2, int *coeff3,
1611 int verbose_level)
1612{
1613 int f_v = (verbose_level >= 1);
1614 int i, j, a, b, c, idx;
1615
1616 if (f_v) {
1617 cout << "homogeneous_polynomial_domain::multiply_mod" << endl;
1618 }
1619
1620 Int_vec_zero(coeff3, nb_monomials);
1621 for (i = 0; i < nb_monomials; i++) {
1622 a = coeff1[i];
1623 if (a == 0) {
1624 continue;
1625 }
1626 if (f_v) {
1627 cout << "coeff1[" << i << "] = " << a << endl;
1628 }
1629 for (j = 0; j < nb_monomials; j++) {
1630 b = coeff2[j];
1631 if (b == 0) {
1632 continue;
1633 }
1634 if (f_v) {
1635 cout << "coeff2[" << j << "] = " << b << endl;
1636 }
1637 c = F->mult(a, b);
1638 idx = (i + j) % nb_monomials;
1639 coeff3[idx] = F->add(coeff3[idx], c);
1640 if (f_v) {
1641 cout << "coeff3[" << idx << "] += " << c << endl;
1642 }
1643 }
1644 }
1645
1646 if (f_v) {
1647 cout << "homogeneous_polynomial_domain::multiply_mod done" << endl;
1648 }
1649}
1650
1652 int *coeff1, int *coeff2, int *coeff3,
1653 int verbose_level)
1654{
1655 int f_v = (verbose_level >= 1);
1656 int i, j, a, b, c, idx;
1657
1658 if (f_v) {
1659 cout << "homogeneous_polynomial_domain::multiply_mod_negatively_wrapped" << endl;
1660 }
1661
1662 Int_vec_zero(coeff3, nb_monomials);
1663 for (i = 0; i < nb_monomials; i++) {
1664 a = coeff1[i];
1665 if (a == 0) {
1666 continue;
1667 }
1668 if (f_v) {
1669 cout << "coeff1[" << i << "] = " << a << endl;
1670 }
1671 for (j = 0; j < nb_monomials; j++) {
1672 b = coeff2[j];
1673 if (b == 0) {
1674 continue;
1675 }
1676 if (f_v) {
1677 cout << "coeff2[" << j << "] = " << b << endl;
1678 }
1679 c = F->mult(a, b);
1680 idx = i + j;
1681 if (idx < nb_monomials) {
1682 coeff3[idx] = F->add(coeff3[idx], c);
1683 }
1684 else {
1685 idx = idx % nb_monomials;
1686 coeff3[idx] = F->add(coeff3[idx], F->negate(c));
1687 }
1688 if (f_v) {
1689 cout << "coeff3[" << idx << "] += " << c << endl;
1690 }
1691 }
1692 }
1693
1694 if (f_v) {
1695 cout << "homogeneous_polynomial_domain::multiply_mod_negatively_wrapped done" << endl;
1696 }
1697}
1698
1699
1701{
1702 int i;
1703
1704 for (i = 0; i < nb_monomials; i++) {
1705 if (coeff[i]) {
1706 return FALSE;
1707 }
1708 }
1709 return TRUE;
1710}
1711
1713{
1714 P->unrank_point(v, rk);
1715}
1716
1718{
1719 int rk;
1720
1721 rk = P->rank_point(v);
1722 return rk;
1723}
1724
1726{
1727 F->PG_element_unrank_modified_lint(v, 1, nb_monomials, rk);
1728}
1729
1731{
1732 long int rk;
1733
1734 F->PG_element_rank_modified_lint(v, 1, nb_monomials, rk);
1735 return rk;
1736}
1737
1739 int &a1, int &a2, int &a3, int &a4, int &a6, int verbose_level)
1740{
1741 int f_v = (verbose_level >= 1);
1742 int m_one;
1743
1744 unrank_coeff_vector(coeff2, rk);
1745 if (f_v) {
1746 cout << "homogeneous_polynomial_domain::test_weierstrass_form"
1747 << endl;
1748 }
1749 if (nb_variables != 3) {
1750 cout << "homogeneous_polynomial_domain::test_weierstrass_form "
1751 "nb_variables != 3" << endl;
1752 exit(1);
1753 }
1754 if (degree != 3) {
1755 cout << "homogeneous_polynomial_domain::test_weierstrass_form "
1756 "degree != 3" << endl;
1757 exit(1);
1758 }
1759 if (coeff2[1] || coeff2[3] || coeff2[6]) {
1760 return FALSE;
1761 }
1762 F->PG_element_normalize_from_front(coeff2, 1, nb_monomials);
1763 if (coeff2[0] != 1) {
1764 return FALSE;
1765 }
1766 m_one = F->negate(1);
1767 if (coeff2[7] != m_one) {
1768 return FALSE;
1769 }
1770 a1 = F->negate(coeff2[4]);
1771 a2 = coeff2[2];
1772 a3 = F->negate(coeff2[8]);
1773 a4 = coeff2[5];
1774 a6 = coeff2[9];
1775 return TRUE;
1776}
1777
1779 int nb_pts, int &r, int *Kernel, int verbose_level)
1780{
1781 int f_v = (verbose_level >= 1);
1782 int f_vv = (verbose_level >= 2);
1783 int i, j;
1784 int *System;
1785
1786 if (f_v) {
1787 cout << "homogeneous_polynomial_domain::vanishing_ideal" << endl;
1788 }
1789 System = NEW_int(MAX(nb_pts, nb_monomials) * nb_monomials);
1790 for (i = 0; i < nb_pts; i++) {
1791 unrank_point(v, Pts[i]);
1792 for (j = 0; j < nb_monomials; j++) {
1793 System[i * nb_monomials + j] =
1795 }
1796 }
1797 if (f_vv) {
1798 cout << "homogeneous_polynomial_domain::vanishing_ideal "
1799 "The system:" << endl;
1800 Int_matrix_print(System, nb_pts, nb_monomials);
1801 }
1802
1803 if (f_v) {
1804 cout << "homogeneous_polynomial_domain::vanishing_ideal "
1805 "before RREF_and_kernel" << endl;
1806 }
1807 r = F->Linear_algebra->RREF_and_kernel(nb_monomials,
1808 nb_pts, System, 0 /* verbose_level */);
1809 if (f_v) {
1810 cout << "homogeneous_polynomial_domain::vanishing_ideal "
1811 "The system has rank " << r << endl;
1812 }
1813 if (f_vv) {
1814 cout << "homogeneous_polynomial_domain::vanishing_ideal "
1815 "The system in RREF:" << endl;
1816 Int_matrix_print(System, r, nb_monomials);
1817 cout << "homogeneous_polynomial_domain::vanishing_ideal "
1818 "The kernel:" << endl;
1819 Int_matrix_print(System + r * nb_monomials,
1820 nb_monomials - r, nb_monomials);
1821 }
1822 Int_vec_copy(System + r * nb_monomials, Kernel,
1823 (nb_monomials - r) * nb_monomials);
1824 FREE_int(System);
1825 if (f_v) {
1826 cout << "homogeneous_polynomial_domain::vanishing_ideal done" << endl;
1827 }
1828}
1829
1831{
1833
1834 if (Monomial_ordering_type == t_PART) {
1835 return compare_monomials_PART(M1, M2);
1836 }
1837 if (Monomial_ordering_type == t_LEX) {
1838 return Sorting.int_vec_compare(M1, M2, nb_variables) * -1;
1839 }
1840 else {
1841 cout << "homogeneous_polynomial_domain::compare_monomials "
1842 "monomial ordering unrecognized" << endl;
1843 exit(1);
1844 }
1845}
1846
1848{
1849 int h, a;
1850 int ret = 0;
1851
1852 Int_vec_zero(type1, degree + 1);
1853 Int_vec_zero(type2, degree + 1);
1854
1855 for (h = 0; h < nb_variables; h++) {
1856 a = M1[h];
1857 type1[a]++;
1858 }
1859 for (h = 0; h < nb_variables; h++) {
1860 a = M2[h];
1861 type2[a]++;
1862 }
1863 for (h = degree; h >= 0; h--) {
1864 if (type2[h] > type1[h]) {
1865 //cout << "type2[h] > type1[h] h=" << h << ", needs swap" << endl;
1866 ret = 1;
1867 goto the_end;
1868 }
1869 if (type2[h] < type1[h]) {
1870 ret = -1;
1871 goto the_end;
1872 }
1873 }
1874
1875 for (a = degree; a >= 1; a--) {
1876 for (h = 0; h < nb_variables; h++) {
1877 if ((M1[h] != a) && (M2[h] != a)) {
1878 continue;
1879 }
1880 if (M1[h] > M2[h]) {
1881 ret = -1;
1882 goto the_end;
1883 }
1884 if (M1[h] < M2[h]) {
1885 //cout << "M1[h] < M2[h] h=" << h << ", needs swap" << endl;
1886 ret = 1;
1887 goto the_end;
1888 }
1889 }
1890 }
1891
1892the_end:
1893 return ret;
1894
1895}
1896
1897
1899{
1900 int h, i, l;
1901
1902 //ost << "The ordering of monomials is:\\\\" << endl;
1903
1904 for (i = 0; i < (nb_monomials + 24) / 25; i++) {
1905
1906 l = MINIMUM((i + 1) * 25, nb_monomials) - i * 25;
1907
1908 ost << "$$" << endl;
1909 ost << "\\begin{array}{|r|r|r|}" << endl;
1910 ost << "\\hline" << endl;
1911 ost << "h & \\mbox{monomial} & \\mbox{vector} \\\\" << endl;
1912 ost << "\\hline" << endl;
1913 ost << "\\hline" << endl;
1914
1915 for (h = 0; h < l; h++) {
1916 ost << i * 25 + h << " & ";
1917 print_monomial_latex(ost, i * 25 + h);
1918 ost << " & ";
1919 Int_vec_print(ost, Monomials + (i * 25 + h) * nb_variables, nb_variables);
1920 ost << "\\\\" << endl;
1921 }
1922 ost << "\\hline" << endl;
1923 ost << "\\end{array}" << endl;
1924 ost << "$$" << endl;
1925
1926 ost << "\\clearpage" << endl;
1927 }
1928}
1929
1931{
1932 int f_v = (verbose_level >= 1);
1933
1934 if (f_v) {
1935 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_pairs" << endl;
1936 }
1937
1938 int *coeff;
1940
1941 coeff = NEW_int(get_nb_monomials());
1942
1944
1945 {
1946 int *coeff_pairs;
1947 int len;
1948 int a, b, i;
1949
1950 Int_vec_scan(str, coeff_pairs, len);
1951 for (i = 0; i < len / 2; i++) {
1952 a = coeff_pairs[2 * i];
1953 b = coeff_pairs[2 * i + 1];
1954 if (b >= get_nb_monomials()) {
1955 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_pairs "
1956 "b >= get_nb_monomials()" << endl;
1957 exit(1);
1958 }
1959 if (b < 0) {
1960 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_pairs "
1961 "b < 0" << endl;
1962 exit(1);
1963 }
1964 if (a < 0 || a >= F->q) {
1965 if (F->e > 1) {
1966 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_pairs "
1967 "In a field extension, what do you mean by " << a << endl;
1968 exit(1);
1969 }
1970 a = NT.mod(a, F->q);
1971 }
1972 coeff[b] = a;
1973
1974 }
1975 FREE_int(coeff_pairs);
1976 }
1977 if (f_v) {
1978 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_pairs done" << endl;
1979 }
1980 return coeff;
1981}
1982
1984{
1985 int f_v = (verbose_level >= 1);
1986
1987 if (f_v) {
1988 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_vector" << endl;
1989 }
1990
1991 int *coeff;
1993
1994 coeff = NEW_int(get_nb_monomials());
1995
1997
1998 {
1999 int *coeffs;
2000 int len;
2001 int a, i;
2002
2003 Int_vec_scan(str, coeffs, len);
2004 if (len != get_nb_monomials()) {
2005 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_vector "
2006 "len >= get_nb_monomials()" << endl;
2007 exit(1);
2008 }
2009
2010 for (i = 0; i < len; i++) {
2011 a = coeffs[i];
2012 if (a < 0 || a >= F->q) {
2013 if (F->e > 1) {
2014 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_vector "
2015 "In a field extension, what do you mean by " << a << endl;
2016 exit(1);
2017 }
2018 a = NT.mod(a, F->q);
2019 }
2020 coeff[i] = a;
2021
2022 }
2023 FREE_int(coeffs);
2024 }
2025 if (f_v) {
2026 cout << "homogeneous_polynomial_domain::read_from_string_coefficient_vector done" << endl;
2027 }
2028 return coeff;
2029}
2030
2031static int homogeneous_polynomial_domain_compare_monomial_with(
2032 void *data, int i, void *data2, void *extra_data)
2033{
2035 (homogeneous_polynomial_domain *) extra_data;
2036 int *Data;
2037 int ret, nb_variables;
2038
2039 Data = (int *) data;
2040 nb_variables = HPD->nb_variables;
2041 ret = HPD->compare_monomials(Data + i * nb_variables, (int *) data2);
2042 return ret;
2043}
2044
2045static int homogeneous_polynomial_domain_compare_monomial(
2046 void *data, int i, int j, void *extra_data)
2047{
2048 homogeneous_polynomial_domain *HPD =
2049 (homogeneous_polynomial_domain *) extra_data;
2050 int *Data;
2051 int ret, nb_variables;
2052
2053 Data = (int *) data;
2054 nb_variables = HPD->nb_variables;
2055 ret = HPD->compare_monomials(Data + i * nb_variables, Data + j * nb_variables);
2056 return ret;
2057}
2058
2059static void homogeneous_polynomial_domain_swap_monomial(
2060 void *data, int i, int j, void *extra_data)
2061{
2062 homogeneous_polynomial_domain *HPD =
2063 (homogeneous_polynomial_domain *) extra_data;
2064 int *Data;
2065 int h, a, nb_variables;
2066
2067 Data = (int *) data;
2068 nb_variables = HPD->nb_variables;
2069
2070 for (h = 0; h < nb_variables; h++) {
2071 a = Data[i * nb_variables + h];
2072 Data[i * nb_variables + h] = Data[j * nb_variables + h];
2073 Data[j * nb_variables + h] = a;
2074 }
2075
2076}
2077
2078#if 0
2079
2080static void HPD_callback_print_function(
2081 stringstream &ost, void *data, void *callback_data)
2082{
2083 homogeneous_polynomial_domain *HPD =
2084 (homogeneous_polynomial_domain *) callback_data;
2085
2086 int *coeff;
2087 int *i_data = (int *) data;
2088
2089 coeff = NEW_int(HPD->get_nb_monomials());
2090 HPD->unrank_coeff_vector(coeff, i_data[0]);
2091 //int_vec_print(cout, coeff, HPD->nb_monomials);
2092 //cout << " = ";
2093 HPD->print_equation_str(ost, coeff);
2094 //ost << endl;
2095 FREE_int(coeff);
2096}
2097
2098static void HPD_callback_print_function2(
2099 stringstream &ost, void *data, void *callback_data)
2100{
2101 homogeneous_polynomial_domain *HPD =
2102 (homogeneous_polynomial_domain *) callback_data;
2103
2104 int *coeff;
2105 int *i_data = (int *) data;
2106 //long int *Pts;
2107 //int nb_pts;
2108 vector<long int> Points;
2109
2110 //Pts = NEW_lint(HPD->get_P()->N_points);
2111 coeff = NEW_int(HPD->get_nb_monomials());
2112 HPD->unrank_coeff_vector(coeff, i_data[0]);
2113 HPD->enumerate_points(coeff, Points, 0 /*verbose_level*/);
2114 ost << Points.size();
2115 //int_vec_print(cout, coeff, HPD->nb_monomials);
2116 //cout << " = ";
2117 //HPD->print_equation_str(ost, coeff);
2118 //ost << endl;
2119 FREE_int(coeff);
2120 //FREE_lint(Pts);
2121}
2122#endif
2123
2124
2125
2126
2127}}}
2128
2129
2130
a collection of functions related to sorted vectors
void Heapsort_general(void *data, int len, int(*compare_func)(void *data, int i, int j, void *extra_data), void(*swap_func)(void *data, int i, int j, void *extra_data), void *extra_data)
Definition: sorting.cpp:1806
int search_general(void *data, int len, void *search_object, int &idx, int(*compare_func)(void *data, int i, void *search_object, void *extra_data), void *extra_data, int verbose_level)
Definition: sorting.cpp:1852
void print_element_str(std::stringstream &ost, int a)
void PG_element_unrank_modified_lint(int *v, int stride, int len, long int a)
void frobenius_power_vec_to_vec(int *v_in, int *v_out, int len, int frob_power)
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 AG_element_unrank(int q, int *v, int stride, int len, long int a)
projective space PG(n,q) of dimension n over Fq
Definition: geometry.h:1916
void projective_space_init(int n, field_theory::finite_field *F, int f_init_incidence_structure, int verbose_level)
int evaluate_monomial(int *monomial, int *variables, int nb_vars)
int RREF_and_kernel(int n, int k, int *A, int verbose_level)
homogeneous polynomials of a given degree in a given number of variables over a finite field GF(q)
Definition: ring_theory.h:88
void multiply_mod_negatively_wrapped(int *coeff1, int *coeff2, int *coeff3, int verbose_level)
void init(field_theory::finite_field *F, int nb_vars, int degree, int f_init_incidence_structure, monomial_ordering_type Monomial_ordering_type, int verbose_level)
void substitute_line(int *coeff_in, int *coeff_out, int *Pt1_coeff, int *Pt2_coeff, int verbose_level)
void print_equation_with_line_breaks_tex_lint(std::ostream &ost, long int *coeffs, int nb_terms_per_line, const char *new_line_text)
int test_weierstrass_form(int rk, int &a1, int &a2, int &a3, int &a4, int &a6, int verbose_level)
void affine_evaluation_kernel(int *&Kernel, int &dim_kernel, int verbose_level)
void enumerate_points(int *coeff, std::vector< long int > &Pts, int verbose_level)
void multiply_by_scalar(int *coeff_in, int scalar, int *coeff_out, int verbose_level)
void remake_symbols(int symbol_offset, const char *symbol_mask, const char *symbol_mask_latex, int verbose_level)
void enumerate_points_lint(int *coeff, long int *&Pts, int &nb_pts, int verbose_level)
void enumerate_points_zariski_open_set(int *coeff, std::vector< long int > &Pts, int verbose_level)
void print_equation_with_line_breaks_tex(std::ostream &ost, int *coeffs, int nb_terms_per_line, const char *new_line_text)
void substitute_semilinear(int *coeff_in, int *coeff_out, int f_semilinear, int frob_power, int *Mtx_inv, int verbose_level)
void multiply_mod(int *coeff1, int *coeff2, int *coeff3, int verbose_level)
void remake_symbols_interval(int symbol_offset, int from, int len, const char *symbol_mask, const char *symbol_mask_latex, int verbose_level)
void algebraic_set(int *Eqns, int nb_eqns, long int *Pts, int &nb_pts, int verbose_level)
void substitute_linear(int *coeff_in, int *coeff_out, int *Mtx_inv, int verbose_level)
void vanishing_ideal(long int *Pts, int nb_pts, int &r, int *Kernel, int verbose_level)
void make_monomials(monomial_ordering_type Monomial_ordering_type, int verbose_level)
diophantine systems of equations (i.e., linear systems over the integers)
Definition: solvers.h:209
void get_solutions_full_length(int *&Sol, int &nb_sol, int verbose_level)
Definition: diophant.cpp:1100
#define Int_vec_scan(A, B, C)
Definition: foundations.h:716
#define NEW_pchar(n)
Definition: foundations.h:635
#define FREE_pchar(p)
Definition: foundations.h:648
#define MINIMUM(x, y)
Definition: foundations.h:216
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define Int_vec_print_fully(A, B, C)
Definition: foundations.h:687
#define ONE_MILLION
Definition: foundations.h:226
#define NEW_char(n)
Definition: foundations.h:632
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define MAX(x, y)
Definition: foundations.h:219
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_char(p)
Definition: foundations.h:646
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define MAXIMUM(x, y)
Definition: foundations.h:217
the orbiter library for the classification of combinatorial objects