Orbiter 2022
Combinatorial Objects
discreta_matrix.cpp
Go to the documentation of this file.
1// discreta_matrix.cpp
2//
3// Anton Betten
4// 10.11.1999
5// moved from D2 to ORBI Nov 15, 2007
6//
7// change in smith normal form: 4/21/2010
8// problems with gcd:
9// when the two elements x,y are constants,
10// u should not be 0.
11//
12// renamed from matrix to discreta_matrix to avoid conflicts with ginac
13// Dec 9, 2019
14
16#include "discreta.h"
17
18
19using namespace std;
20
21
22
23namespace orbiter {
24namespace layer2_discreta {
25
26#undef MATRIX_COPY_VERBOSE
27#undef DEBUG_S_IJ
28
29#undef DEBUG_CONTENT
30
31static int gfq_dep(int n, discreta_matrix& A, discreta_matrix& P,
32 Vector& v, int m, permutation& rho, int verbose_level);
33
34
35
36
37
39{
40 k = MATRIX;
41 self.matrix_pointer = NULL;
42}
43
45 // copy constructor: this := x
46{
47 cout << "discreta_matrix::copy constructor for object: "
48 << const_cast<discreta_base &>(x) << "\n";
49 clearself();
50 const_cast<discreta_base &>(x).copyobject_to(*this);
51}
52
54 // copy assignment
55{
56 cout << "discreta_matrix::operator = (copy assignment)" << endl;
57 copyobject(const_cast<discreta_base &>(x));
58 return *this;
59}
60
62{
63 OBJECTSELF s;
64
65 s = self;
66 new(this) discreta_matrix;
67 k = MATRIX;
68 self = s;
69}
70
72{
74}
75
77{
78 if (self.matrix_pointer == NULL)
79 return;
81 self.matrix_pointer = NULL;
82}
83
85{
86 return MATRIX;
87}
88
90{
91 int i, j, m, n;
92
93#ifdef MATRIX_COPY_VERBOSE
94 cout << "in discreta_matrix::copyobject_to()\n";
95#endif
96 x.freeself();
97 if (x.s_kind() != MATRIX) {
98#ifdef MATRIX_CHANGE_KIND_VERBOSE
99 cout << "waring: discreta_matrix::copyobject_to x not a vector\n";
100#endif
101 x.c_kind(MATRIX);
102 x.clearself();
103 // x.printobjectkindln();
104 }
105 m = s_m();
106 n = s_n();
107 discreta_matrix & xx = x.as_matrix();
108 xx.m_mn(m, n);
109 for (i = 0; i < m; i++) {
110 for (j = 0; j < n; j++) {
111 xx.s_ij(i, j) = s_ij(i, j);
112 }
113 }
114}
115
116
117ostream& discreta_matrix::print(ostream& ost)
118{
119 int i, j, k, m, n, l1, l2, l3;
120 Vector col_width;
121
122 m = s_m();
123 n = s_n();
124#ifdef PRint_WITH_TYPE
125 ost << "(MATRIX of size " << m << " x " << n << ", \n";
126#endif
127 col_width.m_l_n(n);
128 for (i = 0; i < m; i++) {
129 for (j = 0; j < n; j++) {
130 ostringstream s;
131
132 s << s_ij(i, j) << ends;
133 l1 = s.str().length();
134 l2 = col_width.s_ii(j);
135 l3 = MAXIMUM(l1, l2);
136 col_width.m_ii(j, l3);
137 }
138 }
140 for (i = 0; i < m; i++) {
141 for (j = 0; j < n; j++) {
142 int l;
143 ostringstream s;
144
145 s << s_ij(i, j);
146 l = s.str().length();
147 for (k = l; k < col_width.s_ii(j); k++)
148 ost << ' ';
149 ost << s.str();
150 if (j < n - 1)
151 ost << " ";
152 }
153 ost << endl;
154 }
155 }
157 ost << "\\begin{array}{*{" << n << "}{c}}\n";
158 for (i = 0; i < m; i++) {
159 for (j = 0; j < n; j++) {
160 int l;
161 ostringstream s;
162
163 s << s_ij(i, j);
164 l = s.str().length();
165 for (k = l; k < col_width.s_ii(j); k++)
166 ost << ' ';
167 ost << s.str();
168 if (j < n - 1)
169 ost << " & ";
170 }
171 ost << " \\\\" << endl;
172 }
173 ost << "\\end{array}\n";
174 }
175 else {
176 ost << "current_printing_mode() = "
177 << current_printing_mode() << " not yet implemented" << endl;
178 }
179#ifdef PRint_WITH_TYPE
180 ost << ")";
181#endif
182 //ost << "\n";
183 return ost;
184}
185
187{
188 int i, j, m1, n1, m2, n2, r;
189
190 if (a.s_kind() != MATRIX) {
191 cout << "discreta_matrix::compare_with() a is not a matrix object" << endl;
192 exit(1);
193 }
194 discreta_matrix &b = a.as_matrix();
195 m1 = s_m();
196 n1 = s_n();
197 m2 = b.s_m();
198 n2 = b.s_n();
199 if (m1 < m2)
200 return -1;
201 if (m1 > m2)
202 return 1;
203 if (n1 < n2)
204 return -1;
205 if (n1 > n2)
206 return 1;
207 for (i = 0; i < m1; i++) {
208 for (j = 0; j < n1; j++) {
209 r = s_ij(i, j).compare_with(b.s_ij(i, j));
210 if (r != 0)
211 return r;
212 }
213 }
214 return 0;
215}
216
218{
219 freeself();
221 return *this;
222}
223
225{
226 int i, j;
227
228 m_mn(m, n);
229 for (i = 0; i < m; i++) {
230 for (j = 0; j < n; j++) {
231 s_ij(i, j).m_i_i(0);
232 }
233 }
234 return *this;
235}
236
238{
240 int i, j, m1, n1;
241
242 m1 = s_m();
243 n1 = s_n();
244 M.m_mn(m, n);
245 for (i = 0; i < MINIMUM(m, m1); i++) {
246 for (j = 0; j < MINIMUM(n, n1); j++) {
247 M.s_ij(i, j).swap(s_ij(i, j));
248 }
249 }
250 swap(M);
251 return *this;
252}
253
255{
256 if (self.matrix_pointer == NULL)
257 return 0;
258 return self.matrix_pointer[-2].s_i_i();
259}
260
262{
263 if (self.matrix_pointer == NULL)
264 return 0;
265 return self.matrix_pointer[-1].s_i_i();
266}
267
269{
270 int m, n;
271
272#ifdef DEBUG_S_IJ
273 cout << "discreta_matrix::s_ij(" << i << ", " << j << ")" << endl;
274#endif
275 if (self.matrix_pointer == NULL) {
276 cout << "discreta_matrix::s_ij() matrix_pointer == NULL\n";
277 exit(1);
278 }
279 m = self.matrix_pointer[-2].s_i_i();
280 n = self.matrix_pointer[-1].s_i_i();
281 if ( i < 0 || i >= m ) {
282 cout << "discreta_matrix::s_ij() addressing error, i = " << i << ", m = " << m << endl;
283 exit(1);
284 }
285 if ( j < 0 || j >= n ) {
286 cout << "discreta_matrix::s_ij() addressing error, j = " << j << ", n = " << n << endl;
287 exit(1);
288 }
289 return self.matrix_pointer[i * n + j];
290}
291
293{
294 return p->s_ij(i, j);
295}
296
297
298
300{
301 if (x.s_kind() == MATRIX) {
302 discreta_matrix& px = x.as_matrix();
303 matrix_mult_to(px, y);
304 }
305 else if (x.s_kind() == VECTOR) {
306 Vector& px = x.as_vector();
307 vector_mult_to(px, y);
308 }
309 else {
310 cout << "discreta_matrix::mult_to() object x is of bad type" << endl;
311 exit(1);
312 }
313}
314
316{
318 int i, j, k, m, n, l;
319
320 if (s_kind() != MATRIX) {
321 cout << "discreta_matrix::matrix_mult_to() this is not a matrix" << endl;
322 exit(1);
323 }
324 if (x.s_kind() != MATRIX) {
325 cout << "discreta_matrix::matrix_mult_to() x is not a matrix" << endl;
326 exit(1);
327 }
328 m = s_m();
329 l = s_n();
330 if (l != x.s_m()) {
331 cout << "discreta_matrix::matrix_mult_to() l != x.s_m(), cannot multiply" << endl;
332 exit(1);
333 }
334 n = x.s_n();
335
336 py.m_mn(m, n);
337 for (i = 0; i < m; i++) {
338 for (j = 0; j < n; j++) {
339 discreta_base a, b;
340 for (k = 0; k < l; k++) {
341 if (k == 0) {
342 a.mult(s_ij(i, k), x[k][j]);
343 }
344 else {
345 b.mult(s_ij(i, k), x[k][j]);
346 a += b;
347 }
348 }
349 py[i][j].swap(a);
350 }
351 }
352 y.swap(py);
353}
354
356{
357 Vector py;
358 int i, j, m, l;
359
360 if (s_kind() != MATRIX) {
361 cout << "discreta_matrix::vector_mult_to() this is not a matrix\n";
362 exit(1);
363 }
364 if (x.s_kind() != VECTOR) {
365 cout << "discreta_matrix::vector_mult_to() x is not a vector\n";
366 exit(1);
367 }
368 m = s_m();
369 l = s_n();
370 if (l != x.s_l()) {
371 cout << "discreta_matrix::vector_mult_to() l != x.s_l(), cannot multiply\n";
372 exit(1);
373 }
374
375 py.m_l(m);
376 for (i = 0; i < m; i++) {
377 discreta_base a, b;
378 for (j = 0; j < l; j++) {
379 if (j == 0) {
380 a.mult(s_ij(i, j), x[j]);
381 }
382 else {
383 b.mult(s_ij(i, j), x[j]);
384 a += b;
385 }
386 }
387 py[i].swap(a);
388 }
389 y.swap(py);
390}
391
393{
394 int l, i, j, m, n;
395
396 l = x.s_l();
397 m = s_m();
398 n = s_n();
399 if (l != m) {
400 cout << "discreta_matrix::multiply_vector_from_left() l != m, cannot multiply\n";
401 exit(1);
402 }
403 if (y.s_l() != n)
404 y.m_l(n);
405 for (j = 0; j < n; j++) {
406 discreta_base a, b;
407 for (i = 0; i < m; i++) {
408 if (i == 0) {
409 a.mult(x[i], s_ij(i, j));
410 }
411 else {
412 b.mult(x[i], s_ij(i, j));
413 a += b;
414 }
415 }
416 y[j].swap(a);
417 }
418}
419
421{
422 int m, n, rank;
424 Vector base_cols;
425
426 if (s_kind() != MATRIX) {
427 cout << "discreta_matrix::invert_to() this not a matrix\n";
428 exit(1);
429 }
430 m = s_m();
431 n = s_n();
432 if (m != n) {
433 cout << "discreta_matrix::invert_to() m != n\n";
434 exit(1);
435 }
436 P = *this;
437 P.one();
438
439 rank = Gauss(FALSE /* f_special */, TRUE /* f_complete */, base_cols,
440 TRUE /* f_P */, P, FALSE /* f_v */);
441 P.swap(x);
442 if (rank < m) {
443 cout << "warning: matrix is not invertible\n";
444 return FALSE;
445 }
446 return TRUE;
447}
448
450{
451 int i, j, m, n;
452
453 y.freeself();
454 if (s_kind() != MATRIX) {
455 cout << "discreta_matrix::add_to() this is not a matrix\n";
456 exit(1);
457 }
458 if (x.s_kind() != MATRIX) {
459 cout << "discreta_matrix::add_to() x is not a matrix\n";
460 exit(1);
461 }
462 discreta_matrix& px = x.as_matrix();
464
465 m = s_m();
466 n = s_n();
467 if (m != px.s_m()) {
468 cout << "discreta_matrix::add_to() m != px.s_m()\n";
469 exit(1);
470 }
471 if (n != px.s_n()) {
472 cout << "discreta_matrix::add_to() n != px.s_n()\n";
473 exit(1);
474 }
475 py.m_mn(m, n);
476 for (i = 0; i < m; i++) {
477 for (j = 0; j < n; j++) {
478 py[i][j].add(s_ij(i, j), px[i][j]);
479 }
480 }
481 py.swap(y);
482}
483
485{
486 int i, j, m, n;
487
488 if (s_kind() != MATRIX) {
489 cout << "discreta_matrix::negate_to() this not a matrix\n";
490 exit(1);
491 }
493
494 m = s_m();
495 n = s_n();
496 py.m_mn(m, n);
497 for (i = 0; i < m; i++) {
498 for (j = 0; j < n; j++) {
499 py[i][j] = s_ij(i, j);
500 py[i][j].negate();
501 }
502 }
503 py.swap(x);
504}
505
506
508{
509 int i, j, m, n;
510
511 m = s_m();
512 n = s_n();
513 if (m != n) {
514 cout << "discreta_matrix::one() m != n\n";
515 exit(1);
516 }
517 for (i = 0; i < m; i++) {
518 for (j = 0; j < n; j++) {
519 if (i == j)
520 s_ij(i, j).one();
521 else
522 s_ij(i, j).zero();
523 }
524 }
525}
526
528{
529 int i, j, m, n;
530
531 m = s_m();
532 n = s_n();
533 for (i = 0; i < m; i++) {
534 for (j = 0; j < n; j++) {
535 s_ij(i, j).zero();
536 }
537 }
538}
539
541{
543 int m, n;
544
545 m = s_m();
546 n = s_n();
547 B.m_mn_n(m, n);
548 if (compare_with(B) == 0)
549 return TRUE;
550 else
551 return FALSE;
552
553}
554
556{
558 int m, n, i, j;
559
560 m = s_m();
561 n = s_n();
562 B.m_mn_n(m, n);
563 for (i = 0; i < m; i++)
564 {
565 for (j = 0; j < n; j++)
566 {
567 if (i == j)
568 ((integer)B.s_ij(i, j)).m_i(1);
569 }
570 }
571 if (compare_with(B) == 0)
572 return TRUE;
573 else
574 return FALSE;
575
576}
577
578
579int discreta_matrix::Gauss(int f_special, int f_complete, Vector& base_cols,
580 int f_P, discreta_matrix& P, int verbose_level)
581// returns the rank
582{
583 int f_v = (verbose_level >= 1);
584 int rank, i, j, k, jj, m, n, Pn = 0;
585 discreta_base pivot, pivot_inv, a, b, c, z, f;
586
587 base_cols.m_l(0);
588 m = s_m();
589 n = s_n();
590 if (f_P) {
591 if (m != P.s_m()) {
592 cout << "discreta_matrix::Gauss m != P.s_m()" << endl;
593 exit(1);
594 }
595 Pn = P.s_n();
596 }
597
598 i = 0;
599 for (j = 0; j < n; j++) {
600
601 /* search for pivot element: */
602 for (k = i; k < m; k++) {
603 if (!s_ij(k, j).is_zero()) {
604 // pivot element found:
605 if (k != i) {
606 for (jj = j; jj < n; jj++) {
607 s_ij(i, jj).swap(s_ij(k, jj));
608 }
609 if (f_P) {
610 for (jj = 0; jj < Pn; jj++) {
611 P.s_ij(i, jj).swap(P.s_ij(k, jj));
612 }
613 }
614 }
615 break;
616 } // if != 0
617 } // next k
618
619 if (k == m) // no pivot found
620 continue; // increase j, leave i constant
621
622 if (f_v) {
623 cout << "row " << i << " pivot in row " << k << " colum " << j << endl;
624 }
625
626 base_cols.append_integer(j);
627
628 pivot = s_ij(i, j);
629 pivot.invert_to(pivot_inv);
630 if (!f_special) {
631 // make pivot to 1:
632 for (jj = j; jj < n; jj++) {
633 s_ij(i, jj) *= pivot_inv;
634 }
635 if (f_P) {
636 for (jj = 0; jj < Pn; jj++) {
637 P.s_ij(i, jj) *= pivot_inv;
638 }
639 }
640 if (f_v) {
641 cout << "pivot=" << pivot << " pivot_inv=" << pivot_inv
642 << " made to one: " << s_ij(i, j) << endl;
643 }
644 }
645
646 /* do the gaussian elimination: */
647 for (k = i + 1; k < m; k++) {
648 z = s_ij(k, j);
649 if (z.is_zero())
650 continue;
651 if (f_special) {
652 f.mult(z, pivot_inv);
653 }
654 else {
655 f = z;
656 }
657 f.negate();
658 s_ij(k, j).zero();
659 if (f_v) {
660 cout << "eliminating row " << k << endl;
661 }
662 for (jj = j + 1; jj < n; jj++) {
663 a = s_ij(i, jj);
664 b = s_ij(k, jj);
665 // c := b + f * a
666 // = b - z * a if !f_special
667 // b - z * pivot_inv * a if f_special
668 c.mult(f, a);
669 c += b;
670 s_ij(k, jj) = c;
671 if (f_v) {
672 cout << s_ij(k, jj) << " ";
673 }
674 }
675 if (f_P) {
676 for (jj = 0; jj < Pn; jj++) {
677 a = P.s_ij(i, jj);
678 b = P.s_ij(k, jj);
679 // c := b - z * a
680 c.mult(f, a);
681 c += b;
682 P.s_ij(k, jj) = c;
683 }
684 }
685 if (f_v) {
686 cout << endl;
687 }
688 }
689 i++;
690 } // next j
691 rank = i;
692 if (f_complete) {
693 for (i = rank - 1; i >= 0; i--) {
694 j = base_cols.s_ii(i);
695 if (!f_special) {
696 a = s_ij(i, j);
697 }
698 else {
699 pivot = s_ij(i, j);
700 pivot.invert_to(pivot_inv);
701 }
702 // do the gaussian elimination in the upper part:
703 for (k = i - 1; k >= 0; k--) {
704 z = s_ij(k, j);
705 if (z.is_zero())
706 continue;
707 s_ij(k, j).zero();
708 for (jj = j + 1; jj < n; jj++) {
709 a = s_ij(i, jj);
710 b = s_ij(k, jj);
711 if (f_special) {
712 a *= pivot_inv;
713 }
714 c.mult(z, a);
715 c.negate();
716 c += b;
717 s_ij(k, jj) = c;
718 }
719 if (f_P) {
720 for (jj = 0; jj < Pn; jj++) {
721 a = P.s_ij(i, jj);
722 b = P.s_ij(k, jj);
723 if (f_special) {
724 a *= pivot_inv;
725 }
726 c.mult(z, a);
727 c.negate();
728 c += b;
729 P.s_ij(k, jj) = c;
730 }
731 }
732 } // next k
733 } // next i
734 }
735 return rank;
736}
737
739{
740 Vector base_cols;
742
743 return Gauss(FALSE, FALSE, base_cols, FALSE, P, FALSE);
744}
745
747{
748 int r, n, k, i, j, ii, iii, a, b;
749 Vector kcol;
750
751 //m = s_m();
752 n = s_n();
753 r = base_cols.s_l();
754 k = n - r;
755 kernel.m_mn_n(n, k);
756 kcol.m_l(k);
757 ii = 0;
758 j = 0;
759 if (j < r)
760 b = base_cols.s_ii(j);
761 else
762 b = -1;
763 for (i = 0; i < n; i++) {
764 if (i == b) {
765 j++;
766 if (j < r)
767 b = base_cols.s_ii(j);
768 else
769 b = -1;
770 }
771 else {
772 kcol.m_ii(ii, i);
773 ii++;
774 }
775 }
776 if (ii != k) {
777 cout << "discreta_matrix::get_kernel() ii != k" << endl;
778 exit(1);
779 }
780 //cout << "kcol = " << kcol << endl;
781 ii = 0;
782 j = 0;
783 if (j < r)
784 b = base_cols.s_ii(j);
785 else
786 b = -1;
787 for (i = 0; i < n; i++) {
788 if (i == b) {
789 for (iii = 0; iii < k; iii++) {
790 a = kcol.s_ii(iii);
791 kernel[i][iii] = s_ij(j, a);
792 }
793 j++;
794 if (j < r)
795 b = base_cols.s_ii(j);
796 else
797 b = -1;
798 }
799 else {
800 for (iii = 0; iii < k; iii++) {
801 if (iii == ii) {
802 kernel.s_ij(i, iii).m_one();
803 }
804 else {
805 kernel.s_ij(i, iii).zero();
806 }
807 }
808 ii++;
809 }
810 }
811 return TRUE;
812}
813
815{
817 int i, j, m, n;
818
819 m = s_m();
820 n = s_n();
821 A.m_mn(n, m);
822 for (i = 0; i < m; i++) {
823 for (j = 0; j < n; j++) {
824 s_ij(i, j).swap(A.s_ij(j, i));
825 }
826 }
827 swap(A);
828 return *this;
829}
830
832//Computes the Plesken matrix $A^\wedge$ (Ainf) from $A^\vee$ (Asup).
833//Compare Plesken~\cite{Plesken82}.
834{
835 Vector orbit_size;
836 int m, n, i, j;
837
838 m = s_m();
839 n = s_n();
840 if (m != n) {
841 cout << "discreta_matrix::Asup2Ainf() not rectangular\n";
842 exit(1);
843 }
844 orbit_size.m_l(m);
845 for (i = 0; i < m; i++) {
846 orbit_size[i] = s_ij(i, m - 1);
847 if (orbit_size[i].is_zero()) {
848 cout << "discreta_matrix::Asup2Ainf() orbit_size[i].is_zero()\n";
849 exit(1);
850 }
851 }
852 for (j = 0; j < m; j++) {
853 for (i = 0; i < m; i++) {
854 s_ij(i, j) *= orbit_size[j];
855 }
856 }
857 for (i = 0; i < m; i++) {
858 for (j = 0; j < m; j++) {
859 s_ij(i, j).divide_by_exact(orbit_size[i]);
860 }
861 }
862 return TRUE;
863}
864
865
867{
868 transpose();
869 Asup2Ainf();
870 transpose();
871 return TRUE;
872}
873
875//Computes the cover relations of the poset defined by this (=Asup).
876//Assumes that Asup is upper triangular.
877{
878 int m, n, i, j, k;
879
880 m = s_m();
881 n = s_n();
882 /* replace the numbers by a 0/1 flag */
883 for (i = 0; i < m; i++) {
884 for (j = 0; j < n; j++) {
885 if (s_iji(i, j))
886 m_iji(i, j, 1);
887 }
888 }
889 for (i = m - 1; i >= 0; i--) {
890 for (j = i + 1; j < n; j++) {
891 if (s_iji(i, j)) {
892 /* B_i < B_j in the orbit -
893 * poset of the lattice */
894 for (k = 0; k < i; k++) {
895 if (s_iji(k, i)) {
896 /* B_k < B_i < B_j
897 * therefore the entry
898 * B_k < B_j can be deleted. */
899 m_iji(k, j, 0);
900 }
901 }
902 }
903 }
904 }
905 return TRUE;
906}
907
909//Computes the \lq neighbour-list\rq of the poset whose cover relations are given
910//in this (=Acover). This list nl is used as input for the lattice-placement
911//program \lq vbp \rq.
912{
913 int m, n, i, j, k, len, cur;
914
915 m = s_m();
916 n = s_n();
917 /* count the non diagonal entries: */
918 k = 0;
919 for (i = 0; i < m; i++) {
920 for (j = i + 1; j < n; j++) {
921 if (s_iji(i, j))
922 k++;
923 }
924 }
925 len = m + 1 + k; // length of nl vector
926 nl.m_l(len);
927 nl.m_ii(m, len);
928 cur = m + 1;
929 for (i = 0; i < m; i++) {
930 nl.m_ii(i, cur);
931 /* start of neighbour list of i in nl */
932 for (j = i + 1; j < n; j++) {
933 if (s_iji(i, j)) {
934 nl.m_ii(cur, j);
935 /* found a neighbour of i */
936 cur++;
937 }
938 }
939 }
940 return TRUE;
941}
942
943void discreta_matrix::Frobenius(unipoly& m, int p, int verbose_level)
944//computes a $d \times d$ matrix whose j-th column
945//contains the coefficients of $x^{p^j} \mod m$.
946//Here, $d = \deg m.$
947{
948 int f_v = (verbose_level >= 1);
949 unipoly a, b, c;
950 int i, j, d, d1;
951
952 d = m.degree();
953 if (f_v) {
954 cout << "discreta_matrix::Frobenius() d=" << d << " p=" << p << endl;
955 }
956 m_mn_n(d, d);
957 s_ij(0, 0).one();
958 a.x();
959 if (f_v) {
960 cout << "discreta_matrix::Frobenius() x=" << a << endl;
961 }
962 a.power_int_mod(p, m); // a := x^p mod m
963 if (f_v) {
964 cout << "discreta_matrix::Frobenius() a = x^p=" << a << endl;
965 }
966 b.one();
967 for (j = 1; j < d; j++) {
968 c.mult_mod(b, a, m);
969 b = c;
970 // now b = x^{p^j}
971 if (f_v) {
972 cout << "discreta_matrix::Frobenius() x^{p^" << j << "}=" << b << endl;
973 }
974 d1 = b.degree();
975 for (i = 0; i <= d1; i++) {
976 s_ij(i, j) = b[i];
977 }
978 }
979}
980
981void discreta_matrix::Berlekamp(unipoly& m, int p, int verbose_level)
982{
983 int f_v = (verbose_level >= 1);
984 int i, l;
985 integer m1;
986
987 Frobenius(m, p, FALSE);
988 if (f_v) {
989 cout << "discreta_matrix matrix=\n" << *this;
990 }
991 l = s_m();
992 m1.m_one();
993 for (i = 0; i < l; i++) {
994 s_ij(i, i) += m1;
995 }
996 if (f_v) {
997 cout << "discreta_matrix Berlekamp matrix=\n" << *this;
998 }
999}
1000
1002{
1003 int f_v = (verbose_level >= 1);
1004 int i, d;
1005
1006 if (f_v) {
1007 cout << "discreta_matrix::companion_matrix() of the polynomial " << m << endl;
1008 }
1009 d = m.degree();
1010 m_mn_n(d, d);
1011 zero();
1012 for (i = 0; i < d - 1; i++) {
1013 s_ij(i + 1, i).one();
1014 }
1015 for (i = 0; i < d; i++) {
1016 s_ij(i, d - 1) = m.s_i(i);
1017 s_ij(i, d - 1).negate();
1018 }
1019 if (f_v) {
1020 cout << "discreta_matrix::companion_matrix=\n" << *this;
1021 }
1022}
1023
1025{
1026 int i, j, m, n;
1027
1028 // cout << "discreta_matrix::elements_to_unipoly()" << endl;
1029 m = s_m();
1030 n = s_n();
1031 for (i = 0; i < m; i++) {
1032 for (j = 0; j < n; j++) {
1033 // cout << "i=" << i << " j=" << j << endl;
1034 unipoly a;
1035 a.m_l(1);
1036 a[0] = s_ij(i, j);
1037 // cout << "a=" << a << endl;
1038 s_ij(i, j) = a;
1039 // cout << "s_ij=" << s_ij(i,j) << endl;
1040 }
1041 }
1042}
1043
1045{
1046 unipoly a;
1047 int i, m, n, l;
1048
1049 a.x();
1050 a.negate();
1051 // cout << a << endl;
1052 m = s_m();
1053 n = s_n();
1054 l = MINIMUM(m, n);
1055 for (i = 0; i < l; i++) {
1056 s_ij(i, i) += a;
1057 }
1058}
1059
1061{
1062 unipoly a;
1063 int i, j, m, n, l;
1064
1065 a.x();
1066 //a.negate();
1067 // cout << a << endl;
1068 m = s_m();
1069 n = s_n();
1070 l = MINIMUM(m, n);
1071 for (i = 0; i < m; i++) {
1072 for (j = 0; j < n; j++) {
1073 s_ij(i, j).negate();
1074 }
1075 }
1076 for (i = 0; i < l; i++) {
1077 s_ij(i, i) += a;
1078 }
1079}
1080
1082 discreta_matrix& Q, discreta_matrix& Qv, int verbose_level)
1083{
1084 int f_v = (verbose_level >= 1);
1085 int m, n, i, j, l, ii, jj, stable;
1086 discreta_base a0, a1, am1;
1087
1088 if (f_v) {
1089 cout << "discreta_matrix::smith_normal_form" << endl;
1090 cout << *this;
1091 }
1092 m = s_m();
1093 n = s_n();
1094 a0 = s_ij(0, 0);
1095 a1 = s_ij(0, 0);
1096 a0.zero();
1097 a1.one();
1098 P.m_mn(m, m);
1099 Q.m_mn(n, n);
1100 for (i = 0; i < m; i++) {
1101 for (j = 0; j < m; j++) {
1102 if (i == j) {
1103 P[i][j] = a1;
1104 }
1105 else {
1106 P[i][j] = a0;
1107 }
1108 }
1109 }
1110 Pv = P;
1111 for (i = 0; i < n; i++) {
1112 for (j = 0; j < n; j++) {
1113 if (i == j) {
1114 Q[i][j] = a1;
1115 }
1116 else {
1117 Q[i][j] = a0;
1118 }
1119 }
1120 }
1121 Qv = Q;
1122 if (f_v) {
1123 cout << "this=" << endl << *this << endl;
1124 cout << "P=" << endl << P << endl;
1125 cout << "Q=" << endl << Q << endl;
1126 }
1127 l = MINIMUM(m, n);
1128 for (i = 0; i < l; i++) {
1129 if (f_v) {
1130 cout << "discreta_matrix::smith_normal_form "
1131 "pivot column is " << i << " / " << l << endl;
1132 }
1133 stable = FALSE;
1134 while (!stable) {
1135 stable = TRUE;
1136 if (f_v) {
1137 cout << "before smith_eliminate_column " << i << endl;
1138 cout << "this=" << endl << *this << endl;
1139 cout << "P=" << endl << P << endl;
1140 cout << "Q=" << endl << Q << endl;
1141 }
1142 if (smith_eliminate_column(P, Pv, i, verbose_level - 2)) {
1143 stable = FALSE;
1144 }
1145 if (f_v) {
1146 cout << "after smith_eliminate_column " << i << endl;
1147 cout << "this=" << endl << *this << endl;
1148 cout << "P=" << endl << P << endl;
1149 cout << "Q=" << endl << Q << endl;
1150 }
1151
1152 if (f_v) {
1153 cout << "before smith_eliminate_row " << i << endl;
1154 cout << "this=" << endl << *this << endl;
1155 cout << "P=" << endl << P << endl;
1156 cout << "Q=" << endl << Q << endl;
1157 }
1158 if (smith_eliminate_row(Q, Qv, i, verbose_level - 2)) {
1159 stable = FALSE;
1160 }
1161 if (f_v) {
1162 cout << "after smith_eliminate_row " << i << endl;
1163 cout << "this=" << endl << *this << endl;
1164 cout << "P=" << endl << P << endl;
1165 cout << "Q=" << endl << Q << endl;
1166 }
1167
1168 for (jj = i + 1; jj < n; jj++) {
1169 if (f_v) {
1170 cout << "jj=" << jj << endl;
1171 }
1172 for (ii = i + 1; ii < m; ii++) {
1173 if (f_v) {
1174 cout << "ii=" << ii << endl;
1175 }
1176 if (!s_ij(i, i).is_divisor(s_ij(ii, jj))) {
1177 break;
1178 }
1179 }
1180 if (ii < m) {
1181 if (f_v) {
1182 cout << "adding column " << jj
1183 << " to column " << i << endl;
1184 }
1185 multiply_2by2_from_right(i, jj, a1, a0, a1, a1, verbose_level - 2);
1186 Q.multiply_2by2_from_right(i, jj, a1, a0, a1, a1, 0);
1187 am1 = a1;
1188 am1.negate();
1189 Qv.multiply_2by2_from_left(i, jj, a1, a0, am1, a1, 0);
1190 if (f_v) {
1191 cout << *this;
1192 }
1193 stable = FALSE;
1194 break;
1195 }
1196 }
1197 }
1198 }
1199 if (f_v) {
1200 cout << "smith normal form reached" << endl;
1201 cout << "this=" << endl << *this << endl;
1202 cout << "P=" << endl << P << endl;
1203 cout << "Pv=" << endl << Pv << endl;
1204 cout << "Q=" << endl << Q << endl;
1205 cout << "Qv=" << endl << Qv << endl;
1206 }
1207}
1208
1210 discreta_matrix& Pv, int i, int verbose_level)
1211{
1212 int f_v = (verbose_level >= 1);
1213 //int f_vv = (verbose_level >= 2);
1214 int m, j, action = FALSE;
1215 discreta_base x, y, u, v, g, x1, y1;
1216
1217 if (f_v) {
1218 cout << "discreta_matrix::smith_eliminate_column column " << i << endl;
1219 cout << "this=" << endl << *this << endl;
1220 }
1221 m = s_m();
1222 for (j = i + 1; j < m; j++) {
1223 x = s_ij(i, i);
1224 y = s_ij(j, i);
1225 if (f_v) {
1226 cout << "smith_eliminate_column() j=" << j
1227 << " x=" << x << " y=" << y << endl;
1228 cout << "this=" << endl << *this << endl;
1229 }
1230 if (y.is_zero()) {
1231 continue;
1232 }
1233 if (f_v) {
1234 cout << "before extended_gcd" << endl;
1235 cout << "x=" << x << endl;
1236 cout << "y=" << y << endl;
1237 }
1238 x.extended_gcd(y, u, v, g, verbose_level);
1239 if (f_v) {
1240 cout << *this;
1241 cout << "i=" << i << " j=" << j << ": ";
1242 cout << g << " = (" << u << ") * (" << x << ") + "
1243 "(" << v << ") * (" << y << ")" << endl;
1244 }
1245 if (u.is_zero() && x.compare_with_euclidean(y) == 0) {
1246 u.swap(v);
1247 g = x;
1248 if (f_v) {
1249 cout << "after switch:" << endl;
1250 cout << "this=" << endl << *this << endl;
1251 cout << "i=" << i << " j=" << j << ": ";
1252 cout << g << " = (" << u << ") * (" << x << ") + "
1253 "(" << v << ") * (" << y << ")" << endl;
1254 }
1255 }
1256 x.integral_division_exact(g, x1);
1257 y.integral_division_exact(g, y1);
1258 y1.negate();
1259 multiply_2by2_from_left(i, j, u, v, y1, x1, verbose_level - 2);
1260 if (f_v) {
1261 cout << "After multiply_2by2_from_left, "
1262 "this=" << endl << *this << endl;
1263 }
1264 P.multiply_2by2_from_left(i, j, u, v, y1, x1, 0);
1265 if (f_v) {
1266 cout << "After P.multiply_2by2_from_left, "
1267 "P=" << endl << P << endl;
1268 }
1269 v.negate();
1270 y1.negate();
1271 Pv.multiply_2by2_from_right(i, j, x1, v, y1, u, 0);
1272 if (f_v) {
1273 cout << "After Pv.multiply_2by2_from_right, "
1274 "Pv=" << endl << Pv << endl;
1275 }
1276 action = TRUE;
1277 }
1278 return action;
1279}
1280
1282 discreta_matrix& Qv, int i, int verbose_level)
1283{
1284 int f_v = (verbose_level >= 1);
1285 int f_vv = (verbose_level >= 2);
1286 int n, j, action = FALSE;
1287 discreta_base x, y, u, v, g, x1, y1;
1288
1289 if (f_v) {
1290 cout << "discreta_matrix::smith_eliminate_row row " << i << endl;
1291 }
1292 n = s_n();
1293 for (j = i + 1; j < n; j++) {
1294 x = s_ij(i, i);
1295 y = s_ij(i, j);
1296 if (f_v) {
1297 cout << "smith_eliminate_row() "
1298 "j=" << j << " x=" << x << " y=" << y << endl;
1299 }
1300 if (y.is_zero())
1301 continue;
1302 x.extended_gcd(y, u, v, g, verbose_level - 2);
1303 if (f_vv) {
1304 cout << *this;
1305 cout << "i=" << i << " j=" << j << ": ";
1306 cout << g << " = (" << u << ") * (" << x << ") + "
1307 "(" << v << ") * (" << y << ")" << endl;
1308 }
1309 if (u.is_zero() && x.compare_with_euclidean(y) == 0) {
1310 u.swap(v);
1311 g = x;
1312 if (f_vv) {
1313 cout << "after switch:" << endl;
1314 cout << *this;
1315 cout << "i=" << i << " j=" << j << ": ";
1316 cout << g << " = (" << u << ") * (" << x << ") + "
1317 "(" << v << ") * (" << y << ")" << endl;
1318 }
1319 }
1320 x.integral_division_exact(g, x1);
1321 y.integral_division_exact(g, y1);
1322 y1.negate();
1323 multiply_2by2_from_right(i, j, u, y1, v, x1, verbose_level - 2);
1324 if (f_vv) {
1325 cout << *this;
1326 }
1327 Q.multiply_2by2_from_right(i, j, u, y1, v, x1, 0);
1328 v.negate();
1329 y1.negate();
1330 Qv.multiply_2by2_from_left(i, j, x1, y1, v, u, 0);
1331 action = TRUE;
1332 }
1333 return action;
1334}
1335
1337 discreta_base& aii, discreta_base& aij,
1338 discreta_base& aji, discreta_base& ajj, int verbose_level)
1339{
1340 int f_v = (verbose_level >= 1);
1341 int k, n;
1342 discreta_base x, y, xx, yy;
1343
1344 if (f_v) {
1345 cout << "from left: i=" << i << " j=" << j << endl;
1346 cout << "(" << aii << ", " << aij << ")" << endl;
1347 cout << "(" << aji << ", " << ajj << ")" << endl;
1348 }
1349 n = s_n();
1350 for (k = 0; k < n; k++) {
1351 // cout << "k=" << k << endl;
1352 x.mult(aii, s_ij(i, k));
1353 y.mult(aij, s_ij(j, k));
1354 x += y;
1355 xx.mult(aji, s_ij(i, k));
1356 yy.mult(ajj, s_ij(j, k));
1357 yy += xx;
1358 x.swap(s_ij(i, k));
1359 yy.swap(s_ij(j, k));
1360 }
1361}
1362
1364 discreta_base& aii, discreta_base& aij,
1365 discreta_base& aji, discreta_base& ajj, int verbose_level)
1366{
1367 int f_v = (verbose_level >= 1);
1368 int k, m;
1369 discreta_base x, y, xx, yy;
1370
1371 if (f_v) {
1372 cout << "from right: i=" << i << " j=" << j << endl;
1373 cout << "(" << aii << ", " << aij << ")" << endl;
1374 cout << "(" << aji << ", " << ajj << ")" << endl;
1375 }
1376 m = s_m();
1377 for (k = 0; k < m; k++) {
1378 // cout << "k=" << k << endl;
1379 x.mult(aii, s_ij(k, i));
1380 y.mult(aji, s_ij(k, j));
1381 x += y;
1382 xx.mult(aij, s_ij(k, i));
1383 yy.mult(ajj, s_ij(k, j));
1384 yy += xx;
1385 x.swap(s_ij(k, i));
1386 yy.swap(s_ij(k, j));
1387 }
1388}
1389
1391{
1392 Vector vv;
1393 int i, j, m, n;
1394
1395 m = s_m();
1396 n = s_n();
1397 v.m_l(m);
1398 for (i = 0; i < m; i++) {
1399 vv.m_l(n);
1400 for (j = 0; j < n; j++) {
1401 vv[j] = s_ij(i, j);
1402 }
1403 v[i] = vv;
1404 }
1405}
1406
1408{
1409 int i, j, m, n;
1410
1411 m = v.s_l();
1412 if (m <= 0) {
1413 cout << "discreta_matrix::from_vector_of_rows() m <= 0\n";
1414 exit(1);
1415 }
1416 n = v[0].as_vector().s_l();
1417
1418 m_mn(m, n);
1419 for (i = 0; i < m; i++) {
1420 Vector &vv = v.s_i(i).as_vector();
1421 for (j = 0; j < n; j++) {
1422 s_ij(i, j) = vv[j];
1423 }
1424 }
1425}
1426
1428{
1429 Vector vv;
1430 int i, j, m, n;
1431
1432 m = s_m();
1433 n = s_n();
1434 v.m_l(n);
1435 for (j = 0; j < n; j++) {
1436 vv.m_l(m);
1437 for (i = 0; i < m; i++) {
1438 vv[i] = s_ij(i, j);
1439 }
1440 v[j] = vv;
1441 }
1442}
1443
1445{
1446 int i, j, m, n;
1447
1448 n = v.s_l();
1449 if (n <= 0) {
1450 cout << "discreta_matrix::from_vector_of_columns n <= 0" << endl;
1451 exit(1);
1452 }
1453 m = v[0].as_vector().s_l();
1454
1455 m_mn(m, n);
1456 for (j = 0; j < n; j++) {
1457 Vector &vv = v.s_i(j).as_vector();
1458 for (i = 0; i < m; i++) {
1459 s_ij(i, j) = vv[i];
1460 }
1461 }
1462}
1463
1465{
1466 int i, j, m, n;
1467 discreta_base y;
1468
1469 m = s_m();
1470 n = s_n();
1471 for (i = 0; i < m; i++) {
1472 for (j = 0; j < n; j++) {
1473 s_ij(i, j).as_unipoly().evaluate_at(x, y);
1474 s_ij(i, j) = y;
1475 }
1476 }
1477}
1478
1479
1480static int gfq_dep(int n, discreta_matrix& A,
1481 discreta_matrix& P, Vector& v, int m, permutation& rho,
1482 int verbose_level)
1483{
1484 int f_v = (verbose_level >= 1);
1485 int f_vv = (verbose_level >= 2);
1486 int i, j, k, f_null, pp;
1487 discreta_base a0, a1, c;
1488
1489 if (f_v) {
1490 cout << "gfq_dep" << endl;
1491 }
1492 a0 = v[0];
1493 a1 = v[0];
1494 a0.zero();
1495 a1.one();
1496
1497 for (j = 0; j < n; j++)
1498 A[m][j] = v[rho[j]];
1499
1500 for (k = 0; k < m; k++) {
1501 if (f_vv) {
1502 cout << "k=" << k << endl;
1503 }
1504 c = A[k][k];
1505 c.invert();
1506 c *= A[m][k];
1507 c.negate();
1508 A.multiply_2by2_from_left(k, m, a1, a0, c, a1, FALSE);
1509 P.multiply_2by2_from_left(k, m, a1, a0, c, a1, FALSE);
1510 if (f_vv) {
1511 cout << "A=\n" << A << endl;
1512 cout << "P=\n" << P << endl;
1513 }
1514 } // next k
1515
1516 f_null = (m == n);
1517 if (!f_null) {
1518 // search for a non-zero entry in row m starting in column m.
1519 // exchange that column with column m, and change the column
1520 // permutation rho.
1521 j = m;
1522 while (A[m][j].is_zero() && j < n - 1)
1523 j++;
1524 f_null = (A[m][j].is_zero());
1525 if (!f_null && j > m) {
1526 for (i = 0; i <= m; i++) {
1527 A[i][m].swap(A[i][j]);
1528 }
1529 pp = rho[m];
1530 rho[m] = rho[j];
1531 rho[j] = pp;
1532 }
1533 }
1534 return f_null;
1535}
1536
1537void discreta_matrix::KX_module_order_ideal(int i, unipoly& mue, int verbose_level)
1538// Lueneburg~\cite{Lueneburg87a} p. 105
1539// determines the order ideal of $e_i$, the $i$-th unit vector,
1540// in the module over the polynomial ring $K[X]$ ($K$ a field),
1541// which is given by substituting the matrix $F$ into the polynomial.
1542// the matrix $F$ (in this) has dimensions $n \times n$
1543{
1544 int f_v = (verbose_level >= 1);
1545 int f_vv = (verbose_level >= 2);
1546 discreta_matrix A, P;
1547 Vector v, v1;
1548 int n, m, f_null, j;
1549 permutation rho;
1550 discreta_base c;
1551
1552 n = s_m();
1553 A.m_mn_n(n + 1, n);
1554 P.m_mn_n(n + 1, n + 1);
1555 P.one();
1556 v.m_l_n(n);
1557 rho.m_l(n);
1558 rho.one();
1559 v[i].m_i_i(1);
1560
1561 m = 0;
1562 if (f_v) {
1563 cout << "discreta_matrix::KX_module_order_ideal() m=" << m << endl;
1564 cout << "v=\n" << v << endl;
1565 }
1566 f_null = gfq_dep(n, A, P, v, m, rho, verbose_level - 2);
1567 if (f_vv) {
1568 cout << "A=\n" << A << endl;
1569 }
1570 while (!f_null) {
1571
1572 v1.mult(*this, v);
1573 v = v1;
1574 m++;
1575 if (f_vv) {
1576 cout << "discreta_matrix::KX_module_order_ideal m=" << m << endl;
1577 cout << "v=\n" << v << endl;
1578 }
1579 f_null = gfq_dep(n, A, P, v, m, rho, verbose_level - 2);
1580 if (f_vv) {
1581 cout << "A=\n" << A << endl;
1582 }
1583 if (m == n && !f_null) {
1584 cout << "gfq_order_ideal m == n && !f_null" << endl;
1585 exit(1);
1586 }
1587 }
1588
1589 mue.m_l(m + 1);
1590 mue.s_i(m).one();
1591 for (j = m - 1; j >= 0; j--) {
1592 mue[j] = P[m][j];
1593 }
1594
1595 if (f_v) {
1596 cout << "discreta_matrix::KX_module_order_ideal "
1597 "order ideal of e_" << i << ": " << mue << endl;
1598#if 0
1599 v.m_l_n(n);
1600 v[i].one();
1601 KX_module_apply(mue, v);
1602 cout << "mue(v)=" << v << endl;
1603#endif
1604 }
1605}
1606
1608{
1609 int i, d;
1610 Vector w, ww, vv;
1611
1612 d = p.degree();
1613 w = v;
1614 w.mult_scalar(p[d]);
1615 for (i = d - 1; i >= 0; i--) {
1616 // cout << "i=" << i << " ; w=" << w << endl;
1617 ww.mult(*this, w);
1618 // cout << "i=" << i << " ; F * w=" << ww << endl;
1619 vv = v;
1620 vv.mult_scalar(p[i]);
1621 ww += vv;
1622 w.swap(ww);
1623 }
1624 v.swap(w);
1625}
1626
1628 Vector& v2, unipoly& mue2, Vector& v3, unipoly& mue3,
1629 int verbose_level)
1630// compare Lueneburg~\cite{Lueneburg87a} p. 106.
1631{
1632 int f_v = (verbose_level >= 1);
1633 unipoly u, v, g, gg, r, rr, rrr, r4, m1, m2;
1634 Vector vv1, vv2;
1635 int dg, dm2;
1636
1637 if (f_v) {
1638 cout << "discreta_matrix::KX_module_join()" << endl;
1639 cout << "v1=" << v1 << " mue1=" << mue1 << endl;
1640 cout << "v2=" << v2 << " mue2=" << mue2 << endl;
1641 }
1642 dm2 = mue2.degree();
1643 mue1.extended_gcd(mue2, u, v, g, verbose_level - 2);
1644 if (f_v) {
1645 cout << "g=" << g << endl;
1646 }
1647 dg = g.degree();
1648 if (dg < dm2) {
1649 vv1 = v1;
1650 mue2.integral_division_exact(g, m2);
1651 mue1.largest_divisor_prime_to(m2, r);
1652 mue1.integral_division_exact(r, m1);
1653 KX_module_apply(m1, vv1);
1654 // now: order(vv1) = (r)
1655 if (f_v) {
1656 cout << "vv1=" << vv1 << " r=" << r << endl;
1657 }
1658
1659 vv2 = v2;
1660 mue1.integral_division_exact(g, m1);
1661 mue2.largest_divisor_prime_to(m1, rr);
1662 r.extended_gcd(rr, u, v, gg, verbose_level - 2);
1663 rr.integral_division_exact(gg, rrr);
1664 // now (gcd(r, rrr) = 1 and r*rrr = lcm(mue1,mue2)
1665 if (f_v) {
1666 cout << "r=" << r << endl;
1667 cout << "rrr=" << rrr << endl;
1668 r.extended_gcd(rrr, u, v, gg, verbose_level - 2);
1669 cout << "gcd(r,rrr)=" << gg << " (should be 1)" << endl;
1670 r4.mult(r, rrr);
1671 cout << "r*rrr=" << r4 << " (should be = lcd(mue1, mue2))" << endl;
1672 }
1673
1674
1675 mue2.integral_division_exact(rrr, m2);
1676 KX_module_apply(m2, vv2);
1677 // now: order(vv2) = (rrr) and gcd(r, rrr) = 1.
1678 if (f_v) {
1679 cout << "vv2=" << vv2 << " rrr=" << rrr << endl;
1680 }
1681
1682 v3.add(vv1, vv2);
1683 mue3.mult(r, rrr);
1684 if (f_v) {
1685 cout << "discreta_matrix::KX_module_join()" << endl;
1686 cout << "v3=" << v3 << endl;
1687 cout << "mue3=" << mue3 << endl;
1688 vv1 = v3;
1689 KX_module_apply(mue3, vv1);
1690 cout << "mue3(v3)=" << vv1 << " (should be zero)" << endl;
1691 }
1692 }
1693 else {
1694 v3 = v1;
1695 mue3 = mue1;
1696 }
1697}
1698
1700 unipoly& mue, int verbose_level)
1701{
1702 int f_v = (verbose_level > 1);
1703 int f_vv = (verbose_level > 2);
1704 int i, f;
1705 Vector v1, v2, v3;
1706 unipoly mue1, mue2, mue3;
1707
1708 if (f_v) {
1709 cout << "discreta_matrix::KX_cyclic_module_generator" << endl;
1710 }
1711 f = s_m();
1712 v1.m_l_n(f);
1713 v1[0].one();
1714 KX_module_order_ideal(0, mue1, verbose_level - 1);
1715 for (i = 1; i < f; i++) {
1716 if (mue1.degree() == f)
1717 break;
1718 v2.m_l_n(f);
1719 v2[i].one();
1720 KX_module_order_ideal(i, mue2, verbose_level - 1);
1721 KX_module_join(v1, mue1, v2, mue2, v3, mue3, f_vv);
1722 v1 = v3;
1723 mue1 = mue3;
1724 }
1725 if (mue1.degree() < f) {
1726 cout << "discreta_matrix::KX_cyclic_module_generator error: "
1727 "mue1.degree < f" << endl;
1728 exit(1);
1729 }
1730 v1.swap(v);
1731 mue1.swap(mue);
1732}
1733
1735 unipoly& m, unipoly& mue, int verbose_level)
1736{
1737 int f_v = (verbose_level >= 1);
1738 int f_vv = (verbose_level >= 2);
1739 unipoly x, x0, x1, q, y;
1740 Vector V, v, v0;
1741 discreta_base c;
1742 int i, j, d, f, l;
1743
1744 if (f_v) {
1745 cout << "discreta_matrix::KX_module_minpol" << endl;
1746 }
1747 f = s_m();
1748 d = p.degree();
1749 if (d >= f) {
1750 cout << "KX_module_minpol() d >= f\n";
1751 exit(1);
1752 }
1753 x.x();
1754 x0.x();
1755 x0[0].zero();
1756 x0[1].zero();
1757 x1.x();
1758 x1[0].one();
1759 x1[1].zero();
1760 V.m_l(1);
1761 v.m_l_n(f);
1762 for (i = 0; i <= d; i++) {
1763 v[i] = p[i];
1764 }
1765 V[0] = p;
1766 v0 = v;
1767 l = 1;
1768 if (f_vv) {
1769 cout << "p^{sigma^" << l - 1 << "}=" << p << " = " << v << endl;
1770 }
1771 while (TRUE) {
1772 KX_module_apply(x, v);
1773 if (v.compare_with(v0) == 0) {
1774 break;
1775 }
1776 q.m_l(f);
1777 for (i = 0; i < f; i++) {
1778 q[i] = v[i];
1779 }
1780 V.inc();
1781 V[l] = q;
1782 if (f_vv) {
1783 cout << "p^{sigma^" << l << "}=" << q << " = " << v << endl;
1784 }
1785 if (l >= f) {
1786 cout << "KX_module_minpol() l >= f\n";
1787 }
1788 l++;
1789 }
1790 if (f_vv) {
1791 cout << "the degree is " << l << endl;
1792 }
1793 for (i = 0; i < l; i++) {
1794 V[i].negate();
1795 }
1796 y.m_l(l + 1);
1797
1798 // the polynomial (X - p) = (X - p^{sigma^0}),
1799 // but shifted into the top position:
1800 y[l] = x1;
1801 y[l - 1] = V[0];
1802 for (i = l - 2; i >= 0; i--) {
1803 y[i] = x0;
1804 }
1805 for (i = 1; i < l; i++) {
1806 // multiply with (X - p^{sigma^i}):
1807 for (j = i; j >= 0; j--) {
1808 c.mult_mod(y[l - j], V[i], m);
1809 y[l - j - 1] += c;
1810 }
1811 }
1812 if (f_vv) {
1813 cout << "y (coefficients must lie in the ground field):" << endl;
1814 for (i = 0; i <= l; i++) {
1815 cout << y[i] << " * X^" << i << endl;
1816 }
1817 }
1818 mue.m_l(l + 1);
1819 for (i = 0; i <= l; i++) {
1820 mue[i] = y[i].as_unipoly()[0];
1821 }
1822 if (f_v) {
1823 cout << "minpol=" << mue << endl;
1824 }
1825}
1826
1827void discreta_matrix::binomial(int n_min, int n_max,
1828 int k_min, int k_max)
1829{
1830 int i, j, m, n;
1831
1832 m = n_max + 1 - n_min;
1833 n = k_max + 1 - k_min;
1834 m_mn(m, n);
1835 for (i = 0; i < m; i++) {
1836 for (j = 0; j < n; j++) {
1837 orbiter::layer2_discreta::Binomial(n_min + i, k_min + j, s_ij(i, j));
1838 }
1839 }
1840}
1841
1842void discreta_matrix::stirling_second(int n_min, int n_max,
1843 int k_min, int k_max, int f_ordered)
1844{
1845 int i, j, m, n;
1846 int f_v = FALSE;
1847
1848 m = n_max + 1 - n_min;
1849 n = k_max + 1 - k_min;
1850 m_mn(m, n);
1851 for (i = 0; i < m; i++) {
1852 for (j = 0; j < n; j++) {
1854 k_min + j, f_ordered, s_ij(i, j), f_v);
1855 }
1856 }
1857}
1858
1859void discreta_matrix::stirling_first(int n_min, int n_max,
1860 int k_min, int k_max, int f_signless)
1861{
1862 int i, j, m, n;
1863 int f_v = FALSE;
1864
1865 m = n_max + 1 - n_min;
1866 n = k_max + 1 - k_min;
1867 m_mn(m, n);
1868 for (i = 0; i < m; i++) {
1869 for (j = 0; j < n; j++) {
1870 orbiter::layer2_discreta::stirling_first(n_min + i, k_min + j,
1871 f_signless, s_ij(i, j), f_v);
1872 }
1873 }
1874}
1875
1876void discreta_matrix::binomial(int n_min, int n_max,
1877 int k_min, int k_max, int f_inverse)
1878{
1879 int i, j, m, n;
1880
1881 m = n_max + 1 - n_min;
1882 n = k_max + 1 - k_min;
1883 m_mn(m, n);
1884 for (i = 0; i < m; i++) {
1885 for (j = 0; j < n; j++) {
1886 orbiter::layer2_discreta::Binomial(n_min + i, k_min + j, s_ij(i, j));
1887 if (f_inverse && ODD(n_min + i + k_min + j))
1888 s_ij(i, j).negate();
1889 }
1890 }
1891}
1892
1894// homogeneous integer matrix predicate
1895{
1896 int i, j, m, n;
1897
1898 m = s_m();
1899 n = s_n();
1900 for (i = 0; i < m; i++)
1901 for (j = 0; j < n; j++)
1902 if (s_ij(i, j).s_kind() != INTEGER)
1903 return FALSE;
1904 return TRUE;
1905}
1906
1908// homogeneous integer matrix predicate,
1909// test for 1 char numbers;
1910// only to apply if hip TRUE.
1911{
1912 int i, j, m, n, k;
1913
1914 m = s_m();
1915 n = s_n();
1916 for (i = 0; i < m; i++) {
1917 for (j = 0; j < n; j++) {
1918 if (s_ij(i, j).s_kind() != INTEGER) {
1919 cout << "discreta_matrix::hip1(): not INTEGER\n";
1920 exit(1);
1921 }
1922 k = s_iji(i, j);
1923 if (!ONE_char_int(k))
1924 return FALSE;
1925 }
1926 }
1927 return TRUE;
1928}
1929
1930void discreta_matrix::write_mem(memory & M, int debug_depth)
1931{
1932 int i, j, m, n, k;
1933 char f_hip = 0, f_hip1 = 0;
1934
1935 m = s_m();
1936 n = s_n();
1937 M.write_int(n); // !!! first n then m
1938 M.write_int(m);
1939 f_hip = (char) hip();
1940 if (f_hip)
1941 f_hip1 = (char) hip1();
1942 if (debug_depth > 0) {
1943 cout << "writing " << m << " x " << n << " ";
1944 if (f_hip) {
1945 if (f_hip1)
1946 cout << "hip1 ";
1947 else
1948 cout << "hip ";
1949 }
1950 cout << "matrix\n";
1951 }
1952 M.write_char(f_hip);
1953 if (f_hip) {
1954 M.write_char(f_hip1);
1955 if (f_hip1) {
1956 for (i = 0; i < m; i++) {
1957 for (j = 0; j < n; j++) {
1958 k = s_iji(i, j);
1959 M.write_char((char) k);
1960 }
1961 }
1962 }
1963 else {
1964 for (i = 0; i < m; i++) {
1965 for (j = 0; j < n; j++) {
1966 M.write_int(s_iji(i, j));
1967 }
1968 }
1969 }
1970 }
1971 else {
1972 for (i = 0; i < m; i++) {
1973 for (j = 0; j < n; j++) {
1974 s_ij(i, j).write_memory(M, debug_depth - 1);
1975 }
1976 }
1977 }
1978}
1979
1980void discreta_matrix::read_mem(memory & M, int debug_depth)
1981{
1982 int i, j, m, n, k;
1983 char c, f_hip = 0, f_hip1 = 0;
1984
1985 M.read_int(&n);
1986 M.read_int(&m);
1987 m_mn(m, n);
1988 M.read_char(&f_hip);
1989 if (f_hip) {
1990 M.read_char(&f_hip1);
1991 }
1992 if (debug_depth > 0) {
1993 cout << "reading " << m << " x " << n << " ";
1994 if (f_hip) {
1995 if (f_hip1)
1996 cout << "hip1 ";
1997 else
1998 cout << "hip ";
1999 }
2000 cout << "matrix\n";
2001 }
2002 if (f_hip) {
2003 if (f_hip1) {
2004 for (i = 0; i < m; i++) {
2005 for (j = 0; j < n; j++) {
2006 M.read_char(&c);
2007 k = (int) c;
2008 m_iji(i, j, k);
2009 }
2010 }
2011 }
2012 else {
2013 for (i = 0; i < m; i++) {
2014 for (j = 0; j < n; j++) {
2015 M.read_int(&k);
2016 m_iji(i, j, k);
2017 }
2018 }
2019 }
2020 }
2021 else {
2022 for (i = 0; i < m; i++) {
2023 for (j = 0; j < n; j++) {
2024 if (debug_depth > 0) {
2025 cout << "(" << i << "," << j << ") ";
2026 if ((j % 20) == 0)
2027 cout << endl;
2028 }
2029 s_ij(i, j).read_memory(M, debug_depth - 1);
2030 }
2031 }
2032 }
2033}
2034
2036{
2037 int size = 0;
2038 int i, j, m, n;
2039 char f_hip, f_hip1;
2040
2041 m = s_m();
2042 n = s_n();
2043 size += 8; /* n, m */
2044 f_hip = (char) hip();
2045 size += 1; /* f_hip */
2046 if (f_hip) {
2047 f_hip1 = (char) hip1();
2048 size += 1; /* f_hip1 */
2049 if (f_hip1)
2050 size += 1 * m * n;
2051 else
2052 size += 4 * m * n;
2053 }
2054 else {
2055 for (i = 0; i < m; i++) {
2056 for (j = 0; j < n; j++) {
2057 size += s_ij(i, j).calc_size_on_file();
2058 }
2059 }
2060 }
2061 return size;
2062}
2063
2064void discreta_matrix::calc_theX(int & nb_X, int *&theX)
2065{
2066 int m, n, i, j;
2067
2068 m = s_m();
2069 n = s_n();
2070
2071 nb_X = 0;
2072 for (i = 0; i < m; i++) {
2073 for (j = 0; j < n; j++) {
2074 if (s_iji(i, j))
2075 nb_X++;
2076 }
2077 }
2078 theX = (int *) new int[nb_X];
2079
2080 nb_X = 0;
2081 for (i = 0; i < m; i++) {
2082 for (j = 0; j < n; j++) {
2083 if (s_iji(i, j)) {
2084 theX[nb_X++] = i * n + j;
2085 }
2086 }
2087 }
2088}
2089
2090void discreta_matrix::apply_perms(int f_row_perm, permutation &row_perm,
2091 int f_col_perm, permutation &col_perm)
2092{
2094 int m, n, i, ii, j, jj;
2095 permutation rowperm, colperm;
2096
2097 m = s_m();
2098 n = s_n();
2099 M.m_mn(m, n);
2100 if (f_row_perm)
2101 rowperm = row_perm;
2102 else {
2103 rowperm.m_l(m);
2104 rowperm.one();
2105 }
2106 if (f_col_perm)
2107 colperm = col_perm;
2108 else {
2109 colperm.m_l(n);
2110 colperm.one();
2111 }
2112 for (i = 0; i < m; i++) {
2113 ii = rowperm[i];
2114 for (j = 0; j < n; j++) {
2115 jj = colperm[j];
2116 s_ij(i, j).swap(M.s_ij(ii, jj));
2117 }
2118 }
2119 swap(M);
2120}
2121
2123{
2125 int m, n, i, ii, j, jj;
2126
2127 m = s_m();
2128 n = s_n();
2129 M.m_mn(m, n);
2130 for (i = 0; i < m; i++) {
2131 ii = p[n + i] - n;
2132 for (j = 0; j < n; j++) {
2133 jj = p[j];
2134 s_ij(i, j).swap(M.s_ij(ii, jj));
2135 }
2136 }
2137 swap(M);
2138}
2139
2141{
2143 int m, n, i, ii, j, jj;
2144
2145 m = s_m();
2146 n = s_n();
2147 M.m_mn(m, n);
2148 for (i = 0; i < m; i++) {
2149 ii = p[i];
2150 for (j = 0; j < n; j++) {
2151 jj = p[m + j] - m;
2152 s_ij(i, j).swap(M.s_ij(ii, jj));
2153 }
2154 }
2155 swap(M);
2156}
2157
2159 Vector & decomp, permutation & p)
2160{
2162 int n;
2163 Vector row_decomp, col_decomp;
2164 int i, l1, l, ll;
2165
2166 //m = s_m();
2167 n = s_n();
2168 M = *this;
2169 M.apply_col_row_perm(p);
2170 ll = decomp.s_l();
2171 l1 = 0;
2172 col_decomp.m_l(0);
2173 for (i = 0; i < ll; i++) {
2174 l = decomp.s_ii(i);
2175 l1 += l;
2176 col_decomp.append_integer(l);
2177 if (l1 == n) {
2178 break;
2179 }
2180 }
2181 row_decomp.m_l(0);
2182 for (i++; i < ll; i++) {
2183 l = decomp.s_ii(i);
2184 l1 += l;
2185 row_decomp.append_integer(l);
2186 }
2187 M.incma_print_ascii(ost, f_tex, TRUE, row_decomp, TRUE, col_decomp);
2188}
2189
2190void discreta_matrix::print_decomposed(ostream &ost, Vector &row_decomp, Vector &col_decomp)
2191{
2193 int m, n, M, N, i, j, i0, j0, v, h;
2194 Vector hbar, vbar;
2195
2196 m = s_m();
2197 n = s_n();
2198 M = 2 * m + 1;
2199 N = 2 * n + 1;
2200 T.m_mn(M, N);
2201 for (i = 0; i < M; i++) {
2202 for (j = 0; j < N; j++) {
2203 T.s_ij(i, j).change_to_hollerith();
2204 T.s_ij(i, j).as_hollerith().init("");
2205 }
2206 }
2207 hbar.m_l_n(M);
2208 vbar.m_l_n(N);
2209 i0 = 0;
2210 hbar.m_ii(2 * i0, TRUE);
2211 for (i = 0; i < row_decomp.s_l(); i++) {
2212 i0 += row_decomp.s_ii(i);
2213 hbar.m_ii(2 * i0, TRUE);
2214 }
2215 j0 = 0;
2216 vbar.m_ii(2 * j0, TRUE);
2217 for (j = 0; j < col_decomp.s_l(); j++) {
2218 j0 += col_decomp.s_ii(j);
2219 vbar.m_ii(2 * j0, TRUE);
2220 }
2221 // cout << "hbar=" << hbar << endl;
2222 // cout << "vbar=" << vbar << endl;
2223
2224 for (i = 0; i <= 2 * m; i += 2) {
2225 for (j = 0; j <= 2 * n; j += 2) {
2226 h = hbar.s_ii(i);
2227 v = vbar.s_ii(j);
2228 if (v && h) {
2229 T.s_ij(i, j).as_hollerith().init("+");
2230 }
2231#if 0
2232 else if (v && !h) {
2233 T.s_ij(i, j).as_hollerith().init("|");
2234 }
2235 else if (!v && h) {
2236 T.s_ij(i, j).as_hollerith().init("-");
2237 }
2238#endif
2239 }
2240 }
2241 for (i = 0; i <= 2 * m; i += 2) {
2242 if (!hbar.s_ii(i))
2243 continue;
2244 for (j = 0; j < n; j++) {
2245 T.s_ij(i, 2 * j + 1).as_hollerith().init("-");
2246 }
2247 }
2248 for (j = 0; j <= 2 * n; j += 2) {
2249 if (!vbar.s_ii(j))
2250 continue;
2251 for (i = 0; i < m; i++) {
2252 T.s_ij(2 * i + 1, j).as_hollerith().init("|");
2253 }
2254 }
2255 for (i = 0; i < m; i++) {
2256 for (j = 0; j < n; j++) {
2257 T.s_ij(2 * i + 1, 2 * j + 1) = s_ij(i, j);
2258 }
2259 }
2260 ost << T;
2261}
2262
2263void discreta_matrix::incma_print_ascii(ostream &ost, int f_tex,
2264 int f_row_decomp, Vector &row_decomp,
2265 int f_col_decomp, Vector &col_decomp)
2266{
2268 int m, n, M, N, i, j, i0, j0, v, h;
2269 Vector hbar, vbar;
2270 Vector S;
2271 Vector rd, cd;
2272
2273 m = s_m();
2274 n = s_n();
2275 M = 2 * m + 1;
2276 N = 2 * n + 1;
2277 T.m_mn(M, N);
2278 for (i = 0; i < M; i++) {
2279 for (j = 0; j < N; j++) {
2280 T.s_ij(i, j).change_to_hollerith();
2281 T.s_ij(i, j).as_hollerith().init("");
2282 }
2283 }
2284 if (f_row_decomp)
2285 rd = row_decomp;
2286 else {
2287 rd.m_l(1);
2288 rd.m_ii(0, m);
2289 }
2290 if (f_col_decomp)
2291 cd = col_decomp;
2292 else {
2293 cd.m_l(1);
2294 cd.m_ii(0, n);
2295 }
2296 hbar.m_l_n(M);
2297 vbar.m_l_n(N);
2298 i0 = 0;
2299 hbar.m_ii(2 * i0, TRUE);
2300 for (i = 0; i < rd.s_l(); i++) {
2301 i0 += rd.s_ii(i);
2302 hbar.m_ii(2 * i0, TRUE);
2303 }
2304 j0 = 0;
2305 vbar.m_ii(2 * j0, TRUE);
2306 for (j = 0; j < cd.s_l(); j++) {
2307 j0 += cd.s_ii(j);
2308 vbar.m_ii(2 * j0, TRUE);
2309 }
2310 // cout << "hbar=" << hbar << endl;
2311 // cout << "vbar=" << vbar << endl;
2312
2313 for (i = 0; i <= 2 * m; i += 2) {
2314 for (j = 0; j <= 2 * n; j += 2) {
2315 h = hbar.s_ii(i);
2316 v = vbar.s_ii(j);
2317 if (v && h) {
2318 T.s_ij(i, j).as_hollerith().init("+");
2319 }
2320#if 0
2321 else if (v && !h) {
2322 T.s_ij(i, j).as_hollerith().init("|");
2323 }
2324 else if (!v && h) {
2325 T.s_ij(i, j).as_hollerith().init("-");
2326 }
2327#endif
2328 }
2329 }
2330 for (i = 0; i <= 2 * m; i += 2) {
2331 if (!hbar.s_ii(i))
2332 continue;
2333 for (j = 0; j < n; j++) {
2334 T.s_ij(i, 2 * j + 1).as_hollerith().init("-");
2335 }
2336 }
2337 for (j = 0; j <= 2 * n; j += 2) {
2338 if (!vbar.s_ii(j))
2339 continue;
2340 for (i = 0; i < m; i++) {
2341 T.s_ij(2 * i + 1, j).as_hollerith().init("|");
2342 }
2343 }
2344 for (i = 0; i < m; i++) {
2345 for (j = 0; j < n; j++) {
2346 if (s_iji(i, j)) {
2347 T.s_ij(2 * i + 1, 2 * j + 1).as_hollerith().init("X");
2348 }
2349 else {
2350 T.s_ij(2 * i + 1, 2 * j + 1).as_hollerith().init(".");
2351 }
2352 }
2353 }
2354 S.m_l(M);
2355 for (i = 0; i < M; i++) {
2356 S.s_i(i).change_to_hollerith();
2357 S.s_i(i).as_hollerith().init("");
2358 }
2359 for (i = 0; i < M; i++) {
2360 for (j = 0; j < N; j++) {
2361 S.s_i(i).as_hollerith().append(T.s_ij(i, j).as_hollerith().s());
2362 }
2363 }
2364 for (i = 0; i < M; i++) {
2365 if (ODD(i) || hbar.s_ii(i)) {
2366 ost << S.s_i(i).as_hollerith();
2367 if (f_tex) {
2368 ost << "\\\\[-12pt]";
2369 }
2370 ost << endl;
2371 }
2372 }
2373}
2374
2376 int f_row_decomp, Vector &row_decomp,
2377 int f_col_decomp, Vector &col_decomp,
2378 int f_labelling_points, Vector &point_labels,
2379 int f_labelling_blocks, Vector &block_labels)
2380{
2382 40 /* width */,
2383 10 /* width_10 */,
2384 FALSE /* f_outline_thin */,
2385 "0.065mm" /* unit_length */,
2386 "0.5mm" /* thick_lines */ ,
2387 "0.15mm" /* thin_lines */ ,
2388 "0.25mm" /* geo_line_width */ ,
2389 f_row_decomp, row_decomp,
2390 f_col_decomp, col_decomp,
2391 f_labelling_points, point_labels,
2392 f_labelling_blocks, block_labels);
2393}
2394
2396 int width, int width_10,
2397 int f_outline_thin, const char *unit_length,
2398 const char *thick_lines, const char *thin_lines, const char *geo_line_width,
2399 int f_row_decomp, Vector &row_decomp,
2400 int f_col_decomp, Vector &col_decomp,
2401 int f_labelling_points, Vector &point_labels,
2402 int f_labelling_blocks, Vector &block_labels)
2403/* width for one box in 0.1mm
2404 * width_10 is 1 10th of width
2405 * example: width = 40, width_10 = 4 */
2406{
2407 int v, b;
2408 int w, h, w1, h1;
2409 int i, j, k, a;
2410 int x0, y0, x1, y1;
2411 int X0, Y0, X1, Y1;
2412 int width_8, width_5;
2413 const char *tdo_line_width = thick_lines /* "0.7mm" */;
2414 const char *line_width = thin_lines /* "0.15mm" */;
2415 /* char *geo_line_width = "0.25mm"; */
2416 Vector rd, cd;
2417
2418 v = s_m();
2419 b = s_n();
2420 if (f_row_decomp)
2421 rd = row_decomp;
2422 else {
2423 rd.m_l(1);
2424 rd.m_ii(0, v);
2425 }
2426 if (f_col_decomp)
2427 cd = col_decomp;
2428 else {
2429 cd.m_l(1);
2430 cd.m_ii(0, b);
2431 }
2432
2433 width_8 = width - 2 * width_10;
2434 width_5 = width >> 1;
2435 f << "\\unitlength" << unit_length << endl;
2436 w = b * width;
2437 h = v * width;
2438 w1 = w;
2439 h1 = h;
2440 if (f_labelling_points)
2441 w1 += 2 * width;
2442 if (f_labelling_blocks)
2443 h1 += 2 * width;
2444 f << "\\begin{picture}(" << w1 << "," << h1 << ")\n";
2445
2446 /* the grid: */
2447 f << "\\linethickness{" << tdo_line_width << "}\n";
2448 k = 0;
2449 for (i = -1; i < cd.s_l(); i++) {
2450 if (i >= 0) {
2451 a = cd.s_ii(i);
2452 k += a;
2453 }
2454 if (f_outline_thin) {
2455 if (i == -1 || i == cd.s_l() - 1)
2456 continue;
2457 }
2458 f << "\\put(" << k * width << ",0){\\line(0,1){" << h << "}}\n";
2459 }
2460 if (k != b) {
2461 cout << "incma_print_latex2(): k != b\n";
2462 exit(1);
2463 }
2464 k = 0;
2465 for (i = -1; i < rd.s_l(); i++) {
2466 if (i >= 0) {
2467 a = rd.s_ii(i);
2468 k += a;
2469 }
2470 if (f_outline_thin) {
2471 if (i == -1 || i == rd.s_l() - 1)
2472 continue;
2473 }
2474 f << "\\put(0," << h - k * width << "){\\line(1,0){" << w << "}}\n";
2475 }
2476 if (k != v) {
2477 cout << "incma_print_latex2(): k != v\n";
2478 exit(1);
2479 }
2480 if (f_labelling_points) {
2481 for (i = 0; i < v; i++) {
2482 f << "\\put(0," << h - i * width - width_5
2483 << "){\\makebox(0,0)[r]{"
2484 << point_labels.s_i(i) << "$\\,$}}\n";
2485 }
2486 }
2487 if (f_labelling_blocks) {
2488 for (i = 0; i < b; i++) {
2489 f << "\\put(" << i * width + width_5 << ","
2490 << h + width_5 << "){\\makebox(0,0)[b]{"
2491 << block_labels.s_i(i) << "}}\n";
2492 }
2493 }
2494
2495 f << "\\linethickness{" << line_width << "}\n";
2496 f << "\\multiput(0,0)(" << width << ",0){" << b + 1
2497 << "}{\\line(0,1){" << h << "}}\n";
2498 f << "\\multiput(0,0)(0," << width << "){" << v + 1 << "}{\\line(1,0){"
2499 << w << "}}\n";
2500
2501 /* the geometry: */
2502 f << "\\linethickness{" << geo_line_width << "}\n";
2503 for (i = 0; i < v; i++) {
2504 y0 = h - i * width;
2505 y1 = h - (i + 1) * width;
2506 Y0 = y0 - width_10;
2507 Y1 = y1 + width_10;
2508 for (j = 0; j < b; j++) {
2509 if (s_iji(i, j) == 0)
2510 continue;
2511 // printf("%d ", j);
2512 x0 = j * width;
2513 x1 = (j + 1) * width;
2514 X0 = x0 + width_10;
2515 X1 = x1 - width_10;
2516 // hor. lines:
2517 f << "\\put(" << X0 << "," << Y0 << "){\\line(1,0){" << width_8 << "}}\n";
2518 f << "\\put(" << X0 << "," << Y1 << "){\\line(1,0){" << width_8 << "}}\n";
2519
2520 // vert. lines:
2521 f << "\\put(" << X0 << "," << Y1 << "){\\line(0,1){" << width_8 << "}}\n";
2522 f << "\\put(" << X1 << "," << Y1 << "){\\line(0,1){" << width_8 << "}}\n";
2523
2524 }
2525 // printf("\n");
2526 }
2527
2528 f << "\\end{picture}" << endl;
2529}
2530
2531void discreta_matrix::calc_hash_key(int key_len, hollerith & hash_key, int f_v)
2532{
2533 int al_len;
2534 char *alphabet = NULL;
2535 char *inc = NULL;
2536 char *key = NULL;
2537 int i, j, k, v, b, nb_inc, pr, x, y;
2538 char c;
2539 int f_vv = FALSE;
2540 Vector P;
2541 int nb_primes = 25;
2542
2543 v = s_m();
2544 b = s_n();
2545 nb_inc = 0;
2546 for (i = 0; i < v; i++) {
2547 for (j = 0; j < b; j++) {
2548 if (s_iji(i, j) != 0)
2549 nb_inc++;
2550 }
2551 }
2553 al_len = MAXIMUM(256, b);
2554 alphabet = (char *) new char[al_len + 1];
2555 inc = (char *) new char[nb_inc + 1];
2556 key = (char *) new char[key_len + 1];
2557 //i0 = 0;
2558 k = 0;
2559 while (k < al_len) {
2560 for (i = 0; i < 10; i++) {
2561 alphabet[k] = '0' + i;
2562 k++;
2563 if (k >= al_len)
2564 break;
2565 }
2566 for (i = 0; i < 26; i++) {
2567 alphabet[k] = 'a' + i;
2568 k++;
2569 if (k >= al_len)
2570 break;
2571 }
2572 for (i = 0; i < 26; i++) {
2573 alphabet[k] = 'A' + i;
2574 k++;
2575 if (k >= al_len)
2576 break;
2577 }
2578 } // while
2579 alphabet[al_len] = 0;
2580 if (f_vv) {
2581 cout << "alphabet: " << alphabet << endl;
2582 }
2583
2584 k = 0;
2585 for (i = 0; i < v; i++) {
2586 for (j = 0; j < b; j++) {
2587 if (s_iji(i, j) == 0)
2588 continue;
2589 c = alphabet[j];
2590 inc[k] = c;
2591 k++;
2592 }
2593 }
2594 inc[nb_inc] = 0;
2595 if (f_vv) {
2596 cout << "incidences: " << inc << endl;
2597 }
2598
2599 j = 0;
2600 for (k = 0; k < key_len; k++) {
2601 pr = P.s_ii(k % 25);
2602 x = 0;
2603 for (i = 0; i < nb_inc; i++) {
2604 y = (int) inc[j];
2605 x = (x + y) % 256;
2606 j += pr;
2607 if (j >= nb_inc)
2608 j = 0;
2609 }
2610 key[k] = alphabet[x];
2611 // printf("k=%d pr = %d x=%d h[k]=%c\n", k, pr, x, h[k]);
2612 }
2613 key[key_len - 1] = 0;
2614 hash_key.init(key);
2615 if (f_v) {
2616 cout << "discreta_matrix::calc_hash_key() (len=" << key_len << ") hash=" << hash_key << endl;
2617 }
2618 delete [] alphabet;
2619 delete [] inc;
2620 delete [] key;
2621}
2622
2624{
2625 int m, n, i, j;
2627 integer c;
2628
2629 m = s_m();
2630 n = s_n();
2631 A = *this;
2632 c = A[0][0];
2633 for (i = 0; i < m; i++)
2634 {
2635 for (j = 0; j < n; j++)
2636 {
2637 integer e;
2638
2639 e = A[i][j];
2640 if (i != j && e.s_i() != 0)
2641 {
2642 return 0;
2643 }
2644 if (i == j && e.s_i() != c.s_i())
2645 {
2646 return 0;
2647 }
2648 }
2649 }
2650 return 1;
2651}
2652
2654{
2656 int m, n, i, j, l;
2657 int p = P.s_i();
2658
2659 m = s_m();
2660 n = s_n();
2661 if (m != n)
2662 {
2663 cout << "discreta_matrix::power_mod(): m !=n" << endl;
2664 exit(1);
2665 }
2666 B = *this;
2667 C = *this;
2668 B.power_int(r);
2669
2670 for (i = 0; i < m; i++)
2671 {
2672 for (j = 0; j < n; j++)
2673 {
2674 integer e, c;
2675 int em;
2676
2677 e = B[i][j];
2678 l = e.s_i();
2679 em = l%p;
2680 c.m_i(em);
2681 C[i][j] = c;
2682 }
2683 }
2684}
2685
2687{
2689 int m, n;
2690 int p = P.s_i();
2691 int ord = 0;
2692
2693 m = s_m();
2694 n = s_n();
2695 B = *this;
2696 if (m != n)
2697 {
2698 cout << "discreta_matrix::proj_order_mod() m != n" << endl;
2699 exit(1);
2700 }
2701 if (is_zero())
2702 {
2703 ord = 0;
2704 cout << "is zero matrix!" << endl;
2705 }
2706 else
2707 {
2708 while (B.is_in_center() == FALSE)
2709 {
2710 ord++;
2711 power_mod(ord, P, B);
2712 if (ord > p)
2713 {
2714 cout << "ERROR: proj_order_mod() order too big" << endl;
2715 ord = -1;
2716 }
2717 }
2718 }
2719 return ord;
2720}
2721
2722
2723
2724void discreta_matrix::PG_rep(domain *dom, permutation &p, int f_action_from_right, int f_modified)
2725{
2726 with ww(dom);
2727 PG_rep(p, f_action_from_right, f_modified);
2728}
2729
2730void discreta_matrix::PG_rep(permutation &p, int f_action_from_right, int f_modified)
2731{
2732 domain *d;
2733 int m, q, l, i, j;
2734 Vector v, w;
2736
2737 m = s_m();
2738 if (!is_finite_field_domain(d)) {
2739 cout << "discreta_matrix::PG_rep() no finite field domain" << endl;
2740 exit(1);
2741 }
2743 l = Gg.nb_PG_elements(m - 1, q);
2744 p.m_l(l);
2745 v.m_l_n(m);
2746 for (i = 0; i < l; i++) {
2747 if (f_modified)
2749 else
2750 v.PG_element_unrank(i);
2751 if (f_action_from_right)
2752 w.mult(v, *this);
2753 else
2754 w.mult(*this, v);
2755 if (f_modified)
2757 else
2758 w.PG_element_rank(j);
2759 p.m_ii(i, j);
2760 }
2761}
2762
2763void discreta_matrix::AG_rep(domain *dom, permutation &p, int f_action_from_right)
2764{
2765 with ww(dom);
2766 AG_rep(p, f_action_from_right);
2767}
2768
2769void discreta_matrix::AG_rep(permutation &p, int f_action_from_right)
2770{
2771 domain *d;
2772 int m, q, l, i, j;
2773 Vector v, w;
2775
2776 m = s_m();
2777 if (!is_finite_field_domain(d)) {
2778 cout << "discreta_matrix::AG_rep() no finite field domain" << endl;
2779 exit(1);
2780 }
2782 l = Gg.nb_AG_elements(m, q);
2783 p.m_l(l);
2784 v.m_l_n(m);
2785 for (i = 0; i < l; i++) {
2786 v.AG_element_unrank(i);
2787 if (f_action_from_right)
2788 w.mult(v, *this);
2789 else
2790 w.mult(*this, v);
2791 w.AG_element_rank(j);
2792 p.m_ii(i, j);
2793 }
2794}
2795
2796void discreta_matrix::MacWilliamsTransform(int n, int q, int f_v)
2797{
2798 int i, j;
2799
2800 m_mn(n + 1, n + 1);
2801 for (i = 0; i <= n; i++) {
2802 for (j = 0; j <= n; j++) {
2803 Krawtchouk(n, q, i, j, s_ij(i, j));
2804 }
2805 }
2806 if (f_v) {
2807 cout << "discreta_matrix::MacWilliamsTransform(" << n << ", " << q << ")" << endl;
2808 cout << *this;
2809 }
2810}
2811
2813{
2814 with ww(dom);
2815 domain *dom1 = NULL;
2817
2818 int q = finite_field_domain_order_int(dom1);
2819 int k, n, i, j, h;
2820 Vector w, c;
2821
2822 k = s_m();
2823 n = s_n();
2824 int l = Gg.nb_AG_elements(k, q);
2825
2826 w.m_l(k);
2827 v.m_l_n(n + 1);
2828 for (i = 0; i < l; i++) {
2829 w.AG_element_unrank(i);
2831 j = c.hamming_weight();
2832 h = v.s_ii(j);
2833 h++;
2834 v.m_ii(j, h);
2835 }
2836}
2837
2839{
2840 with ww(dom);
2841 domain *dom1 = NULL;
2842 Vector w;
2843 int i, j;
2845
2846 int q = finite_field_domain_order_int(dom1);
2847 int n = Gg.nb_PG_elements(k - 1, q);
2848 m_mn(k, n);
2849 w.m_l_n(k);
2850 for (j = 0; j < n; j++) {
2851 w.PG_element_unrank(j);
2852 for (i = 0; i < k; i++) {
2853 s_ij(i, j) = w[i];
2854 }
2855 }
2856 if (f_v) {
2857 cout << "discreta_matrix::Simplex_code_generator_matrix(" << k << ", " << q << ")" << endl;
2858 cout << *this;
2859 }
2860}
2861
2863{
2864 with ww(dom);
2865 int i, j, l;
2867
2868 int q = dom->order_int();
2869 l = Gg.nb_PG_elements(k, q);
2870 m_mn_n(l, l);
2871 Vector v, w;
2872 discreta_base a;
2873
2874 v.m_l_n(k + 1);
2875 w.m_l_n(k + 1);
2876 for (i = 0; i < l; i++) {
2877 v.PG_element_unrank(i);
2878 for (j = 0; j < l; j++) {
2879 w.PG_element_unrank(j);
2880 v.scalar_product(w, a);
2881 if (a.is_zero())
2882 m_iji(i, j, 1);
2883 }
2884 }
2885 if (f_v) {
2886 cout << "discreta_matrix::PG_design_point_vs_hyperplane(" << k << ", " << q << ")" << endl;
2887 cout << *this;
2888 }
2889}
2890
2891void discreta_matrix::PG_k_q_design(domain *dom, int k, int f_v, int f_vv)
2892{
2893 with ww(dom);
2894 int ii, i, j, nb_pts, nb_lines, r;
2895 discreta_matrix v, w, z;
2896 discreta_base a;
2898
2899 int q = dom->order_int();
2900 nb_pts = Gg.nb_PG_elements(k, q);
2901 nb_lines = nb_PG_lines(k, q);
2902 if (f_v) {
2903 cout << "nb_pts=" << nb_pts << " nb_lines=" << nb_lines << endl;
2904 }
2905 if (f_vv) {
2906 cout << "points:" << endl;
2907 v.m_mn_n(1, k + 1);
2908 for (i = 0; i < nb_pts; i++) {
2909 v.PG_point_unrank(0, 0, 0, 1, k + 1, i);
2910 cout << i << " : " << v << endl;
2911 }
2912 cout << "lines:" << endl;
2913 w.m_mn_n(k + 1, 2);
2914 for (j = 0; j < nb_lines; j++) {
2915 w.PG_line_unrank(j);
2916 z = w;
2917 z.transpose();
2918 cout << j << " : \n" << z << endl;
2919 }
2920 }
2921 m_mn_n(nb_pts, nb_lines);
2922
2923 v.m_mn_n(k + 1, 1);
2924 w.m_mn_n(k + 1, 2);
2925 z.m_mn_n(k + 1, 3);
2926 for (i = 0; i < nb_pts; i++) {
2927 v.PG_point_unrank(0, 0, 1, 0, k + 1, i);
2928 for (j = 0; j < nb_lines; j++) {
2929 w.PG_line_unrank(j);
2930 for (ii = 0; ii < k + 1; ii++) {
2931 z[ii][0] = v[ii][0];
2932 z[ii][1] = w[ii][0];
2933 z[ii][2] = w[ii][1];
2934 }
2935 r = z.rank();
2936 if (r == 2)
2937 m_iji(i, j, 1);
2938 if (r != 2 && r != 3) {
2939 cout << "error rank != 2 and rank != 3" << endl;
2940 cout << "rank=" << r << endl;
2941 cout << z << endl;
2942 exit(1);
2943 }
2944 }
2945 }
2946 if (f_v) {
2947 cout << "PG_k_q_design(" << k << ", " << q << ")" << endl;
2948 cout << *this;
2949 }
2950}
2951
2953{
2954 int f_v = (verbose_level >= 1);
2955 int n, h, i, j, ii, jj;
2956 discreta_matrix M1;
2957 discreta_base a;
2958
2959 if (f_v) {
2960 cout << "discreta_matrix::determinant" << endl;
2961 }
2962 if (s_m() != s_n()) {
2963 cout << "discreta_matrix::determinant the matrix is not square" << endl;
2964 exit(1);
2965 }
2966 n = s_n();
2967 if (n == 1) {
2968 d = s_ij(0, 0);
2969 }
2970 else {
2971 d = s_ij(0, 0);
2972 d.zero();
2973
2974 M1.m_mn(n - 1, n - 1);
2975 for (h = 0; h < n; h++) {
2976 if (f_v) {
2977 cout << "discreta_matrix::determinant h=" << h << " d=" << d << endl;
2978 }
2979 for (i = 0, ii = 0; i < n; i++) {
2980 if (i == 0) {
2981 continue;
2982 }
2983 for (j = 0, jj = 0; j < n; j++) {
2984 if (j == h) {
2985 continue;
2986 }
2987 M1.s_ij(ii, jj) = s_ij(i, j);
2988 jj++;
2989 }
2990 ii++;
2991 }
2992 if (f_v) {
2993 cout << "discreta_matrix::determinant M1=" << endl << M1 << endl;
2994 }
2995 M1.determinant(a, verbose_level);
2996 if (f_v) {
2997 cout << "discreta_matrix::determinant a=" << a << endl;
2998 }
2999 if ((h % 2) == 1) {
3000 a.negate();
3001 }
3002 a.mult_apply(s_ij(0, h));
3003 d.add_apply(a);
3004 }
3005 }
3006}
3007
3008void discreta_matrix::det(discreta_base & d, int f_v, int f_vv)
3009{
3011
3012 A = *this;
3013 A.det_modify_input_matrix(d, f_v, f_vv);
3014}
3015
3017{
3018 int rk, i;
3019 int f_special = TRUE;
3020 int f_complete = FALSE;
3021
3022 Vector base_cols;
3024 int f_P = FALSE;
3025
3026 if (f_v) {
3027 cout << "in det():" << endl << *this << endl;
3028 }
3029 rk = Gauss(f_special, f_complete, base_cols, f_P, P, f_vv);
3030 if (f_v) {
3031 cout << "Gauss:" << endl << *this << endl;
3032 }
3033 if (rk < s_m()) {
3034 if (f_v) {
3035 cout << "singular" << endl;
3036 }
3037 }
3038 d = s_ij(0, 0);
3039 for (i = 1; i < rk; i++) {
3040 d *= s_ij(i, i);
3041 }
3042 if (f_v) {
3043 cout << "det = " << d << endl;
3044 }
3045}
3046
3048{
3049 if (x.s_kind() != MATRIX) {
3050 cout << "determinant_map() x must be a MATRIX" << endl;
3051 exit(1);
3052 }
3053 discreta_matrix & M = x.as_matrix();
3054 int f_v = FALSE;
3055 int f_vv = FALSE;
3056 M.det(d, f_v, f_vv);
3057}
3058
3060{
3061 domain *d;
3062 int q, m, n, l, s, i, a1, a2, a3, nb, ql, pivot_row, pivot_row2 = 0;
3063 discreta_base x;
3066
3067 if (!is_finite_field_domain(d)) {
3068 cout << "discreta_matrix::PG_line_rank() no finite field domain" << endl;
3069 exit(1);
3070 }
3072 m = s_m();
3073 n = s_n();
3074 if (m <= 0) {
3075 cout << "discreta_matrix::PG_line_rank() matrix not allocated()" << endl;
3076 exit(1);
3077 }
3078 if (n != 2) {
3079 cout << "discreta_matrix::PG_line_rank() matrix not allocated()" << endl;
3080 exit(1);
3081 }
3082
3083 pivot_row = 0;
3084 // do a little Gauss algorithm:
3085 for (i = m - 1; i >= 0; i--) {
3086 if (!s_ij(i, 0).is_zero() || !s_ij(i, 1).is_zero()) {
3087 pivot_row = i;
3088 if (s_ij(i, 1).is_zero()) {
3089 for ( ; i >= 0; i--) {
3090 s_ij(i, 0).swap(s_ij(i, 1));
3091 }
3092 }
3093 break;
3094 }
3095 }
3096 if (f_v) {
3097 cout << "after permuting:\n" << *this << endl;
3098 cout << "PG_line_rank() pivot_row=" << pivot_row << endl;
3099 }
3100 PG_point_normalize(0, 1, 1, 0, m);
3101 if (!s_ij(pivot_row, 1).is_one()) {
3102 cout << "matrix::PG_line_rank() pivot element is not one" << endl;
3103 exit(1);
3104 }
3105 if (!s_ij(pivot_row, 0).is_zero()) {
3106 discreta_base x;
3107
3108 x = s_ij(pivot_row, 0);
3109 for (i = pivot_row; i >= 0; i--) {
3110 discreta_base y;
3111
3112 y = s_ij(i, 1);
3113 y *= x;
3114 y.negate();
3115 s_ij(i, 0) += y;
3116 }
3117 }
3118 PG_point_normalize(0, 0, 1, 0, m);
3119 if (f_v) {
3120 cout << "PG_line_rank() after gauss right to left and normalize:\n" << *this << endl;
3121 }
3122 for (i = pivot_row - 1; i >= 0; i--) {
3123 if (!s_ij(i, 0).is_zero()) {
3124 pivot_row2 = i;
3125 break;
3126 }
3127 }
3128 if (i < 0) {
3129 cout << "discreta_matrix::PG_line_rank() zero column" << endl;
3130 exit(1);
3131 }
3132
3133 // due to normalize, this element must already be one:
3134 if (!s_ij(pivot_row2, 0).is_one()) {
3135 cout << "matrix::PG_line_rank() pivot element 2 is not one" << endl;
3136 exit(1);
3137 }
3138 if (!s_ij(pivot_row2, 1).is_zero()) {
3139 discreta_base x;
3140
3141 x = s_ij(pivot_row2, 1);
3142 for (i = pivot_row2; i >= 0; i--) {
3143 discreta_base y;
3144
3145 y = s_ij(i, 0);
3146 y *= x;
3147 y.negate();
3148 s_ij(i, 1) += y;
3149 }
3150 }
3151 if (f_v) {
3152 cout << "PG_line_rank() after gauss left to right:\n" << *this << endl;
3153 }
3154
3155 l = pivot_row2;
3156 if (!s_ij(l, 1).is_zero()) {
3157 cout << "!s_ij(l, 1).is_zero()" << endl;
3158 exit(1);
3159 }
3160 ql = NT.i_power_j(q, l);
3161 nb = Gg.nb_PG_elements(m - l - 2, q);
3162 s = ql * ql * nb;
3163 if (f_v) {
3164 cout << "l=" << l << " ql=" << ql << " nb=" << nb << " s=" << s << endl;
3165 }
3166 PG_point_rank(l + 1, 1, 1, 0, m - l - 1, a3);
3167 if (f_v) {
3168 cout << "a3=" << a3 << endl;
3169 }
3170 if (l) {
3171 AG_point_rank(0, 1, 1, 0, l, a2);
3172 if (f_v) {
3173 cout << "a2=" << a2 << endl;
3174 }
3175 AG_point_rank(0, 0, 1, 0, l, a1);
3176 if (f_v) {
3177 cout << "a1=" << a1 << endl;
3178 }
3179 }
3180 else {
3181 a1 = 0;
3182 a2 = 0;
3183 }
3184 a = (a1 * nb + a3) * ql + a2;
3185 if (f_v) {
3186 cout << "a=" << a << endl;
3187 }
3188 for (l--; l >= 0; l--) {
3189 ql = NT.i_power_j(q, l);
3190 nb = Gg.nb_PG_elements(m - l - 2, q);
3191 s = ql * ql * nb;
3192 a += s;
3193 }
3194}
3195
3197{
3198 domain *d;
3199 int q, m, n, l, s, k, a1, a2, a3, nb, ql;
3202
3203 if (!is_finite_field_domain(d)) {
3204 cout << "discreta_matrix::PG_line_unrank no finite field domain" << endl;
3205 exit(1);
3206 }
3208 m = s_m();
3209 n = s_n();
3210 if (m <= 0) {
3211 cout << "discreta_matrix::PG_line_unrank matrix not allocated" << endl;
3212 exit(1);
3213 }
3214 if (n != 2) {
3215 cout << "discreta_matrix::PG_line_unrank matrix not allocated" << endl;
3216 exit(1);
3217 }
3218
3219
3220 // cout << "matrix::PG_line_unrank() a=" << a << endl;
3221 l = 0;
3222 while (l < m) {
3223 ql = NT.i_power_j(q, l);
3224 nb = Gg.nb_PG_elements(m - l - 2, q);
3225 s = ql * ql * nb;
3226 // cout << "matrix::PG_line_unrank() a=" << a
3227 //<< " l=" << l << " s=" << s << " ql=" << ql
3228 //<< " nb=" << nb << endl;
3229 if (a >= s) {
3230 a -= s;
3231 l++;
3232 continue;
3233 }
3234 // cout << "choosing l=" << l << endl;
3235 // cout << "nb = " << nb << endl;
3236 a2 = a % ql;
3237 a -= a2;
3238 a /= ql;
3239 a3 = a % nb;
3240 a -= a3;
3241 a /= nb;
3242 a1 = a;
3243 // cout << "a1=" << a1 << endl;
3244 // cout << "a2=" << a2 << endl;
3245 // cout << "a3=" << a3 << endl;
3246
3247 s_ij(l, 0).one();
3248 s_ij(l, 1).zero();
3249 for (k = l + 1; k < m; k++) {
3250 s_ij(k, 0).zero();
3251 }
3252
3253 if (l) {
3254 AG_point_unrank(0, 0, 1, 0, l, a1);
3255 AG_point_unrank(0, 1, 1, 0, l, a2);
3256 }
3257
3258 PG_point_unrank(l + 1, 1, 1, 0, m - l - 1, a3);
3259 return;
3260 }
3261 cout << "discreta_matrix::PG_line_unrank a too large" << endl;
3262 exit(1);
3263}
3264
3266 int di, int dj, int length)
3267{
3268 int i, j;
3269 discreta_base a;
3270
3271 j = 0;
3272 for (i = length - 1; i >= 0; i--) {
3273 if (!s_ij(i0 + i * di, j0 + j * dj).is_zero()) {
3274 if (s_ij(i0 + i * di, j0 + i * dj).is_one())
3275 return;
3276 a = s_ij(i0 + i * di, j0 + i * dj);
3277 a.invert();
3278 for (j = i; j >= 0; j--) {
3279 s_ij(i0 + j * di, j0 + j * dj) *= a;
3280 }
3281 return;
3282 }
3283 }
3284 cout << "discreta_matrix::PG_point_normalize zero vector" << endl;
3285 exit(1);
3286}
3287
3289 int di, int dj, int length, int a)
3290{
3291 domain *d;
3292 int q, n, l, qhl, k, j, r, a1 = a;
3293
3294 if (!is_finite_field_domain(d)) {
3295 cout << "discreta_matrix::PG_point_unrank no finite field domain" << endl;
3296 exit(1);
3297 }
3299 n = length;
3300 if (n <= 0) {
3301 cout << "discreta_matrix::PG_point_unrank n <= 0" << endl;
3302 exit(1);
3303 }
3304
3305
3306 l = 0;
3307 qhl = 1;
3308 while (l < n) {
3309 if (a >= qhl) {
3310 a -= qhl;
3311 qhl *= q;
3312 l++;
3313 continue;
3314 }
3315 s_ij(i0 + l * di, j0 + l * dj).one();
3316 for (k = l + 1; k < n; k++) {
3317 s_ij(i0 + k * di, j0 + k * dj).zero();
3318 }
3319 j = 0;
3320 while (a != 0) {
3321 r = a % q;
3322 m_iji(i0 + j * di, j0 + j * dj, r);
3323 j++;
3324 a -= r;
3325 a /= q;
3326 }
3327 for ( ; j < l; j++)
3328 m_iji(i0 + j * di, j0 + j * dj, 0);
3329 return;
3330 }
3331 cout << "discreta_matrix::PG_point_unrank() a too large" << endl;
3332 cout << "length = " << length << endl;
3333 cout << "a = " << a1 << endl;
3334 exit(1);
3335}
3336
3338 int di, int dj, int length, int &a)
3339{
3340 domain *d;
3341 int i, j, q, q_power_j, b;
3342
3343 if (!is_finite_field_domain(d)) {
3344 cout << "discreta_matrix::PG_point_rank no finite field domain" << endl;
3345 exit(1);
3346 }
3348 PG_point_normalize(i0, j0, di, dj, length);
3349 if (length <= 0) {
3350 cout << "discreta_matrix::PG_point_rank length <= 0" << endl;
3351 exit(1);
3352 }
3353 for (i = length - 1; i >= 0; i--) {
3354 if (!s_ij(i0 + i * di, j0 + i * dj).is_zero())
3355 break;
3356 }
3357 if (i < 0) {
3358 cout << "discreta_matrix::PG_point_rank zero vector" << endl;
3359 exit(1);
3360 }
3361 if (!s_ij(i0 + i * di, j0 + i * dj).is_one()) {
3362 cout << "discreta_matrix::PG_point_rank vector not normalized" << endl;
3363 exit(1);
3364 }
3365
3366 b = 0;
3367 q_power_j = 1;
3368 for (j = 0; j < i; j++) {
3369 b += q_power_j;
3370 q_power_j *= q;
3371 }
3372
3373
3374 a = 0;
3375 for (j = i - 1; j >= 0; j--) {
3376 a += s_iji(i0 + j * di, j0 + j * dj);
3377 if (j > 0)
3378 a *= q;
3379 }
3380 a += b;
3381}
3382
3383
3385// lowest element which is different from zero becomes one in each column
3386{
3387 int i, ii, j, m, n;
3388 discreta_base a;
3389
3390 m = s_m();
3391 n = s_n();
3392 for (j = 0; j < n; j++) {
3393 for (i = m - 1; i >= 0; i--) {
3394 if (!s_ij(i, j).is_zero()) {
3395 if (s_ij(i, j).is_one())
3396 break;
3397 a = s_ij(i, j);
3398 a.invert();
3399 for (ii = i; ii >= 0; ii--) {
3400 s_ij(ii, j) *= a;
3401 }
3402 break;
3403 }
3404 }
3405 if (i == -1) {
3406 cout << "discreta_matrix::PG_element_normalize zero column" << endl;
3407 exit(1);
3408 }
3409 }
3410}
3411
3413 int di, int dj, int length, int &a)
3414{
3415 domain *d;
3416 int q, i;
3417
3418 if (!is_finite_field_domain(d)) {
3419 cout << "discreta_matrix::AG_point_rank no finite field domain" << endl;
3420 exit(1);
3421 }
3423 if (length <= 0) {
3424 cout << "discreta_matrix::AG_point_rank length <= 0" << endl;
3425 exit(1);
3426 }
3427 a = 0;
3428 for (i = length - 1; i >= 0; i--) {
3429 a += s_iji(i0 + i * di, j0 + i * dj);
3430 if (i > 0)
3431 a *= q;
3432 }
3433}
3434
3436 int di, int dj, int length, int a)
3437{
3438 domain *d;
3439 int q, i, b;
3440
3441 if (!is_finite_field_domain(d)) {
3442 cout << "discreta_matrix::AG_point_unrank no finite field domain" << endl;
3443 exit(1);
3444 }
3446 if (length <= 0) {
3447 cout << "discreta_matrix::AG_point_unrank length <= 0" << endl;
3448 exit(1);
3449 }
3450 for (i = 0; i < length; i++) {
3451 b = a % q;
3452 m_iji(i0 + i * di, j0 + i * dj, b);
3453 a /= q;
3454 }
3455}
3456
3457int nb_PG_lines(int n, int q)
3458{
3459 int l, ql, nb, s, a = 0, m;
3462
3463 m = n + 1;
3464 for (l = 0; l < m; l++) {
3465 ql = NT.i_power_j(q, l);
3466 nb = Gg.nb_PG_elements(m - l - 2, q);
3467 s = ql * ql * nb;
3468 a += s;
3469 }
3470 return a;
3471}
3472
3474{
3475 int i, j = 0, m, n, nb_X = 0;
3476 m = s_m();
3477 n = s_n();
3478 for (i = 0; i < m; i++) {
3479 for (j = 0; j < n; j++) {
3480 if (s_iji(i, j))
3481 nb_X++;
3482 }
3483 }
3484 ofstream f(fname);
3485 f << i << " " << j << " " << nb_X << endl;
3486 save_as_inc(f);
3487 f << "-1 1" << endl;
3488}
3489
3491{
3492 int i, j, m, n;
3493 m = s_m();
3494 n = s_n();
3495 for (i = 0; i < m; i++) {
3496 for (j = 0; j < n; j++) {
3497 if (s_iji(i, j))
3498 f << i * n + j << " ";
3499 }
3500 }
3501 f << endl;
3502}
3503
3504
3505}}
various functions related to geometries
Definition: geometry.h:721
DISCRETA vector class for vectors of DISCRETA objects.
Definition: discreta.h:797
void PG_element_unrank_modified(int a)
Definition: vector.cpp:1446
void mult_scalar(discreta_base &a)
Definition: vector.cpp:781
void scalar_product(Vector &w, discreta_base &a)
Definition: vector.cpp:1561
int compare_with(discreta_base &a)
Definition: vector.cpp:343
Vector & append_integer(int a)
Definition: vector.cpp:390
discreta_base & s_i(int i)
Definition: vector.cpp:202
void m_ii(int i, int a)
Definition: discreta.h:824
void PG_element_rank_modified(int &a)
Definition: vector.cpp:1334
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
void add_apply(discreta_base &x)
Definition: base.cpp:724
virtual int compare_with_euclidean(discreta_base &a)
Definition: base.cpp:880
int is_divisor(discreta_base &y)
Definition: base.cpp:953
void add(discreta_base &x, discreta_base &y)
Definition: base.cpp:674
void mult(discreta_base &x, discreta_base &y)
Definition: base.cpp:367
virtual int compare_with(discreta_base &a)
Definition: base.cpp:274
discreta_base & power_int_mod(int l, discreta_base &p)
Definition: base.cpp:499
void read_memory(memory &m, int debug_depth)
Definition: base.cpp:1201
void swap(discreta_base &a)
Definition: base.cpp:179
discreta_base & divide_by_exact(discreta_base &x)
Definition: base.cpp:629
void copyobject(discreta_base &x)
Definition: base.cpp:194
void mult_mod(discreta_base &x, discreta_base &y, discreta_base &p)
Definition: base.cpp:372
discreta_base & power_int(int l)
Definition: base.cpp:447
virtual int invert_to(discreta_base &x)
Definition: base.cpp:424
void write_memory(memory &m, int debug_depth)
Definition: base.cpp:1103
void mult_apply(discreta_base &x)
Definition: base.cpp:436
void extended_gcd(discreta_base &n, discreta_base &u, discreta_base &v, discreta_base &g, int verbose_level)
Definition: base.cpp:972
void vector_mult_to(Vector &x, discreta_base &y)
void binomial(int n_min, int n_max, int k_min, int k_max)
int smith_eliminate_column(discreta_matrix &P, discreta_matrix &Pv, int i, int verbose_level)
void weight_enumerator_brute_force(domain *dom, Vector &v)
void incma_print_ascii(std::ostream &ost, int f_tex, int f_row_decomp, Vector &row_decomp, int f_col_decomp, Vector &col_decomp)
void print_decomposed(std::ostream &ost, Vector &row_decomp, Vector &col_decomp)
void KX_module_join(Vector &v1, unipoly &mue1, Vector &v2, unipoly &mue2, Vector &v3, unipoly &mue3, int verbose_level)
void PG_point_unrank(int i0, int j0, int di, int dj, int length, int a)
void KX_module_order_ideal(int i, unipoly &mue, int verbose_level)
void read_mem(memory &M, int debug_depth)
void det(discreta_base &d, int f_v, int f_vv)
void multiply_2by2_from_right(int i, int j, discreta_base &aii, discreta_base &aij, discreta_base &aji, discreta_base &ajj, int verbose_level)
void calc_hash_key(int key_len, hollerith &hash_key, int f_v)
void companion_matrix(unipoly &m, int verbose_level)
void PG_point_normalize(int i0, int j0, int di, int dj, int length)
int smith_eliminate_row(discreta_matrix &Q, discreta_matrix &Qv, int i, int verbose_level)
void stirling_first(int n_min, int n_max, int k_min, int k_max, int f_signless)
discreta_matrix & m_mn(int m, int n)
void KX_module_apply(unipoly &p, Vector &v)
void power_mod(int r, integer &P, discreta_matrix &C)
void smith_normal_form(discreta_matrix &P, discreta_matrix &Pv, discreta_matrix &Q, discreta_matrix &Qv, int verbose_level)
discreta_matrix & m_mn_n(int m, int n)
void Berlekamp(unipoly &m, int p, int verbose_level)
void mult_to(discreta_base &x, discreta_base &y)
void multiply_2by2_from_left(int i, int j, discreta_base &aii, discreta_base &aij, discreta_base &aji, discreta_base &ajj, int verbose_level)
discreta_matrix & operator=(const discreta_base &x)
void AG_point_rank(int i0, int j0, int di, int dj, int length, int &a)
void incma_print_latex(std::ostream &f, int f_row_decomp, Vector &row_decomp, int f_col_decomp, Vector &col_decomp, int f_labelling_points, Vector &point_labels, int f_labelling_blocks, Vector &block_labels)
void PG_k_q_design(domain *dom, int k, int f_v, int f_vv)
void apply_perms(int f_row_perm, permutation &row_perm, int f_col_perm, permutation &col_perm)
void AG_point_unrank(int i0, int j0, int di, int dj, int length, int a)
void add_to(discreta_base &x, discreta_base &y)
void incma_print_ascii_permuted_and_decomposed(std::ostream &ost, int f_tex, Vector &decomp, permutation &p)
void Simplex_code_generator_matrix(domain *dom, int k, int f_v)
void matrix_mult_to(discreta_matrix &x, discreta_base &y)
void m_iji(int i, int j, int a)
Definition: discreta.h:1099
int get_kernel(Vector &base_cols, discreta_matrix &kernel)
int Gauss(int f_special, int f_complete, Vector &base_cols, int f_P, discreta_matrix &P, int verbose_level)
void MacWilliamsTransform(int n, int q, int f_v)
void write_mem(memory &m, int debug_depth)
void stirling_second(int n_min, int n_max, int k_min, int k_max, int f_ordered)
discreta_matrix & realloc(int m, int n)
void AG_rep(domain *dom, permutation &p, int f_action_from_right)
std::ostream & print(std::ostream &)
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 PG_design_point_vs_hyperplane(domain *dom, int k, int f_v)
void multiply_vector_from_left(Vector &x, Vector &y)
void determinant(discreta_base &d, int verbose_level)
void PG_rep(domain *dom, permutation &p, int f_action_from_right, int f_modified)
void incma_print_latex2(std::ostream &f, int width, int width_10, int f_outline_thin, const char *unit_length, const char *thick_lines, const char *thin_lines, const char *geo_line_width, int f_row_decomp, Vector &row_decomp, int f_col_decomp, Vector &col_decomp, int f_labelling_points, Vector &point_labels, int f_labelling_blocks, Vector &block_labels)
void det_modify_input_matrix(discreta_base &d, int f_v, int f_vv)
void Frobenius(unipoly &m, int p, int verbose_level)
void PG_point_rank(int i0, int j0, int di, int dj, int length, int &a)
DISCRETA class for influencing arithmetic operations.
Definition: discreta.h:1360
DISCRETA string class.
Definition: discreta.h:626
DISCRETA integer class.
Definition: discreta.h:667
DISCRETA class to serialize data structures.
Definition: discreta.h:582
DISCRETA permutation class.
Definition: discreta.h:976
DISCRETA class for polynomials in one variable.
Definition: discreta.h:1236
void largest_divisor_prime_to(unipoly &q, unipoly &r)
Definition: unipoly.cpp:676
void evaluate_at(discreta_base &x, discreta_base &y)
Definition: unipoly.cpp:662
DISCRETA class related to class domain.
Definition: discreta.h:1413
#define MINIMUM(x, y)
Definition: foundations.h:216
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define ODD(x)
Definition: foundations.h:222
#define ONE_char_int(a)
Definition: foundations.h:225
#define MAXIMUM(x, y)
Definition: foundations.h:217
enum printing_mode_enum current_printing_mode()
Definition: global.cpp:1573
void determinant_map(discreta_base &x, discreta_base &d)
void stirling_first(int n, int k, int f_signless, discreta_base &res, int verbose_level)
Definition: global.cpp:997
void free_m_times_n_objects(discreta_base *p)
Definition: global.cpp:186
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 stirling_second(int n, int k, int f_ordered, discreta_base &res, int verbose_level)
Definition: global.cpp:938
int nb_PG_lines(int n, int q)
void the_first_n_primes(Vector &P, int n)
Definition: global.cpp:1420
void Krawtchouk(int n, int q, int i, int j, discreta_base &a)
Definition: global.cpp:1305
discreta_base * calloc_m_times_n_objects(int m, int n, kind k)
Definition: global.cpp:163
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