Orbiter 2022
Combinatorial Objects
unipoly_domain2.cpp
Go to the documentation of this file.
1/*
2 * unipoly_domain2.cpp
3 *
4 * Created on: Feb 17, 2021
5 * Author: betten
6 */
7
8
9
10#include "foundations.h"
11
12using namespace std;
13
14
15namespace orbiter {
16namespace layer1_foundations {
17namespace ring_theory {
18
19
22{
23 int *ra = (int *) a;
24 int *rb = (int *) b;
25 int m = ra[0]; // degree of a
26 int n = rb[0]; // degree of b
27 int mn = m + n; // degree of a * b
28
29 int *rc = (int *) c;
30 FREE_int(rc);
31 rc = NEW_int(mn + 2);
32 // +1 since the number of coeffs is one more than the degree,
33 // +1 since we allocate one unit for the degree itself
34
35 int *A = ra + 1;
36 int *B = rb + 1;
37 int *C = rc + 1;
38 int i, j, k, x, y;
39
40 rc[0] = mn;
41 for (i = 0; i <= mn; i++) {
42 C[i] = 0;
43 }
44 for (i = m; i >= 0; i--) {
45 for (j = n; j >= 0; j--) {
46 k = i + j;
47 x = C[k];
48 y = F->mult(A[i], B[j]);
49 if (x == 0) {
50 C[k] = y;
51 }
52 else {
53 C[k] = F->add(x, y);
54 }
55 }
56 }
57 c = (void *) rc;
58}
59
61{
62 int *ra = (int *) a;
63 int m = ra[0]; // degree of a
64 int *A = ra + 1;
65 int i;
66
67 for (i = m; i >= 0; i--) {
68 ost << A[i];
69 }
70}
71
73{
74 int *ra = (int *) a;
75 //int m = ra[0]; // degree of a
76 int *A = ra + 1;
77 int i;
78 int d = ra[0];
79
80 for (i = m; i >= 0; i--) {
81 if (i > d) {
82 ost << "0";
83 }
84 else {
85 ost << A[i];
86 }
87 }
88}
89
90void unipoly_domain::mult_easy_with_report(long int rk_a, long int rk_b, long int &rk_c,
91 std::ostream &ost, int verbose_level)
92{
93 int f_v = (verbose_level >= 1);
94
95 if (f_v) {
96 cout << "unipoly_domain::mult_easy_with_report" << endl;
97 }
102
103 if (f_v) {
104 cout << "unipoly_domain::mult_easy_with_report rk_a=" << rk_a << endl;
105 cout << "unipoly_domain::mult_easy_with_report rk_b=" << rk_b << endl;
106 }
107 create_object_by_rank(a, rk_a,
108 __FILE__, __LINE__, verbose_level);
109 create_object_by_rank(b, rk_b,
110 __FILE__, __LINE__, 0 /* verbose_level */);
111
112 if (f_v) {
113 cout << "unipoly_domain::mult_easy_with_report after create_object_by_rank" << endl;
114 }
115
116 int *ra = (int *) a;
117 int *rb = (int *) b;
118 int m = ra[0]; // degree of a
119 int n = rb[0]; // degree of b
120 int mn = m + n; // degree of a * b
121
122 int *rc; // = (int *) c;
123 //FREE_int(rc);
124 if (f_v) {
125 cout << "unipoly_domain::mult_easy_with_report before NEW_int, mn=" << mn << endl;
126 }
127 rc = NEW_int(mn + 2);
128 // +1 since the number of coeffs is one more than the degree,
129 // +1 since we allocate one unit for the degree itself
130
131 int *A = ra + 1;
132 int *B = rb + 1;
133 int *C = rc + 1;
134 int i, j, k, x, y;
135
136 if (f_v) {
137 cout << "unipoly_domain::mult_easy_with_report before rc[0] = mn;" << endl;
138 }
139 rc[0] = mn;
140 for (i = 0; i <= mn; i++) {
141 C[i] = 0;
142 }
143
144 ost << "\\begin{verbatim}" << endl;
145 ost << setw(m + 1) << rk_a << " x " << setw(n + 1) << rk_b << " = " << endl;
146 if (f_v) {
147 cout << "unipoly_domain::mult_easy_with_report before print_coeffs_top_down_assuming_one_character_per_digit" << endl;
148 }
150 ost << " x ";
152 ost << endl;
153 Algo.print_repeated_character(ost, '=', m + 1 + 3 + n + 1);
154 ost << endl;
155 for (j = n; j >= 0; j--) {
156 if (f_v) {
157 cout << "unipoly_domain::mult_easy_with_report j=" << j << endl;
158 }
159 if (B[j] == 0) {
160 continue;
161 }
162 Algo.print_repeated_character(ost, ' ', 4 + n - j);
164 ost << endl;
165 }
166 Algo.print_repeated_character(ost, ' ', 4);
167 Algo.print_repeated_character(ost, '=', m + 1 + n);
168 ost << endl;
169
170 if (f_v) {
171 cout << "unipoly_domain::mult_easy_with_report multiplying" << endl;
172 }
173 for (i = m; i >= 0; i--) {
174 if (f_v) {
175 cout << "unipoly_domain::mult_easy_with_report i=" << i << endl;
176 }
177 for (j = n; j >= 0; j--) {
178 if (f_v) {
179 cout << "unipoly_domain::mult_easy_with_report j=" << j << endl;
180 }
181 k = i + j;
182 x = C[k];
183 y = F->mult(A[i], B[j]);
184 if (x == 0) {
185 C[k] = y;
186 }
187 else {
188 C[k] = F->add(x, y);
189 }
190 }
191 }
192 c = (void *) rc;
193 Algo.print_repeated_character(ost, ' ', 4);
195 ost << endl;
196 rk_c = rank(c);
197 if (f_v) {
198 cout << "unipoly_domain::mult_easy_with_report rk_c=" << rk_c << endl;
199 }
200 Algo.print_repeated_character(ost, ' ', 3);
201 ost << "=" << setw(mn + 1) << rk_c << endl;
202 ost << endl;
203 ost << "\\end{verbatim}" << endl;
204
205 delete_object(a);
206 delete_object(b);
207 delete_object(c);
208 if (f_v) {
209 cout << "unipoly_domain::mult_easy_with_report done" << endl;
210 }
211
212}
213
215 std::string &input_fname, long int rk_b,
216 long int &rk_q, long int &rk_r, std::ostream &ost, int verbose_level)
217 //unipoly_object a, unipoly_object b,
218 //unipoly_object &q, unipoly_object &r,
219 //int verbose_level)
220{
221 int f_v = (verbose_level >= 1);
222
223
224 if (f_v) {
225 cout << "unipoly_domain::division_with_remainder_from_file_with_report" << endl;
226 }
227
233
234
236 a, input_fname,
237 __FILE__, __LINE__,
238 verbose_level);
239 create_object_by_rank(b, rk_b,
240 __FILE__, __LINE__, 0 /* verbose_level */);
242 __FILE__, __LINE__, 0 /* verbose_level */);
244 __FILE__, __LINE__, 0 /* verbose_level */);
245
246
247 int da, db;
248 int i;
249
250 da = degree(a);
251 db = degree(b);
252
253 ost << "\\begin{verbatim}" << endl;
254 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
255 ost << input_fname << " / " << setw(db + 1) << rk_b << " = " << endl;
256
257
258 division_with_remainder_with_report(a, b, q, r, TRUE, ost, verbose_level);
259
260 int *rr = (int *) r;
261 int *R = rr + 1;
262 for (i = db - 1; i >= 0; i--) {
263 if (R[i]) {
264 break;
265 }
266 }
267 rk_q = rank(q);
268 rk_r = rank(r);
269 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
270 Algo.print_repeated_character(ost, ' ', da - i - 2);
271 ost << "= " << setw(i + 1) << rk_r << endl;
272 ost << endl;
273 ost << "\\end{verbatim}" << endl;
274
275 if (f_v) {
276 cout << "unipoly_domain::division_with_remainder_from_file_with_report done" << endl;
277 }
278
279}
280
281
283 std::string &input_fname, long int rk_b, int k,
284 long int *&rk_q, long int *&rk_r, int &n, int &N, std::ostream &ost, int verbose_level)
285{
286 int f_v = (verbose_level >= 1);
287
288
289 if (f_v) {
290 cout << "unipoly_domain::division_with_remainder_from_file_all_k_bit_error_patterns" << endl;
291 }
293
294
299
300
302 a, input_fname,
303 __FILE__, __LINE__,
304 verbose_level);
305 create_object_by_rank(b, rk_b,
306 __FILE__, __LINE__, 0 /* verbose_level */);
308 __FILE__, __LINE__, 0 /* verbose_level */);
310 __FILE__, __LINE__, 0 /* verbose_level */);
311
312
313 int da, db;
314 int *aa = (int *) a;
315 int i, h;
316
317 da = aa[0]; //degree(a);
318 db = degree(b);
319
320 n = da + 1;
321 N = Combi.int_n_choose_k(n, k);
322
323 rk_q = NEW_lint(N);
324 rk_r = NEW_lint(N);
325
326 int *set;
327 int j, u;
328
329 set = NEW_int(k);
330
331
332 ost << "\\begin{verbatim}" << endl;
333 ost << " : ";
335 ost << endl;
336
337 for (h = 0; h < N; h++) {
338 Int_vec_zero(set, k);
339 Combi.unrank_k_subset(h, set, n, k);
340
341
343 a, input_fname,
344 __FILE__, __LINE__,
345 verbose_level);
346 create_object_by_rank(b, rk_b,
347 __FILE__, __LINE__, 0 /* verbose_level */);
349 __FILE__, __LINE__, 0 /* verbose_level */);
351 __FILE__, __LINE__, 0 /* verbose_level */);
352
353 int *aa = (int *) a;
354 int *A = aa + 1;
355
356 for (j = 0; j < k; j++) {
357 u = set[j];
358 if (A[u]) {
359 A[u] = 0;
360 }
361 else {
362 A[u] = 1;
363 }
364 }
365
366 ost << setw(5) << h;
367 ost << " : ";
369
370 cout << setw(5) << h;
371 cout << " : ";
373 cout << endl;
374
375
376 division_with_remainder_with_report(a, b, q, r, FALSE, ost, verbose_level);
377
378 ost << " : ";
380
381 int *rr = (int *) r;
382 int *R = rr + 1;
383 for (i = db - 1; i >= 0; i--) {
384 if (R[i]) {
385 break;
386 }
387 }
388 rk_q[h] = rank(q);
389 rk_r[h] = rank(r);
390 ost << " : ";
391 ost << setw(5) << rk_r[h];
392 ost << " : ";
393 print_object(r, ost);
394 ost << endl;
395
396 }
397 ost << "\\end{verbatim}" << endl;
398 FREE_int(set);
399
400 if (f_v) {
401 cout << "unipoly_domain::division_with_remainder_from_file_all_k_bit_error_patterns done" << endl;
402 }
403
404}
405
406
408 long int &rk_q, long int &rk_r, std::ostream &ost, int verbose_level)
409 //unipoly_object a, unipoly_object b,
410 //unipoly_object &q, unipoly_object &r,
411 //int verbose_level)
412{
413 int f_v = (verbose_level >= 1);
414
415
416 if (f_v) {
417 cout << "unipoly_domain::division_with_remainder_numerically_with_report" << endl;
418 }
419
425
426 create_object_by_rank(a, rk_a,
427 __FILE__, __LINE__, 0 /* verbose_level */);
428 create_object_by_rank(b, rk_b,
429 __FILE__, __LINE__, 0 /* verbose_level */);
431 __FILE__, __LINE__, 0 /* verbose_level */);
433 __FILE__, __LINE__, 0 /* verbose_level */);
434
435 int da, db;
436 int i;
437
438 da = degree(a);
439 db = degree(b);
440
441 ost << "\\begin{verbatim}" << endl;
442 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
443 ost << setw(da + 1) << rk_a << " / " << setw(db + 1) << rk_b << " = " << endl;
444
445
446
447 division_with_remainder_with_report(a, b, q, r, TRUE, ost, verbose_level);
448
449
450 int *rr = (int *) r;
451 int *R = rr + 1;
452 for (i = db - 1; i >= 0; i--) {
453 if (R[i]) {
454 break;
455 }
456 }
457 rk_q = rank(q);
458 rk_r = rank(r);
459 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
460 Algo.print_repeated_character(ost, ' ', da - i - 2);
461 ost << "= " << setw(i + 1) << rk_r << endl;
462 ost << endl;
463 ost << "\\end{verbatim}" << endl;
464}
465
466
468 unipoly_object &q, unipoly_object &r, int f_report, std::ostream &ost, int verbose_level)
469 //unipoly_object a, unipoly_object b,
470 //unipoly_object &q, unipoly_object &r,
471 //int verbose_level)
472{
473 int f_v = (verbose_level >= 1);
474
475
476 if (f_v) {
477 cout << "unipoly_domain::division_with_remainder_with_report" << endl;
478 }
479
480
481
482 //int *ra = (int *) a;
483 int *rb = (int *) b;
484 //int *A = ra + 1;
485 int *B = rb + 1;
486
487 int da, db;
488
489 da = degree(a);
490 db = degree(b);
491
492 if (f_factorring) {
493 cout << "unipoly_domain::division_with_remainder_with_report "
494 "not good for a factorring" << endl;
495 exit(1);
496 }
497 if (db == 0) {
498 if (B[0] == 0) {
499 cout << "unipoly_domain::division_with_remainder_with_report: "
500 "division by zero" << endl;
501 exit(1);
502 }
503 }
504 if (db > da) {
505 cout << "unipoly_domain::division_with_remainder_with_report db > da" << endl;
506 int *rq = (int *) q;
507 FREE_int(rq);
508 rq = NEW_int(2);
509 int *Q = rq + 1;
510 Q[0] = 0;
511 rq[0] = 0;
512 assign(a, r, 0 /*verbose_level*/);
513 q = rq;
514 goto done;
515 }
516
517 {
518 int dq = da - db;
519 int *rq = (int *) q;
520 FREE_int(rq);
521 rq = NEW_int(dq + 2);
522 rq[0] = dq;
523
524 assign(a, r, 0 /*verbose_level*/);
525
526 int *rr = (int *) r;
527
528 int *Q = rq + 1;
529 int *R = rr + 1;
530
531 int i, j, ii, jj, pivot, pivot_inv, x, c, d;
532
533 pivot = B[db];
534 pivot_inv = F->inverse(pivot);
535
536 Int_vec_zero(Q, dq + 1);
538
539 if (f_report) {
540 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
542 ost << " / ";
544 ost << " = " << endl << endl;
545
546 }
547 // quotient should be here, so we need to do the computation
548
549
550 for (i = da, j = dq; i >= db; i--, j--) {
551
552
553 x = R[i];
554 if (x == 0) {
555 continue;
556 }
557
558 c = F->mult(x, pivot_inv);
559 Q[j] = c;
560 c = F->negate(c);
561 //cout << "i=" << i << " c=" << c << endl;
562 for (ii = i, jj = db; jj >= 0; ii--, jj--) {
563 d = B[jj];
564 d = F->mult(c, d);
565 R[ii] = F->add(d, R[ii]);
566 }
567 if (R[i] != 0) {
568 cout << "unipoly::division_with_remainder_with_report: R[i] != 0" << endl;
569 exit(1);
570 }
571 //cout << "i=" << i << endl;
572 //cout << "q="; print_object((unipoly_object)
573 // rq, cout); cout << endl;
574 //cout << "r="; print_object(r, cout); cout << endl;
575 }
576 rr[0] = MAXIMUM(db - 1, 0);
577 q = rq;
578
579 if (f_report) {
580 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
582 }
583
584 assign(a, r, 0 /*verbose_level*/);
585
586
587 if (f_report) {
588 ost << endl;
589 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
590 Algo.print_repeated_character(ost, '=', da + 1);
591 ost << endl;
592 }
593
594
595 for (i = da, j = dq; i >= db; i--, j--) {
596
597
598 x = R[i];
599 if (x == 0) {
600 continue;
601 }
602
603 if (f_report) {
604 if (i == da) {
606 ost << " | ";
607 }
608 else {
610 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
611 }
612 Algo.print_repeated_character(ost, ' ', da - i);
614 ost << endl;
615 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
616 Algo.print_repeated_character(ost, ' ', da - i);
618 ost << endl;
619 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
620 Algo.print_repeated_character(ost, ' ', da - i);
621 Algo.print_repeated_character(ost, '=', db + 1);
622 ost << endl;
623 }
624
625 c = F->mult(x, pivot_inv);
626 Q[j] = c;
627 c = F->negate(c);
628 //cout << "i=" << i << " c=" << c << endl;
629 for (ii = i, jj = db; jj >= 0; ii--, jj--) {
630 d = B[jj];
631 d = F->mult(c, d);
632 R[ii] = F->add(d, R[ii]);
633 }
634 if (R[i] != 0) {
635 cout << "unipoly::division_with_remainder_with_report: R[i] != 0" << endl;
636 exit(1);
637 }
638 //cout << "i=" << i << endl;
639 //cout << "q="; print_object((unipoly_object)
640 // rq, cout); cout << endl;
641 //cout << "r="; print_object(r, cout); cout << endl;
642 }
643 q = rq;
644 //cout << "q="; print_object(q, cout); cout << endl;
645 //cout << "r="; print_object(r, cout); cout << endl;
646
647 while (i > 0 && R[i] == 0) {
648 i--;
649 }
650 rr[0] = i;
651 if (rr[0] < 0) {
652 rr[0] = 0;
653 }
654 if (f_report) {
655 Algo.print_repeated_character(ost, ' ', db + 1 + 3);
656 Algo.print_repeated_character(ost, ' ', da - i);
658 ost << endl;
659 }
660 }
661done:
662 if (f_v) {
663 cout << "unipoly_domain::division_with_remainder_with_report done" << endl;
664 }
665}
666
667
668}}}
669
670
void print_repeated_character(std::ostream &ost, char c, int n)
Definition: algorithms.cpp:147
void mult_easy_with_report(long int rk_a, long int rk_b, long int &rk_c, std::ostream &ost, int verbose_level)
void division_with_remainder_from_file_all_k_bit_error_patterns(std::string &input_fname, long int rk_b, int k, long int *&rk_q, long int *&rk_r, int &n, int &N, std::ostream &ost, int verbose_level)
void division_with_remainder_from_file_with_report(std::string &input_fname, long int rk_b, long int &rk_q, long int &rk_r, std::ostream &ost, int verbose_level)
void division_with_remainder_with_report(unipoly_object &a, unipoly_object &b, unipoly_object &q, unipoly_object &r, int f_report, std::ostream &ost, int verbose_level)
void create_object_by_rank(unipoly_object &p, long int rk, const char *file, int line, int verbose_level)
void division_with_remainder_numerically_with_report(long int rk_a, long int rk_b, long int &rk_q, long int &rk_r, std::ostream &ost, int verbose_level)
void print_coeffs_top_down_assuming_one_character_per_digit(unipoly_object a, std::ostream &ost)
void mult_easy(unipoly_object a, unipoly_object b, unipoly_object &c)
void create_object_from_csv_file(unipoly_object &p, std::string &fname, const char *file, int line, int verbose_level)
void print_coeffs_top_down_assuming_one_character_per_digit_with_degree_given(unipoly_object a, int m, std::ostream &ost)
void assign(unipoly_object a, unipoly_object &b, int verbose_level)
void print_object(unipoly_object p, std::ostream &ost)
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define NEW_lint(n)
Definition: foundations.h:628
#define MAXIMUM(x, y)
Definition: foundations.h:217
the orbiter library for the classification of combinatorial objects