Orbiter 2022
Combinatorial Objects
unipoly.cpp
Go to the documentation of this file.
1// unipoly.cpp
2//
3// Anton Betten
4// 24.12.1999
5// moved from D2 to ORBI Nov 15, 2007
6
8#include "discreta.h"
9
10using namespace std;
11
12
13
14namespace orbiter {
15namespace layer2_discreta {
16
17
18#undef CHANGE_KIND_VERBOSE
19#undef COPY_VERBOSE
20
21
23{
24 k = UNIPOLY;
25}
26
28 // copy constructor: this := x
29{
30 cout << "unipoly::copy constructor for object: "
31 << const_cast<discreta_base &>(x) << "\n";
32 const_cast<discreta_base &>(x).copyobject_to(*this);
33}
34
36 // copy assignment
37{
38 //cout << "unipoly::operator = (copy assignment)" << endl;
39 copyobject(const_cast<discreta_base &>(x));
40 return *this;
41}
42
44{
45 OBJECTSELF s;
46
47 s = self;
48 new(this) unipoly;
49 self = s;
50 k = UNIPOLY;
51}
52
54{
56}
57
59{
60 // cout << "unipoly::freeself_unipoly()\n";
62}
63
65{
66 return UNIPOLY;
67}
68
70{
71#ifdef COPY_VERBOSE
72 cout << "unipoly::copyobject_to()" << endl;
73 print_as_vector(cout);
74#endif
76 x.as_unipoly().settype_unipoly();
77#ifdef COPY_VERBOSE
78 x.as_unipoly().print_as_vector(cout);
79#endif
80}
81
85
86
87ostream& unipoly::print(ostream& ost)
88{
89 int d, i, f_print_k, k, f_prev = FALSE;
90 discreta_base coef;
91 const char *x, *y;
92 int f_nothing_printed_at_all = TRUE;
93
96 else
97 x = "x";
99 y = "_";
100 else
101 y = "^";
102 d = degree();
103 // ost << "(";
104 for (i = d; i >= 0; i--) {
105 coef = s_i(i);
106 if (coef.s_kind() == INTEGER) {
107 k = coef.s_i_i();
108 if (k == 0) {
109 if (i == 0 && f_nothing_printed_at_all) {
110 ost << "0";
111 }
112 continue;
113 }
114 f_nothing_printed_at_all = FALSE;
115 if (k < 0) {
116 ost << " - ";
117 }
118 else if (f_prev) {
119 ost << " + ";
120 }
121 if (k < 0)
122 k = -k;
123 if (k != 1 || (i == 0 && !my_unip_f_use_variable_name)) {
124 ost << k;
125 }
126 }
127 else {
128 f_nothing_printed_at_all = FALSE;
129 f_print_k = TRUE;
130 if (coef.is_one() && i > 0)
131 f_print_k = FALSE;
132 if (f_prev)
133 ost << " + ";
134 if (f_print_k) {
135 ost << coef;
136 }
137 }
138 if (i == 0) {
140 ost << x;
141 ost << y;
142 ost << "0";
143 }
144 }
145 else if (i == 1) {
146 ost << x;
148 ost << y;
149 ost << "1";
150 }
151 }
152 else if (i > 1) {
153 ost << x;
154 ost << y;
156 if (i < 10)
157 ost << i;
158 else
159 ost << "{" << i << "}";
160 }
161 else {
162 ost << i;
163 }
164 }
165 f_prev = TRUE;
166 }
167 // ost << ")";
168 return ost;
169}
170
171ostream& unipoly::print_as_vector(ostream& ost)
172{
173 // cout << "unipoly::print_as_vector()" << endl;
174 return Vector::print(ost);
175}
176
177void unipoly::m_l(int l)
178{
179 // cout << "unipoly::m_l()\n";
180 Vector::m_l_n(l);
182}
183
185{
186 int l = s_l();
187 int i;
188
189 for (i = l - 1; i >= 0; i--) {
190 if (!s_i(i).is_zero())
191 return i;
192 }
193 return 0;
194}
195
197{
198 unipoly& px = x.as_unipoly();
199 unipoly py;
201 int d1, d2, d3, i, j, k;
202
203 if (s_kind() != UNIPOLY) {
204 cout << "unipoly::mult_to() this not a unipoly" << endl;
205 exit(1);
206 }
207 if (x.s_kind() != UNIPOLY) {
208 cout << "unipoly::mult_to() x is not a unipoly" << endl;
209 exit(1);
210 }
211 d1 = degree();
212 d2 = px.degree();
213 d3 = d1 + d2;
214
215 py.m_l(d3 + 1);
216 a = s_i(0);
217 a.zero();
218 for (i = 0; i <= d3; i++) {
219 py[i] = a;
220 }
221 for (i = 0; i <= d1; i++) {
222 for (j = 0; j <= d2; j++) {
223 k = i + j;
224 a.mult(s_i(i), px.s_i(j));
225 py[k] += a;
226 }
227 }
228 py.swap(y);
229}
230
232{
233 unipoly& px = x.as_unipoly();
234 unipoly py;
236 int d1, d2, d3, i;
237
238 if (s_kind() != UNIPOLY) {
239 cout << "unipoly::add_to() this not a unipoly" << endl;
240 exit(1);
241 }
242 if (x.s_kind() != UNIPOLY) {
243 cout << "unipoly::add_to() x is not a unipoly" << endl;
244 exit(1);
245 }
246 d1 = degree();
247 d2 = px.degree();
248 d3 = MAXIMUM(d1, d2);
249
250 py.m_l(d3 + 1);
251 a = s_i(0);
252 a.zero();
253 for (i = 0; i <= d1; i++) {
254 py[i] = s_i(i);
255 }
256 for (; i <= d3; i++) {
257 py[i] = a;
258 }
259 for (i = 0; i <= d2; i++) {
260 py[i] += px.s_i(i);
261 }
262 py.swap(y);
263}
264
266{
267 unipoly px;
268 int i, l;
269
270 if (s_kind() != UNIPOLY) {
271 cout << "unipoly::negate_to() this is not a unipoly" << endl;
272 exit(1);
273 }
274 l = s_l();
275 px.m_l(l);
276 for (i = 0; i < l; i++) {
277 s_i(i).negate_to(px.s_i(i));
278 }
279 x.swap(px);
280}
281
283{
284 m_l(1);
285 s_i(0).one();
286}
287
289{
290 m_l(1);
291 s_i(0).zero();
292}
293
295{
296 m_l(2);
297 s_i(0).zero();
298 s_i(1).one();
299}
300
302{
303 int j;
304
305 m_l(i + 1);
306 for (j = 0; j < i; j++) {
307 s_i(j).zero();
308 }
309 s_i(i).one();
310}
311
313{
314 int d;
315
316 d = degree();
317 if (d > 0)
318 return FALSE;
319 return s_i(0).is_one();
320}
321
323{
324 int d;
325
326 d = degree();
327 if (d > 0)
328 return FALSE;
329 return s_i(0).is_zero();
330}
331
333{
334 int d1, d2;
335 unipoly &pa = a.as_unipoly();
336
337 d1 = degree();
338 d2 = pa.degree();
339 if (d1 < d2)
340 return -1;
341 else if (d1 > d2)
342 return 1;
343 return 0;
344}
345
347 discreta_base &q, discreta_base &r, int verbose_level)
348{
349 int f_v = (verbose_level >= 1);
350 int dm, dn, dq, i, j, ii, jj;
351 discreta_base a, av, b, bav, c;
352 unipoly &n = x.as_unipoly();
353 unipoly qq, rr;
354
355 if (f_v) {
356 cout << "unipoly::integral_division" << endl;
357 cout << "m=" << *this << endl;
358 cout << "n=" << x << endl;
359 }
360 dm = degree();
361 dn = n.degree();
362 if (dn == 0) {
363 if (n[0].is_zero()) {
364 cout << "unipoly::integral_division(): division by zero" << endl;
365 exit(1);
366 }
367 }
368 if (dn > dm) {
369 if (f_v) {
370 cout << "unipoly::integral_division dn > dm, no division possible" << endl;
371 }
372 qq.zero();
373 rr = *this;
374 qq.swap(q);
375 rr.swap(r);
376 return;
377 }
378 dq = dm - dn;
379 qq.m_l(dq + 1);
380 rr = *this;
381 // cout << "rr=" << rr << endl;
382 a = n[dn];
383 if (f_v) {
384 cout << "unipoly::integral_division a=" << a << endl;
385 }
386 av = a;
387 if (f_v) {
388 cout << "unipoly::integral_division before av.invert" << endl;
389 }
390 av.invert();
391 if (f_v) {
392 cout << "unipoly::integral_division av=" << av << endl;
393 }
394 for (i = dm, j = dq; i >= dn; i--, j--) {
395 if (f_v) {
396 cout << "unipoly::integral_division i=" << i << " j=" << j << endl;
397 }
398
399 b = rr[i];
400 if (f_v) {
401 cout << "unipoly::integral_division b=" << b << endl;
402 cout << "unipoly::integral_division av=" << av << endl;
403 cout << "unipoly::integral_division before mult" << endl;
404 }
405
406 bav.mult(b, av);
407 qq[j] = bav;
408 // cout << "i=" << i << " bav=" << bav << endl;
409 for (ii = i, jj = dn; jj >= 0; ii--, jj--) {
410 if (f_v) {
411 cout << "unipoly::integral_division ii=" << ii << " jj=" << jj << endl;
412 }
413 c = n[jj];
414 c *= bav;
415 c.negate();
416 rr[ii] += c; // rr[ii] -= bav * this[jj]
417 if (ii == i && !rr[ii].is_zero()) {
418 cout << "unipoly::integral_division(): ii == i && !rr[ii].is_zero()" << endl;
419 exit(1);
420 }
421 // cout << "c=" << c << endl;
422 // cout << "rr[ii]=" << rr[ii] << endl;
423 }
424 // cout << "i=" << i << " rr=" << rr << endl;
425 }
426 qq.swap(q);
427 rr.swap(r);
428 if (f_v) {
429 cout << "q=" << q << endl;
430 cout << "r=" << r << endl;
431 }
432}
433
435{
436 int i, d;
438
439 d = degree();
440 for (i = 1; i <= d; i++) {
441 a = s_i(i); // get the object type
442 a.homo_z(i);
443 a *= s_i(i);
444 s_i(i - 1) = a;
445 }
446 s_i(d).zero();
447}
448
449int unipoly::is_squarefree(int verbose_level)
450{
451 int f_v = (verbose_level >= 1);
452 unipoly a, u, v, g;
453 int d;
454
455 a = *this;
456 a.derive();
457 if (f_v) {
458 cout << "unipoly::is_squarefree() derivative p' = " << a << endl;
459 }
460 extended_gcd(a, u, v, g, verbose_level - 2);
461 if (f_v) {
462 cout << "unipoly::is_squarefree() gcd(p, p') = " << g << endl;
463 }
464 d = g.degree();
465 if (d >= 1)
466 return FALSE;
467 else
468 return TRUE;
469}
470
471int unipoly::is_irreducible_GFp(int p, int verbose_level)
472{
473 int f_v = (verbose_level >= 1);
475 domain d(p);
476 with w(&d);
477 int l, r;
478
479 if (!is_squarefree(verbose_level))
480 return FALSE;
481 B.Berlekamp(*this, p, verbose_level - 1);
482 l = B.s_m();
483 r = B.rank();
484 if (f_v) {
485 cout << "has rank " << r << endl;
486 }
487 if (r == l - 1)
488 return TRUE;
489 else
490 return FALSE;
491}
492
493int unipoly::is_irreducible(int q, int verbose_level)
494{
495 int f_v = (verbose_level = 1);
497 int l, r;
498
499 if (!is_squarefree(verbose_level))
500 return FALSE;
501 B.Berlekamp(*this, q, verbose_level);
502 l = B.s_m();
503 r = B.rank();
504 if (f_v) {
505 cout << "has rank " << r << endl;
506 }
507 if (r == l - 1)
508 return TRUE;
509 else
510 return FALSE;
511}
512
513int unipoly::is_primitive(int m, int p, Vector& vp, int verbose_level)
514//Returns TRUE iff the polynomial $x$ has order $m$
515//modulo the polynomial this (over GF(p)).
516//The prime factorization of $m$ must be given in vp (only the primes).
517//A polynomial $a$ has order $m$ mod $q$ ($q = this$) iff
518//$a^m =1 mod q$ and $a^{m/p_i} \not= 1 mod q$ for all $p_i \mid m.$
519//In this case, we have $a=x$ and we assume that $a^m = 1 mod q.$
520{
521 int l, i, m1;
522 unipoly a;
523 domain d(p);
524 with w(&d);
525
526 l = vp.s_l();
527 for (i = 0; i < l; i++) {
528 m1 = m / vp.s_ii(i);
529 a.x();
530 a.power_int_mod(m1, *this);
531 if (a.is_one())
532 return FALSE;
533 }
534 return TRUE;
535}
536
538{
539 Vector v;
540 int i, l;
541
542 v.q_adic(n, q);
543 l = v.s_l();
544 m_l(l);
545 for (i = 0; i < l; i++) {
546 m_ii(i, v.s_ii(i));
547 }
548}
549
551{
552 return q_adic_as_int(q);
553}
554
555void unipoly::singer_candidate(int p, int f, int b, int a)
556{
557 m_l(f + 1);
558 s_i(f).one();
559 s_i(f - 1).one();
560 s_i(1).m_i_i(b);
561 s_i(0).m_i_i(a);
562}
563
564void unipoly::Singer(int p, int f, int verbose_level)
565{
566 int f_v = (verbose_level >= 1);
567 int f_vv = (verbose_level >= 2);
568 int m, i, a, b, low, high;
569 Vector vp, ve;
570 unipoly x;
572
573 if (p <= 1) {
574 cout << "unipoly::Singer: p <= 1" << endl;
575 exit(1);
576 }
577 if (!NT.is_prime(p)) {
578 cout << "unipoly::Singer: p not prime" << endl;
579 exit(1);
580 }
581 m = NT.i_power_j(p, f) - 1;
582 factor_integer(m, vp, ve);
583 a = NT.primitive_root(p, f_v);
584 for (b = 0; b < p; b++) {
585 x.singer_candidate(p, f, b, a);
586 if (f_v) {
587 cout << "singer candidate " << x << endl;
588 }
589 if (x.is_irreducible_GFp(p, verbose_level) &&
590 x.is_primitive(m, p, vp, verbose_level)) {
591 if (f_v) {
592 cout << "OK" << endl;
593 }
594 swap(x);
595 return;
596 }
597 }
598 low = m + 1;
599 high = low << 1;
600 for (i = low; i <= high; i++) {
601 x.numeric_polynomial(i, p);
602 if (f_v) {
603 cout << "candidate " << i - low + 1 << " : " << x << endl;
604 }
605 if (x.is_irreducible_GFp(p, f_vv) &&
606 x.is_primitive(m, p, vp, verbose_level)) {
607 if (f_v) {
608 cout << "OK" << endl;
609 }
610 swap(x);
611 return;
612 }
613 }
614 cout << "unipoly::Singer did not find an irrducible primitive polynomial" << endl;
615 exit(1);
616}
617
618void unipoly::get_an_irreducible_polynomial(int f, int verbose_level)
619{
620 int f_v = (verbose_level >= 1);
621 int f_vv = (verbose_level >= 2);
622 int low, high, q, i;
623 domain *d;
624 unipoly x;
626
627 if (f_v) {
628 cout << "unipoly::get_an_irreducible_polynomial" << endl;
629 }
630 if (!is_finite_field_domain(d)) {
631 cout << "unipoly::get_an_irreducible_polynomial() no finite field domain" << endl;
632 exit(1);
633 }
635 if (f_v) {
636 cout << "unipoly::get_an_irreducible_polynomial() \n"
637 "searching for an irreducible polynomial of degree " << f <<
638 " over GF(" << q << ")" << endl;
639 }
640 low = NT.i_power_j(q, f);
641 high = low << 1; // only monic polynomials
642 for (i = low; i <= high; i++) {
643 x.numeric_polynomial(i, q);
644 if (f_vv) {
645 cout << "candidate " << i - low + 1 << " : " << x << endl;
646 }
647 if (x.is_irreducible(q, verbose_level - 2)) {
648 if (f_vv) {
649 cout << "is irreducible" << endl;
650 }
651 if (f_v) {
652 cout << "unipoly::get_an_irreducible_polynomial() " << x << endl;
653 }
654 swap(x);
655 return;
656 }
657 }
658 cout << "unipoly::get_an_irreducible_polynomial() no polynomial found" << endl;
659 exit(1);
660}
661
663{
664 int i, d;
666
667 d = degree();
668 z = s_i(d);
669 for (i = d - 1; i >= 0; i--) {
670 z *= x;
671 z += s_i(i);
672 }
673 y = z;
674}
675
677//computes the monic polynomial $r$ with ($p$ is the polynomial in this)
678//\begin{enumerate}
679//\item
680//$r \mid p$
681//\item
682//$\gcd(r,q) = 1$ and
683//\item
684//each irreducible polynomial dividing $p/r$ divides $q$.
685//Lueneburg~\cite{Lueneburg87a}, p. 37.
686//\end{enumerate}
687//In other words, $r$ is the maximal divisor of $p$ which is prime to $q$.
688{
689 unipoly rr, g, u, v;
690 //int d;
691
692 //d = degree();
693 r = *this;
694 r.extended_gcd(q, u, v, g, 0);
695 while (g.degree()) {
697 r.swap(rr);
698 r.extended_gcd(q, u, v, g, 0);
699 }
700 r.monic();
701}
702
704{
705 int d, i;
707
708 d = degree();
709 a = s_i(d);
710 if (a.is_one())
711 return;
712 a.invert();
713 for (i = 0; i < d; i++) {
714 s_i(i) *= a;
715 }
716}
717
718void unipoly::normal_base(int p, discreta_matrix& F, discreta_matrix& N, int verbose_level)
719// compare Lueneburg~\cite{Lueneburg87a} p. 106.
720{
721 int f_v = (verbose_level >= 1);
722 domain d(p);
723 with ww(&d);
724 int i, f;
725 Vector v, V;
726 unipoly x, mue;
727
728 f = degree();
729 F.Frobenius(*this, p, FALSE);
730 if (f_v) {
731 cout << "unipoly::normal_base(): Frobenius:\n" << F << endl;
732 }
733 F.KX_cyclic_module_generator(v, mue, verbose_level - 1);
734 V.m_l(f);
735 V[0] = v;
736 x.x();
737 if (f_v) {
738 cout << "unipoly::normal_base(): V[0]=" << v << endl;
739 }
740 for (i = 1; i < f; i++) {
741 F.KX_module_apply(x, v);
742 V[i] = v;
743 if (f_v) {
744 cout << "unipoly::normal_base(): V["<<i<<"]=" << v << endl;
745 }
746 }
748 if (f_v) {
749 cout << "unipoly::normal_base(): N=\n" << N << endl;
750 }
751
752#if 0
753 matrix T, P, Pv, Q, Qv;
754 integer a1;
755 Vector v, vv, b, bb;
756
757 T = F;
759 T.minus_X_times_id();
760 if (f_v) {
761 cout << "F - x * Id=\n" << T << endl;
762 }
763 T.smith_normal_form(P, Pv, Q, Qv, f_vv, FALSE);
764
765 if (f_v) {
766 cout << "Q=\n" << Q << endl;
767 }
768 a1.m_i_i(1);
769 Q.evaluate_at(a1);
770 if (f_v) {
771 cout << "Q(1)=\n" << Q << endl;
772 cout << "F=\n" << F << endl;
773 }
775 b = v.s_i(d - 1);
776 vv.m_l(d);
777 vv[1] = b;
778 if (f_v) {
779 cout << "N[0]=" << b << endl;
780 }
781 for (i = 1; i < d; i++) {
782 bb.mult(F, b);
783 b = bb;
784 vv[i] = b;
785 if (f_v) {
786 cout << "N[" << i << "]=" << b << endl;
787 }
788 }
790 if (f_v) {
791 cout << "N=" << N << endl;
792 }
793#endif
794
795}
796
798 unipoly& m, discreta_matrix& F, discreta_matrix& N, Vector &v, int verbose_level)
799{
800 int f_v = (verbose_level >= 1);
801 domain d(p);
802 with ww(&d);
803 Vector w;
804 unipoly a;
805 int f, i;
806
807 f = F.s_m();
808 v.first_regular_word(f, p);
809 if (!v.next_regular_word(p))
810 return FALSE;
811
812 if (f_v) {
813 cout << "regular word:" << v << endl;
814 }
815 w.mult(N, v);
816 a.m_l(f);
817 for (i = 0; i < f; i++) {
818 a[i] = w[i];
819 }
820 F.KX_module_minpol(a, m, *this, verbose_level - 1);
821 return TRUE;
822}
823
825 unipoly& m, discreta_matrix& F, discreta_matrix& N, Vector &v, int verbose_level)
826{
827 int f_v = (verbose_level >= 1);
828 domain d(p);
829 with ww(&d);
830 Vector w;
831 unipoly a;
832 int f, i;
833
834 f = F.s_m();
835 if (!v.next_regular_word(p))
836 return FALSE;
837
838 if (f_v) {
839 cout << "regular word:" << v << endl;
840 }
841 w.mult(N, v);
842 a.m_l(f);
843 for (i = 0; i < f; i++) {
844 a[i] = w[i];
845 }
846 F.KX_module_minpol(a, m, *this, verbose_level - 1);
847 return TRUE;
848}
849
851{
852 if (p.s_kind() != UNIPOLY) {
853 cout << "unipoly::normalize() p not an UNIPOLY" << endl;
854 exit(1);
855 }
856 unipoly p1 = p.as_unipoly();
857 unipoly q, r;
858
859 integral_division(p1, q, r, 0);
860 swap(r);
861}
862
863
864void unipoly::Xnm1(int n)
865{
866 m_l_n(n + 1);
867 s_i(n).one();
868 s_i(0).one();
869 s_i(0).negate();
870}
871
872
873static int multiply(Vector & vp, Vector & ve);
874
875void unipoly::Phi(int n, int f_v)
876{
877 Vector vp, ve, vd;
878 int i, j, l, mu, d, nd;
879 unipoly p, q, r;
880
881 if (f_v) {
882 cout << "Phi(" << n << "):" << endl;
883 }
884 factor_integer(n, vp, ve);
885 l = vp.s_l();
886 vd.m_l_n(l);
887 p.m_l(1);
888 q.m_l(1);
889 p.s_i(0).one();
890 q.s_i(0).one();
891
892 while (TRUE) {
893 d = multiply(vp, vd);
894 nd = n / d;
895 mu = Moebius(nd);
896 r.Xnm1(d);
897 if (f_v) {
898 cout << "d=" << d << " mu(d)=" << mu << " r=" << r << endl;
899 cout << "p=" << p << endl;
900 cout << "q=" << q << endl;
901 }
902 if (mu == 1) {
903 p *= r;
904 }
905 else if (mu == -1) {
906 q *= r;
907 }
908
909 for (i = 0; i < l; i++) {
910 j = vd.s_ii(i);
911 if (j < ve.s_ii(i)) {
912 vd.m_ii(i, j + 1);
913 break;
914 }
915 vd.m_ii(i, 0);
916 }
917 if (i == l)
918 break;
919 }
920 p.integral_division_exact(q, *this);
921}
922
923static int multiply(Vector & vp, Vector & ve)
924{
925 int i, l, n, m;
927
928 n = 1;
929 l = vp.s_l();
930 for (i = 0; i < l; i++) {
931 m = NT.i_power_j(vp.s_ii(i), ve.s_ii(i));
932 n *= m;
933 }
934 return n;
935}
936
937
938void unipoly::weight_enumerator_MDS_code(int n, int k, int q, int verbose_level)
939{
940 int f_v = (verbose_level = 1);
941 int f_vv = (verbose_level = 2);
942 int f_vvv = (verbose_level = 3);
943 int j, h, l;
944 discreta_base a, b, c, d, e;
945
946 m_l_n(n + 1);
947 e.m_i_i(-1);
948 s_i(0).m_i_i(1);
949 for (j = n - k + 1; j <= n; j++) {
950 l = k - n + j - 1;
955 if (f_vvv) {
956 cout << "j=" << j << endl;
957 }
958 Binomial(n, j, a);
959 if (f_vvv) {
960 cout << " \\binom{" << n << "}{" << j << "}=a=" << a << endl;
961 }
962 b.m_i_i(0);
963 for (h = 0; h <= l; h++) {
964 if (f_vvv) {
965 cout << " h=" << h;
966 }
967 Binomial(j, h, c);
968 if (f_vvv) {
969 cout << " {j \\choose h} = c=" << c << endl;
970 }
971 d.m_i_i(q);
972 d.power_int(l - h + 1);
973 if (f_vvv) {
974 cout << " q^" << l - h + 1 << "=" << d << endl;
975 }
976 d += e;
977 if (f_vvv) {
978 cout << " minus 1, d=" << d << endl;
979 }
980 c *= d;
981 if (ODD(h)) {
982 c.negate();
983 }
984 if (f_vvv) {
985 cout << " c=" << c << endl;
986 }
987 b += c;
988 if (f_vvv) {
989 cout << " new b=" << b << endl;
990 }
991 }
992 b *= a;
993 if (f_vv) {
994 cout << " coeff=" << b << endl;
995 }
996 s_i(j) = b;
997 }
998 if (f_v) {
999 cout << "unipoly::weight_enumerator_MDS_code "
1000 "n=" << n << " k=" << k << " q=" << q << endl;
1001 cout << *this << endl;
1002 }
1003}
1004
1005void unipoly::charpoly(int q, int size, int *mtx, int verbose_level)
1006{
1007 int f_v = (verbose_level >= 1);
1008 int f_vv = (verbose_level >= 2);
1010 int i, j, k, a, p, h;
1012 //unipoly_domain U;
1013 //unipoly_object char_poly;
1015
1016 if (f_v) {
1017 cout << "unipoly::charpoly" << endl;
1018 }
1019 M.m_mn(size, size);
1020 k = 0;
1021 for (i = 0; i < size; i++) {
1022 for (j = 0; j < size; j++) {
1023 a = mtx[k++];
1024 M.m_iji(i, j, a);
1025 }
1026 }
1027 if (f_vv) {
1028 cout << "M=" << endl;
1029 cout << M << endl;
1030 }
1031
1032 if (!NT.is_prime_power(q, p, h)) {
1033 cout << "q is not prime, we need a prime" << endl;
1034 exit(1);
1035 }
1036 Fq.finite_field_init(q, FALSE /* f_without_tables */, verbose_level - 1);
1037
1038 domain d(q);
1039 with w(&d);
1040
1041#if 0
1042
1043 matrix M2;
1044 M2 = M;
1045 for (i = 0; i < size; i++) {
1046 unipoly mue;
1047 M2.KX_module_order_ideal(i, mue, verbose_level - 1);
1048 cout << "order ideal " << i << ":" << endl;
1049 cout << mue << endl;
1050 }
1051#endif
1052
1053 discreta_matrix M1, P, Pv, Q, Qv, S, T;
1054
1056 M.minus_X_times_id();
1057 M1 = M;
1058 if (f_vv) {
1059 cout << "M - x * Id=\n" << M << endl;
1060 }
1061 M.smith_normal_form(P, Pv, Q, Qv, verbose_level - 2);
1062
1063 if (f_vv) {
1064 cout << "the Smith normal form is:" << endl;
1065 cout << M << endl;
1066 }
1067
1068 S.mult(P, Pv);
1069 if (f_vv) {
1070 cout << "P * Pv=\n" << S << endl;
1071 }
1072
1073 S.mult(Q, Qv);
1074 if (f_vv) {
1075 cout << "Q * Qv=\n" << S << endl;
1076 }
1077
1078 S.mult(P, M1);
1079 if (f_vv) {
1080 cout << "T.mult(S, Q):\n";
1081 }
1082 T.mult(S, Q);
1083 if (f_vv) {
1084 cout << "T=\n" << T << endl;
1085 }
1086
1087
1089 int deg;
1090 int l, lv, b, c;
1091
1092 charpoly = M.s_ij(size - 1, size - 1);
1093
1094 if (f_vv) {
1095 cout << "characteristic polynomial:" << charpoly << endl;
1096 }
1097 deg = charpoly.degree();
1098 if (f_vv) {
1099 cout << "has degree " << deg << endl;
1100 }
1101 l = charpoly.s_ii(deg);
1102 if (f_vv) {
1103 cout << "leading coefficient " << l << endl;
1104 }
1105 lv = Fq.inverse(l);
1106 if (f_vv) {
1107 cout << "leading coefficient inverse " << lv << endl;
1108 }
1109 for (i = 0; i <= deg; i++) {
1110 b = charpoly.s_ii(i);
1111 c = Fq.mult(b, lv);
1112 charpoly.m_ii(i, c);
1113 }
1114 if (f_v) {
1115 cout << "monic characteristic polynomial:" << charpoly << endl;
1116 }
1117 swap(charpoly);
1118}
1119
1120}}
1121
1122
void finite_field_init(int q, int f_without_tables, int verbose_level)
DISCRETA vector class for vectors of DISCRETA objects.
Definition: discreta.h:797
void q_adic(int n, int q)
Definition: vector.cpp:753
void first_regular_word(int n, int q)
Definition: vector.cpp:812
discreta_base & s_i(int i)
Definition: vector.cpp:202
void m_ii(int i, int a)
Definition: discreta.h:824
std::ostream & print(std::ostream &)
Definition: vector.cpp:135
void copyobject_to(discreta_base &x)
Definition: vector.cpp:72
DISCRETA base class. All DISCRETA classes are derived from this class.
Definition: discreta.h:382
void integral_division_exact(discreta_base &x, discreta_base &q)
Definition: base.cpp:907
virtual void negate_to(discreta_base &x)
Definition: base.cpp:711
void mult(discreta_base &x, discreta_base &y)
Definition: base.cpp:367
discreta_base & power_int_mod(int l, discreta_base &p)
Definition: base.cpp:499
void swap(discreta_base &a)
Definition: base.cpp:179
void copyobject(discreta_base &x)
Definition: base.cpp:194
discreta_base & power_int(int l)
Definition: base.cpp:447
void extended_gcd(discreta_base &n, discreta_base &u, discreta_base &v, discreta_base &g, int verbose_level)
Definition: base.cpp:972
discreta_matrix & m_mn(int m, int n)
void KX_module_apply(unipoly &p, Vector &v)
void smith_normal_form(discreta_matrix &P, discreta_matrix &Pv, discreta_matrix &Q, discreta_matrix &Qv, int verbose_level)
void Berlekamp(unipoly &m, int p, int verbose_level)
void m_iji(int i, int j, int a)
Definition: discreta.h:1099
void KX_cyclic_module_generator(Vector &v, unipoly &mue, int verbose_level)
void KX_module_minpol(unipoly &p, unipoly &m, unipoly &mue, int verbose_level)
void Frobenius(unipoly &m, int p, int verbose_level)
DISCRETA class for influencing arithmetic operations.
Definition: discreta.h:1360
DISCRETA integer class.
Definition: discreta.h:667
DISCRETA class for polynomials in one variable.
Definition: discreta.h:1236
int is_squarefree(int verbose_level)
Definition: unipoly.cpp:449
void singer_candidate(int p, int f, int b, int a)
Definition: unipoly.cpp:555
void normal_base(int p, discreta_matrix &F, discreta_matrix &N, int verbose_level)
Definition: unipoly.cpp:718
void mult_to(discreta_base &x, discreta_base &y)
Definition: unipoly.cpp:196
void integral_division(discreta_base &x, discreta_base &q, discreta_base &r, int verbose_level)
Definition: unipoly.cpp:346
void weight_enumerator_MDS_code(int n, int k, int q, int verbose_level)
Definition: unipoly.cpp:938
void largest_divisor_prime_to(unipoly &q, unipoly &r)
Definition: unipoly.cpp:676
int first_irreducible_polynomial(int p, unipoly &m, discreta_matrix &F, discreta_matrix &N, Vector &v, int verbose_level)
Definition: unipoly.cpp:797
void add_to(discreta_base &x, discreta_base &y)
Definition: unipoly.cpp:231
void numeric_polynomial(int n, int q)
Definition: unipoly.cpp:537
void Singer(int p, int f, int verbose_level)
Definition: unipoly.cpp:564
int next_irreducible_polynomial(int p, unipoly &m, discreta_matrix &F, discreta_matrix &N, Vector &v, int verbose_level)
Definition: unipoly.cpp:824
int is_irreducible_GFp(int p, int verbose_level)
Definition: unipoly.cpp:471
unipoly & operator=(const discreta_base &x)
Definition: unipoly.cpp:35
void copyobject_to(discreta_base &x)
Definition: unipoly.cpp:69
int is_irreducible(int q, int verbose_level)
Definition: unipoly.cpp:493
void charpoly(int q, int size, int *mtx, int verbose_level)
Definition: unipoly.cpp:1005
void get_an_irreducible_polynomial(int f, int verbose_level)
Definition: unipoly.cpp:618
std::ostream & print_as_vector(std::ostream &ost)
Definition: unipoly.cpp:171
void Phi(int n, int f_v)
Definition: unipoly.cpp:875
void negate_to(discreta_base &x)
Definition: unipoly.cpp:265
int compare_with_euclidean(discreta_base &a)
Definition: unipoly.cpp:332
std::ostream & print(std::ostream &)
Definition: unipoly.cpp:87
int is_primitive(int m, int p, Vector &vp, int verbose_level)
Definition: unipoly.cpp:513
void evaluate_at(discreta_base &x, discreta_base &y)
Definition: unipoly.cpp:662
void normalize(discreta_base &p)
Definition: unipoly.cpp:850
DISCRETA class related to class domain.
Definition: discreta.h:1413
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define ODD(x)
Definition: foundations.h:222
#define MAXIMUM(x, y)
Definition: foundations.h:217
enum printing_mode_enum current_printing_mode()
Definition: global.cpp:1573
char my_unip_variable_name[128]
Definition: unipoly.cpp:84
void Binomial(int n, int k, discreta_base &n_choose_k)
Definition: global.cpp:1203
int is_finite_field_domain(domain *&d)
Definition: domain.cpp:242
void factor_integer(int n, Vector &primes, Vector &exponents)
Definition: global.cpp:330
int finite_field_domain_order_int(domain *d)
Definition: domain.cpp:251
the orbiter library for the classification of combinatorial objects
DISCRETA internal class.
Definition: discreta.h:353