Orbiter 2022
Combinatorial Objects
unipoly_domain.cpp
Go to the documentation of this file.
1// unipoly_domain.cpp
2//
3// Anton Betten
4//
5// started: November 16, 2002
6
7
8
9
10#include "foundations.h"
11
12using namespace std;
13
14
15namespace orbiter {
16namespace layer1_foundations {
17namespace ring_theory {
18
19
21{
22 F = NULL;
23 variable_name.assign("X");
24 f_factorring = FALSE;
25 factor_degree = 0;
26 factor_coeffs = NULL;
27 factor_poly = NULL;
28 f_print_sub = FALSE;
29 //f_use_variable_name = FALSE;
30 //std::string variable_name;
31}
32
34{
35 unipoly_domain::F = F;
36 variable_name.assign("X");
37 f_factorring = FALSE;
38 factor_degree = 0;
39 factor_coeffs = NULL;
40 factor_poly = NULL;
41 f_print_sub = FALSE;
42 //f_use_variable_name = FALSE;
43 //std::string variable_name;
44}
45
47{
48 int f_v = (verbose_level >= 1);
49
50 if (f_v) {
51 cout << "unipoly_domain::init_basic" << endl;
52 }
53 unipoly_domain::F = F;
54 variable_name.assign("X");
55 f_factorring = FALSE;
56 factor_degree = 0;
57 factor_coeffs = NULL;
58 factor_poly = NULL;
59 f_print_sub = FALSE;
60 //f_use_variable_name = FALSE;
61 //std::string variable_name;
62 if (f_v) {
63 cout << "unipoly_domain::init_basic done" << endl;
64 }
65}
66
68{
69 int f_v = (verbose_level >= 1);
70 //int i, a, b;
71
72 unipoly_domain::F = F;
73 variable_name.assign("X");
74 f_print_sub = FALSE;
75 f_factorring = FALSE;
76
77 if (f_v) {
78 cout << "unipoly_domain::unipoly_domain creating factorring modulo " << endl;
79 print_object(m, cout);
80 cout << endl;
81 //cout << " of degree " << ((int *)m)[0] << endl;
82 }
83
84#if 0
85 variable_name.assign("X");
86 f_factorring = TRUE;
87 factor_degree = ((int *)m)[0];
88 factor_coeffs = NEW_int(factor_degree + 1);
89 for (i = 0; i <= factor_degree; i++) {
90 factor_coeffs[i] = ((int *)m)[1 + i];
91 }
92 //factor_coeffs = ((int *)m) + 1;
93 if (factor_coeffs[factor_degree] != 1) {
94 cout << "unipoly_domain::unipoly_domain "
95 "factor polynomial is not monic" << endl;
96 exit(1);
97 }
98 for (i = 0; i < factor_degree; i++) {
99 a = factor_coeffs[i];
100 b = F->negate(a);
101 factor_coeffs[i] = b;
102 }
103 create_object_of_degree_no_test(factor_poly, factor_degree);
104 for (i = 0; i <= factor_degree; i++) {
105 ((int *)factor_poly)[1 + i] = ((int *)m)[1 + i];
106 }
107 //factor_poly = m;
108 if (f_v) {
109 cout << "unipoly_domain::unipoly_domain factor_coeffs = ";
110 Orbiter->Int_vec.print(cout, factor_coeffs, factor_degree + 1);
111 cout << endl;
112 }
113 f_print_sub = FALSE;
114#else
115
116 init_factorring(F, m, verbose_level);
117
118#endif
119 if (f_v) {
120 cout << "unipoly_domain::unipoly_domain creating factorring done" << endl;
121 }
122}
123
125{
126 //int i, a, b;
127
128 if (f_factorring) {
129 FREE_int(factor_coeffs);
130 delete_object(factor_poly);
131 }
132}
133
135{
136 variable_name.assign(label);
137}
138
140{
141 int f_v = (verbose_level >= 1);
142 int i, a, b;
143
144 if (f_v) {
145 cout << "unipoly_domain::init_factorring creating factorring modulo ";
146 print_object(m, cout);
147 cout << " of degree " << ((int *)m)[0] << endl;
148 }
149 unipoly_domain::F = F;
150 variable_name.assign("X");
151 f_factorring = TRUE;
152 factor_degree = ((int *)m)[0];
153 factor_coeffs = NEW_int(factor_degree + 1);
154 for (i = 0; i <= factor_degree; i++) {
155 factor_coeffs[i] = ((int *)m)[1 + i];
156 }
157 //factor_coeffs = ((int *)m) + 1;
158 if (factor_coeffs[factor_degree] != 1) {
159 cout << "unipoly_domain::init_factorring "
160 "factor polynomial is not monic" << endl;
161 exit(1);
162 }
163 for (i = 0; i < factor_degree; i++) {
164 a = factor_coeffs[i];
165 b = F->negate(a);
166 factor_coeffs[i] = b;
167 }
168 create_object_of_degree_no_test(factor_poly, factor_degree);
169 for (i = 0; i <= factor_degree; i++) {
170 ((int *)factor_poly)[1 + i] = ((int *)m)[1 + i];
171 }
172 //factor_poly = m;
173 if (f_v) {
174 cout << "unipoly_domain::init_factorring factor_coeffs = ";
175 Int_vec_print(cout, factor_coeffs, factor_degree + 1);
176 cout << endl;
177 }
178 f_print_sub = FALSE;
179 if (f_v) {
180 cout << "unipoly_domain::init_factorring done" << endl;
181 }
182}
183
184
185
186
188{
189 return F;
190}
191
193 unipoly_object &p, int d)
194{
195 if (f_factorring) {
196 cout << "unipoly_domain::create_object_of_degree "
197 "a factorring" << endl;
198 exit(1);
199 }
201}
202
204 unipoly_object &p, int d)
205{
206 int *rep = NEW_int(d + 2);
207 rep[0] = d;
208 int *coeff = rep + 1;
209 int i;
210
211 for (i = 0; i <= d; i++) {
212 coeff[i] = 0;
213 }
214 rep[0] = d;
215 p = (void *) rep;
216}
217
219 unipoly_object &p, int d, int *coeff)
220{
221 if (f_factorring) {
222 cout << "unipoly_domain::create_object_of_degree_with_coefficients a factorring" << endl;
223 exit(1);
224 }
225 int *rep = NEW_int(d + 2);
226 rep[0] = d;
227 int *C = rep + 1;
228 int i;
229
230 for (i = 0; i <= d; i++) {
231 C[i] = coeff[i];
232 }
233 rep[0] = d;
234 p = (void *) rep;
235}
236
238 unipoly_object &p, long int rk,
239 const char *file, int line, int verbose_level)
240{
241 int f_v = (verbose_level >= 1);
243
244 if (f_v) {
245 cout << "unipoly_domain::create_object_by_rank rk=" << rk << endl;
246 cout << "unipoly_domain::create_object_by_rank f_factorring=" << f_factorring << endl;
247 }
248
249 int len = NT.lint_logq(rk, F->q);
250
251 if (f_factorring) {
252 if (len > factor_degree) {
253 cout << "unipoly_domain::create_object_by_rank "
254 "len > factor_degree" << endl;
255 exit(1);
256 }
257 if (f_v) {
258 cout << "unipoly_domain::create_object_by_rank modulo - (";
259 Int_vec_print(cout,
260 factor_coeffs,
261 factor_degree + 1);
262 cout << ")" << endl;
263 }
264 len = factor_degree;
265 int *rep = NEW_int_with_tracking(len + 1, file, line);
266 rep[0] = len - 1;
267 int *coeff = rep + 1;
268 int i = 0;
269
270 for (i = 0; i < factor_degree; i++) {
271 coeff[i] = rk % F->q;
272 rk /= F->q;
273 }
274 rep[0] = factor_degree - 1; //i - 1;
275 p = (void *) rep;
276 }
277 else {
278 int *rep = NEW_int_with_tracking(len + 1, file, line);
279 rep[0] = len - 1;
280 int *coeff = rep + 1;
281 int i = 0;
282
283 do {
284 coeff[i] = rk % F->q;
285 rk /= F->q;
286 i++;
287 } while (rk);
288 rep[0] = i - 1;
289 p = (void *) rep;
290 }
291 if (f_v) {
292 cout << "unipoly_domain::create_object_by_rank done" << endl;
293 }
294}
295
297 unipoly_object &p, std::string &fname,
298 const char *file, int line,
299 int verbose_level)
300{
301 int f_v = (verbose_level >= 1);
304 int m, n, len;
305 long int *M;
306
307 if (f_v) {
308 cout << "unipoly_domain::create_object_from_csv_file" << endl;
309 }
310 if (f_factorring) {
311 cout << "unipoly_domain::create_object_from_csv_file "
312 "f_factorring" << endl;
313 exit(1);
314 }
315 Fio.lint_matrix_read_csv(fname, M, m, n, 0 /* verbose_level */);
316 len = m * n;
317
318
319 int *rep = NEW_int_with_tracking(len + 1, file, line);
320 rep[0] = len - 1;
321 int *coeff = rep + 1;
322 int i = 0;
323
324 for (i = 0; i < len; i++) {
325 coeff[len - 1 - i] = M[i];
326 }
327 //rep[0] = i - 1;
328 p = (void *) rep;
329 FREE_lint(M);
330}
331
334 longinteger_object &rank,
335 const char *file, int line,
336 int verbose_level)
337{
338 int f_v = (verbose_level >= 1);
339 int f_vv = (verbose_level >= 2);
340 longinteger_object rk, rk1;
342
343 int len = D.logarithm_base_b(rank, F->q);
344 //cout << "len = " << len << endl;
345
346 if (f_v) {
347 cout << "unipoly_domain::create_object_by_rank_longinteger rank=" << rank << endl;
348 }
349 if (f_factorring) {
350 if (len > factor_degree) {
351 cout << "unipoly_domain::create_object_by_rank_longinteger len > factor_degree" << endl;
352 exit(1);
353 }
354 if (f_v) {
355 cout << "unipoly_domain::create_object_by_rank_longinteger modulo - (";
356 Int_vec_print(cout,
357 factor_coeffs,
358 factor_degree + 1);
359 cout << ")" << endl;
360 }
361 len = factor_degree;
362 }
363 int *rep = NEW_int_with_tracking(len + 1, file, line);
364 rep[0] = len - 1;
365 int *coeff = rep + 1;
366 int i = 0;
367
368 rank.assign_to(rk);
369 do {
370 D.integral_division_by_int(rk, F->q, rk1, coeff[i]);
371 //cout << "rk=" << rk << " coeff[" << i
372 // << "] = " << coeff[i] << endl;
373 // coeff[i] = rk % F->q;
374 if (f_vv) {
375 cout << "unipoly_domain::create_object_by_rank_longinteger "
376 "i=" << i << " rk=" << rk << " quotient " << rk1
377 << " remainder " << coeff[i] << endl;
378 }
379 rk1.assign_to(rk);
380 //rk /= F->q;
381 i++;
382 } while (!rk.is_zero());
383 rep[0] = i - 1;
384 p = (void *) rep;
385 //print_object(p, cout); cout << endl;
386}
387
389 unipoly_object &p, std::string &rk, int verbose_level)
390{
391 int f_v = (verbose_level >= 1);
393
394 rank.create_from_base_10_string(rk);
395
396 create_object_by_rank_longinteger(p, rank, __FILE__, __LINE__, verbose_level);
397 if (f_v) {
398 cout << "unipoly_domain::create_object_by_rank_string ";
399 print_object(p, cout);
400 cout << endl;
401 }
402}
403
405 unipoly_object &p, int *map)
406{
407 if (f_factorring) {
408 cout << "unipoly_domain::create_Dickson_polynomial "
409 "a factorring" << endl;
410 exit(1);
411 }
412 int d = F->q - 1;
413 int *rep = NEW_int(d + 2);
414 rep[0] = d;
415 int *coeff = rep + 1;
416
417 F->Linear_algebra->Dickson_polynomial(map, coeff);
418 rep[0] = d;
419 p = (void *) rep;
420 degree(p);
421}
422
424{
425 int *rep = (int *) p;
426 FREE_int(rep);
427 p = NULL;
428}
429
431{
432 int *rep = (int *) p;
433 int *coeff = rep + 1;
434 int i = 0;
435
436 do {
437 coeff[i] = rk % F->q;
438 rk /= F->q;
439 i++;
440 } while (rk);
441 rep[0] = i - 1;
442}
443
446{
447 int *rep = (int *) p;
448 int *coeff = rep + 1;
449 int i = 0;
450
451 longinteger_object rank1, rank2;
453
454 rank.assign_to(rank1);
455 do {
456 D.integral_division_by_int(rank1, F->q, rank2, coeff[i]);
457 //coeff[i] = rk % F->q;
458 //rk /= F->q;
459 rank2.assign_to(rank1);
460 i++;
461 } while (!rank1.is_zero());
462 rep[0] = i - 1;
463}
464
466{
467 int *rep = (int *) p;
468 int d = rep[0]; // degree
469 int *coeff = rep + 1;
470 int rk = 0;
471 int i;
472
473 for (i = d; i >= 0; i--) {
474 rk *= F->q;
475 rk += coeff[i];
476 }
477 return rk;
478}
479
482{
483 int *rep = (int *) p;
484 int d = rep[0]; // degree
485 int *coeff = rep + 1;
486 int i;
487 longinteger_object q, rk, rk1, c;
489
490 rk.create(0, __FILE__, __LINE__);
491 q.create(F->q, __FILE__, __LINE__);
492 for (i = d; i >= 0; i--) {
493 D.mult(rk, q, rk1);
494 c.create(coeff[i], __FILE__, __LINE__);
495 D.add(rk1, c, rk);
496 //rk *= F->q;
497 //rk += coeff[i];
498 }
499 rk.assign_to(rank);
500}
501
503{
504 int *rep = (int *) p;
505 int d = rep[0]; // degree
506 int *coeff = rep + 1;
507 int i;
508
509 for (i = d; i >= 0; i--) {
510 if (coeff[i]) {
511 break;
512 }
513 }
514 rep[0] = i;
515 return i;
516}
517
518
520{
521 int i, k;
522 int f_prev = FALSE;
523 string x, y;
524 int f_nothing_printed_at_all = TRUE;
525 int *rep = (int *) p;
526 int d = rep[0]; // degree
527 int *coeff = rep + 1;
528
529 x.assign(variable_name);
530 if (f_print_sub) {
531 y.assign("_");
532 }
533 else {
534 y.assign("^");
535 }
536 // ost << "(";
537 for (i = d; i >= 0; i--) {
538 k = coeff[i];
539 if (k == 0) {
540 continue;
541 }
542 f_nothing_printed_at_all = FALSE;
543 if (f_prev) {
544 ost << " + ";
545 }
546 if (k != 1 || (i == 0 /*&& !unip_f_use_variable_name*/)) {
547 //l = F->log_alpha(k);
548 //ost << "\\alpha^{" << l << "}";
549 ost << k;
550 }
551 if (i == 0) {
552 //ost << x;
553 //ost << y;
554 //ost << "0";
555 }
556 else if (i == 1) {
557 ost << x;
558 if (f_print_sub) {
559 ost << y;
560 ost << "1";
561 }
562 }
563 else if (i > 1) {
564 ost << x;
565 ost << y;
566 ost << "{" << i << "}";
567 }
568 f_prev = TRUE;
569 }
570 if (f_nothing_printed_at_all) {
571 ost << "0";
572 }
573 // ost << ")";
574 //return ost;
575}
576
578{
579 int i, k;
580 int *rep = (int *) p;
581 int d = rep[0]; // degree
582 int *coeff = rep + 1;
583
584
585 for (i = 0; i <= d; i++) {
586 k = coeff[i];
587 ost << k;
588 }
589}
590
592{
593 int i, a;
594 int *rep = (int *) p;
595 int d = rep[0]; // degree
596 int *coeff = rep + 1;
597 int f_first = TRUE;
598
599
600 for (i = 0; i <= d; i++) {
601 a = coeff[i];
602
603 if (a) {
604 if (f_first) {
605 f_first = FALSE;
606 }
607 else {
608 ost << ",";
609 }
610 ost << a << "," << i;
611 }
612 }
613}
614
616{
617 int i, a;
618 int *rep = (int *) p;
619 int d = rep[0]; // degree
620 int *coeff = rep + 1;
621
622
623 for (i = 0; i <= d; i++) {
624 a = coeff[i];
625
626 ost << a;
627 if (i < d) {
628 ost << ",";
629 }
630 }
631}
632
633
634
636{
637 int f_v = (verbose_level >= 1);
638
639 if (f_v) {
640 cout << "unipoly_domain::assign" << endl;
641 }
642 if (f_factorring) {
643 if (f_v) {
644 cout << "unipoly_domain::assign with factorring";
645 cout << " modulo - (";
646 Int_vec_print(cout,
647 factor_coeffs,
648 factor_degree + 1);
649 cout << ")" << endl;
650 }
651 if (a == NULL) {
652 cout << "unipoly_domain::assign with factorring a == NULL" << endl;
653 exit(1);
654 }
655 if (b == NULL) {
656 cout << "unipoly_domain::assign with factorring b == NULL" << endl;
657 exit(1);
658 }
659 int *ra = (int *) a;
660 int *rb = (int *) b;
661 if (rb[0] < factor_degree - 1) {
662 cout << "unipoly_domain::assign rb[0] < factor_degree - 1" << endl;
663 cout << "rb[0] = " << rb[0] << endl;
664 cout << "factor_degree = " << factor_degree << endl;
665 exit(1);
666 }
667 int *A = ra + 1;
668 int *B = rb + 1;
669 int i;
670 for (i = 0; i < factor_degree; i++) {
671 B[i] = A[i];
672 }
673 rb[0] = ra[0];
674 if (f_v) {
675 cout << "unipoly_domain::assign after copy" << endl;
676 }
677 }
678 else {
679 if (f_v) {
680 cout << "unipoly_domain::assign not a factorring" << endl;
681 }
682 int *ra = (int *) a;
683 int *rb = (int *) b;
684 int m = ra[0];
685 FREE_int(rb);
686 rb = NEW_int(m + 2);
687 rb[0] = m;
688 b = (void *) rb;
689 if (f_v) {
690 cout << "unipoly_domain::assign m=" << m << endl;
691 cout << "a=";
692 print_object(a, cout);
693 cout << endl;
694 }
695 int *A = ra + 1;
696 int *B = rb + 1;
697 int i;
698 for (i = 0; i <= m; i++) {
699 B[i] = A[i];
700 if (f_v) {
701 cout << "i=" << i << " A[i]=" << A[i]
702 << " B[i]=" << B[i] << endl;
703 }
704 }
705 if (f_v) {
706 cout << "unipoly_domain::assign after copy" << endl;
707 }
708 }
709 if (f_v) {
710 cout << "unipoly_domain::assign done" << endl;
711 }
712}
713
715{
716 int *rep = (int *) p;
717 int d = rep[0]; // degree
718 int *coeff = rep + 1;
719 int i;
720
721 for (i = d; i >= 1; i--) {
722 coeff[i] = 0;
723 }
724 coeff[0] = 1;
725 rep[0] = 0;
726}
727
729{
730 int *rep = (int *) p;
731 int d = rep[0]; // degree
732 int *coeff = rep + 1;
733 int i;
734
735 for (i = d; i >= 1; i--) {
736 coeff[i] = 0;
737 }
738 coeff[0] = F->negate(1);
739 rep[0] = 0;
740}
741
743{
744 int *rep = (int *) p;
745 int d = rep[0]; // degree
746 int *coeff = rep + 1;
747 int i;
748
749 for (i = d; i >= 1; i--) {
750 coeff[i] = 0;
751 }
752 coeff[0] = 0;
753 rep[0] = 0;
754}
755
757{
758 int *rep = (int *) p;
759 if (rep == NULL) {
760 cout << "unipoly_domain::is_one rep == NULL" << endl;
761 exit(1);
762 }
763 int d = rep[0]; // degree
764 int *coeff = rep + 1;
765 int i;
766
767 for (i = d; i >= 1; i--) {
768 if (coeff[i]) {
769 return FALSE;
770 }
771 }
772 if (coeff[0] != 1) {
773 return FALSE;
774 }
775 return TRUE;
776}
777
779{
780 int *rep = (int *) p;
781 if (rep == NULL) {
782 cout << "unipoly_domain::is_zero rep == NULL" << endl;
783 exit(1);
784 }
785 int d = rep[0]; // degree
786 int *coeff = rep + 1;
787 int i;
788
789 for (i = d; i >= 0; i--) {
790 if (coeff[i]) {
791 return FALSE;
792 }
793 }
794 return TRUE;
795}
796
798{
799 int *ra = (int *) a;
800 if (ra == NULL) {
801 cout << "unipoly_domain::negate rep == NULL" << endl;
802 exit(1);
803 }
804 int m = ra[0];
805 int *A = ra + 1;
806 int i;
807
808 for (i = 0; i <= m; i++) {
809 A[i] = F->negate(A[i]);
810 }
811}
812
814{
815 int *ra = (int *) a;
816 if (ra == NULL) {
817 cout << "unipoly_domain::make_monic rep == NULL" << endl;
818 exit(1);
819 }
820 int m = ra[0];
821 int *A = ra + 1;
822 int i, c, cv;
823
824 while (A[m] == 0 && m > 0) {
825 m--;
826 }
827 if (m == 0 && A[0] == 0) {
828 cout << "unipoly_domain::make_monic "
829 "the polynomial is zero" << endl;
830 exit(1);
831 }
832 c = A[m];
833 if (c != 1) {
834 cv = F->inverse(c);
835 for (i = 0; i <= m; i++) {
836 A[i] = F->mult(A[i], cv);
837 }
838 }
839}
840
843{
844 int verbose_level = 0;
845 int f_v = (verbose_level >= 1);
846 int *ra = (int *) a;
847 int *rb = (int *) b;
848 int m = ra[0];
849 int n = rb[0];
850 int mn = MAXIMUM(m, n);
851
852 int *rc = (int *) c;
853 FREE_int(rc);
854 rc = NEW_int(mn + 2);
855
856 int *A = ra + 1;
857 int *B = rb + 1;
858 int *C = rc + 1;
859 int i, x, y;
860
861 rc[0] = mn;
862 for (i = 0; i <= MAXIMUM(m, n); i++) {
863 if (i <= m) {
864 x = A[i];
865 }
866 else {
867 x = 0;
868 }
869 if (i <= n) {
870 y = B[i];
871 }
872 else {
873 y = 0;
874 }
875 if (f_v) {
876 cout << "unipoly_domain::add "
877 "x=" << x << " y=" << y << endl;
878 }
879 C[i] = F->add(x, y);
880 }
881 c = (void *) rc;
882}
883
885 unipoly_object b, unipoly_object &c, int verbose_level)
886{
887 int f_v = (verbose_level >= 1);
888
889 if (f_v) {
890 cout << "unipoly_domain::mult" << endl;
891 }
892 if (f_factorring) {
893 if (f_v) {
894 cout << "unipoly_domain::mult before mult_mod" << endl;
895 }
896 mult_mod_negated(a, b, c, factor_degree, factor_coeffs, verbose_level);
897 if (f_v) {
898 cout << "unipoly_domain::mult after mult_mod" << endl;
899 }
900 }
901 else {
902 mult_easy(a, b, c);
903 }
904 if (f_v) {
905 cout << "unipoly_domain::mult done" << endl;
906 }
907}
908
911 int verbose_level)
912{
913 int f_v = (verbose_level >= 1);
914
915 if (f_v) {
916 cout << "unipoly_domain::mult_mod" << endl;
917 }
918
919 int d;
920 int *factor_polynomial_coefficients_negated;
921 int i;
922
923
924 d = degree(m);
925 factor_polynomial_coefficients_negated = NEW_int(d + 1);
926 for (i = 0; i <= d; i++) {
927 factor_polynomial_coefficients_negated[i] = F->negate(s_i(m, i));
928 }
929
930 mult_mod_negated(a, b, c,
931 d,
932 factor_polynomial_coefficients_negated,
933 verbose_level);
934
935 FREE_int(factor_polynomial_coefficients_negated);
936
937 if (f_v) {
938 cout << "unipoly_domain::mult_mod done" << endl;
939 }
940}
941
944 int factor_polynomial_degree,
945 int *factor_polynomial_coefficients_negated,
946 int verbose_level)
947{
948 int f_v = (verbose_level >= 1);
949 int f_vv = (verbose_level >= 2);
950 int *ra = (int *) a;
951 int *rb = (int *) b;
952 int *rc = (int *) c;
953 int m = ra[0];
954 int n = rb[0];
955 int *A = ra + 1;
956 int *B = rb + 1;
957 int *C = rc + 1;
958 int carry, c1;
959 int i, j;
960
961 if (f_v) {
962 cout << "unipoly_domain::mult_mod_negated" << endl;
963 }
964 if (f_vv) {
965 cout << "unipoly_domain::mult_mod_negated computing ";
966 print_object(ra, cout);
967 cout << " x ";
968 print_object(rb, cout);
969 cout << " modulo - (";
970 Int_vec_print(cout,
971 factor_polynomial_coefficients_negated,
972 factor_polynomial_degree + 1);
973 cout << ")";
974 cout << endl;
975 }
976#if 0
977 if (!f_factorring) {
978 cout << "unipoly_domain::mult_mod_negated not a factorring" << endl;
979 exit(1);
980 }
981#endif
982 if (rc[0] != factor_polynomial_degree - 1) {
983 FREE_int(rc);
984 rc = NEW_int(factor_polynomial_degree - 1 + 2);
985 rc[0] = factor_polynomial_degree - 1;
986 c = rc;
987 C = rc + 1;
988 }
989 for (j = 0 ; j < factor_polynomial_degree; j++) {
990 C[j] = 0;
991 }
992
993 for (i = m; i >= 0; i--) {
994 for (j = 0; j <= n; j++) {
995 c1 = F->mult(A[i], B[j]);
996 C[j] = F->add(C[j], c1);
997 if (f_vv) {
998 if (c1) {
999 cout << A[i] << "x^" << i << " * "
1000 << B[j] << " x^" << j << " = "
1001 << c1 << " x^" << i + j << " = ";
1002 print_object(rc, cout);
1003 cout << endl;
1004 }
1005 }
1006 }
1007 //cout << "i=" << i << " ";
1008 //print_object(C, cout);
1009 //cout << endl;
1010
1011 if (i > 0) {
1012 carry = C[factor_polynomial_degree - 1];
1013 for (j = factor_polynomial_degree - 1; j > 0; j--) {
1014 C[j] = C[j - 1];
1015 }
1016 C[0] = 0;
1017 if (carry) {
1018 if (carry == 1) {
1019 for (j = 0; j < factor_polynomial_degree; j++) {
1020 C[j] = F->add(C[j],
1021 factor_polynomial_coefficients_negated[j]);
1022 }
1023 }
1024 else {
1025 for (j = 0; j < factor_polynomial_degree; j++) {
1026 c1 = F->mult(carry,
1027 factor_polynomial_coefficients_negated[j]);
1028 C[j] = F->add(C[j], c1);
1029 }
1030 }
1031 }
1032 }
1033 }
1034 c = rc;
1035 if (f_v) {
1036 cout << "unipoly_domain::mult_mod_negated done" << endl;
1037 }
1038}
1039
1041 unipoly_object factor_polynomial, int verbose_level)
1042// the j-th row of Frob is x^{j*q} mod m
1043{
1044 int f_v = (verbose_level >= 1);
1045 int d;
1046
1047 if (f_v) {
1048 cout << "unipoly_domain::Frobenius_matrix_by_rows" << endl;
1049 }
1050 d = degree(factor_polynomial);
1051 Frobenius_matrix(Frob, factor_polynomial, verbose_level);
1053 if (f_v) {
1054 cout << "unipoly_domain::Frobenius_matrix_by_rows done" << endl;
1055 }
1056}
1057
1059 unipoly_object factor_polynomial, int verbose_level)
1060// the j-th column of Frob is x^{j*q} mod m
1061
1062{
1063 int f_v = (verbose_level >= 1);
1064 int f_vv = (verbose_level >= 2);
1065 int f_vvv = FALSE;
1066
1067 if (f_v) {
1068 cout << "unipoly_domain::Frobenius_matrix" << endl;
1069 }
1070 if (f_v) {
1071 cout << "unipoly_domain::Frobenius_matrix "
1072 "q=" << F->q << endl;
1073 }
1074#if 0
1075 if (!f_factorring) {
1076 cout << "unipoly_domain::Frobenius_matrix "
1077 "not a factorring" << endl;
1078 exit(1);
1079 }
1080#endif
1081 unipoly_object a, b, c, m_mod, Q, R;
1082 int i, j, d1;
1083 int factor_polynomial_degree;
1084
1085 factor_polynomial_degree = degree(factor_polynomial);
1086 if (f_v) {
1087 cout << "unipoly_domain::Frobenius_matrix "
1088 "degree=" << factor_polynomial_degree << endl;
1089 cout << "unipoly_domain::Frobenius_matrix m = ";
1090 print_object(factor_polynomial, cout);
1091 cout << endl;
1092 }
1093
1094 Frob = NEW_int(factor_polynomial_degree * factor_polynomial_degree);
1095 Int_vec_zero(Frob,
1096 factor_polynomial_degree * factor_polynomial_degree);
1097 Frob[0] = 1; // the first column of Frob is (1,0,...,0)
1098
1099 create_object_by_rank(a, F->q, __FILE__, __LINE__, 0 /*verbose_level*/); // the polynomial X
1100 create_object_by_rank(b, 1, __FILE__, __LINE__, 0 /*verbose_level*/); // the polynomial 1
1101 create_object_by_rank(c, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1102 create_object_by_rank(m_mod, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1103 create_object_by_rank(Q, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1104 create_object_by_rank(R, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1105
1106 assign(factor_polynomial, m_mod, 0 /*verbose_level */);
1107 negate(m_mod);
1108 if (f_v) {
1109 cout << "unipoly_domain::Frobenius_matrix m_mod = ";
1110 print_object(m_mod, cout);
1111 cout << endl;
1112 }
1113
1114 if (f_v) {
1115 cout << "unipoly_domain::Frobenius_matrix before power_int" << endl;
1116 }
1117 power_int(a, F->q, 0 /*verbose_level*/);
1118 if (f_v) {
1119 cout << "unipoly_domain::Frobenius_matrix after power_int" << endl;
1120 cout << "unipoly_domain::Frobenius_matrix a = x^q = ";
1121 print_object(a, cout);
1122 cout << endl;
1123 }
1124 if (f_v) {
1125 cout << "unipoly_domain::Frobenius_matrix before division_with_remainder" << endl;
1126 }
1128 factor_polynomial,
1129 Q, R, 0 /*verbose_level*/);
1130 if (f_v) {
1131 cout << "unipoly_domain::Frobenius_matrix after division_with_remainder" << endl;
1132 }
1133 assign(R, a, 0 /*verbose_level */);
1134 if (f_vv) {
1135 cout << "unipoly_domain::Frobenius_matrix "
1136 "a(X) = X^q mod m(X) = ";
1137 print_object(a, cout);
1138 cout << endl;
1139 }
1140 for (j = 1; j < factor_polynomial_degree; j++) {
1141 if (f_vvv) {
1142 cout << "unipoly_domain::Frobenius_matrix j = " << j << endl;
1143 cout << "b = ";
1144 print_object(b, cout);
1145 cout << endl;
1146 cout << "a = ";
1147 print_object(a, cout);
1148 cout << endl;
1149 }
1150 mult_mod_negated(b, a, c,
1151 factor_polynomial_degree, ((int *)m_mod) + 1, 0);
1152 if (f_vvv) {
1153 cout << "c = ";
1154 print_object(c, cout);
1155 cout << endl;
1156 }
1157 assign(c, b, 0 /*verbose_level */);
1158 // now b = X^{j*q}
1159 if (f_vvv) {
1160 cout << "unipoly_domain::Frobenius_matrix X^{" << j << "*q}=";
1161 print_object(b, cout);
1162 cout << endl;
1163 }
1164 d1 = degree(b);
1165 int *rb = (int *) b;
1166 int *B = rb + 1;
1167
1168 // put B in the j-th column of F:
1169 for (i = 0; i <= d1; i++) {
1170 Frob[i * factor_polynomial_degree + j] = B[i];
1171 }
1172 }
1173 if (f_vv) {
1174 cout << "unipoly_domain::Frobenius_matrix=" << endl;
1175 Int_matrix_print(Frob,
1176 factor_polynomial_degree, factor_polynomial_degree);
1177 cout << endl;
1178 }
1179 delete_object(a);
1180 delete_object(b);
1181 delete_object(c);
1182 delete_object(m_mod);
1183 delete_object(Q);
1184 delete_object(R);
1185 if (f_v) {
1186 cout << "unipoly_domain::Frobenius_matrix done" << endl;
1187 }
1188}
1189
1191 unipoly_object factor_polynomial, int verbose_level)
1192// subtracts the identity matrix off the Frobenius matrix
1193{
1194 int f_v = (verbose_level >= 1);
1195 int i, m1, a, b;
1196 int factor_polynomial_degree;
1197
1198 if (f_v) {
1199 cout << "unipoly_domain::Berlekamp_matrix" << endl;
1200 }
1201 factor_polynomial_degree = degree(factor_polynomial);
1202 if (f_v) {
1203 cout << "unipoly_domain::Berlekamp_matrix before Frobenius_matrix" << endl;
1204 }
1205 Frobenius_matrix(B, factor_polynomial, verbose_level - 2);
1206 if (f_v) {
1207 cout << "unipoly_domain::Berlekamp_matrix after Frobenius_matrix" << endl;
1208 cout << "Frobenius matros:" << endl;
1210 factor_polynomial_degree, factor_polynomial_degree);
1211 }
1212 m1 = F->negate(1);
1213
1214 for (i = 0; i < factor_polynomial_degree; i++) {
1215 a = B[i * factor_polynomial_degree + i];
1216 b = F->add(m1, a);
1217 B[i * factor_polynomial_degree + i] = b;
1218 }
1219 if (f_v) {
1220 cout << "unipoly_domain::Berlekamp_matrix "
1221 "of degree " << factor_polynomial_degree
1222 << " = " << endl;
1224 factor_polynomial_degree, factor_polynomial_degree);
1225 cout << endl;
1226 }
1227}
1228
1231 int verbose_level)
1232{
1233 int f_v = (verbose_level >= 1);
1234
1235 if (f_v) {
1236 cout << "unipoly_domain::exact_division" << endl;
1237 }
1238
1240
1241 create_object_by_rank(r, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1242
1243 division_with_remainder(a, b, q, r, verbose_level - 1);
1244
1245 delete_object(r);
1246
1247 if (f_v) {
1248 cout << "unipoly_domain::exact_division done" << endl;
1249 }
1250}
1251
1255 int verbose_level)
1256{
1257 int f_v = (verbose_level >= 1);
1258 //int *ra = (int *) a;
1259 int *rb = (int *) b;
1260 //int *A = ra + 1;
1261 int *B = rb + 1;
1262
1263 int da, db;
1264
1265 if (f_v) {
1266 cout << "unipoly_domain::division_with_remainder" << endl;
1267 }
1268 da = degree(a);
1269 db = degree(b);
1270
1271 if (f_factorring) {
1272 cout << "unipoly_domain::division_with_remainder "
1273 "not good for a factorring" << endl;
1274 exit(1);
1275 }
1276 if (db == 0) {
1277 if (B[0] == 0) {
1278 cout << "unipoly_domain::division_with_remainder: "
1279 "division by zero" << endl;
1280 exit(1);
1281 }
1282 }
1283 if (db > da) {
1284 int *rq = (int *) q;
1285 FREE_int(rq);
1286 rq = NEW_int(2);
1287 int *Q = rq + 1;
1288 Q[0] = 0;
1289 rq[0] = 0;
1290 assign(a, r, 0 /*verbose_level*/);
1291 q = rq;
1292 goto done;
1293 }
1294
1295 {
1296 int dq = da - db;
1297 int *rq = (int *) q;
1298 FREE_int(rq);
1299 rq = NEW_int(dq + 2);
1300 rq[0] = dq;
1301
1302 assign(a, r, 0 /*verbose_level*/);
1303
1304 int *rr = (int *) r;
1305
1306 int *Q = rq + 1;
1307 int *R = rr + 1;
1308
1309 int i, j, ii, jj, pivot, pivot_inv, x, c, d;
1310
1311 pivot = B[db];
1312 pivot_inv = F->inverse(pivot);
1313
1314 Int_vec_zero(Q, dq + 1);
1315
1316 for (i = da, j = dq; i >= db; i--, j--) {
1317 x = R[i];
1318 c = F->mult(x, pivot_inv);
1319 Q[j] = c;
1320 c = F->negate(c);
1321 //cout << "i=" << i << " c=" << c << endl;
1322 for (ii = i, jj = db; jj >= 0; ii--, jj--) {
1323 d = B[jj];
1324 d = F->mult(c, d);
1325 R[ii] = F->add(d, R[ii]);
1326 }
1327 if (R[i] != 0) {
1328 cout << "unipoly::division_with_remainder: R[i] != 0" << endl;
1329 exit(1);
1330 }
1331 //cout << "i=" << i << endl;
1332 //cout << "q="; print_object((unipoly_object)
1333 // rq, cout); cout << endl;
1334 //cout << "r="; print_object(r, cout); cout << endl;
1335 }
1336 rr[0] = MAXIMUM(db - 1, 0);
1337 q = rq;
1338 //cout << "q="; print_object(q, cout); cout << endl;
1339 //cout << "r="; print_object(r, cout); cout << endl;
1340 }
1341done:
1342 if (f_v) {
1343 cout << "unipoly_domain::division_with_remainder done" << endl;
1344 }
1345}
1346
1348{
1349 int *ra = (int *) a;
1350 int *A = ra + 1;
1351 int d = degree(a);
1352 int *rb = (int *) b;
1353 FREE_int(rb);
1354 rb = NEW_int(d - 1 + 2);
1355 int *B = rb + 1;
1356 int i, ai, bi;
1357
1358 for (i = 1; i <= d; i++) {
1359 ai = A[i];
1360 bi = i % F->p;
1361 bi = F->mult(ai, bi);
1362 B[i - 1] = bi;
1363 }
1364 rb[0] = d - 1;
1365 b = rb;
1366}
1367
1369{
1370 int dm = degree(m);
1371 int dn = degree(n);
1372
1373 if (dm < dn) {
1374 return -1;
1375 }
1376 else if (dm > dn) {
1377 return 1;
1378 }
1379 return 0;
1380}
1381
1384 unipoly_object &g, int verbose_level)
1385{
1386 int f_v = (verbose_level >= 1);
1387 int f_vv = (verbose_level >= 2);
1388 int c;
1389
1390 if (f_v) {
1391 cout << "unipoly::greatest_common_divisor m=";
1392 print_object(m, cout);
1393 cout << " n=";
1394 print_object(n, cout);
1395 cout << endl;
1396 }
1397 if (f_v) {
1398 cout << "unipoly::greatest_common_divisor before compare_euclidean" << endl;
1399 }
1400 c = compare_euclidean(m, n);
1401 if (f_v) {
1402 cout << "unipoly::greatest_common_divisor compare_euclidean returns " << c << endl;
1403 }
1404 if (c < 0) {
1405 greatest_common_divisor(n, m, g, verbose_level);
1406 return;
1407 }
1408 if (c == 0 && is_zero(n)) {
1409 assign(m, g, 0 /*verbose_level*/);
1410 if (f_v) {
1411 cout << "unipoly::greatest_common_divisor of m=";
1412 print_object(m, cout);
1413 cout << " n=";
1414 print_object(n, cout);
1415 cout << " is ";
1416 print_object(g, cout);
1417 cout << endl;
1418 }
1419 return;
1420 }
1421
1422 unipoly_object M, N, Q, R;
1423
1424 create_object_by_rank(M, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1425 create_object_by_rank(N, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1426 create_object_by_rank(Q, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1427 create_object_by_rank(R, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1428
1429 assign(m, M, 0 /*verbose_level*/);
1430 assign(n, N, 0 /*verbose_level*/);
1431
1432 while (TRUE) {
1433 if (f_vv) {
1434 cout << "unipoly::greatest_common_divisor M=";
1435 print_object(M, cout);
1436 cout << " N=";
1437 print_object(N, cout);
1438 cout << endl;
1439 }
1440 division_with_remainder(M, N, Q, R, verbose_level - 2);
1441 if (f_vv) {
1442 cout << "unipoly::greatest_common_divisor Q=";
1443 print_object(Q, cout);
1444 cout << " R=";
1445 print_object(R, cout);
1446 cout << endl;
1447 }
1448 if (is_zero(R)) {
1449 break;
1450 }
1451
1452 negate(Q);
1453
1454 assign(N, M, 0 /*verbose_level*/);
1455 assign(R, N, 0 /*verbose_level*/);
1456 }
1457 assign(N, g, 0 /*verbose_level*/);
1458 if (f_v) {
1459 cout << "unipoly::greatest_common_divisor g=";
1460 print_object(g, cout);
1461 cout << endl;
1462 }
1463
1464 delete_object(M);
1465 delete_object(N);
1466 delete_object(Q);
1467 delete_object(R);
1468
1469 if (f_v) {
1470 cout << "unipoly::greatest_common_divisor of m=";
1471 print_object(m, cout);
1472 cout << " n=";
1473 print_object(n, cout);
1474 cout << " is ";
1475 print_object(g, cout);
1476 cout << endl;
1477 }
1478 if (f_v) {
1479 cout << "unipoly::greatest_common_divisor done" << endl;
1480 }
1481
1482}
1483
1487 unipoly_object &g, int verbose_level)
1488{
1489 int f_v = (verbose_level >= 1);
1490 int f_vv = (verbose_level >= 2);
1491 int c;
1492
1493 if (f_v) {
1494 cout << "unipoly::extended_gcd" << endl;
1495 }
1496 if (f_vv) {
1497 cout << "m=";
1498 print_object(m, cout);
1499 cout << " n=";
1500 print_object(n, cout);
1501 cout << endl;
1502 }
1503 c = compare_euclidean(m, n);
1504 if (c < 0) {
1505 extended_gcd(n, m, v, u, g, verbose_level);
1506 if (f_v) {
1507 cout << "unipoly::extended_gcd done" << endl;
1508 }
1509 return;
1510 }
1511 assign(m, u, 0 /*verbose_level*/);
1512 assign(n, v, 0 /*verbose_level*/);
1513 if (c == 0 || is_zero(n)) {
1514 one(u);
1515 zero(v);
1516 assign(m, g, 0 /*verbose_level*/);
1517 if (f_v) {
1518 cout << "unipoly::extended_gcd done" << endl;
1519 }
1520 return;
1521 }
1522
1523 unipoly_object M, N, Q, R;
1524 unipoly_object u1, u2, u3, v1, v2, v3, tmp;
1525
1526 create_object_by_rank(M, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1527 create_object_by_rank(N, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1528 create_object_by_rank(Q, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1529 create_object_by_rank(R, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1530 create_object_by_rank(u1, 1, __FILE__, __LINE__, 0 /*verbose_level*/);
1531 create_object_by_rank(u2, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1532 create_object_by_rank(u3, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1533 create_object_by_rank(v1, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1534 create_object_by_rank(v2, 1, __FILE__, __LINE__, 0 /*verbose_level*/);
1535 create_object_by_rank(v3, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1536 create_object_by_rank(tmp, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1537
1538 assign(m, M, 0 /*verbose_level*/);
1539 assign(n, N, 0 /*verbose_level*/);
1540
1541 while (TRUE) {
1542 if (f_vv) {
1543 cout << "M=";
1544 print_object(M, cout);
1545 cout << " N=";
1546 print_object(N, cout);
1547 cout << endl;
1548 }
1549 division_with_remainder(M, N, Q, R, 0);
1550 if (f_vv) {
1551 cout << "Q=";
1552 print_object(Q, cout);
1553 cout << " R=";
1554 print_object(R, cout);
1555 cout << endl;
1556 }
1557 if (is_zero(R)) {
1558 break;
1559 }
1560
1561 negate(Q);
1562
1563 // u3 := u1 - Q * u2
1564 mult(Q, u2, tmp, verbose_level - 1);
1565 add(u1, tmp, u3);
1566
1567 // v3 := v1 - Q * v2
1568 mult(Q, v2, tmp, verbose_level - 1);
1569 add(v1, tmp, v3);
1570
1571 assign(N, M, 0 /*verbose_level*/);
1572 assign(R, N, 0 /*verbose_level*/);
1573 assign(u2, u1, 0 /*verbose_level*/);
1574 assign(u3, u2, 0 /*verbose_level*/);
1575 assign(v2, v1, 0 /*verbose_level*/);
1576 assign(v3, v2, 0 /*verbose_level*/);
1577 }
1578 assign(u2, u, 0 /*verbose_level*/);
1579 assign(v2, v, 0 /*verbose_level*/);
1580 assign(N, g, 0 /*verbose_level*/);
1581 if (f_vv) {
1582 cout << "g=";
1583 print_object(g, cout);
1584 cout << " u=";
1585 print_object(u, cout);
1586 cout << " v=";
1587 print_object(v, cout);
1588 cout << endl;
1589 }
1590
1591 delete_object(M);
1592 delete_object(N);
1593 delete_object(Q);
1594 delete_object(R);
1595 delete_object(u1);
1596 delete_object(u2);
1597 delete_object(u3);
1598 delete_object(v1);
1599 delete_object(v2);
1600 delete_object(v3);
1601 delete_object(tmp);
1602 if (f_v) {
1603 cout << "unipoly::extended_gcd done" << endl;
1604 }
1605}
1606
1608{
1609 int f_v = (verbose_level >= 1);
1610 int f_vv = (verbose_level >= 2);
1611 unipoly_object a, b, u, v, g;
1612 int d;
1613
1614 if (f_v) {
1615 cout << "unipoly::is_squarefree" << endl;
1616 }
1617 create_object_by_rank(a, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1618 create_object_by_rank(b, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1619 create_object_by_rank(u, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1620 create_object_by_rank(v, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1621 create_object_by_rank(g, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1622
1623 assign(p, a, 0 /*verbose_level*/);
1624 if (f_v) {
1625 cout << "unipoly::is_squarefree before derivative" << endl;
1626 }
1627 derivative(a, b);
1628 if (f_v) {
1629 cout << "unipoly::is_squarefree after derivative" << endl;
1630 }
1631 if (f_vv) {
1632 cout << "unipoly::is_squarefree derivative p' = ";
1633 print_object(b, cout);
1634 cout << endl;
1635 }
1636 if (f_v) {
1637 cout << "unipoly::is_squarefree before extended_gcd" << endl;
1638 }
1639 extended_gcd(a, b, u, v, g, verbose_level - 1);
1640 if (f_v) {
1641 cout << "unipoly::is_squarefree after extended_gcd" << endl;
1642 }
1643 if (f_vv) {
1644 cout << "unipoly::is_squarefree gcd(p, p') = ";
1645 print_object(g, cout);
1646 cout << endl;
1647 }
1648 d = degree(g);
1649
1650 delete_object(a);
1651 delete_object(b);
1652 delete_object(u);
1653 delete_object(v);
1654 delete_object(g);
1655
1656 if (f_v) {
1657 cout << "unipoly::is_squarefree done" << endl;
1658 }
1659 if (d >= 1) {
1660 return FALSE;
1661 }
1662 else {
1663 return TRUE;
1664 }
1665}
1666
1668 int *Normal_basis, int *Frobenius,
1669 int verbose_level)
1670{
1671 int f_v = (verbose_level >= 1);
1672 int f_vv = (verbose_level >= 2);
1673 int *v, *b, *A, deg;
1674 int i, j;
1675 unipoly_object mue, lambda, GCD, Q, R, R1, R2;
1676
1677 if (f_v) {
1678 cout << "unipoly_domain::compute_normal_basis "
1679 "d=" << d << endl;
1680 }
1681 deg = d;
1682
1683 v = NEW_int(deg);
1684 b = NEW_int(deg);
1685 A = NEW_int((deg + 1) * deg);
1686
1687 create_object_by_rank(mue, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1688 create_object_by_rank(lambda, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1689 create_object_by_rank(GCD, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1690 create_object_by_rank(Q, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1691 create_object_by_rank(R, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1692 create_object_by_rank(R1, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1693 create_object_by_rank(R2, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
1694
1695 i = 0;
1696 if (f_v) {
1697 cout << "unipoly_domain::compute_normal_basis before order_ideal_generator" << endl;
1698 }
1699 order_ideal_generator(d, i, mue,
1700 A, Frobenius,
1701 verbose_level - 10);
1702 if (f_v) {
1703 cout << "unipoly_domain::compute_normal_basis after order_ideal_generator" << endl;
1704 }
1705
1706 if (f_v) {
1707 cout << "unipoly_domain::compute_normal_basis "
1708 "Ideal(e_" << i << ") = (";
1709 print_object(mue, cout);
1710 cout << ")" << endl;
1711 }
1712 Int_vec_zero(v, deg);
1713 v[0] = 1;
1714
1715 while (degree(mue) < deg) {
1716 i++;
1717 if (f_v) {
1718 cout << "unipoly_domain::compute_normal_basis "
1719 "i = " << i << " / " << deg << endl;
1720 }
1721
1722 if (i == deg) {
1723 cout << "unipoly_domain::compute_normal_basis "
1724 "error: i == deg" << endl;
1725 exit(1);
1726 }
1727
1728 if (f_v) {
1729 cout << "unipoly_domain::compute_normal_basis "
1730 "before order_ideal_generator" << endl;
1731 }
1732 order_ideal_generator(d, i, lambda,
1733 A, Frobenius,
1734 verbose_level - 10);
1735 if (f_v) {
1736 cout << "unipoly_domain::compute_normal_basis "
1737 "after order_ideal_generator" << endl;
1738 }
1739 if (f_vv) {
1740 cout << "unipoly_domain::compute_normal_basis "
1741 "Ideal(e_" << i << ") = ( lambda ), "
1742 "where lambda = ";
1743 print_object(lambda, cout);
1744 cout << endl;
1745 cout << "unipoly_domain::compute_normal_basis "
1746 "Ideal(e_1,..,e_" << i - 1 << ") = ( mue ), "
1747 "where mue = ";
1748 print_object(mue, cout);
1749 cout << endl;
1750 cout << "v = ";
1751 Int_vec_print(cout, v, deg);
1752 cout << endl;
1753 }
1754
1755 if (f_vv) {
1756 cout << "unipoly_domain::compute_normal_basis "
1757 "computing greatest_common_divisor(mue, lambda):" << endl;
1758 }
1759 greatest_common_divisor(mue, lambda, GCD, verbose_level);
1760
1761 if (f_vv) {
1762 cout << "unipoly_domain::compute_normal_basis "
1763 "greatest_common_divisor(mue, lambda) = ";
1764 print_object(GCD, cout);
1765 cout << endl;
1766 }
1767
1768 if (degree(GCD) < degree(lambda)) {
1769
1770 // b = (0, 0, \ldots, 0, 1, 0, ..., 0) = X^i
1771 Int_vec_zero(b, deg);
1772 b[i] = 1;
1773
1774 exact_division(lambda, GCD, Q, 0 /* verbose_level - 2 */);
1775 if (f_vv) {
1776 cout << "unipoly_domain::compute_normal_basis "
1777 "Q = lambda / GCD = ";
1778 print_object(Q, cout);
1779 cout << endl;
1780 }
1781
1782
1783 take_away_all_factors_from_b(mue, Q, R, 0 /* verbose_level - 2 */);
1784 if (f_vv) {
1785 cout << "unipoly_domain::compute_normal_basis "
1786 "R = take_away_all_factors_from_b(mue, Q) = ";
1787 print_object(R, cout);
1788 cout << endl;
1789 }
1790
1791 exact_division(mue, R, Q, 0 /* verbose_level - 2 */);
1792 if (f_vv) {
1793 cout << "unipoly_domain::compute_normal_basis "
1794 "Q = mue / R = ";
1795 print_object(Q, cout);
1796 cout << endl;
1797 }
1798
1799 // Frobenius Module structure: apply Q to v (q is monic):
1800 if (f_vv) {
1801 cout << "unipoly_domain::compute_normal_basis "
1802 "before module_structure_apply" << endl;
1803 }
1804 module_structure_apply(v, Frobenius, deg, Q, 0 /* verbose_level */);
1805 if (f_vv) {
1806 cout << "unipoly_domain::compute_normal_basis "
1807 "after module_structure_apply" << endl;
1808 }
1809
1810
1811 // now: Orderideal(v1) = Ideal(r)
1812 // v = v *(mue/R)(Frobenius) = v * Q (Frobenius)
1813
1814 exact_division(mue, GCD, Q, 0 /* verbose_level - 2 */);
1815 if (f_vv) {
1816 cout << "unipoly_domain::compute_normal_basis "
1817 "Q = mue / GCD = ";
1818 print_object(Q, cout);
1819 cout << endl;
1820 }
1821
1823 Q, R1, 0 /* verbose_level - 2 */);
1824 if (f_vv) {
1825 cout << "unipoly_domain::compute_normal_basis "
1826 "R1 = take_away_all_factors_from_b(lambda, Q) = ";
1827 print_object(R, cout);
1828 cout << endl;
1829 }
1830
1832 R1, GCD, 0 /* verbose_level */);
1833 if (f_vv) {
1834 cout << "unipoly_domain::compute_normal_basis "
1835 "greatest_common_divisor(R, R1) = ";
1836 print_object(GCD, cout);
1837 cout << endl;
1838 }
1839
1840 exact_division(R1,
1841 GCD, R2, 0 /* verbose_level - 2 */);
1842 if (f_vv) {
1843 cout << "unipoly_domain::compute_normal_basis "
1844 "Q = mue / GCD = ";
1845 print_object(Q, cout);
1846 cout << endl;
1847 }
1848
1849 // now: greatest_common_divisor(R, R2) = 1
1850 // R * R2 = lcm(mue, lambda)
1851
1852 exact_division(lambda,
1853 R2, Q, 0 /* verbose_level - 2 */);
1854 if (f_vv) {
1855 cout << "unipoly_domain::compute_normal_basis "
1856 "Q = lambda / R2 = ";
1857 print_object(Q, cout);
1858 cout << endl;
1859 }
1860
1861 if (f_vv) {
1862 cout << "unipoly_domain::compute_normal_basis "
1863 "before module_structure_apply" << endl;
1864 }
1866 Frobenius, deg, Q, 0 /* verbose_level */);
1867 if (f_vv) {
1868 cout << "unipoly_domain::compute_normal_basis "
1869 "after module_structure_apply" << endl;
1870 }
1871
1872 // now: Orderideal(b) = Ideal(r2)
1873 // b = b * (lambda/R2)(Frobenius) = v * Q(Frobenius)
1874
1875 for (j = 0; j < deg; j++) {
1876 v[j] = F->add(v[j], b[j]);
1877 }
1878
1879 // Orderideal(v) = Ideal(R * R2),
1880 // greatest_common_divisor(R, R2) = 1
1881
1882 mult(R, R2, mue, 0 /* verbose_level */);
1883 } // if
1884 if (f_v) {
1885 cout << "unipoly_domain::compute_normal_basis "
1886 "Ideal(e_1,..,e_" << i << ") = ( mue ), where mue = ";
1887 print_object(mue, cout);
1888 cout << endl;
1889 }
1890 } // while
1891
1892 if (f_vv) {
1893 cout << "unipoly_domain::compute_normal_basis "
1894 "generator = ";
1895 Int_vec_print(cout, v, deg);
1896 cout << endl;
1897 }
1898
1899 if (f_v) {
1900 cout << "unipoly_domain::compute_normal_basis "
1901 "before span_cyclic_module" << endl;
1902 }
1903 F->Linear_algebra->span_cyclic_module(Normal_basis,
1904 v, deg, Frobenius, 0 /* verbose_level */);
1905 if (f_v) {
1906 cout << "unipoly_domain::compute_normal_basis "
1907 "after span_cyclic_module" << endl;
1908 }
1909
1910 if (f_vv) {
1911 cout << "unipoly_domain::compute_normal_basis "
1912 "Normal_basis = " << endl;
1913 Int_matrix_print(Normal_basis, deg, deg);
1914 }
1915
1916 FREE_int(v);
1917 FREE_int(b);
1918 FREE_int(A);
1919
1920 delete_object(mue);
1921 delete_object(lambda);
1922 delete_object(GCD);
1923 delete_object(Q);
1924 delete_object(R);
1925 delete_object(R1);
1926 delete_object(R2);
1927
1928
1929 if (f_v) {
1930 cout << "unipoly_domain::compute_normal_basis done" << endl;
1931 }
1932}
1933
1935 int d, int idx, unipoly_object &mue,
1936 int *A, int *Frobenius,
1937 int verbose_level)
1938// Lueneburg~\cite{Lueneburg87a} p. 105.
1939// Frobenius is a matrix of size d x d
1940// A is a matrix of size (d + 1) x d
1941{
1942 int f_v = (verbose_level >= 1);
1943 int *my_mue, mue_deg;
1944
1945 if (f_v) {
1946 cout << "unipoly_domain::order_ideal_generator "
1947 "d=" << d << " idx = " << idx << endl;
1948 }
1949
1950 my_mue = NEW_int(d + 1);
1951
1952
1953 if (f_v) {
1954 cout << "unipoly_domain::order_ideal_generator "
1955 "before F->order_ideal_generator" << endl;
1956 }
1957 F->Linear_algebra->order_ideal_generator(d, idx, my_mue, mue_deg,
1958 A, Frobenius,
1959 verbose_level - 1);
1960 if (f_v) {
1961 cout << "unipoly_domain::order_ideal_generator "
1962 "after F->order_ideal_generator" << endl;
1963 }
1964
1965
1966 int *Mue = (int *) mue;
1967 FREE_int(Mue);
1968 Mue = NEW_int(mue_deg + 2);
1969 Mue[0] = mue_deg;
1970 int *B = Mue + 1;
1971 int i;
1972 for (i = 0; i <= mue_deg; i++) {
1973 B[i] = my_mue[i];
1974 }
1975 mue = (void *) Mue;
1976
1977 FREE_int(my_mue);
1978
1979
1980 // testing:
1981 if (f_v) {
1982 cout << "unipoly_domain::order_ideal_generator "
1983 "d=" << d << " idx = " << idx << " testing" << endl;
1984 cout << "mue=";
1985 print_object(mue, cout);
1986 cout << endl;
1987 }
1988 int *v;
1989
1990 v = NEW_int(d);
1991 Int_vec_zero(v, d);
1992 v[idx] = 1;
1993
1994 if (f_v) {
1995 cout << "unipoly_domain::order_ideal_generator "
1996 "before module_structure_apply" << endl;
1997 }
1999 Frobenius, d, mue, 0 /*verbose_level*/);
2000 if (f_v) {
2001 cout << "unipoly_domain::order_ideal_generator "
2002 "after module_structure_apply" << endl;
2003 }
2004 for (i = 0; i < d; i++) {
2005 if (v[i]) {
2006 cout << "unipoly_domain::order_ideal_generator "
2007 "d=" << d << " idx = " << idx << " test fails, v=" << endl;
2008 Int_vec_print(cout, v, d);
2009 cout << endl;
2010 exit(1);
2011 }
2012 }
2013 FREE_int(v);
2014 if (f_v) {
2015 cout << "unipoly_domain::order_ideal_generator "
2016 "d=" << d << " idx = " << idx << " test passed" << endl;
2017 }
2018
2019 if (f_v) {
2020 cout << "unipoly_domain::order_ideal_generator done" << endl;
2021 }
2022}
2023
2025 int *Mtx, int n, int verbose_level)
2026// The matrix is applied on the left
2027{
2028 int f_v = (verbose_level >= 1);
2029 int *v1, *v2;
2030 int i, d;
2031
2032 if (f_v) {
2033 cout << "unipoly_domain::matrix_apply" << endl;
2034 }
2035 v1 = NEW_int(n);
2036 v2 = NEW_int(n);
2037
2038 d = degree(p);
2039 if (d >= n) {
2040 cout << "unipoly_domain::matrix_apply d >= n" << endl;
2041 exit(1);
2042 }
2043 for (i = 0; i <= d; i++) {
2044 v1[i] = ((int *)p)[1 + i];
2045 }
2046 for ( ; i < n; i++) {
2047 v1[i] = 0;
2048 }
2049 if (f_v) {
2050 cout << "unipoly_domain::matrix_apply v1 = ";
2051 Int_vec_print(cout, v1, n);
2052 cout << endl;
2053 }
2054 F->Linear_algebra->mult_vector_from_the_right(Mtx, v1, v2, n, n);
2055 if (f_v) {
2056 cout << "unipoly_domain::matrix_apply v2 = ";
2057 Int_vec_print(cout, v2, n);
2058 cout << endl;
2059 }
2060
2061 delete_object(p);
2063 for (i = 0; i < n; i++) {
2064 ((int *)p)[1 + i] = v2[i];
2065 }
2066
2067
2068 FREE_int(v1);
2069 FREE_int(v2);
2070
2071 if (f_v) {
2072 cout << "unipoly_domain::matrix_apply done" << endl;
2073 }
2074}
2075
2077 unipoly_object &p, int *Mtx_in, int *Mtx_out, int k,
2078 int verbose_level)
2079// The matrix is substituted into the polynomial
2080{
2081 int f_v = (verbose_level >= 1);
2082 int *M1, *M2;
2083 int i, j, h, c, d, *P, *coeffs;
2084
2085 if (f_v) {
2086 cout << "unipoly_domain::substitute_matrix_in_polynomial" << endl;
2087 }
2088 M1 = NEW_int(k * k);
2089 M2 = NEW_int(k * k);
2090 P = (int *)p;
2091 d = P[0];
2092 coeffs = P + 1;
2093 h = d;
2094 c = coeffs[h];
2095 for (i = 0; i < k * k; i++) {
2096 M1[i] = F->mult(c, Mtx_in[i]);
2097 }
2098 for (h--; h >= 0; h--) {
2099 c = coeffs[h];
2100 for (i = 0; i < k; i++) {
2101 for (j = 0; j < k; j++) {
2102 if (i == j) {
2103 M2[i * k + j] = F->add(c, M1[i * k + j]);
2104 }
2105 else {
2106 M2[i * k + j] = M1[i * k + j];
2107 }
2108 }
2109 }
2110 if (h) {
2111 F->Linear_algebra->mult_matrix_matrix(M2, Mtx_in, M1, k, k, k,
2112 0 /* verbose_level */);
2113 }
2114 else {
2115 Int_vec_copy(M2, M1, k * k);
2116 }
2117 }
2118 Int_vec_copy(M1, Mtx_out, k * k);
2119
2120 FREE_int(M1);
2121 FREE_int(M2);
2122 if (f_v) {
2123 cout << "unipoly_domain::substitute_matrix_in_polynomial done" << endl;
2124 }
2125}
2126
2127
2129 unipoly_object &p, int scalar, int verbose_level)
2130// The scalar 'scalar' is substituted into the polynomial
2131{
2132 int f_v = (verbose_level >= 1);
2133 int m1, m2;
2134 int h, c, d, *P, *coeffs;
2135
2136 if (f_v) {
2137 cout << "unipoly_domain::substitute_scalar_in_polynomial" << endl;
2138 }
2139 P = (int *)p;
2140 d = P[0];
2141 coeffs = P + 1;
2142 h = d;
2143 c = coeffs[h];
2144 m1 = F->mult(c, scalar);
2145 for (h--; h >= 0; h--) {
2146 c = coeffs[h];
2147 m2 = F->add(c, m1);
2148 if (h) {
2149 m1 = F->mult(m2, scalar);
2150 }
2151 else {
2152 m1 = m2;
2153 }
2154 }
2155 if (f_v) {
2156 cout << "unipoly_domain::substitute_scalar_in_polynomial done" << endl;
2157 }
2158 return m1;
2159}
2160
2162 int *Mtx, int n, unipoly_object p,
2163 int verbose_level)
2164// computes the effect of Mtx substituted into p=p(x) applied to the vector v.
2165// Uses Horner's scheme.
2166// The result is put back into v.
2167{
2168 int f_v = (verbose_level >= 1);
2169 int f_vv = (verbose_level >= 2);
2170 int *v1, *v2;
2171 int i, j, d, c;
2172
2173 if (f_v) {
2174 cout << "unipoly_domain::module_structure_apply" << endl;
2175 }
2176 if (f_vv) {
2177 cout << "unipoly_domain::module_structure_apply "
2178 "applying p=" << endl;
2179 print_object(p, cout);
2180 cout << endl;
2181 }
2182
2183
2184 v1 = NEW_int(n);
2185 v2 = NEW_int(n);
2186
2187 Int_vec_copy(v, v1, n);
2188
2189 d = degree(p);
2190 int *pp;
2191
2192 pp = ((int *)p) + 1;
2193 c = pp[d];
2194 if (c != 1) {
2195 for (j = 0; j < n; j++) {
2196 v1[j] = F->mult(v1[j], c);
2197 }
2198 }
2199#if 0
2200 if (!F->is_one(pp[d])) {
2201 cout << "unipoly_domain::module_structure_apply "
2202 "p is not monic, leading coefficient is "
2203 << pp[d] << endl;
2204 exit(1);
2205 }
2206#endif
2207 for (i = d - 1; i >= 0; i--) {
2208 if (f_vv) {
2209 cout << "unipoly_domain::module_structure_apply "
2210 "i = " << i << endl;
2211 cout << "unipoly_domain::module_structure_apply "
2212 "v1 = ";
2213 Int_vec_print(cout, v1, n);
2214 cout << endl;
2215 }
2216
2217 F->Linear_algebra->mult_vector_from_the_right(Mtx, v1, v2, n, n);
2218
2219 if (f_vv) {
2220 cout << "unipoly_domain::module_structure_apply "
2221 "i = " << i << endl;
2222 cout << "unipoly_domain::module_structure_apply "
2223 "v2 = ";
2224 Int_vec_print(cout, v1, n);
2225 cout << endl;
2226 }
2227
2228 c = pp[i];
2229
2230
2231 if (f_vv) {
2232 cout << "unipoly_domain::module_structure_apply "
2233 "i = " << i;
2234 cout << " c = " << c << endl;
2235 }
2236 for (j = 0; j < n; j++) {
2237 v1[j] = F->add(F->mult(v[j], c), v2[j]);
2238 }
2239
2240 if (f_vv) {
2241 cout << "unipoly_domain::module_structure_apply "
2242 "i = " << i << endl;
2243 cout << "unipoly_domain::module_structure_apply "
2244 "v1 = ";
2245 Int_vec_print(cout, v1, n);
2246 cout << endl;
2247 }
2248
2249 } // next i
2250
2251 for (j = 0; j < n; j++) {
2252 v[j] = v1[j];
2253 }
2254
2255 FREE_int(v1);
2256 FREE_int(v2);
2257
2258 if (f_v) {
2259 cout << "unipoly_domain::module_structure_apply done" << endl;
2260 }
2261}
2262
2263
2266 unipoly_object b, unipoly_object &a_without_b,
2267 int verbose_level)
2268// Computes the polynomial $r$ with
2269//\begin{enumerate}
2270//\item
2271//$r$ divides $a$
2272//\item
2273//$gcd(r,b) = 1$ and
2274//\item
2275//each irreducible polynomial dividing $a/r$ divides $b$.
2276//Lueneburg~\cite{Lueneburg87a}, p. 37.
2277//\end{enumerate}
2278{
2279 int f_v = (verbose_level >= 1);
2280
2281 if (f_v) {
2282 cout << "unipoly_domain::take_away_all_factors_from_b" << endl;
2283 }
2284
2285
2286 unipoly_object G, A, Q;
2287
2288 create_object_by_rank(G, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2289 create_object_by_rank(A, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2290 create_object_by_rank(Q, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2291
2292 assign(a, A, verbose_level);
2293
2294 greatest_common_divisor(A, b, G, verbose_level - 2);
2295
2296 while (degree(G)) {
2297
2298 exact_division(A, G, Q, 0 /* verbose_level - 2 */);
2299
2300 assign(Q, A, 0 /*verbose_level*/);
2301
2302 greatest_common_divisor(A, b, G, verbose_level - 2);
2303
2304 }
2305
2306 assign(A, a_without_b, 0 /*verbose_level*/);
2307
2308 delete_object(G);
2309 delete_object(A);
2310 delete_object(Q);
2311
2312 if (f_v) {
2313 cout << "unipoly_domain::take_away_all_factors_from_b done" << endl;
2314 }
2315}
2316
2318 int verbose_level)
2319{
2320 int f_v = (verbose_level >= 1);
2321 int f_vv = (verbose_level >= 2);
2322 int *B;
2323 int r, ret;
2324 int *base_cols;
2325 int factor_polynomial_degree;
2326
2327 if (f_v) {
2328 cout << "unipoly_domain::is_irreducible" << endl;
2329 }
2330 factor_polynomial_degree = degree(a);
2331
2332 if (f_v) {
2333 cout << "unipoly_domain::is_irreducible before is_squarefree" << endl;
2334 }
2335 if (!is_squarefree(a, verbose_level - 2)) {
2336 if (f_v) {
2337 cout << "unipoly_domain::is_irreducible is not squarefree" << endl;
2338 }
2339 return FALSE;
2340 }
2341 if (f_v) {
2342 cout << "unipoly_domain::is_irreducible is squarefree" << endl;
2343 }
2344
2345 //unipoly_domain Fq(F, a);
2346
2347 if (f_v) {
2348 cout << "unipoly_domain::is_irreducible before Berlekamp_matrix" << endl;
2349 }
2350 Berlekamp_matrix(B, a, verbose_level - 2);
2351 if (f_v) {
2352 cout << "unipoly_domain::is_irreducible after Berlekamp_matrix" << endl;
2353 }
2354 if (f_vv) {
2355 cout << "unipoly_domain::is_irreducible Berlekamp_matrix=" << endl;
2356 Int_matrix_print(B, factor_polynomial_degree, factor_polynomial_degree);
2357 }
2358
2359 base_cols = NEW_int(factor_polynomial_degree);
2360
2361 r = F->Linear_algebra->Gauss_int(B,
2362 FALSE /* f_special */,
2363 FALSE /* f_complete */,
2364 base_cols,
2365 FALSE /* f_P */, NULL /* P */,
2366 factor_polynomial_degree, factor_polynomial_degree,
2367 0 /* Pn */, 0 /* verbose_level */);
2368
2369 if (f_v) {
2370 cout << "unipoly_domain::is_irreducible Berlekamp_matrix has rank " << r << endl;
2371 }
2372
2373 FREE_int(B);
2374 FREE_int(base_cols);
2375
2376 if (r == factor_polynomial_degree - 1) {
2377 ret = TRUE;
2378 }
2379 else {
2380 ret = FALSE;
2381 }
2382 if (f_v) {
2383 cout << "unipoly_domain::is_irreducible done" << endl;
2384 }
2385 return ret;
2386}
2387
2389 int p, int d, int b, int a)
2390{
2392 int *M = ((int *)m) + 1;
2393 M[d] = 1;
2394 M[d - 1] = 1;
2395 M[1] = b;
2396 M[0] = a;
2397}
2398
2400 longinteger_object &qm1,
2401 int nb_primes, longinteger_object *primes,
2402 int verbose_level)
2403//Returns TRUE iff the polynomial $x$ has order $qm1$
2404//modulo the polynomial m (over GF(p)).
2405//The prime factorization of $qm1$
2406// must be given in primes (only the primes).
2407//A polynomial $a$ has order $s$ mod $m$ ($q = this$) iff
2408//$a^m =1 mod q$ and $a^{s/p_i} \not= 1 mod m$ for all $p_i \mid s.$
2409//In this case, we have $a=x$ and we assume that $a^qm1 = 1 mod q.$
2410{
2411 int f_v = (verbose_level >= 1);
2412 longinteger_object qm1_over_p, r, u;
2415 int i;
2416
2417 if (f_v) {
2418 cout << "unipoly_domain::is_primitive" << endl;
2419 }
2420 create_object_of_degree(M, ((int*)m)[0]);
2421 assign(m, M, 0 /*verbose_level*/);
2422 unipoly_domain Fq(F, M, verbose_level - 1);
2423
2424 if (f_v) {
2425 cout << "unipoly_domain::is_primitive "
2426 "q=" << F->q << endl;
2427 cout << "m=";
2428 print_object(m, cout);
2429 cout << endl;
2430 cout << "M=";
2431 print_object(M, cout);
2432 cout << endl;
2433 cout << "primes:" << endl;
2434 for (i = 0; i < nb_primes; i++) {
2435 cout << i << " : " << primes[i] << endl;
2436 }
2437 }
2438
2439 for (i = 0; i < nb_primes; i++) {
2440
2441 if (f_v) {
2442 cout << "unipoly_domain::is_primitive testing prime " << i << " / "
2443 << nb_primes << " which is " << primes[i] << endl;
2444 }
2445
2446
2447 D.integral_division(qm1, primes[i], qm1_over_p, r, 0);
2448 if (f_v) {
2449 cout << "qm1 / " << primes[i] << " = "
2450 << qm1_over_p << " remainder " << r << endl;
2451 }
2452 if (!r.is_zero()) {
2453 cout << "unipoly_domain::is_primitive "
2454 "the prime does not divide!" << endl;
2455 cout << "qm1=" << qm1 << endl;
2456 cout << "primes[i]=" << primes[i] << endl;
2457 cout << "qm1_over_p=" << qm1_over_p << endl;
2458 cout << "r=" << r << endl;
2459 exit(1);
2460 }
2461
2463
2464 Fq.create_object_by_rank(a, F->q, __FILE__, __LINE__, 0 /*verbose_level*/); // the polynomial X
2465 Fq.power_longinteger(a, qm1_over_p, 0 /*verbose_level - 1*/);
2466
2467 if (f_v) {
2468 cout << "unipoly_domain::is_primitive X^" << qm1_over_p << " mod ";
2469 print_object(m, cout);
2470 cout << " = ";
2471 print_object(a, cout);
2472 cout << endl;
2473 }
2474
2475 if (Fq.is_one(a)) {
2476 if (f_v) {
2477 cout << "unipoly_domain::is_primitive is one, hence m is not primitive" << endl;
2478 }
2479 Fq.delete_object(a);
2480 return FALSE;
2481 }
2482
2483 Fq.delete_object(a);
2484
2485 }
2486 if (f_v) {
2487 cout << "unipoly_domain::is_primitive ";
2488 cout << "m=";
2489 print_object(m, cout);
2490 cout << " is primitive" << endl;
2491
2492#if 0
2494 for (i = 0; i <= qm1.as_int(); i++) {
2495 Fq.create_object_by_rank(a, F->q); // the polynomial X
2496 u.create(i);
2497 Fq.power_longinteger(a, u);
2498 cout << "X^" << u << " = ";
2499 print_object(a, cout);
2500 cout << endl;
2501 }
2502 Fq.delete_object(a);
2503#endif
2504 }
2505
2506 if (f_v) {
2507 cout << "unipoly_domain::is_primitive done" << endl;
2508 }
2509 return TRUE;
2510}
2511
2513 unipoly_object &m,
2514 int f, int verbose_level)
2515{
2516 int f_v = (verbose_level >= 1);
2517 int f_vv = (verbose_level >= 2);
2518 int a, b, p, nb_primes, i;
2520 longinteger_object q, m1, qm1;
2521 longinteger_object low, high, current, one, tmp;
2523 longinteger_object *primes;
2524 int *exponents;
2525
2526 if (f_v) {
2527 cout << "unipoly::get_a_primitive_polynomial" << endl;
2528 cout << "Searching for a primitive polynomial of degree " << f <<
2529 " over GF(" << F->q << ")" << endl;
2530 }
2531 p = F->q;
2532 q.create(p, __FILE__, __LINE__);
2533 m1.create(-1, __FILE__, __LINE__);
2534 D.power_int(q, f);
2535 D.add(q, m1, qm1);
2536 if (f_vv) {
2537 cout << "unipoly_domain::get_a_primitive_polynomial factoring " << qm1 << endl;
2538 }
2540 primes, exponents, verbose_level - 2);
2541 if (f_vv) {
2542 cout << "unipoly_domain::get_a_primitive_polynomial after factoring "
2543 << qm1 << " nb_primes=" << nb_primes << endl;
2544 cout << "primes:" << endl;
2545 for (i = 0; i < nb_primes; i++) {
2546 cout << i << " : " << primes[i] << endl;
2547 }
2548 }
2549 if (f_vv) {
2550 cout << "unipoly_domain::get_a_primitive_polynomial "
2551 "before F->primitive_root" << endl;
2552 }
2553 a = F->primitive_root();
2554 if (f_vv) {
2555 cout << "unipoly_domain::get_a_primitive_polynomial "
2556 "a primitive root is " << a << endl;
2557 }
2558
2559 for (b = 0; b < p; b++) {
2560 singer_candidate(x, p, f, b, a);
2561 if (f_v) {
2562 cout << "singer candidate ";
2563 print_object(x, cout);
2564 cout << endl;
2565 }
2566 if (is_irreducible(x, verbose_level - 1)) {
2567 if (f_v) {
2568 cout << "IS irreducible" << endl;
2569 }
2570 if (is_primitive(x, qm1, nb_primes, primes, verbose_level - 1)) {
2571 if (f_v) {
2572 cout << "OK, we found an irreducible "
2573 "and primitive polynomial ";
2574 print_object(x, cout);
2575 cout << endl;
2576 }
2577 assign(x, m, 0 /*verbose_level*/);
2578 if (f_v) {
2579 cout << "before delete_object(x)" << endl;
2580 }
2581 delete_object(x);
2582 if (f_v) {
2583 cout << "before FREE_OBJECTS(primes)" << endl;
2584 }
2585 FREE_OBJECTS(primes);
2586 if (f_v) {
2587 cout << "before FREE_int(exponents)" << endl;
2588 }
2589 FREE_int(exponents);
2590 return;
2591 }
2592 else {
2593 if (f_v) {
2594 cout << "is not primitive" << endl;
2595 }
2596 }
2597 }
2598 else {
2599 if (f_v) {
2600 cout << "is not irreducible" << endl;
2601 }
2602 }
2603 delete_object(x);
2604 }
2605
2606 low.create(F->q, __FILE__, __LINE__);
2607 one.create(1, __FILE__, __LINE__);
2608 D.power_int(low, f);
2609
2610 D.mult(low, low, high); // only monic polynomials
2611
2612 low.assign_to(current);
2613
2614 while (TRUE) {
2615
2616 create_object_by_rank_longinteger(x, current, __FILE__, __LINE__, 0 /*verbose_level*/);
2617
2618 if (f_v) {
2619 cout << "candidate " << current << " : ";
2620 print_object(x, cout);
2621 cout << endl;
2622 }
2623 if (is_irreducible(x, verbose_level - 1)) {
2624 if (f_v) {
2625 cout << "is irreducible" << endl;
2626 }
2627 if (is_primitive(x, qm1, nb_primes,
2628 primes, verbose_level - 1)) {
2629 if (f_v) {
2630 cout << "is irreducible and primitive" << endl;
2631 }
2632 if (f_v) {
2633 cout << "unipoly::get_a_primitive_polynomial ";
2634 print_object(x, cout);
2635 cout << endl;
2636 }
2637 assign(x, m, 0 /*verbose_level*/);
2638 if (f_v) {
2639 cout << "before delete_object(x)" << endl;
2640 }
2641 delete_object(x);
2642 if (f_v) {
2643 cout << "before FREE_OBJECTS(primes)" << endl;
2644 }
2645 FREE_OBJECTS(primes);
2646 if (f_v) {
2647 cout << "before FREE_int(exponents)" << endl;
2648 }
2649 FREE_int(exponents);
2650 return;
2651 }
2652 else {
2653 if (f_v) {
2654 cout << "is not primitive" << endl;
2655 }
2656 }
2657
2658 }
2659 else {
2660 if (f_v) {
2661 cout << "is not irreducible" << endl;
2662 }
2663 }
2664
2665 delete_object(x);
2666
2667 D.add(current, one, tmp);
2668 tmp.assign_to(current);
2669
2670 if (D.compare(current, high) == 0) {
2671 cout << "unipoly::get_an_irreducible_polynomial "
2672 "did not find an irreducible polynomial" << endl;
2673 exit(1);
2674 }
2675 }
2676}
2677
2679 unipoly_object &m,
2680 int f, int verbose_level)
2681{
2682 int f_v = (verbose_level >= 1);
2683 int f_vv = (verbose_level >= 2);
2685 longinteger_object low, high, current, one, tmp;
2687
2688 if (f_v) {
2689 cout << "unipoly::get_an_irreducible_polynomial" << endl;
2690 cout << "Searching for an irreducible polynomial "
2691 "of degree " << f <<
2692 " over GF(" << F->q << ")" << endl;
2693 }
2694 low.create(F->q, __FILE__, __LINE__);
2695 one.create(1, __FILE__, __LINE__);
2696 D.power_int(low, f);
2697
2698 D.mult(low, low, high); // only monic polynomials
2699
2700 low.assign_to(current);
2701
2702 while (TRUE) {
2703
2705 current, __FILE__, __LINE__, 0 /*verbose_level - 2*/);
2706
2707 if (f_vv) {
2708 cout << "unipoly::get_an_irreducible_polynomial "
2709 "candidate " << current << " : ";
2710 print_object(x, cout);
2711 cout << endl;
2712 }
2713 if (is_irreducible(x, verbose_level - 3)) {
2714 if (f_vv) {
2715 cout << "unipoly::get_an_irreducible_polynomial "
2716 "candidate " << current << " : ";
2717 print_object(x, cout);
2718 cout << " is irreducible" << endl;
2719 }
2720 assign(x, m, 0 /*verbose_level*/);
2721 delete_object(x);
2722 return;
2723 }
2724
2725 delete_object(x);
2726
2727 D.add(current, one, tmp);
2728 tmp.assign_to(current);
2729
2730 if (D.compare(current, high) == 0) {
2731 cout << "unipoly::get_an_irreducible_polynomial "
2732 "did not find an irreducible polynomial" << endl;
2733 exit(1);
2734 }
2735 }
2736}
2737
2739 int n, int verbose_level)
2740// does not mod out by factor polynomial
2741{
2742 int f_v = (verbose_level >= 1);
2743 int f_vv = (verbose_level >= 2);
2744 unipoly_object b, c, d;
2745
2746 if (f_v) {
2747 cout << "unipoly_domain::power_int, verbose_level=" << verbose_level << endl;
2748 }
2749 if (f_vv) {
2750 cout << "unipoly_domain::power_int computing a=";
2751 print_object(a, cout);
2752 cout << " to the power " << n << endl;
2753 }
2754 //cout << "power_int a=";
2755 //print_object(a, cout);
2756 //cout << " n=" << n << endl;
2757 create_object_by_rank(b, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2758 create_object_by_rank(c, 1, __FILE__, __LINE__, 0 /*verbose_level*/); // c = 1
2759 create_object_by_rank(d, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2760 assign(a, b, verbose_level);
2761 while (n) {
2762 if (f_vv) {
2763 cout << "unipoly_domain::power_int n=" << n;
2764 cout << " b=";
2765 print_object(b, cout);
2766 cout << " c=";
2767 print_object(c, cout);
2768 cout << endl;
2769 }
2770
2771 if (n % 2) {
2772 if (f_vv) {
2773 cout << "unipoly_domain::power_int n is odd" << endl;
2774 cout << "unipoly_domain::power_int before mult(b,c,d)" << endl;
2775 }
2776 mult(b, c, d, verbose_level - 1);
2777 if (f_vv) {
2778 cout << "unipoly_domain::power_int before assign(d,c)" << endl;
2779 }
2780 if (f_vv) {
2781 cout << "b*c=d";
2782 print_object(d, cout);
2783 cout << endl;
2784 }
2785 assign(d, c, 0 /*verbose_level*/);
2786 }
2787 else {
2788 if (f_vv) {
2789 cout << "unipoly_domain::power_int n is even" << endl;
2790 }
2791 }
2792 if (f_vv) {
2793 cout << "unipoly_domain::power_int before mult(b,b,d)" << endl;
2794 }
2795 mult(b, b, d, verbose_level - 1);
2796 if (f_vv) {
2797 cout << "unipoly_domain::power_int b*b=d";
2798 print_object(d, cout);
2799 cout << endl;
2800 }
2801 if (f_vv) {
2802 cout << "unipoly_domain::power_int before assign(d,b)" << endl;
2803 }
2804 assign(d, b, 0 /*verbose_level*/);
2805 n >>= 1;
2806 }
2807 if (f_vv) {
2808 cout << "unipoly_domain::power_int before assign(c,a)" << endl;
2809 }
2810 assign(c, a, 0 /*verbose_level*/);
2811 if (f_vv) {
2812 cout << "unipoly_domain::power_int before delete_object(b)" << endl;
2813 }
2814 delete_object(b);
2815 delete_object(c);
2816 delete_object(d);
2817 if (f_v) {
2818 cout << "unipoly_domain::power_int done" << endl;
2819 }
2820}
2821
2823 unipoly_object &a, longinteger_object &n, int verbose_level)
2824{
2825 int f_v = (verbose_level >= 1);
2826 longinteger_object m, q;
2828 unipoly_object b, c, d;
2829 int r;
2830
2831 if (f_v) {
2832 cout << "unipoly_domain::power_longinteger" << endl;
2833 }
2834 //cout << "power_int() a=";
2835 //print_object(a, cout);
2836 //cout << " n=" << n << endl;
2837 create_object_by_rank(b, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2838 create_object_by_rank(c, 1, __FILE__, __LINE__, 0 /*verbose_level*/); // c = 1
2839 create_object_by_rank(d, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2840 n.assign_to(m);
2841 assign(a, b, 0 /*verbose_level*/);
2842 while (!m.is_zero()) {
2843 D.integral_division_by_int(m, 2, q, r);
2844 if (r) {
2845 mult(b, c, d, verbose_level - 1);
2846 assign(d, c, verbose_level);
2847 }
2848 mult(b, b, d, verbose_level - 1);
2849 assign(d, b, 0 /*verbose_level*/);
2850 q.assign_to(m);
2851 }
2852 assign(c, a, 0 /*verbose_level*/);
2853 delete_object(b);
2854 delete_object(c);
2855 delete_object(d);
2856 if (f_v) {
2857 cout << "unipoly_domain::power_longinteger done" << endl;
2858 }
2859}
2860
2862 unipoly_object &a, int n)
2863{
2864 int *ra = (int *) a;
2865 int m = ra[0];
2866 int *A = ra + 1;
2867 int i;
2868
2869 for (i = 0; i <= m; i++) {
2870 A[i] = F->power(A[i], n);
2871 }
2872}
2873
2875 unipoly_object &a,
2876 int alpha, int p, int verbose_level)
2877// computes the minimum polynomial of alpha with respect to the ground
2878// field of order p (BTW: p might also be a prime power)
2879{
2880 int f_v = (verbose_level >= 1);
2881 int f_vv = (verbose_level >= 2);
2882 int q, m_alpha, u0, cnt;
2883 unipoly_object u, v, w;
2884
2885 if (f_v) {
2886 cout << "unipoly_domain::minimum_polynomial" << endl;
2887 }
2888 if (f_factorring) {
2889 cout << "unipoly_domain::minimum_polynomial "
2890 "does not work for factorring" << endl;
2891 exit(1);
2892 }
2893 if (f_v) {
2894 cout << "unipoly_domain::minimum_polynomial "
2895 "alpha = " << alpha << endl;
2896 }
2897 q = F->q;
2898 m_alpha = F->negate(alpha);
2899 if (f_v) {
2900 cout << "unipoly_domain::minimum_polynomial "
2901 "m_alpha = " << m_alpha << endl;
2902 }
2903 create_object_by_rank(u, q + m_alpha, __FILE__, __LINE__, 0 /*verbose_level*/);
2904 create_object_by_rank(v, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2905 create_object_by_rank(w, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2906 if (f_vv) {
2907 cout << "unipoly_domain::minimum_polynomial X - alpha = ";
2908 print_object(u, cout);
2909 cout << endl;
2910 }
2911 assign(u, v, 0 /*verbose_level*/);
2912
2913 cnt = 0;
2914 while (TRUE) {
2915 if (f_vv) {
2916 cout << "unipoly_domain::minimum_polynomial "
2917 "Iteration " << cnt;
2918 cout << "u=";
2919 print_object(u, cout);
2920 cout << endl;
2921 cout << "v=";
2922 print_object(v, cout);
2923 cout << endl;
2924 }
2925 power_coefficients(v, p);
2926 if (f_vv) {
2927 cout << "unipoly_domain::minimum_polynomial conjugate = ";
2928 print_object(v, cout);
2929 cout << endl;
2930 }
2931 u0 = ((int *)v)[1];
2932 if (u0 == m_alpha) {
2933 if (f_vv) {
2934 cout << "unipoly_domain::minimum_polynomial finished" << endl;
2935 }
2936 break;
2937 }
2938 mult(u, v, w, verbose_level - 1);
2939 if (f_vv) {
2940 cout << "unipoly_domain::minimum_polynomial product = ";
2941 print_object(w, cout);
2942 cout << endl;
2943 }
2944 assign(w, u, 0 /*verbose_level*/);
2945 cnt++;
2946 }
2947
2948 if (f_vv) {
2949 cout << "unipoly_domain::minimum_polynomial "
2950 "Iteration " << cnt << " done";
2951 cout << "u=";
2952 print_object(u, cout);
2953 cout << endl;
2954 }
2955 assign(u, a, 0 /*verbose_level*/);
2956 if (f_v) {
2957 cout << "unipoly_domain::minimum_polynomial "
2958 "the minimum polynomial of " << alpha
2959 << " over GF(" << p << ") is ";
2960 print_object(a, cout);
2961 cout << endl;
2962 }
2963 delete_object(u);
2964 delete_object(v);
2965 delete_object(w);
2966 if (f_v) {
2967 cout << "unipoly_domain::minimum_polynomial done" << endl;
2968 }
2969}
2970
2972 int alpha, int p, int verbose_level)
2973// compute the minimum polynomial of alpha over F_p.
2974{
2975 int f_v = (verbose_level >= 1);
2976 int f_vv = (verbose_level >= 2);
2977 int rk, r;
2978
2979 if (!f_factorring) {
2980 cout << "unipoly_domain::minimum_polynomial_factorring "
2981 "must be a factorring" << endl;
2982 exit(1);
2983 }
2984 if (f_vv) {
2985 cout << "factor_degree = " << factor_degree << endl;
2986 }
2987 unipoly_object *coeffs =
2988 NEW_OBJECTS(unipoly_object, factor_degree + 1);
2989 unipoly_object b, c, d;
2990 int a0, ai, i, j;
2991
2992 // create the polynomial Y - alpha:
2993 for (i = 0; i <= factor_degree; i++) {
2994 if (i == 1) {
2995 create_object_by_rank(coeffs[i], 1, __FILE__, __LINE__, 0 /*verbose_level*/);
2996 }
2997 else {
2998 create_object_by_rank(coeffs[i], 0, __FILE__, __LINE__, 0 /*verbose_level*/);
2999 }
3000 }
3001 create_object_by_rank(b, alpha, __FILE__, __LINE__, 0 /*verbose_level*/);
3002 create_object_by_rank(c, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3003 create_object_by_rank(d, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3004 if (f_v) {
3005 cout << "unipoly_domain::minimum_polynomial_factorring "
3006 "minimum polynomial of ";
3007 print_object(b, cout);
3008 cout << " = " << alpha << endl;
3009 }
3010 negate(b);
3011 if (f_vv) {
3012 cout << "-b = ";
3013 print_object(b, cout);
3014 cout << endl;
3015 }
3016 a0 = rank(b);
3017 if (f_vv) {
3018 cout << "a0 = " << a0 << endl;
3019 }
3020 assign(b, coeffs[0], 0 /*verbose_level*/);
3021
3022 i = 1;
3023 while (TRUE) {
3024 if (f_vv) {
3025 cout << "unipoly_domain::minimum_polynomial_factorring "
3026 "i=" << i << " b=";
3027 print_object(b, cout);
3028 cout << " the polynomial is ";
3029 for (j = i; j >= 0; j--) {
3030 print_object(coeffs[j], cout);
3031 if (j > 0) {
3032 cout << " Y^" << j << " + ";
3033 }
3034 }
3035 cout << endl;
3036 }
3037
3038 power_int(b, p, 0 /* verbose_level */);
3039
3040 ai = rank(b);
3041 if (ai == a0) {
3042 break;
3043 }
3044
3045 if (i == factor_degree) {
3046 cout << "unipoly_domain::minimum_polynomial_factorring "
3047 "i == factor_degree && ai != a0" << endl;
3048 exit(1);
3049 }
3050
3051 unipoly_object tmp = coeffs[i + 1];
3052
3053 for (j = i; j >= 0; j--) {
3054 coeffs[j + 1] = coeffs[j];
3055 }
3056 coeffs[0] = tmp;
3057
3058 for (j = 1; j <= i + 1; j++) {
3059 mult(coeffs[j], b, c, verbose_level - 1);
3060 add(c, coeffs[j - 1], d);
3061 assign(d, coeffs[j - 1], verbose_level);
3062
3063 // coeffs[j - 1] = coeffs[j] * b + coeffs[j - 1]
3064 }
3065
3066 i++;
3067 }
3068 if (f_v) {
3069 cout << "unipoly_domain::minimum_polynomial_factorring minimum polynomial is: ";
3070 for (j = i; j >= 0; j--) {
3071 print_object(coeffs[j], cout);
3072 if (j > 0) {
3073 cout << "Y^" << j << " + ";
3074 }
3075 }
3076 cout << endl;
3077 }
3078 rk = 0;
3079 for (j = i; j >= 0; j--) {
3080 r = rank(coeffs[j]);
3081 rk *= p;
3082 rk += r;
3083 }
3084 if (f_v) {
3085 cout << "the rank of this polynomial over "
3086 "GF(" << p << ") is " << rk << endl;
3087 }
3088 for (j = 0; j <= factor_degree; j++) {
3089 delete_object(coeffs[j]);
3090 }
3091 delete_object(b);
3092 delete_object(c);
3093 delete_object(d);
3094 return rk;
3095}
3096
3098 longinteger_object &alpha, longinteger_object &rk_minpoly,
3099 int p, int verbose_level)
3100// compute the minimum polynomial of alpha over F_p.
3101{
3102 int f_v = (verbose_level >= 1);
3103 int f_vv = (verbose_level >= 2);
3104
3105 if (!f_factorring) {
3106 cout << "unipoly_domain::minimum_polynomial_factorring_longinteger "
3107 "must be a factorring" << endl;
3108 exit(1);
3109 }
3110 if (f_vv) {
3111 cout << "factor_degree = " << factor_degree << endl;
3112 }
3113
3114
3115 // Let M(Y) be the minimum polynomial of alpha over F_p.
3116
3117 // M(Y) has the form
3118
3119 // M(Y) = (Y - alpha) * (Y - alpha^\varphi) * (Y - alpha^{\varphi^2}) * ...
3120
3121 // Using b = -alpha, we write
3122
3123 // M(Y) = (Y + b) * (Y + b^\varphi)*(Y + b^{\varphi^2}) * ...
3124
3125 // we will maintain a vector of polynomials to represent M(Y)
3126 // In the end, all coefficients will be constant polynomials.
3127 // The constants are the coefficients of the minimum polynomial.
3128
3129 unipoly_object *coeffs = NEW_OBJECTS(unipoly_object, factor_degree + 1);
3130
3131 unipoly_object b, c, d;
3132 int i, j;
3133
3134
3135
3136
3137 // create the polynomial Y - alpha:
3138
3139
3140 // we first create (0,1,0,0,...) as vector of polynomials
3141 for (i = 0; i <= factor_degree; i++) {
3142 if (i == 1) {
3143 create_object_by_rank(coeffs[i], 1, __FILE__, __LINE__, 0 /*verbose_level*/);
3144 }
3145 else {
3146 create_object_by_rank(coeffs[i], 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3147 }
3148 }
3149
3150 // b = alpha (constant polynomial)
3151 create_object_by_rank_longinteger(b, alpha, __FILE__, __LINE__, 0 /*verbose_level*/);
3152
3153 // c and d are needed later:
3154 create_object_by_rank(c, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3155 create_object_by_rank(d, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3156
3157 if (f_v) {
3158 cout << "unipoly_domain::minimum_polynomial_factorring_longinteger "
3159 "minimum polynomial of ";
3160 print_object(b, cout);
3161 cout << " = " << alpha << endl;
3162 }
3163 negate(b);
3164 if (f_vv) {
3165 cout << "-b = ";
3166 print_object(b, cout);
3167 cout << endl;
3168 }
3169 // now b = -alpha
3170
3171 longinteger_object a0, ai;
3173
3174 // we remember the rank of b (=-alpha) so that we can
3175 // easily detect when the orbit under the Frobenius closes.
3176 // Let a0 be the rank of b = -alpha
3177
3178 rank_longinteger(b, a0);
3179 // here we use rank_longinteger and not rank
3180
3181 if (f_vv) {
3182 cout << "a0 = " << a0 << endl;
3183 }
3184
3185 assign(b, coeffs[0], 0 /*verbose_level*/);
3186
3187 // now we have the vector of polynomials (-alpha,1,0,0,...)
3188 // which represents Y + b = Y - alpha.
3189 // Y - alpha is the first factor in the minimum polynomial
3190 // Next, we apply the Frobenius automorphism to b and multiply up.
3191 // Thus, we loop over the conjugates of b.
3192 // We do this until the orbit of b closes.
3193 // Then we have M(Y) = (Y + b) * (Y + b^\varphi) * (Y + b^{\varphi^2}) * ...
3194
3195 i = 1;
3196 while (TRUE) {
3197
3198 if (f_vv) {
3199 cout << "i=" << i << " b=";
3200 print_object(b, cout);
3201 cout << " the polynomial is ";
3202 for (j = i; j >= 0; j--) {
3203 print_object(coeffs[j], cout);
3204 if (j > 0) {
3205 cout << " Y^" << j << " + ";
3206 }
3207 }
3208 cout << endl;
3209 }
3210
3211 // apply the Frobenius automorphism to b.
3212 // this gives another conjugate of -alpha
3213
3214 power_int(b, p, 0 /* verbose_level */);
3215
3216 // test if the orbit has closed:
3217
3218 rank_longinteger(b, ai);
3219
3220 if (D.compare(ai, a0) == 0) {
3221
3222 // yes, the orbit has closed. Now b = -alpha
3223
3224 break;
3225 }
3226
3227 if (i == factor_degree) {
3228 cout << "unipoly_domain::minimum_polynomial_factorring_longinteger "
3229 "i == factor_degree && ai != a0" << endl;
3230 exit(1);
3231 }
3232
3233 // every coefficient is a polynomial
3234 // move every coefficient up by one,
3235 // move the next unused coefficient to the constant term at the bottom.
3236 // We are only switching pointers.
3237 // There is no copying going on here
3238
3239 unipoly_object tmp = coeffs[i + 1];
3240 for (j = i; j >= 0; j--) {
3241 coeffs[j + 1] = coeffs[j];
3242 }
3243 coeffs[0] = tmp;
3244
3245 for (j = 1; j <= i + 1; j++) {
3246 mult(coeffs[j], b, c, verbose_level - 1);
3247 add(c, coeffs[j - 1], d);
3248 assign(d, coeffs[j - 1], 0 /*verbose_level*/);
3249 }
3250
3251 i++;
3252 }
3253 if (f_v) {
3254 cout << "is: ";
3255 for (j = i; j >= 0; j--) {
3256 print_object(coeffs[j], cout);
3257 if (j > 0) {
3258 cout << "Y^" << j << " + ";
3259 }
3260 }
3261 cout << endl;
3262 }
3263
3264 longinteger_object rk, r, p_object, rk1;
3265
3266 rk.create(0, __FILE__, __LINE__);
3267 p_object.create(p, __FILE__, __LINE__);
3268 for (j = i; j >= 0; j--) {
3269 rank_longinteger(coeffs[j], r);
3270 D.mult(rk, p_object, rk1);
3271 D.add(rk1, r, rk);
3272
3273 }
3274 if (f_v) {
3275 cout << "the rank of this polynomial over "
3276 "GF(" << p << ") is " << rk << endl;
3277 }
3278 for (j = 0; j <= factor_degree; j++) {
3279 delete_object(coeffs[j]);
3280 }
3281 delete_object(b);
3282 delete_object(c);
3283 delete_object(d);
3284 rk.assign_to(rk_minpoly);
3285}
3286
3288 unipoly_object *sigma, int deg)
3289{
3290 int i;
3291
3292 for (i = 0; i < deg; i++) {
3293 cout << i << ": ";
3294 print_object(sigma[i], cout);
3295 cout << endl;
3296 }
3297}
3298
3301 unipoly_object &minpol, int d, int *Frobenius,
3302 int verbose_level)
3303// Lueneburg~\cite{Lueneburg87a}, p. 112.
3304{
3305 int f_v = (verbose_level >= 1);
3306 int f_vv = (verbose_level >= 2);
3307 int deg, i, j, k;
3308 unipoly_object mm, h, h2, *sigma;
3309
3310 if (f_v) {
3311 cout << "unipoly_domain::minimum_polynomial_extension_field of ";
3312 print_object(g, cout);
3313 cout << endl;
3314 }
3315 deg = d;
3316 sigma = NEW_OBJECTS(unipoly_object, deg + 2);
3317 for (i = 0; i < deg + 2; i++) {
3318 if (i == 0) {
3319 create_object_by_rank(sigma[i], 1, __FILE__, __LINE__, 0 /*verbose_level*/);
3320 }
3321 else {
3322 create_object_by_rank(sigma[i], 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3323 }
3324 }
3325 create_object_by_rank(h, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3326 create_object_by_rank(h2, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3327 create_object_by_rank(mm, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3328
3329 assign(m, mm, 0 /*verbose_level*/);
3330 negate(mm);
3331 if (f_v) {
3332 cout << "unipoly_domain::minimum_polynomial_extension_field "
3333 "we are working modulo - (";
3334 print_object(mm, cout);
3335 cout << ")" << endl;
3336 }
3337
3338 assign(g, sigma[1], 0 /*verbose_level*/);
3339
3340 i = 1;
3341 while (TRUE) {
3342 i++;
3343
3344 if (f_vv) {
3345 cout << "unipoly_domain::minimum_polynomial_extension_field "
3346 "i = " << i << " : g = ";
3347 print_object(g, cout);
3348 cout << endl;
3349 cout << "sigma=" << endl;
3350 print_vector_of_polynomials(sigma, deg);
3351 }
3352
3353 if (f_vv) {
3354 cout << "unipoly_domain::minimum_polynomial_extension_field "
3355 "i = " << i << " before matrix_apply" << endl;
3356 }
3357 matrix_apply(g, Frobenius, deg, verbose_level - 2);
3358 if (f_vv) {
3359 cout << "unipoly_domain::minimum_polynomial_extension_field "
3360 "i = " << i << " after matrix_apply" << endl;
3361 }
3362
3363 if (f_vv) {
3364 cout << "unipoly_domain::minimum_polynomial_extension_field "
3365 "i = " << i << " : g=";
3366 print_object(g, cout);
3367 cout << endl;
3368 }
3369
3370
3371 if (f_vv) {
3372 cout << "unipoly_domain::minimum_polynomial_extension_field "
3373 "i = " << i
3374 << " before mult_mod" << endl;
3375 }
3376 mult_mod_negated(g, sigma[i - 1], sigma[i],
3377 degree(mm), ((int *)mm) + 1,
3378 verbose_level - 2);
3379 if (f_vv) {
3380 cout << "unipoly_domain::minimum_polynomial_extension_field "
3381 "i = " << i
3382 << " after mult_mod" << endl;
3383 cout << "sigma=" << endl;
3384 print_vector_of_polynomials(sigma, deg);
3385 }
3386
3387 for (j = i - 1; j >= 1; j--) {
3388 if (f_vv) {
3389 cout << "unipoly_domain::minimum_polynomial_extension_field "
3390 "i = " << i << " j = "
3391 << j << endl;
3392 }
3393 if (f_vv) {
3394 cout << "unipoly_domain::minimum_polynomial_extension_field "
3395 "i = " << i << " j = "
3396 << j << " before mult_mod" << endl;
3397 }
3398 mult_mod_negated(g, sigma[j - 1], h, degree(mm), ((int *)mm) + 1, 0);
3399 if (f_vv) {
3400 cout << "unipoly_domain::minimum_polynomial_extension_field "
3401 "i = " << i << " j = "
3402 << j << " after mult_mod" << endl;
3403 cout << "sigma=" << endl;
3404 print_vector_of_polynomials(sigma, deg);
3405 }
3406 if (f_vv) {
3407 cout << "unipoly_domain::minimum_polynomial_extension_field "
3408 "i = " << i << " j = "
3409 << j << " before add" << endl;
3410 }
3411 add(sigma[j], h, h2);
3412 if (f_vv) {
3413 cout << "unipoly_domain::minimum_polynomial_extension_field "
3414 "i = " << i << " j = "
3415 << j << " after add" << endl;
3416 }
3417 if (f_vv) {
3418 cout << "unipoly_domain::minimum_polynomial_extension_field "
3419 "i = " << i << " j = "
3420 << j << " before assign" << endl;
3421 cout << "sigma=" << endl;
3422 print_vector_of_polynomials(sigma, deg);
3423 }
3424 assign(h2, sigma[j], 0 /*verbose_level*/);
3425 if (f_vv) {
3426 cout << "unipoly_domain::minimum_polynomial_extension_field "
3427 "i = " << i << " j = "
3428 << j << " after assign" << endl;
3429 }
3430
3431 if (f_vv) {
3432 cout << "unipoly_domain::minimum_polynomial_extension_field "
3433 "i = " << i << " j = "
3434 << j << " iteration finished" << endl;
3435 }
3436 }
3437 for (k = i; k >= 0; k--) {
3438 if (degree(sigma[k]) > 0) {
3439 break;
3440 }
3441 }
3442 if (k == -1) {
3443 break;
3444 }
3445 }
3446 delete_object(minpol);
3447 create_object_of_degree(minpol, i);
3448 for (j = i; j >= 0; j--) {
3449 ((int *) minpol)[1 + j] = ((int *)sigma[i - j])[1 + 0];
3450 }
3451 for (j = 0; j <= i; j += 2) {
3452 ((int *) minpol)[1 + j] = F->negate(
3453 ((int *) minpol)[1 + j]);
3454 }
3455 make_monic(minpol);
3456 if (f_vv) {
3457 cout << "unipoly_domain::minimum_polynomial_extension_field "
3458 "after make_monic";
3459 cout << "minpol=";
3460 print_object(minpol, cout);
3461 cout << endl;
3462 }
3463
3464 if (f_v) {
3465 cout << "unipoly_domain::minimum_polynomial_extension_field "
3466 "minpol is ";
3467 print_object(minpol, cout);
3468 cout << endl;
3469 }
3470
3471 delete_object(h);
3472 delete_object(h2);
3473 delete_object(mm);
3474 for (i = 0; i < deg + 2; i++) {
3475 delete_object(sigma[i]);
3476 }
3477 FREE_OBJECTS(sigma);
3478 if (f_v) {
3479 cout << "unipoly_domain::minimum_polynomial_extension_field done" << endl;
3480 }
3481}
3482
3484 int *Mtx, int k, unipoly_object &char_poly,
3485 int verbose_level)
3486{
3487 int f_v = (verbose_level >= 1);
3488 int f_vv = (verbose_level >= 2);
3489 unipoly_object *M;
3490 int i, j, a, m_one;
3491
3492 if (f_v) {
3493 cout << "unipoly_domain::characteristic_polynomial" << endl;
3494 }
3495 if (f_vv) {
3496 cout << "unipoly_domain::characteristic_polynomial M=" << endl;
3497 Int_matrix_print(Mtx, k, k);
3498 }
3499 m_one = F->negate(1);
3500 M = NEW_OBJECTS(unipoly_object, k * k);
3501 for (i = 0; i < k; i++) {
3502 for (j = 0; j < k; j++) {
3503 a = Mtx[i * k + j];
3504 if (i == j) {
3505 create_object_of_degree(M[i * k + j], 1);
3506 ((int *)M[i * k + j])[1 + 0] = a;
3507 ((int *)M[i * k + j])[1 + 1] = m_one;
3508 }
3509 else {
3510 create_object_of_degree(M[i * k + j], 0);
3511 ((int *)M[i * k + j])[1 + 0] = a;
3512 }
3513 }
3514 }
3515
3516
3517 if (f_vv) {
3518 cout << "unipoly_domain::characteristic_polynomial M - X Id=" << endl;
3519 print_matrix(M, k);
3520 }
3521
3522 if (f_vv) {
3523 cout << "unipoly_domain::characteristic_polynomial before determinant" << endl;
3524 }
3525 determinant(M, k, char_poly, verbose_level);
3526 if (f_vv) {
3527 cout << "unipoly_domain::characteristic_polynomial after determinant" << endl;
3528 }
3529
3530 if (f_vv) {
3531 cout << "unipoly_domain::characteristic_polynomial before delete_object(M[i * k + j]);" << endl;
3532 }
3533 for (i = 0; i < k; i++) {
3534 for (j = 0; j < k; j++) {
3535 if (f_vv) {
3536 cout << "unipoly_domain::characteristic_polynomial i=" << i << " j=" << j << endl;
3537 }
3538 delete_object(M[i * k + j]);
3539 }
3540 }
3541 if (f_vv) {
3542 cout << "unipoly_domain::characteristic_polynomial before FREE_OBJECTS(M);" << endl;
3543 }
3544 FREE_OBJECTS(M);
3545 if (f_v) {
3546 cout << "unipoly_domain::characteristic_polynomial done" << endl;
3547 }
3548}
3549
3551// M is a matrix with polynomial entries
3552{
3553 int i, j;
3554
3555 for (i = 0; i < k; i++) {
3556 for (j = 0; j < k; j++) {
3557 print_object(M[i * k + j], cout);
3558 if (j < k - 1) {
3559 cout << "; ";
3560 }
3561 }
3562 cout << endl;
3563 }
3564}
3565
3567 unipoly_object *M,
3568 int k, unipoly_object &p,
3569 int verbose_level)
3570// M is a matrix with polynomial entries
3571{
3572 int f_v = (verbose_level >= 1);
3573 int i, j;
3574 unipoly_object p1, p2, p3;
3575
3576 if (f_v) {
3577 cout << "unipoly_domain::determinant k=" << k << endl;
3578 }
3579 if (k == 0) {
3580 delete_object(p);
3581 create_object_by_rank(p, 1, __FILE__, __LINE__, 0 /*verbose_level*/);
3582 if (f_v) {
3583 cout << "unipoly_domain::determinant done" << endl;
3584 }
3585 return;
3586 }
3587 delete_object(p);
3588 create_object_by_rank(p, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3589 create_object_by_rank(p1, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3590 create_object_by_rank(p2, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3591 create_object_by_rank(p3, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
3592
3593 for (i = 0; i < k; i++) {
3594 unipoly_object *N;
3595
3596 deletion_matrix(M, k,
3597 i /* delete_row */,
3598 0 /* delete_column */,
3599 N,
3600 0 /*verbose_level - 2*/);
3601
3602 determinant(N, k - 1, p1, verbose_level - 2);
3603 if (f_v) {
3604 cout << "unipoly_domain::determinant "
3605 "deletion of row " << i << " leads to determinant ";
3606 print_object(p1, cout);
3607 cout << endl;
3608 }
3609
3610 mult(p1, M[i * k + 0], p2, verbose_level - 1);
3611
3612 if (ODD(i)) {
3613 negate(p2);
3614 }
3615
3616
3617 add(p, p2, p3);
3618 assign(p3, p, 0 /*verbose_level*/);
3619
3620 for (j = 0; j < (k - 1) * (k - 1); j++) {
3621 delete_object(N[j]);
3622 }
3623 FREE_OBJECTS(N);
3624 }
3625
3626 delete_object(p1);
3627 delete_object(p2);
3628 delete_object(p3);
3629 if (f_v) {
3630 cout << "unipoly_domain::determinant done" << endl;
3631 }
3632}
3633
3635 int k, int delete_row, int delete_column,
3636 unipoly_object *&N,
3637 int verbose_level)
3638{
3639 int f_v = (verbose_level >= 1);
3640 int k1;
3641 int i, j, ii, jj;
3642
3643 if (f_v) {
3644 cout << "unipoly_domain::deletion_matrix" << endl;
3645 }
3646 k1 = k - 1;
3647 N = NEW_OBJECTS(unipoly_object, k1 * k1);
3648 for (i = 0; i < k1 * k1; i++) {
3649 create_object_of_degree(N[i], 0);
3650 }
3651
3652 for (i = 0, ii = 0; i < k; i++) {
3653 if (i == delete_row) {
3654 continue;
3655 }
3656 for (j = 0, jj = 0; j < k; j++) {
3657 if (j == delete_column) {
3658 continue;
3659 }
3660
3661 assign(M[i * k + j], N[ii * k1 + jj], 0 /*verbose_level*/);
3662
3663 jj++;
3664 }
3665 ii++;
3666 }
3667 if (f_v) {
3668 cout << "unipoly_domain::deletion_matrix done" << endl;
3669 }
3670}
3671
3673{
3674 //int verbose_level = 0;
3675 //int f_v = (verbose_level >= 1);
3676 int *ra = (int *) a;
3677 int m = ra[0];
3678 int q2;
3679
3680 q2 = q >> 1;
3681
3682 int *A = ra + 1;
3683 int i, x;
3684
3685 for (i = 0; i <= m; i++) {
3686 x = A[i];
3687 if (x > q2) {
3688 x -= q;
3689 }
3690 A[i] = x;
3691 }
3692}
3693
3695{
3696 //int verbose_level = 0;
3697 //int f_v = (verbose_level >= 1);
3698 int *ra = (int *) a;
3699 int m = ra[0];
3700
3701 int *A = ra + 1;
3702 int i, x;
3703
3704 for (i = 0; i <= m; i++) {
3705 x = A[i];
3706 A[i] = x % p;
3707 }
3708}
3709
3710
3711}}}
3712
3713
void print(std::ostream &ost, std::vector< int > &v)
Definition: int_vec.cpp:413
int Gauss_int(int *A, int f_special, int f_complete, int *base_cols, int f_P, int *P, int m, int n, int Pn, int verbose_level)
void order_ideal_generator(int d, int idx, int *mue, int &mue_deg, int *A, int *Frobenius, int verbose_level)
void mult_matrix_matrix(int *A, int *B, int *C, int m, int n, int o, int verbose_level)
void mult_vector_from_the_right(int *A, int *v, int *Av, int m, int n)
void span_cyclic_module(int *A, int *v, int n, int *Mtx, int verbose_level)
void lint_matrix_read_csv(std::string &fname, long int *&M, int &m, int &n, int verbose_level)
Definition: file_io.cpp:1558
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
int compare(longinteger_object &a, longinteger_object &b)
void add(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void integral_division_by_int(longinteger_object &a, int b, longinteger_object &q, int &r)
void mult(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void integral_division(longinteger_object &a, longinteger_object &b, longinteger_object &q, longinteger_object &r, int verbose_level)
void factor_into_longintegers(longinteger_object &a, int &nb_primes, longinteger_object *&primes, int *&exponents, int verbose_level)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
domain of polynomials in one variable over a finite field
Definition: ring_theory.h:691
int substitute_scalar_in_polynomial(unipoly_object &p, int scalar, int verbose_level)
void add(unipoly_object a, unipoly_object b, unipoly_object &c)
int minimum_polynomial_factorring(int alpha, int p, int verbose_level)
void deletion_matrix(unipoly_object *M, int k, int delete_row, int delete_column, unipoly_object *&N, int verbose_level)
void create_object_of_degree_with_coefficients(unipoly_object &p, int d, int *coeff)
void power_int(unipoly_object &a, int n, int verbose_level)
void get_a_primitive_polynomial(unipoly_object &m, int f, int verbose_level)
void substitute_matrix_in_polynomial(unipoly_object &p, int *Mtx_in, int *Mtx_out, int k, int verbose_level)
void print_object_tight(unipoly_object p, std::ostream &ost)
int is_squarefree(unipoly_object p, int verbose_level)
void derivative(unipoly_object a, unipoly_object &b)
void print_object_dense(unipoly_object p, std::ostream &ost)
int is_primitive(unipoly_object &m, longinteger_object &qm1, int nb_primes, longinteger_object *primes, int verbose_level)
void Frobenius_matrix_by_rows(int *&Frob, unipoly_object factor_polynomial, int verbose_level)
void mult_mod(unipoly_object a, unipoly_object b, unipoly_object &c, unipoly_object m, int verbose_level)
void module_structure_apply(int *v, int *Mtx, int n, unipoly_object p, int verbose_level)
void exact_division(unipoly_object a, unipoly_object b, unipoly_object &q, int verbose_level)
void mult(unipoly_object a, unipoly_object b, unipoly_object &c, int verbose_level)
void compute_normal_basis(int d, int *Normal_basis, int *Frobenius, int verbose_level)
void mult_mod_negated(unipoly_object a, unipoly_object b, unipoly_object &c, int factor_polynomial_degree, int *factor_polynomial_coefficients_negated, int verbose_level)
void order_ideal_generator(int d, int idx, unipoly_object &mue, int *A, int *Frobenius, int verbose_level)
void extended_gcd(unipoly_object m, unipoly_object n, unipoly_object &u, unipoly_object &v, unipoly_object &g, int verbose_level)
void minimum_polynomial_extension_field(unipoly_object &g, unipoly_object m, unipoly_object &minpol, int d, int *Frobenius, int verbose_level)
void get_an_irreducible_polynomial(unipoly_object &m, int f, int verbose_level)
void print_vector_of_polynomials(unipoly_object *sigma, int deg)
void greatest_common_divisor(unipoly_object m, unipoly_object n, unipoly_object &g, int verbose_level)
void division_with_remainder(unipoly_object a, unipoly_object b, unipoly_object &q, unipoly_object &r, int verbose_level)
int is_irreducible(unipoly_object a, int verbose_level)
void determinant(unipoly_object *M, int k, unipoly_object &p, int verbose_level)
int compare_euclidean(unipoly_object m, unipoly_object n)
void singer_candidate(unipoly_object &m, int p, int d, int b, int a)
void power_longinteger(unipoly_object &a, longinteger_object &n, int verbose_level)
void Frobenius_matrix(int *&Frob, unipoly_object factor_polynomial, int verbose_level)
void create_object_by_rank_longinteger(unipoly_object &p, longinteger_object &rank, const char *file, int line, int verbose_level)
void create_object_by_rank(unipoly_object &p, long int rk, const char *file, int line, int verbose_level)
void create_Dickson_polynomial(unipoly_object &p, int *map)
void unrank_longinteger(unipoly_object p, longinteger_object &rank)
void create_object_by_rank_string(unipoly_object &p, std::string &rk, int verbose_level)
void matrix_apply(unipoly_object &p, int *Mtx, int n, int verbose_level)
void rank_longinteger(unipoly_object p, longinteger_object &rank)
void characteristic_polynomial(int *Mtx, int k, unipoly_object &char_poly, int verbose_level)
void minimum_polynomial_factorring_longinteger(longinteger_object &alpha, longinteger_object &rk_minpoly, int p, int verbose_level)
void init_basic(field_theory::finite_field *F, int verbose_level)
void create_object_of_degree_no_test(unipoly_object &p, int d)
void mult_easy(unipoly_object a, unipoly_object b, unipoly_object &c)
void print_object_sparse(unipoly_object p, std::ostream &ost)
void create_object_from_csv_file(unipoly_object &p, std::string &fname, const char *file, int line, int verbose_level)
void assign(unipoly_object a, unipoly_object &b, int verbose_level)
void minimum_polynomial(unipoly_object &a, int alpha, int p, int verbose_level)
void Berlekamp_matrix(int *&B, unipoly_object factor_polynomial, int verbose_level)
void take_away_all_factors_from_b(unipoly_object a, unipoly_object b, unipoly_object &a_without_b, int verbose_level)
void print_object(unipoly_object p, std::ostream &ost)
void init_factorring(field_theory::finite_field *F, unipoly_object m, int verbose_level)
#define NEW_int_with_tracking(n, file, line)
Definition: foundations.h:626
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define Int_vec_print_integer_matrix(A, B, C, D)
Definition: foundations.h:690
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_int(n)
Definition: foundations.h:625
#define Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define ODD(x)
Definition: foundations.h:222
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_lint(p)
Definition: foundations.h:642
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define MAXIMUM(x, y)
Definition: foundations.h:217
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects