Orbiter 2022
Combinatorial Objects
grassmann.cpp
Go to the documentation of this file.
1// grassmann.cpp
2//
3// Anton Betten
4//
5// started: June 5, 2009
6//
7//
8//
9//
10//
11
12#include "foundations.h"
13
14using namespace std;
15
16
17namespace orbiter {
18namespace layer1_foundations {
19namespace geometry {
20
21
23{
24 n = 0;
25 k = 0;
26 q = 0;
27 nCkq = NULL;
28 F = NULL;
29 base_cols = NULL;
30 coset = NULL;
31 M = NULL;
32 M2 = NULL;
33 v = NULL;
34 w = NULL;
35 G = NULL;
36}
37
39{
40 //cout << "grassmann::~grassmann 1" << endl;
41 if (nCkq) {
43 }
44 if (base_cols) {
46 }
47 //cout << "grassmann::~grassmann 2" << endl;
48 if (coset) {
50 }
51 //cout << "grassmann::~grassmann 3" << endl;
52 if (M) {
53 FREE_int(M);
54 }
55 if (M2) {
56 FREE_int(M2);
57 }
58 if (v) {
59 FREE_int(v);
60 }
61 if (w) {
62 FREE_int(w);
63 }
64 //cout << "grassmann::~grassmann 4" << endl;
65 if (G) {
67 }
68}
69
70void grassmann::init(int n, int k, field_theory::finite_field *F, int verbose_level)
71{
72 int f_v = (verbose_level >= 1);
73
74 if (f_v) {
75 cout << "grassmann::init n=" << n
76 << " k=" << k << " q=" << F->q << endl;
77 }
78
79
83 q = F->q;
84
86
88
89 D.q_binomial(*nCkq, n, k, q, 0 /* verbose_level */);
90 if (f_v) {
91 cout << "grassmann::init nCkq=" << *nCkq << endl;
92 }
93
94
95
96
98 coset = NEW_int(n);
99 M = NEW_int(n * n);
100 // changed to n * n to allow for embedded subspaces.
101 M2 = NEW_int(n * n);
102 v = NEW_int(n);
103 w = NEW_int(n);
104 if (k > 1) {
106 G->init(n - 1, k - 1, F, verbose_level);
107 }
108 else {
109 G = NULL;
110 }
111}
112
113long int grassmann::nb_of_subspaces(int verbose_level)
114{
115 long int nb;
117
118 nb = Combi.generalized_binomial(n, k, q);
119 return nb;
120}
121
123 ostream &ost, long int a)
124{
125 unrank_lint(a, 0 /*verbose_level*/);
126 latex_matrix(ost, M);
127
128 if (F->e > 1) {
129 ost << " = ";
131 }
132 //print_integer_matrix_tex(ost, M, k, n);
133}
134
136 std::ostream &ost, long int a)
137{
138 unrank_lint(a, 0 /*verbose_level*/);
140 //print_integer_matrix_tex(ost, M, k, n);
141}
142
143void grassmann::print_set(long int *v, int len)
144{
145 int i;
146
147 for (i = 0; i < len; i++) {
148 cout << "subspace " << i << " / " << len
149 << " is " << v[i] << ":" << endl;
150 unrank_lint(v[i], 0 /*verbose_level*/);
151 latex_matrix(cout, M);
152 //print_integer_matrix_width(cout, M,
153 // k, n, n, F->log10_of_q + 1);
154 }
155}
156
157void grassmann::print_set_tex(ostream &ost, long int *v, int len)
158{
159 int i;
160 int *Mtx;
161
162 Mtx = NEW_int(n * n);
163
164 for (i = 0; i < len; i++) {
165 ost << "subspace " << i << " / " << len << " is "
166 << v[i] << ":\\\\" << endl;
167 //unrank_lint(v[i], 0 /*verbose_level*/);
168
170 Mtx, v[i], 0 /*verbose_level*/);
171
172
173 ost << "$$" << endl;
174 //ost << "\\left[" << endl;
175 //print_integer_matrix_width(cout,
176 // M, k, n, n, F->log10_of_q + 1);
177 //print_integer_matrix_tex(ost, M, k, n);
178 //ost << "\\right]" << endl;
179 //latex_matrix(ost, Mtx);
180
181 F->print_matrix_latex(ost, Mtx, k, n);
182
183#if 0
184 ost << "\\qquad" << endl;
185
186 F->print_matrix_numerical_latex(ost, Mtx, k, n);
187
188 ost << "\\qquad" << endl;
189
190 F->print_matrix_latex(ost, Mtx + k * n, n - k, n);
191
192 ost << "\\qquad" << endl;
193
194 F->print_matrix_numerical_latex(ost, Mtx + k * n, n - k, n);
195#endif
196
197 ost << "$$" << endl;
198 }
199 FREE_int(Mtx);
200}
201
202void grassmann::print_set_tex_with_perp(ostream &ost, long int *v, int len)
203{
204 int i;
205 int *Mtx;
206
207 Mtx = NEW_int(n * n);
208
209 for (i = 0; i < len; i++) {
210 ost << "subspace " << i << " / " << len << " and its dual are "
211 << v[i] << ":\\\\" << endl;
212 //unrank_lint(v[i], 0 /*verbose_level*/);
213
215 Mtx, v[i], 0 /*verbose_level*/);
216
217
218 ost << "$$" << endl;
219 //ost << "\\left[" << endl;
220 //print_integer_matrix_width(cout,
221 // M, k, n, n, F->log10_of_q + 1);
222 //print_integer_matrix_tex(ost, M, k, n);
223 //ost << "\\right]" << endl;
224 //latex_matrix(ost, Mtx);
225
226 F->print_matrix_latex(ost, Mtx, k, n);
227
228 ost << "\\qquad" << endl;
229
230 F->print_matrix_numerical_latex(ost, Mtx, k, n);
231
232 ost << "\\qquad" << endl;
233
234 F->print_matrix_latex(ost, Mtx + k * n, n - k, n);
235
236 ost << "\\qquad" << endl;
237
238 F->print_matrix_numerical_latex(ost, Mtx + k * n, n - k, n);
239
240 ost << "$$" << endl;
241 }
242 FREE_int(Mtx);
243}
244
245
246int grassmann::nb_points_covered(int verbose_level)
247{
248 int nb;
250
251 nb = Combi.generalized_binomial(k, 1, q);
252 return nb;
253}
254
255void grassmann::points_covered(long int *the_points, int verbose_level)
256{
257 int i, nb;
258 long int a;
259
260 nb = nb_points_covered(0 /* verbose_level*/);
261 for (i = 0; i < nb; i++) {
265 the_points[i] = a;
266 }
267}
268
269void grassmann::unrank_lint_here(int *Mtx, long int rk, int verbose_level)
270{
271 unrank_lint(rk, verbose_level);
272 Int_vec_copy(M, Mtx, k * n);
273}
274
275long int grassmann::rank_lint_here(int *Mtx, int verbose_level)
276{
277 Int_vec_copy(Mtx, M, k * n);
278 return rank_lint(verbose_level);
279}
280
281void grassmann::unrank_embedded_subspace_lint(long int rk, int verbose_level)
282{
283 int f_v = (verbose_level >= 1);
284 int i, j;
285
286 if (f_v) {
287 cout << "grassmann::unrank_embedded_subspace_lint " << rk << endl;
288 }
289 unrank_lint(rk, verbose_level);
290 Int_vec_zero(M + k * n, (n - k) * n);
291 if (k == 0) {
293 }
294 else {
295 for (i = 0; i < n - k; i++) {
296 j = base_cols[k + i];
297 M[(k + i) * n + j] = 1;
298 }
299 }
300 if (f_v) {
301 cout << "unrank_embedded_subspace_lint done" << endl;
302 }
303}
304
305long int grassmann::rank_embedded_subspace_lint(int verbose_level)
306{
307 int f_v = (verbose_level >= 1);
308 long int rk;
309
310 if (f_v) {
311 cout << "grassmann::rank_embedded_subspace_lint " << endl;
312 }
313 rk = rank_lint(verbose_level);
314 return rk;
315
316}
317
318void grassmann::unrank_embedded_subspace_lint_here(int *Basis, long int rk, int verbose_level)
319{
320 int f_v = (verbose_level >= 1);
321 int i, j;
322
323 if (f_v) {
324 cout << "grassmann::unrank_embedded_subspace_int_here " << rk << endl;
325 }
326 unrank_lint_here(Basis, rk, verbose_level);
327 Int_vec_zero(Basis + k * n, (n - k) * n);
328 if (k == 0) {
330 }
331 else {
332 for (i = 0; i < n - k; i++) {
333 j = base_cols[k + i];
334 Basis[(k + i) * n + j] = 1;
335 }
336 }
337 if (f_v) {
338 cout << "unrank_embedded_subspace_int_here done" << endl;
339 }
340}
341
342
343void grassmann::unrank_lint(long int rk, int verbose_level)
344{
345 int f_v = (verbose_level >= 1);
346 long int r, h, a = 1, A;
347 int nb_free_cols = 0;
348 long int Q, b, c, i, j;
352
353 if (f_v) {
354 cout << "grassmann::unrank_lint " << rk << endl;
355 }
356 if (k == 0) {
357 return;
358 }
359 // null the first row:
360 Int_vec_zero(M, n);
361
362
363 // find out the value of h:
364 // h is the column of the pivot element in the first row
365 r = rk;
366 if (f_v) {
367 cout << "r=" << r << endl;
368 }
369 h = 0;
370 while (h < n) {
371 a = Combi.generalized_binomial(n - h - 1, k - 1, q);
372 if (f_v) {
373 cout << "[" << n - h - 1 << " choose " << k - 1
374 << "]_" << q << " = " << a << endl;
375 }
376 nb_free_cols = n - h - 1 - (k - 1);
377 Q = NT.i_power_j_lint(q, nb_free_cols);
378 if (f_v) {
379 cout << "Q=" << Q << endl;
380 }
381 A = a * Q;
382 if (f_v) {
383 cout << "A=" << A << endl;
384 }
385 if (r < A) {
386 break;
387 }
388 r -= A;
389 if (f_v) {
390 cout << "r=" << r << endl;
391 }
392 h++;
393 }
394 if (h == n) {
395 cout << "grassmann::unrank_lint h == n" << endl;
396 cout << "h=" << h << endl;
397 cout << "r=" << r << endl;
398 exit(1);
399 }
400
401 // now h has been determined
402 if (f_v) {
403 cout << "grassmann::unrank_lint " << rk << " h=" << h
404 << " nb_free_cols=" << nb_free_cols << endl;
405 }
406 base_cols[0] = h;
407 M[h] = 1;
408
409 // find out the coset number b and the rank c of the subspace:
410 b = r / a;
411 c = r % a;
412 if (f_v) {
413 cout << "r=" << r << " coset " << b
414 << " subspace rank " << c << endl;
415 }
416
417 // unrank the coset:
418 if (nb_free_cols) {
419 Gg.AG_element_unrank(q, coset, 1, nb_free_cols, b);
420 }
421 if (f_v) {
422 cout << "grassmann::unrank_lint coset " << b << " = ";
423 Int_vec_print(cout, coset, nb_free_cols);
424 cout << endl;
425 }
426
427 //unrank the subspace (if there is one)
428 if (k > 1) {
429 G->n = n - h - 1;
430 G->unrank_lint(c, verbose_level - 1);
431 for (j = 0; j < k - 1; j++) {
432 base_cols[j + 1] = G->base_cols[j] + h + 1;
433 }
434 }
435 if (f_v) {
436 cout << "grassmann::unrank_lint calling "
437 "int_vec_complement n=" << n << " k=" << k << " : ";
438 Int_vec_print(cout, base_cols, k);
439 cout << endl;
440 }
442
443 // fill in the coset:
444 if (k == 1) {
445 for (j = 0; j < nb_free_cols; j++) {
446 M[h + 1 + j] = coset[j];
447 }
448 }
449 else {
450 for (j = 0; j < nb_free_cols; j++) {
451 M[h + 1 + G->base_cols[G->k + j]] = coset[j];
452 }
453 }
454
455
456 // copy the subspace (rows i=1,..,k-1):
457 if (k > 1) {
458 for (i = 0; i < G->k; i++) {
459
460 // zero beginning:
461 for (j = 0; j <= h; j++) {
462 M[(1 + i) * n + j] = 0;
463 }
464
465 // the non-trivial part of the row:
466 for (j = 0; j < G->n; j++) {
467 M[(1 + i) * n + h + 1 + j] = G->M[i * G->n + j];
468 }
469 }
470 }
471 if (f_v) {
472 cout << "grassmann::unrank_lint " << rk << ", we found the matrix" << endl;
474 cout << "grassmann::unrank_lint base_cols = ";
475 Int_vec_print(cout, base_cols, k);
476 cout << endl;
477 cout << "grassmann::unrank_lint complement = ";
478 Int_vec_print(cout, base_cols + k, n - k);
479 cout << endl;
480 }
481 if (f_v) {
482 cout << "grassmann::unrank_lint " << rk << " finished" << endl;
483 }
484}
485
486long int grassmann::rank_lint(int verbose_level)
487{
488 int f_v = (verbose_level >= 1);
489 long int k1, r, h, a, A;
490 int nb_free_cols;
491 long int Q, b, c, i, j;
495
496 r = 0;
497 if (f_v) {
498 cout << "grassmann::rank_lint " << endl;
500 M, k, n, n, F->log10_of_q + 1);
501 }
502 if (k == 0) {
503 return 0;
504 }
505 k1 = F->Linear_algebra->Gauss_int(M, FALSE /*f_special */,
506 TRUE /* f_complete */, base_cols,
507 FALSE /* f_P */, NULL, k, n, n,
508 0 /* verbose_level */);
509
510 if (f_v) {
511 cout << "grassmann::rank_lint after Gauss:" << endl;
513 M, k, n, n, F->log10_of_q + 1);
514 }
515 if (k1 != k) {
516 cout << "grassmann::rank_lint error, does not have full rank" << endl;
517 exit(1);
518 }
519 if (f_v) {
520 cout << "grassmann::rank_lint base_cols: ";
521 Int_vec_print(cout, base_cols, k);
522 cout << endl;
523 }
524
525
526 if (f_v) {
527 cout << "grassmann::rank_lint calling int_vec_complement n=" << n
528 << " k=" << k << " : ";
529 Int_vec_print(cout, base_cols, k);
530 cout << endl;
531 }
533 if (f_v) {
534 cout << "grassmann::rank_lint complement : ";
535 Int_vec_print(cout, base_cols + k, n - k);
536 cout << endl;
537 }
538
539 for (h = 0; h < base_cols[0]; h++) {
540 nb_free_cols = n - h - 1 - (k - 1);
541 Q = NT.i_power_j(q, nb_free_cols);
542 a = Combi.generalized_binomial(n - h - 1, k - 1, q);
543 A = a * Q;
544 r += A;
545 }
546 nb_free_cols = n - h - 1 - (k - 1);
547 a = Combi.generalized_binomial(n - h - 1, k - 1, q);
548
549 // now h has been determined
550 if (f_v) {
551 cout << "grassmann::rank_lint h=" << h << " nb_free_cols="
552 << nb_free_cols << " r=" << r << endl;
553 }
554
555 // copy the subspace (rows i=1,..,k-1):
556 if (k > 1) {
557 G->n = n - h - 1;
558 for (i = 0; i < G->k; i++) {
559
560 // the non-trivial part of the row:
561 for (j = 0; j < G->n; j++) {
562 G->M[i * G->n + j] = M[(1 + i) * n + h + 1 + j];
563 }
564 }
565 }
566
567
568 // rank the subspace (if there is one)
569 if (k > 1) {
570 c = G->rank_lint(verbose_level - 1);
571 }
572 else {
573 c = 0;
574 }
575
576 // get in the coset:
577 if (k == 1) {
578 for (j = 0; j < nb_free_cols; j++) {
579 coset[j] = M[h + 1 + j];
580 }
581 }
582 else {
583 for (j = 0; j < nb_free_cols; j++) {
584 coset[j] = M[h + 1 + G->base_cols[G->k + j]];
585 }
586 }
587 // rank the coset:
588 if (nb_free_cols) {
589 b = Gg.AG_element_rank(q, coset, 1, nb_free_cols);
590 }
591 else {
592 b = 0;
593 }
594 if (f_v) {
595 cout << "grassmann::rank_lint coset " << b << " = ";
596 Int_vec_print(cout, coset, nb_free_cols);
597 cout << endl;
598 }
599
600
601 // compose the rank from the coset number b
602 // and the rank c of the subspace:
603 r += b * a + c;
604 if (f_v) {
605 cout << "grassmann::rank_lint b * a + c = " << b << " * "
606 << a << " + " << c << endl;
607 cout << "grassmann::rank_lint r=" << r << " coset " << b
608 << " subspace rank " << c << endl;
609 }
610 return r;
611}
612
614 ring_theory::longinteger_object &rk, int verbose_level)
615{
616 unrank_longinteger(rk, verbose_level);
617 Int_vec_copy(M, Mtx, k * n);
618}
619
621 ring_theory::longinteger_object &rk, int verbose_level)
622{
623 Int_vec_copy(Mtx, M, k * n);
624 rank_longinteger(rk, verbose_level);
625}
626
628 ring_theory::longinteger_object &rk, int verbose_level)
629{
630 int f_v = (verbose_level >= 1);
631 ring_theory::longinteger_object r, r1, a, A, mA, Q, b, c;
634 int i, j, h, nb_free_cols = 0;
636
637 if (f_v) {
638 cout << "unrank_longinteger " << rk << endl;
639 }
640 if (k == 0) {
641 return;
642 }
643 // null the first row:
644 for (j = 0; j < n; j++) {
645 M[j] = 0;
646 }
647
648
649 // find out the value of h:
650 rk.assign_to(r);
651 h = 0;
652 while (h < n) {
653 C.q_binomial(a, n - h - 1, k - 1, q, 0);
654 if (f_v) {
655 cout << "[" << n - h - 1 << " choose " << k - 1
656 << "]_" << q << " = " << a << endl;
657 }
658 nb_free_cols = n - h - 1 - (k - 1);
659 Q.create_i_power_j(q, nb_free_cols);
660 D.mult(a, Q, A);
661 //A = a * Q;
662 if (D.compare(r, A) < 0) {
663 break;
664 }
665 A.assign_to(mA);
666 mA.negate();
667 D.add(r, mA, r1);
668 r.swap_with(r1);
669 //r -= A;
670 h++;
671 }
672 if (h == n) {
673 cout << "grassmann::unrank_longinteger h == n" << endl;
674 exit(1);
675 }
676
677 // now h has been determined
678 if (f_v) {
679 cout << "grassmann::unrank_longinteger " << rk
680 << " h=" << h << " nb_free_cols=" << nb_free_cols << endl;
681 }
682 base_cols[0] = h;
683 M[h] = 1;
684
685 // find out the coset number b and the rank c of the subspace:
686 D.integral_division(r, a, b, c, 0);
687 //b = r / a;
688 //c = r % a;
689 if (f_v) {
690 cout << "r=" << r << " coset " << b
691 << " subspace rank " << c << endl;
692 }
693
694 // unrank the coset:
695 if (nb_free_cols) {
696 Gg.AG_element_unrank_longinteger(q, coset, 1, nb_free_cols, b);
697 }
698 if (f_v) {
699 cout << "grassmann::unrank_longinteger coset " << b << " = ";
700 Int_vec_print(cout, coset, nb_free_cols);
701 cout << endl;
702 }
703
704 //unrank the subspace (if there is one)
705 if (k > 1) {
706 G->n = n - h - 1;
707 G->unrank_longinteger(c, verbose_level - 1);
708 for (j = 0; j < k - 1; j++) {
709 base_cols[j + 1] = G->base_cols[j] + h + 1;
710 }
711 }
712 if (f_v) {
713 cout << "grassmann::unrank_longinteger calling "
714 "int_vec_complement n=" << n << " k=" << k << " : ";
715 Int_vec_print(cout, base_cols, k);
716 cout << endl;
717 }
719
720 // fill in the coset:
721 if (k == 1) {
722 for (j = 0; j < nb_free_cols; j++) {
723 M[h + 1 + j] = coset[j];
724 }
725 }
726 else {
727 for (j = 0; j < nb_free_cols; j++) {
728 M[h + 1 + G->base_cols[G->k + j]] = coset[j];
729 }
730 }
731
732
733 // copy the subspace (rows i=1,..,k-1):
734 if (k > 1) {
735 for (i = 0; i < G->k; i++) {
736
737 // zero beginning:
738 for (j = 0; j <= h; j++) {
739 M[(1 + i) * n + j] = 0;
740 }
741
742 // the non-trivial part of the row:
743 for (j = 0; j < G->n; j++) {
744 M[(1 + i) * n + h + 1 + j] = G->M[i * G->n + j];
745 }
746 }
747 }
748 if (f_v) {
749 cout << "unrank_longinteger " << rk
750 << ", we found the matrix" << endl;
752 cout << "grassmann::unrank_longinteger base_cols = ";
753 Int_vec_print(cout, base_cols, k);
754 cout << endl;
755 cout << "grassmann::unrank_longinteger complement = ";
756 Int_vec_print(cout, base_cols + k, n - k);
757 cout << endl;
758 }
759 if (f_v) {
760 cout << "unrank_longinteger " << rk << " finished" << endl;
761 }
762}
763
765 int verbose_level)
766{
767 int f_v = (verbose_level >= 1);
768 ring_theory::longinteger_object r1, a, A, Q, b, c, tmp1, tmp2;
771 int k1, nb_free_cols, h, i, j;
773
774 r.create(0, __FILE__, __LINE__);
775 if (f_v) {
776 cout << "grassmann::rank_longinteger " << endl;
778 }
779 if (k == 0) {
780 return;
781 }
782 k1 = F->Linear_algebra->Gauss_int(M, FALSE /*f_special */,
783 TRUE /* f_complete */, base_cols,
784 FALSE /* f_P */, NULL, k, n, n,
785 0 /* verbose_level */);
786
787 if (f_v) {
788 cout << "grassmann::rank_longinteger after Gauss:" << endl;
790 M, k, n, n, F->log10_of_q + 1);
791 }
792 if (k1 != k) {
793 cout << "grassmann::rank_longinteger error, does not have full rank" << endl;
794 exit(1);
795 }
796 if (f_v) {
797 cout << "grassmann::rank_longinteger base_cols: ";
798 Int_vec_print(cout, base_cols, k);
799 cout << endl;
800 }
801
802
803 if (f_v) {
804 cout << "grassmann::rank_longinteger calling int_vec_complement for ";
805 Int_vec_print(cout, base_cols, k);
806 cout << endl;
807 }
809 if (f_v) {
810 cout << "yields: ";
811 Int_vec_print(cout, base_cols + k, n - k);
812 cout << endl;
813 }
814
815 for (h = 0; h < base_cols[0]; h++) {
816 nb_free_cols = n - h - 1 - (k - 1);
817 Q.create_i_power_j(q, nb_free_cols);
818 if (f_v) {
819 cout << "create_i_power_j q=" << q
820 << " nb_free_cols=" << nb_free_cols
821 << " yields " << Q << endl;
822 }
823 C.q_binomial(a, n - h - 1, k - 1, q, 0);
824 if (f_v) {
825 cout << "q_binomial [" << n - h - 1 << "," << k - 1
826 << "]_" << q << " = " << a << endl;
827 }
828 D.mult(a, Q, A);
829 D.add(r, A, r1);
830 r.swap_with(r1);
831 }
832 nb_free_cols = n - h - 1 - (k - 1);
833 C.q_binomial(a, n - h - 1, k - 1, q, 0);
834 if (f_v) {
835 cout << "q_binomial [" << n - h - 1 << "," << k - 1
836 << "]_" << q << " = " << a << endl;
837 }
838
839 // now h has been determined
840 if (f_v) {
841 cout << "grassmann::rank_longinteger h=" << h
842 << " nb_free_cols=" << nb_free_cols
843 << " r=" << r << endl;
844 }
845
846 // copy the subspace (rows i=1,..,k-1):
847 if (k > 1) {
848 G->n = n - h - 1;
849 for (i = 0; i < G->k; i++) {
850
851 // the non-trivial part of the row:
852 for (j = 0; j < G->n; j++) {
853 G->M[i * G->n + j] = M[(1 + i) * n + h + 1 + j];
854 }
855 }
856 }
857
858
859 // rank the subspace (if there is one)
860 if (k > 1) {
861 G->rank_longinteger(c, verbose_level);
862 }
863 else {
864 c.create(0, __FILE__, __LINE__);
865 }
866 if (f_v) {
867 cout << "grassmann::rank_longinteger rank of subspace by induction is " << c << endl;
868 }
869
870 // get in the coset:
871 if (k == 1) {
872 for (j = 0; j < nb_free_cols; j++) {
873 coset[j] = M[h + 1 + j];
874 }
875 }
876 else {
877 for (j = 0; j < nb_free_cols; j++) {
878 coset[j] = M[h + 1 + G->base_cols[G->k + j]];
879 }
880 }
881 // rank the coset:
882 if (nb_free_cols) {
883 Gg.AG_element_rank_longinteger(q, coset, 1, nb_free_cols, b);
884 if (f_v) {
885 cout << "AG_element_rank_longinteger for coset ";
886 Int_vec_print(cout, coset, nb_free_cols);
887 cout << " yields " << b << endl;
888 }
889 }
890 else {
891 b.create(0, __FILE__, __LINE__);
892 }
893 if (f_v) {
894 cout << "grassmann::rank_longinteger coset " << b << " = ";
895 Int_vec_print(cout, coset, nb_free_cols);
896 cout << endl;
897 }
898
899
900 // compose the rank from the coset number b
901 // and the rank c of the subspace:
902 if (f_v) {
903 cout << "grassmann::rank_longinteger computing r:=" << r << " + " << b
904 << " * " << a << " + " << c << endl;
905 }
906 D.mult(b, a, tmp1);
907 if (f_v) {
908 cout << b << " * " << a << " = " << tmp1 << endl;
909 }
910 D.add(tmp1, c, tmp2);
911 if (f_v) {
912 cout << tmp1 << " + " << c << " = " << tmp2 << endl;
913 }
914 D.add(r, tmp2, r1);
915 r.swap_with(r1);
916 //r += b * a + c;
917 if (f_v) {
918 cout << "grassmann::rank_longinteger r=" << r << " coset " << b
919 << " subspace rank " << c << endl;
920 }
921}
922
924{
926}
927
928int grassmann::dimension_of_join(long int rk1, long int rk2, int verbose_level)
929{
930 int *A;
931 int i, r;
932
933 A = NEW_int(2 * k * n);
934 unrank_lint(rk1, 0);
935 for (i = 0; i < k * n; i++) {
936 A[i] = M[i];
937 }
938 unrank_lint(rk2, 0);
939 for (i = 0; i < k * n; i++) {
940 A[k * n + i] = M[i];
941 }
942 r = F->Linear_algebra->rank_of_rectangular_matrix(A, 2 * k, n, 0 /*verbose_level*/);
943 return r;
944}
945
947 int *Mtx, long int rk, int verbose_level)
948// Mtx must be n x n
949{
950 int f_v = (verbose_level >= 1);
951 int r, i;
952 int *base_cols;
953 int *embedding;
954
955 if (f_v) {
956 cout << "grassmann::unrank_lint_here_and_extend_basis" << endl;
957 }
958 unrank_lint(rk, verbose_level);
959 Int_vec_copy(M, Mtx, k * n);
961 embedding = base_cols + k;
963 base_cols, embedding, 0/*verbose_level*/);
964 if (r != k) {
965 cout << "r != k" << endl;
966 exit(1);
967 }
968 Int_vec_zero(Mtx + k * n, (n - k) * n);
969 for (i = 0; i < n - k; i++) {
970 Mtx[(k + i) * n + embedding[i]] = 1;
971 }
972
974 if (f_v) {
975 cout << "grassmann::unrank_lint_here_and_extend_basis done" << endl;
976 }
977}
978
980 int *Mtx, long int rk, int verbose_level)
981// Mtx must be n x n
982{
983 int f_v = (verbose_level >= 1);
984 int r;
985 int *base_cols; // [n]
986 //int *embedding;
987
988 if (f_v) {
989 cout << "grassmann::unrank_int_here_and_compute_perp" << endl;
990 }
991 unrank_lint(rk, verbose_level);
992 Int_vec_copy(M, Mtx, k * n);
994 //embedding = base_cols + k;
995 r = F->Linear_algebra->RREF_and_kernel(n, k, Mtx, 0 /* verbose_level */);
996 if (r != k) {
997 cout << "r != k" << endl;
998 exit(1);
999 }
1000
1002 if (f_v) {
1003 cout << "grassmann::unrank_int_here_and_compute_perp done" << endl;
1004 }
1005}
1006
1008 long int *&regulus, int &regulus_size, int f_opposite, int verbose_level)
1009// the equation of the hyperboloid is x_0x_3-x_1x_2 = 0
1010{
1011 int f_v = (verbose_level >= 1);
1012 int f_vv = (verbose_level >= 2);
1013 int f_v3 = (verbose_level >= 3);
1014 int u, a;
1015 int M[8];
1016
1017 if (f_v) {
1018 cout << "grassmann::line_regulus_in_PG_3_q" << endl;
1019 }
1020 if (n != 4) {
1021 cout << "grassmann::line_regulus_in_PG_3_q n != 4" << endl;
1022 exit(1);
1023 }
1024 if (k != 2) {
1025 cout << "grassmann::line_regulus_in_PG_3_q k != 2" << endl;
1026 exit(1);
1027 }
1028 regulus_size = q + 1;
1029 regulus = NEW_lint(regulus_size);
1030 // the equation of the hyperboloid is x_0x_3-x_1x_2 = 0
1031 for (u = 0; u < regulus_size; u++) {
1032 Int_vec_zero(M, 8);
1033 if (u == 0) {
1034
1035 if (f_opposite) {
1036 // create the infinity component, which is
1037 // [0,1,0,0]
1038 // [0,0,0,1]
1039 M[0 * 4 + 1] = 1;
1040 M[1 * 4 + 3] = 1;
1041 }
1042 else {
1043 // create the infinity component, which is
1044 // [0,0,1,0]
1045 // [0,0,0,1]
1046 M[0 * 4 + 2] = 1;
1047 M[1 * 4 + 3] = 1;
1048 }
1049 }
1050 else {
1051 if (f_opposite) {
1052 // create
1053 // [1,a,0,0]
1054 // [0,0,1,a]
1055 a = u - 1;
1056 M[0 * 4 + 0] = 1;
1057 M[0 * 4 + 1] = a;
1058 M[1 * 4 + 2] = 1;
1059 M[1 * 4 + 3] = a;
1060 }
1061 else {
1062 // create
1063 // [1,0,a,0]
1064 // [0,1,0,a]
1065 a = u - 1;
1066 M[0 * 4 + 0] = 1;
1067 M[1 * 4 + 1] = 1;
1068 M[0 * 4 + 2] = a;
1069 M[1 * 4 + 3] = a;
1070 }
1071 }
1072
1073 if (f_v3) {
1074 cout << "grassmann::line_regulus_in_PG_3_q "
1075 "regulus element " << u << ":" << endl;
1076 Int_matrix_print(M, 2, 4);
1077 }
1078 regulus[u] = rank_lint_here(M, 0);
1079
1080 } // next u
1081 if (f_vv) {
1082 cout << "grassmann::line_regulus_in_PG_3_q regulus:" << endl;
1083 Lint_vec_print(cout, regulus, regulus_size);
1084 cout << endl;
1085 }
1086 if (f_v) {
1087 cout << "grassmann::line_regulus_in_PG_3_q done" << endl;
1088 }
1089}
1090
1091void grassmann::compute_dual_line_idx(int *&dual_line_idx,
1092 int *&self_dual_lines, int &nb_self_dual_lines,
1093 int verbose_level)
1094{
1095 int f_v = (verbose_level >= 1);
1096 int f_vv = (verbose_level >= 1);
1097 int *Basis;
1098 int nb_lines;
1099 int a, b;
1100
1101 if (f_v) {
1102 cout << "grassmann::compute_dual_line_idx" << endl;
1103 }
1104 if (2 * k != n) {
1105 cout << "grassmann::compute_dual_line_idx need 2 * k == n" << endl;
1106 exit(1);
1107 }
1108 nb_lines = nCkq->as_int();
1109 Basis = NEW_int(n * n);
1110 dual_line_idx = NEW_int(nb_lines);
1111 self_dual_lines = NEW_int(nb_lines);
1112
1113 nb_self_dual_lines = 0;
1114 for (a = 0; a < nb_lines; a++) {
1115 unrank_lint_here(Basis, a, 0/*verbose_level - 4*/);
1116 if (f_vv) {
1117 cout << "line " << a << " / " << nb_lines << ":" << endl;
1118 cout << "line is generated by" << endl;
1119 Int_matrix_print(Basis, k, n);
1120 }
1121 F->Linear_algebra->perp_standard(n, k, Basis, 0 /*verbose_level*/);
1122 if (f_vv) {
1123 cout << "after perp:" << endl;
1124 Int_matrix_print(Basis, n, n);
1125 }
1126 b = rank_lint_here(Basis + k * n, 0/*verbose_level - 4*/);
1127 if (f_vv) {
1128 cout << "line " << a << " / " << nb_lines
1129 << " the dual is " << b << endl;
1130 cout << "dual line is generated by" << endl;
1131 Int_matrix_print(Basis + k * n, k, n);
1132 }
1133 dual_line_idx[a] = b;
1134 if (b == a) {
1135 self_dual_lines[nb_self_dual_lines++] = a;
1136 }
1137 }
1138 if (f_v) {
1139 cout << "grassmann::compute_dual_line_idx done" << endl;
1140 }
1141}
1142
1144 int *spread, int *dual_spread, int spread_size,
1145 int verbose_level)
1146{
1147 int f_v = (verbose_level >= 1);
1148 int f_vv = (verbose_level >= 5);
1149 int *Basis;
1150 int i, a, b;
1151
1152 if (f_v) {
1153 cout << "grassmann::compute_dual_spread" << endl;
1154 }
1155 if (2 * k != n) {
1156 cout << "grassmann::compute_dual_spread, need 2 * k == n" << endl;
1157 exit(1);
1158 }
1159 //Basis = NEW_int(n * n);
1160 Basis = M2;
1161 if (f_v) {
1162 cout << "grassmann::compute_dual_spread The spread is : ";
1163 Int_vec_print(cout, spread, spread_size);
1164 cout << endl;
1165 }
1166 for (i = 0; i < spread_size; i++) {
1167 a = spread[i];
1168 unrank_lint_here(Basis, a, 0/*verbose_level - 4*/);
1169 if (f_vv) {
1170 cout << i << "-th Line has rank " << a
1171 << " and is generated by" << endl;
1172 Int_matrix_print(Basis, k, n);
1173 }
1174 F->Linear_algebra->perp_standard(n, k, Basis, 0 /*verbose_level*/);
1175 if (f_vv) {
1176 cout << "after perp:" << endl;
1177 Int_matrix_print(Basis, n, n);
1178 }
1179 b = rank_lint_here(Basis + k * n, 0/*verbose_level - 4*/);
1180 if (f_vv) {
1181 cout << i << "-th Line dual has rank " << b
1182 << " and is generated by" << endl;
1183 Int_matrix_print(Basis + k * n, k, n);
1184 }
1185 dual_spread[i] = b;
1186 }
1187 if (f_v) {
1188 cout << "grassmann::compute_dual_spread The dual spread is : ";
1189 Int_vec_print(cout, dual_spread, spread_size);
1190 cout << endl;
1191 }
1192
1193 //FREE_int(Basis);
1194 if (f_v) {
1195 cout << "grassmann::compute_dual_spread done" << endl;
1196 }
1197}
1198
1199
1200void grassmann::latex_matrix(ostream &ost, int *p)
1201{
1202
1203 F->print_matrix_latex(ost, p, k, n);
1204
1205}
1206
1207void grassmann::latex_matrix_numerical(ostream &ost, int *p)
1208{
1209
1210 F->print_matrix_numerical_latex(ost, p, k, n);
1211
1212}
1213
1214void grassmann::create_Schlaefli_graph(int *&Adj, int &sz, int verbose_level)
1215{
1216 int f_v = (verbose_level >= 1);
1217
1218 if (f_v) {
1219 cout << "grassmann::create_Schlaefli_graph" << endl;
1220 }
1221
1222 long int i, j, N;
1223 int rr;
1224 int *M1;
1225 int *M2;
1226 int *M;
1227 int v[2];
1228 int w[4];
1229 int *List;
1231
1232
1233 M1 = NEW_int(k * n);
1234 M2 = NEW_int(k * n);
1235 M = NEW_int(2 * k * n);
1236
1237 N = Combi.generalized_binomial(n, k, q);
1238
1239 List = NEW_int(N);
1240 sz = 0;
1241
1242 for (i = 0; i < N; i++) {
1243 unrank_lint_here(M1, i, 0 /* verbose_level */);
1244
1245 for (j = 0; j < q + 1; j++) {
1248 if (F->evaluate_Fermat_cubic(w)) {
1249 break;
1250 }
1251 }
1252 if (j == q + 1) {
1253 List[sz++] = i;
1254 }
1255 }
1256 if (f_v) {
1257 cout << "create_graph::create_Schlaefli We found " << sz << " lines on the surface" << endl;
1258 }
1259
1260
1261 Adj = NEW_int(sz * sz);
1262 Int_vec_zero(Adj, sz * sz);
1263
1264 for (i = 0; i < sz; i++) {
1265 unrank_lint_here(M1, List[i], 0 /* verbose_level */);
1266
1267 for (j = i + 1; j < sz; j++) {
1268 unrank_lint_here(M2, List[j], 0 /* verbose_level */);
1269
1270 Int_vec_copy(M1, M, k * n);
1271 Int_vec_copy(M2, M + k * n, k * n);
1272
1273 rr = F->Linear_algebra->rank_of_rectangular_matrix(M, 2 * k, n, 0 /* verbose_level */);
1274 if (rr == 2 * k) {
1275 Adj[i * sz + j] = 1;
1276 Adj[j * sz + i] = 1;
1277 }
1278 }
1279 }
1280
1281
1282 FREE_int(List);
1283 FREE_int(M1);
1284 FREE_int(M2);
1285 FREE_int(M);
1286 if (f_v) {
1287 cout << "grassmann::create_Schlaefli_graph done" << endl;
1288 }
1289
1290}
1291
1292long int grassmann::make_special_element_zero(int verbose_level)
1293{
1294 int f_v = (verbose_level >= 1);
1295 int f_v3 = (verbose_level >= 3);
1296 long int a;
1297
1298 if (f_v) {
1299 cout << "grassmann::make_special_element_zero" << endl;
1300 }
1301
1302 int i;
1303
1304 // make the element (I_k | 0).
1305 // Let a be its rank
1306 Int_vec_zero(M, k * n);
1307 for (i = 0; i < k; i++) {
1308 M[i * n + i] = 1;
1309 }
1310 if (f_v3) {
1311 cout << "grassmann::make_special_element_zero M:" << endl;
1313 }
1314 a = rank_lint(0/*verbose_level - 4*/);
1315 if (f_v3) {
1316 cout << "grassmann::make_special_element_zero a=" << a << endl;
1317 }
1318 return a;
1319}
1320
1321long int grassmann::make_special_element_one(int verbose_level)
1322{
1323 int f_v = (verbose_level >= 1);
1324 int f_v3 = (verbose_level >= 3);
1325 long int a;
1326
1327 if (f_v) {
1328 cout << "grassmann::make_special_element_one" << endl;
1329 }
1330
1331 int i;
1332
1333 // make the element (I_k | I_k).
1334 // Let a be its rank
1335 Int_vec_zero(M, k * n);
1336 for (i = 0; i < k; i++) {
1337 M[i * n + i] = 1;
1338 M[i * n + k + i] = 1;
1339 }
1340 if (f_v3) {
1341 cout << "grassmann::make_special_element_one M:" << endl;
1343 }
1344 a = rank_lint(0/*verbose_level - 4*/);
1345 if (f_v3) {
1346 cout << "grassmann::make_special_element_one a=" << a << endl;
1347 }
1348 return a;
1349}
1350
1352{
1353 int f_v = (verbose_level >= 1);
1354 int f_v3 = (verbose_level >= 3);
1355 long int a;
1356
1357 if (f_v) {
1358 cout << "grassmann::make_special_element_infinity" << endl;
1359 }
1360
1361 int i;
1362
1363 // make the element (I_k | I_k).
1364 // Let a be its rank
1365 Int_vec_zero(M, k * n);
1366 for (i = 0; i < k; i++) {
1367 M[i * n + k + i] = 1;
1368 }
1369 if (f_v3) {
1370 cout << "grassmann::make_special_element_infinity M:" << endl;
1372 }
1373 a = rank_lint(0/*verbose_level - 4*/);
1374 if (f_v3) {
1375 cout << "grassmann::make_special_element_infinity a=" << a << endl;
1376 }
1377 return a;
1378}
1379
1380
1381}}}
1382
1383
1384
1385
1386
1387
void q_binomial(ring_theory::longinteger_object &a, int n, int k, int q, int verbose_level)
void print_matrix_latex(std::ostream &ost, int *A, int m, int n)
void print_matrix_numerical_latex(std::ostream &ost, int *A, int m, int n)
void PG_element_unrank_modified(int *v, int stride, int len, int a)
void PG_element_rank_modified_lint(int *v, int stride, int len, long int &a)
various functions related to geometries
Definition: geometry.h:721
void AG_element_unrank(int q, int *v, int stride, int len, long int a)
void AG_element_rank_longinteger(int q, int *v, int stride, int len, ring_theory::longinteger_object &a)
void AG_element_unrank_longinteger(int q, int *v, int stride, int len, ring_theory::longinteger_object &a)
long int AG_element_rank(int q, int *v, int stride, int len)
to rank and unrank subspaces of a fixed dimension in F_q^n
Definition: geometry.h:892
void print_set_tex_with_perp(std::ostream &ost, long int *v, int len)
Definition: grassmann.cpp:202
void create_Schlaefli_graph(int *&Adj, int &sz, int verbose_level)
Definition: grassmann.cpp:1214
long int make_special_element_infinity(int verbose_level)
Definition: grassmann.cpp:1351
void unrank_longinteger(ring_theory::longinteger_object &rk, int verbose_level)
Definition: grassmann.cpp:627
void unrank_longinteger_here(int *Mtx, ring_theory::longinteger_object &rk, int verbose_level)
Definition: grassmann.cpp:613
long int nb_of_subspaces(int verbose_level)
Definition: grassmann.cpp:113
long int make_special_element_one(int verbose_level)
Definition: grassmann.cpp:1321
void unrank_lint(long int rk, int verbose_level)
Definition: grassmann.cpp:343
void unrank_embedded_subspace_lint_here(int *Basis, long int rk, int verbose_level)
Definition: grassmann.cpp:318
void unrank_lint_here_and_compute_perp(int *Mtx, long int rk, int verbose_level)
Definition: grassmann.cpp:979
ring_theory::longinteger_object * nCkq
Definition: geometry.h:895
void latex_matrix_numerical(std::ostream &ost, int *p)
Definition: grassmann.cpp:1207
void rank_longinteger(ring_theory::longinteger_object &r, int verbose_level)
Definition: grassmann.cpp:764
void line_regulus_in_PG_3_q(long int *&regulus, int &regulus_size, int f_opposite, int verbose_level)
Definition: grassmann.cpp:1007
long int rank_embedded_subspace_lint(int verbose_level)
Definition: grassmann.cpp:305
void latex_matrix(std::ostream &ost, int *p)
Definition: grassmann.cpp:1200
void compute_dual_line_idx(int *&dual_line_idx, int *&self_dual_lines, int &nb_self_dual_lines, int verbose_level)
Definition: grassmann.cpp:1091
void print_set_tex(std::ostream &ost, long int *v, int len)
Definition: grassmann.cpp:157
long int rank_lint_here(int *Mtx, int verbose_level)
Definition: grassmann.cpp:275
void rank_longinteger_here(int *Mtx, ring_theory::longinteger_object &rk, int verbose_level)
Definition: grassmann.cpp:620
int dimension_of_join(long int rk1, long int rk2, int verbose_level)
Definition: grassmann.cpp:928
void print_single_generator_matrix_tex_numerical(std::ostream &ost, long int a)
Definition: grassmann.cpp:135
void compute_dual_spread(int *spread, int *dual_spread, int spread_size, int verbose_level)
Definition: grassmann.cpp:1143
void unrank_embedded_subspace_lint(long int rk, int verbose_level)
Definition: grassmann.cpp:281
void unrank_lint_here(int *Mtx, long int rk, int verbose_level)
Definition: grassmann.cpp:269
void init(int n, int k, field_theory::finite_field *F, int verbose_level)
Definition: grassmann.cpp:70
long int make_special_element_zero(int verbose_level)
Definition: grassmann.cpp:1292
void unrank_lint_here_and_extend_basis(int *Mtx, long int rk, int verbose_level)
Definition: grassmann.cpp:946
void points_covered(long int *the_points, int verbose_level)
Definition: grassmann.cpp:255
void print_single_generator_matrix_tex(std::ostream &ost, long int a)
Definition: grassmann.cpp:122
void mult_vector_from_the_left(int *v, int *A, int *vA, int m, int n)
int Gauss_int(int *A, int f_special, int f_complete, int *base_cols, int f_P, int *P, int m, int n, int Pn, int verbose_level)
int base_cols_and_embedding(int m, int n, int *A, int *base_cols, int *embedding, int verbose_level)
int RREF_and_kernel(int n, int k, int *A, int verbose_level)
int rank_of_rectangular_matrix(int *A, int m, int n, int verbose_level)
int perp_standard(int n, int k, int *A, int verbose_level)
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
int compare(longinteger_object &a, longinteger_object &b)
void add(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void mult(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void integral_division(longinteger_object &a, longinteger_object &b, longinteger_object &q, longinteger_object &r, int verbose_level)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define Int_vec_print_integer_matrix_width(A, B, C, D, E, F)
Definition: foundations.h:691
#define Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects