Orbiter 2022
Combinatorial Objects
linear_algebra_global.cpp
Go to the documentation of this file.
1/*
2 * linear_algebra_global.cpp
3 *
4 * Created on: Jan 10, 2022
5 * Author: betten
6 */
7
8
9
10
11
12
13#include "foundations.h"
14
15using namespace std;
16
17
18
19namespace orbiter {
20namespace layer1_foundations {
21namespace linear_algebra {
22
23
25{
26
27}
28
30{
31
32}
33
34
35
38 std::string &Berlekamp_matrix_coeffs,
39 int verbose_level)
40{
41 int f_v = (verbose_level >= 1);
42
43 if (f_v) {
44 cout << "linear_algebra_global::Berlekamp_matrix" << endl;
45 }
46
47 int *data_A;
48 int sz_A;
49
50
51 orbiter_kernel_system::Orbiter->get_vector_from_label(Berlekamp_matrix_coeffs, data_A, sz_A, verbose_level);
52
53
55
56
57
58
61
62
63 int da = sz_A - 1;
64 int i;
65
67
68 for (i = 0; i <= da; i++) {
69 if (data_A[i] < 0 || data_A[i] >= F->q) {
70 data_A[i] = NT.mod(data_A[i], F->q);
71 }
72 FX.s_i(A, i) = data_A[i];
73 }
74
75
76
77 if (f_v) {
78 cout << "A(X)=";
79 FX.print_object(A, cout);
80 cout << endl;
81 }
82
83
84 int *B;
85 int r;
86
87
88
89 if (f_v) {
90 cout << "linear_algebra_global::Berlekamp_matrix before FX.Berlekamp_matrix" << endl;
91 }
92
93 {
94 FX.Berlekamp_matrix(B, A, verbose_level);
95 }
96
97 if (f_v) {
98 cout << "linear_algebra_global::Berlekamp_matrix after FX.Berlekamp_matrix" << endl;
99 }
100
101 if (f_v) {
102 cout << "B=" << endl;
103 Int_matrix_print(B, da, da);
104 cout << endl;
105 }
106
107 r = F->Linear_algebra->rank_of_matrix(B, da, 0 /* verbose_level */);
108
109 if (f_v) {
110 cout << "The matrix B has rank " << r << endl;
111 }
112
113 FREE_int(B);
114
115 if (f_v) {
116 cout << "linear_algebra_global::Berlekamp_matrix done" << endl;
117 }
118}
119
120
121
122
125 int d, int verbose_level)
126{
127 int f_v = (verbose_level >= 1);
129
130 if (f_v) {
131 cout << "linear_algebra_global::compute_normal_basis "
132 << " q=" << F->q << endl;
133 cout << "verbose_level=" << verbose_level << endl;
134 }
135
136
138
139 string poly;
141
142 K.get_primitive_polynomial(poly, F->q, d, 0 /* verbose_level */);
143
144 if (f_v) {
145 cout << "linear_algebra_global::compute_normal_basis "
146 "chosen irreducible polynomial is " << poly << endl;
147 }
148
153
154
155 FX.create_object_by_rank_string(m, poly, 0 /* verbose_level */);
156
157 if (f_v) {
158 cout << "linear_algebra_global::compute_normal_basis "
159 "chosen irreducible polynomial m = ";
160 FX.print_object(m, cout);
161 cout << endl;
162 }
163
164 FX.create_object_by_rank(g, 0, __FILE__, __LINE__, 0 /* verbose_level */);
165 FX.create_object_by_rank(minpol, 0, __FILE__, __LINE__, 0 /* verbose_level */);
166
167 int *Frobenius;
168 int *Normal_basis;
169
170 //Frobenius = NEW_int(d * d);
171 Normal_basis = NEW_int(d * d);
172
173 if (f_v) {
174 cout << "linear_algebra_global::compute_normal_basis "
175 "before FX.Frobenius_matrix" << endl;
176 }
177 FX.Frobenius_matrix(Frobenius, m, verbose_level - 2);
178 if (f_v) {
179 cout << "linear_algebra_global::compute_normal_basis "
180 "Frobenius_matrix = " << endl;
181 Int_matrix_print(Frobenius, d, d);
182 cout << endl;
183 }
184
185 if (f_v) {
186 cout << "linear_algebra_global::compute_normal_basis "
187 "before compute_normal_basis" << endl;
188 }
189
190 FX.compute_normal_basis(d, Normal_basis, Frobenius, verbose_level - 1);
191
192 if (f_v) {
193 cout << "linear_algebra_global::compute_normal_basis "
194 "Normal_basis = " << endl;
195 Int_matrix_print(Normal_basis, d, d);
196 cout << endl;
197 }
198
199 if (f_v) {
200 cout << "linear_algebra_global::compute_normal_basis done" << endl;
201 }
202}
203
204
207 int *M, int m, int n,
208 int f_normalize_from_the_left, int f_normalize_from_the_right,
209 int verbose_level)
210{
211 int f_v = (verbose_level >= 1);
212 int *A;
213 int *base_cols;
214 int rk, i, rk1;
215
217
218 if (f_v) {
219 cout << "linear_algebra_global::do_nullspace" << endl;
220 }
221
222
223 A = NEW_int(n * n);
224 base_cols = NEW_int(n);
225 Int_vec_copy(M, A, m * n);
226
227 if (f_v) {
228 cout << "linear_algebra_global::do_nullspace before Linear_algebra->perp_standard" << endl;
229 }
230
231 rk = F->Linear_algebra->perp_standard(n, m, A, 0 /*verbose_level*/);
232
233 if (f_v) {
234 cout << "linear_algebra_global::do_nullspace after Linear_algebra->perp_standard" << endl;
235 }
236
237
238 if (f_v) {
239 cout << "linear_algebra_global::do_nullspace after perp_standard:" << endl;
240 Int_matrix_print(A, n, n);
241 cout << "rk=" << rk << endl;
242 }
243
244 rk1 = F->Linear_algebra->Gauss_int(A + rk * n,
245 FALSE /* f_special */, TRUE /* f_complete */, base_cols,
246 FALSE /* f_P */, NULL /*P*/, n - rk, n, n,
247 0 /*verbose_level*/);
248
249
250 if (f_v) {
251 cout << "linear_algebra_global::do_nullspace after RREF" << endl;
252 Int_matrix_print(A + rk * n, rk1, n);
253 cout << "rank of nullspace = " << rk1 << endl;
254
255 cout << "linear_algebra_global::do_nullspace coefficients:" << endl;
256 Int_vec_print_fully(cout, A + rk * n, rk1 * n);
257 cout << endl;
258
259 cout << "$$" << endl;
260 cout << "\\left[" << endl;
261 Li.int_matrix_print_tex(cout, A + rk * n, rk1, n);
262 cout << "\\right]" << endl;
263 cout << "$$" << endl;
264 }
265
266 if (f_normalize_from_the_left) {
267 if (f_v) {
268 cout << "linear_algebra_global::do_nullspace normalizing from the left" << endl;
269 }
270 for (i = rk; i < n; i++) {
271 F->PG_element_normalize_from_front(A + i * n, 1, n);
272 }
273
274 if (f_v) {
275 cout << "linear_algebra_global::do_nullspace after normalize from the left:" << endl;
276 Int_matrix_print(A, n, n);
277 cout << "rk=" << rk << endl;
278
279 cout << "$$" << endl;
280 cout << "\\left[" << endl;
281 Li.int_matrix_print_tex(cout, A + rk * n, rk1, n);
282 cout << "\\right]" << endl;
283 cout << "$$" << endl;
284 }
285 }
286
287 if (f_normalize_from_the_right) {
288 if (f_v) {
289 cout << "linear_algebra_global::do_nullspace normalizing from the right" << endl;
290 }
291 for (i = rk; i < n; i++) {
292 F->PG_element_normalize(A + i * n, 1, n);
293 }
294
295 if (f_v) {
296 cout << "linear_algebra_global::do_nullspace after normalize from the right:" << endl;
297 Int_matrix_print(A, n, n);
298 cout << "rk=" << rk << endl;
299
300 cout << "$$" << endl;
301 cout << "\\left[" << endl;
302 Li.int_matrix_print_tex(cout, A + rk * n, rk1, n);
303 cout << "\\right]" << endl;
304 cout << "$$" << endl;
305 }
306 }
307
308
309 {
310 char str[1000];
311 string fname;
312 char title[1000];
313 char author[1000];
314
315 snprintf(str, 1000, "nullspace_%d_%d.tex", m, n);
316 fname.assign(str);
317 snprintf(title, 1000, "Nullspace");
318 //strcpy(author, "");
319 author[0] = 0;
320
321
322 {
323 ofstream ost(fname);
325
326 L.head(ost,
327 FALSE /* f_book*/,
328 TRUE /* f_title */,
329 title, author,
330 FALSE /* f_toc */,
331 FALSE /* f_landscape */,
332 TRUE /* f_12pt */,
333 TRUE /* f_enlarged_page */,
334 TRUE /* f_pagenumbers */,
335 NULL /* extra_praeamble */);
336
337
338 if (f_v) {
339 cout << "linear_algebra_global::do_nullspace before report" << endl;
340 }
341 //report(ost, verbose_level);
342
343 ost << "\\noindent Input matrix:" << endl;
344 ost << "$$" << endl;
345 ost << "\\left[" << endl;
346 Li.int_matrix_print_tex(ost, M, m, n);
347 ost << "\\right]" << endl;
348 ost << "$$" << endl;
349
350 ost << "RREF:" << endl;
351 ost << "$$" << endl;
352 ost << "\\left[" << endl;
353 Li.int_matrix_print_tex(ost, A, rk, n);
354 ost << "\\right]" << endl;
355 ost << "$$" << endl;
356
357 ost << "Basis for Perp:" << endl;
358 ost << "$$" << endl;
359 ost << "\\left[" << endl;
360 Li.int_matrix_print_tex(ost, A + rk * n, rk1, n);
361 ost << "\\right]" << endl;
362 ost << "$$" << endl;
363
364
365 if (f_v) {
366 cout << "linear_algebra_global::do_nullspace after report" << endl;
367 }
368
369
370 L.foot(ost);
371
372 }
374
375 cout << "linear_algebra_global::do_nullspace written file " << fname << " of size "
376 << Fio.file_size(fname) << endl;
377 }
378
379
380
381
382 FREE_int(A);
383 FREE_int(base_cols);
384
385 if (f_v) {
386 cout << "linear_algebra_global::do_nullspace done" << endl;
387 }
388}
389
392 int *M, int m, int n,
393 int f_normalize_from_the_left, int f_normalize_from_the_right,
394 int verbose_level)
395{
396 int f_v = (verbose_level >= 1);
397 int *A;
398 int *base_cols;
399 int rk, i;
401
402 if (f_v) {
403 cout << "linear_algebra_global::do_RREF" << endl;
404 }
405
406
407
408 A = NEW_int(n * n);
409 base_cols = NEW_int(n);
410 Int_vec_copy(M, A, m * n);
411 if (f_v) {
412 cout << "linear_algebra_global::do_RREF input matrix A:" << endl;
413 Int_matrix_print(A, m, n);
414 }
415
416 rk = F->Linear_algebra->Gauss_int(A,
417 FALSE /* f_special */, TRUE /* f_complete */, base_cols,
418 FALSE /* f_P */, NULL /*P*/, m, n, n,
419 0 /*verbose_level*/);
420
421
422 if (f_v) {
423 cout << "linear_algebra_global::do_RREF after RREF:" << endl;
424 Int_matrix_print(A, rk, n);
425 cout << "rk=" << rk << endl;
426
427 cout << "coefficients:" << endl;
428 Int_vec_print(cout, A, rk * n);
429 cout << endl;
430
431 cout << "$$" << endl;
432 cout << "\\left[" << endl;
433 Li.int_matrix_print_tex(cout, A, rk, n);
434 cout << "\\right]" << endl;
435 cout << "$$" << endl;
436 }
437
438
439
440 if (f_normalize_from_the_left) {
441 if (f_v) {
442 cout << "normalizing from the left" << endl;
443 }
444 for (i = 0; i < rk; i++) {
445 F->PG_element_normalize_from_front(A + i * n, 1, n);
446 }
447
448 if (f_v) {
449 cout << "after normalize from the left:" << endl;
450 Int_matrix_print(A, rk, n);
451 cout << "rk=" << rk << endl;
452 }
453 }
454
455 if (f_normalize_from_the_right) {
456 if (f_v) {
457 cout << "normalizing from the right" << endl;
458 }
459 for (i = 0; i < rk; i++) {
460 F->PG_element_normalize(A + i * n, 1, n);
461 }
462
463 if (f_v) {
464 cout << "after normalize from the right:" << endl;
465 Int_matrix_print(A, rk, n);
466 cout << "rk=" << rk << endl;
467 }
468 }
469
470
471 Int_vec_copy(M, A, m * n);
472
473 RREF_demo(F, A, m, n, verbose_level);
474
475
476
477 FREE_int(A);
478 FREE_int(base_cols);
479
480 if (f_v) {
481 cout << "linear_algebra_global::do_RREF done" << endl;
482 }
483}
484
487 int *A, int m, int n, int verbose_level)
488{
489 int f_v = (verbose_level >= 1);
490
491 if (f_v) {
492 cout << "linear_algebra_global::RREF_demo" << endl;
493 }
494
495
496 {
497 char str[1000];
498 string fname;
499 char title[1000];
500 char author[1000];
501
502 snprintf(str, 1000, "RREF_example_q%d_%d_%d.tex", F->q, m, n);
503 fname.assign(str);
504 snprintf(title, 1000, "RREF example $q=%d$", F->q);
505 //strcpy(author, "");
506 author[0] = 0;
507
508
509 {
510 ofstream ost(fname);
512
513 L.head(ost,
514 FALSE /* f_book*/,
515 TRUE /* f_title */,
516 title, author,
517 FALSE /* f_toc */,
518 FALSE /* f_landscape */,
519 TRUE /* f_12pt */,
520 TRUE /* f_enlarged_page */,
521 FALSE /* f_pagenumbers */,
522 NULL /* extra_praeamble */);
523
524
525 if (f_v) {
526 cout << "linear_algebra_global::RREF_demo before RREF_with_steps_latex" << endl;
527 }
528 RREF_with_steps_latex(F, ost, A, m, n, verbose_level);
529 if (f_v) {
530 cout << "linear_algebra_global::RREF_demo after RREF_with_steps_latex" << endl;
531 }
532
533
534 L.foot(ost);
535
536 }
538
539 cout << "written file " << fname << " of size "
540 << Fio.file_size(fname) << endl;
541 }
542
543
544 if (f_v) {
545 cout << "linear_algebra_global::RREF_demo done" << endl;
546 }
547}
548
551 std::ostream &ost, int *A, int m, int n, int verbose_level)
552{
553 int f_v = (verbose_level >= 1);
554 int *base_cols;
555 int i, j, rk;
557 int cnt = 0;
558
559 if (f_v) {
560 cout << "linear_algebra_global::RREF_with_steps_latex" << endl;
561 }
562
563
564 ost << "{\\bf \\Large" << endl;
565
566 ost << endl;
567 //ost << "\\clearpage" << endl;
568 //ost << "\\vspace*{\\fill}" << endl;
569 ost << endl;
570
571 ost << "\\noindent A matrix over the field ${\\mathbb F}_{" << F->q << "}$\\\\" << endl;
572 ost << "$$" << endl;
573 ost << "\\left[" << endl;
574 Li.int_matrix_print_tex(ost, A, m, n);
575 ost << "\\right]" << endl;
576 ost << "$$" << endl;
577 cnt++;
578 if ((cnt % 3) == 0) {
579 ost << endl;
580 //ost << "\\clearpage" << endl;
581 ost << endl;
582 }
583
584 base_cols = NEW_int(n);
585
586 i = 0;
587 j = 0;
588 while (TRUE) {
589 if (F->Linear_algebra->RREF_search_pivot(A, m, n,
590 i, j, base_cols, verbose_level)) {
591 ost << "\\noindent Position $(i,j)=(" << i << "," << j << "),$ found pivot in column " << base_cols[i] << "\\\\" << endl;
592 ost << "$$" << endl;
593 ost << "\\left[" << endl;
594 Li.int_matrix_print_tex(ost, A, m, n);
595 ost << "\\right]" << endl;
596 ost << "$$" << endl;
597 cnt++;
598 if ((cnt % 3) == 0) {
599 ost << endl;
600 //ost << "\\clearpage" << endl;
601 //ost << "\\vspace*{\\fill}" << endl;
602 ost << endl;
603 }
604
605
606 F->Linear_algebra->RREF_make_pivot_one(A, m, n, i, j, base_cols, verbose_level);
607 ost << "\\noindent After making pivot 1:\\\\" << endl;
608 ost << "$$" << endl;
609 ost << "\\left[" << endl;
610 Li.int_matrix_print_tex(ost, A, m, n);
611 ost << "\\right]" << endl;
612 ost << "$$" << endl;
613 cnt++;
614 if ((cnt % 3) == 0) {
615 ost << endl;
616 //ost << "\\clearpage" << endl;
617 //ost << "\\vspace*{\\fill}" << endl;
618 ost << endl;
619 }
620
621
622 F->Linear_algebra->RREF_elimination_below(A, m, n, i, j, base_cols, verbose_level);
623 ost << "\\noindent After elimination below pivot:\\\\" << endl;
624 ost << "$$" << endl;
625 ost << "\\left[" << endl;
626 Li.int_matrix_print_tex(ost, A, m, n);
627 ost << "\\right]" << endl;
628 ost << "$$" << endl;
629 cnt++;
630 if ((cnt % 3) == 0) {
631 ost << endl;
632 //ost << "\\clearpage" << endl;
633 //ost << "\\vspace*{\\fill}" << endl;
634 ost << endl;
635 }
636
637 }
638 else {
639 rk = i;
640 ost << "Did not find pivot. The rank of the matrix is " << rk << ".\\\\" << endl;
641 break;
642 }
643 }
644 for (i = rk - 1; i >= 0; i--) {
645 F->Linear_algebra->RREF_elimination_above(A, m, n, i, base_cols, verbose_level);
646 ost << "\\noindent After elimination above pivot " << i << " in position (" << i << "," << base_cols[i] << "):\\\\" << endl;
647 ost << "$$" << endl;
648 ost << "\\left[" << endl;
649 Li.int_matrix_print_tex(ost, A, m, n);
650 ost << "\\right]" << endl;
651 ost << "$$" << endl;
652 cnt++;
653 if ((cnt % 3) == 0) {
654 ost << endl;
655 //ost << "\\clearpage" << endl;
656 //ost << "\\vspace*{\\fill}" << endl;
657 ost << endl;
658 }
659 }
660
661 Int_vec_print_fully(ost, A, m * n);
662 ost << "\\\\" << endl;
663
664
665 ost << "}" << endl;
666
667 FREE_int(base_cols);
668
669 if (f_v) {
670 cout << "linear_algebra_global::RREF_with_steps_latex done" << endl;
671 }
672
673}
674
675
676
677}}}
678
provides access to pre-computed combinatorial data in encoded form
void get_primitive_polynomial(std::string &poly, int p, int e, int verbose_level)
void do_nullspace(field_theory::finite_field *F, int *M, int m, int n, int f_normalize_from_the_left, int f_normalize_from_the_right, int verbose_level)
void compute_normal_basis(field_theory::finite_field *F, int d, int verbose_level)
void Berlekamp_matrix(field_theory::finite_field *F, std::string &Berlekamp_matrix_coeffs, int verbose_level)
void RREF_demo(field_theory::finite_field *F, int *A, int m, int n, int verbose_level)
void RREF_with_steps_latex(field_theory::finite_field *F, std::ostream &ost, int *A, int m, int n, int verbose_level)
void do_RREF(field_theory::finite_field *F, int *M, int m, int n, int f_normalize_from_the_left, int f_normalize_from_the_right, int verbose_level)
void RREF_elimination_above(int *A, int m, int n, int i, int *base_cols, int verbose_level)
int RREF_search_pivot(int *A, int m, int n, int &i, int &j, int *base_cols, int verbose_level)
int Gauss_int(int *A, int f_special, int f_complete, int *base_cols, int f_P, int *P, int m, int n, int Pn, int verbose_level)
void RREF_elimination_below(int *A, int m, int n, int &i, int &j, int *base_cols, int verbose_level)
void RREF_make_pivot_one(int *A, int m, int n, int &i, int &j, int *base_cols, int verbose_level)
int perp_standard(int n, int k, int *A, int verbose_level)
void int_matrix_print_tex(std::ostream &ost, int *p, int m, int n)
void head(std::ostream &ost, int f_book, int f_title, const char *title, const char *author, int f_toc, int f_landscape, int f_12pt, int f_enlarged_page, int f_pagenumbers, const char *extras_for_preamble)
void get_vector_from_label(std::string &label, int *&v, int &sz, int verbose_level)
domain of polynomials in one variable over a finite field
Definition: ring_theory.h:691
void compute_normal_basis(int d, int *Normal_basis, int *Frobenius, int verbose_level)
void Frobenius_matrix(int *&Frob, unipoly_object factor_polynomial, int verbose_level)
void create_object_by_rank(unipoly_object &p, long int rk, const char *file, int line, int verbose_level)
void create_object_by_rank_string(unipoly_object &p, std::string &rk, int verbose_level)
void Berlekamp_matrix(int *&B, unipoly_object factor_polynomial, int verbose_level)
void print_object(unipoly_object p, std::ostream &ost)
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_print_fully(A, B, C)
Definition: foundations.h:687
#define NEW_int(n)
Definition: foundations.h:625
#define Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#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