Orbiter 2022
Combinatorial Objects
elliptic_curve.cpp
Go to the documentation of this file.
1// elliptic_curve.cpp
2//
3// Anton Betten
4// Oct 27, 2009
5//
6//
7// pulled out of crypto.cpp: November 19, 2014
8//
9//
10
11#include "foundations.h"
12
13using namespace std;
14
15
16namespace orbiter {
17namespace layer1_foundations {
18namespace number_theory {
19
20
21
23{
24 null();
25}
26
28{
29 freeself();
30}
31
32
34{
35 T = NULL;
36 A = NULL;
37}
38
40{
41 if (T) {
42 FREE_int(T);
43 }
44 if (A) {
45 FREE_int(A);
46 }
47}
48
49
51 int verbose_level)
52{
53 int f_v = (verbose_level >= 1);
54
55 if (f_v) {
56 cout << "elliptic_curve::init q=" << F->q
57 << " b=" << b << " c=" << c << endl;
58 }
60 q = F->q;
61 p = F->p;
62 e = F->e;
65
66
67 if (f_v) {
68 cout << "elliptic_curve::init before compute_points" << endl;
69 }
70
71 compute_points(verbose_level);
72
73 if (f_v) {
74 cout << "elliptic_curve::init after compute_points" << endl;
75 }
76
77#if 0
78 if (E.nb < 20) {
79 print_integer_matrix_width(cout, E.A, E.nb, E.nb, E.nb, 3);
80 }
81
82#endif
83
84
85
86#if 0
87 cout << "point : order" << endl;
88 for (i = 0; i < E.nb; i++) {
89 j = order_of_point(E, i);
90 cout << setw(4) << i << " : " << setw(4) << j << endl;
91 }
92
93 cout << "the curve has " << E.nb << " points" << endl;
94#endif
95
96#if 0
97 {
98 int a, b, c;
99 a = 1;
100 b = 2;
101 c = E.A[a * E.nb + b];
102 cout << "P_" << a << " + P_" << b << " = P_" << c << endl;
103 }
104
105 j = multiple_of_point(E, 0, 37);
106 cout << "37 * P_0 = P_" << j << endl;
107#endif
108 if (f_v) {
109 cout << "elliptic_curve::init done" << endl;
110 }
111}
112
113
114void elliptic_curve::compute_points(int verbose_level)
115{
116 int f_v = (verbose_level >= 1);
117 int x, y, y1, y2;
118 int r;
119 int bound;
120
121 if (f_v) {
122 cout << "elliptic_curve::compute_points" << endl;
123 }
124 bound = q + 1 + 2 * ((int)(sqrt(q)) + 1); // Hasse Weil bound
125
126
127
128 T = NEW_int(bound * 3);
129 nb = 0;
130
131
132 // the point at infinity comes first:
133 add_point_to_table(0, 1, 0);
134
135
136 for (x = 0; x < q; x++) {
137 r = evaluate_RHS(x);
138 if (r == 0) {
139 add_point_to_table(x, 0, 1);
140 if (nb == bound) {
141 cout << "elliptic_curve::compute_points The number of points exceeds the bound" << endl;
142 exit(1);
143 }
144 //cout << nb++ << " : (" << x << "," << 0 << ",1)" << endl;
145 }
146 else {
147 if (F->is_square(r)) {
148
149 y = F->square_root(r);
150
151 y1 = y;
152 y2 = F->negate(y);
153 if (y2 == y1) {
154 add_point_to_table(x, y1, 1);
155 if (nb == bound) {
156 cout << "elliptic_curve::compute_points The number of points "
157 "exceeds the bound" << endl;
158 exit(1);
159 }
160 }
161 else {
162 if (y2 < y1) {
163 y1 = y2;
164 y2 = y;
165 }
166 add_point_to_table(x, y1, 1);
167 if (nb == bound) {
168 cout << "elliptic_curve::compute_points The number of points "
169 "exceeds the bound" << endl;
170 exit(1);
171 }
172 add_point_to_table(x, y2, 1);
173 if (nb == bound) {
174 cout << "elliptic_curve::compute_points The number of points "
175 "exceeds the bound" << endl;
176 exit(1);
177 }
178 }
179 }
180 else {
181 // no point for this x coordinate
182 }
183
184#if 0
185 if (p != 2) {
186 l = Legendre(r, q, 0);
187
188 if (l == 1) {
189 y = sqrt_mod_involved(r, q);
190 // DISCRETA/global.cpp
191
192 if (F->mult(y, y) != r) {
193 cout << "elliptic_curve::compute_points There is a problem "
194 "with the square root" << endl;
195 exit(1);
196 }
197 y1 = y;
198 y2 = F->negate(y);
199 if (y2 < y1) {
200 y1 = y2;
201 y2 = y;
202 }
203 add_point_to_table(x, y1, 1);
204 if (nb == bound) {
205 cout << "elliptic_curve::compute_points The number of points "
206 "exceeds the bound" << endl;
207 exit(1);
208 }
209 add_point_to_table(x, y2, 1);
210 if (nb == bound) {
211 cout << "elliptic_curve::compute_points The number of points "
212 "exceeds the bound" << endl;
213 exit(1);
214 }
215 //cout << nb++ << " : (" << x << ","
216 // << y << ",1)" << endl;
217 //cout << nb++ << " : (" << x << ","
218 // << F.negate(y) << ",1)" << endl;
219 }
220 }
221 else {
222 y = F->frobenius_power(r, e - 1);
223 add_point_to_table(x, y, 1);
224 if (nb == bound) {
225 cout << "elliptic_curve::compute_points The number of points exceeds "
226 "the bound" << endl;
227 exit(1);
228 }
229 //cout << nb++ << " : (" << x << ","
230 // << y << ",1)" << endl;
231 }
232#endif
233
234 }
235 }
236
237
238 if (nb == bound) {
239 cout << "elliptic_curve::compute_points The number of points exceeds the bound" << endl;
240 exit(1);
241 }
242
243
244 if (f_v) {
245 cout << "elliptic_curve::compute_points done, "
246 "we found " << nb << " points" << endl;
247 }
248}
249
250void elliptic_curve::add_point_to_table(int x, int y, int z)
251{
252 T[nb * 3 + 0] = x;
253 T[nb * 3 + 1] = y;
254 T[nb * 3 + 2] = z;
255 nb++;
256}
257
259// evaluates x^3 + bx + c
260{
261 int x2, x3, t;
262
263 x2 = F->mult(x, x);
264 x3 = F->mult(x2, x);
265 t = F->add(x3, F->mult(b, x));
266 t = F->add(t, c);
267 return t;
268}
269
271{
272 int i;
273
274 cout << "i : point (x,y,z)" << endl;
275 for (i = 0; i < nb; i++) {
276 cout << setw(4) << i << " & " << T[i * 3 + 0] << ","
277 << T[i * 3 + 1] << "," << T[i * 3 + 2] << "\\\\" << endl;
278 }
279}
280
282{
283 int i;
284
285 cout << "i : point (x,y,z)" << endl;
286 for (i = 0; i < nb; i++) {
287 cout << setw(4) << i << " & ";
288 if (T[i * 3 + 2] == 0) {
289 cout << "\\cO";
290 }
291 else {
292 cout << "(" << T[i * 3 + 0] << "," << T[i * 3 + 1] << ")";
293 }
294 cout << "\\\\" << endl;
295 }
296}
297
298
300 int x1, int y1, int z1,
301 int x2, int y2, int z2,
302 int &x3, int &y3, int &z3, int verbose_level)
303{
304 int f_v = (verbose_level >= 1);
305
306 if (f_v) {
307 cout << "elliptic_curve::addition: ";
308 cout << "(" << x1 << "," << y1 << "," << z1 << ")";
309 cout << " + ";
310 cout << "(" << x2 << "," << y2 << "," << z2 << ")";
311 cout << endl;
312 }
313
315
317 x1, y1, z1,
318 x2, y2, z2,
319 x3, y3, z3, verbose_level);
320
321 if (f_v) {
322 cout << "elliptic_curve::addition done";
323 }
324}
325
327 int verbose_level)
328{
329 int f_v = (verbose_level >= 1);
330 int *M;
331 int i, x, y, z;
333
334 if (f_v) {
335 cout << "elliptic_curve::save_incidence_matrix" << endl;
336 }
337 M = NEW_int(q * q);
338 Int_vec_zero(M, q * q);
339 for (i = 0; i < nb; i++) {
340 x = T[i * 3 + 0];
341 y = T[i * 3 + 1];
342 z = T[i * 3 + 2];
343 if (z == 0) {
344 continue;
345 }
346 if (z != 1) {
347 cout << "elliptic_curve::save_incidence_matrix point is not normalized" << endl;
348 exit(1);
349 }
350 M[(q - 1 - y) * q + x] = 1;
351 }
352 Fio.int_matrix_write_csv(fname, M, q, q);
353 if (f_v) {
354 cout << "elliptic_curve::save_incidence_matrix written file "
355 << fname << " of size " << Fio.file_size(fname) << endl;
356 }
357 FREE_int(M);
358 if (f_v) {
359 cout << "elliptic_curve::save_incidence_matrix done" << endl;
360 }
361}
362
364 std::string &fname,
366 int f_with_grid, int f_with_points, int point_density,
367 int f_path, int start_idx, int nb_steps,
368 int verbose_level)
369{
370 int f_v = (verbose_level >= 1);
371 int factor_1000 = 1000;
372 string fname_full;
373
374 if (f_v) {
375 cout << "draw_grid" << endl;
376 }
377 fname_full.assign(fname);
378 fname_full.append(".mp");
379
380 {
381
383
384 G.init(fname_full, Draw_options, verbose_level - 1);
385
386 G.header();
387 G.begin_figure(factor_1000);
388
389 draw_grid2(G, f_with_grid, f_with_points, point_density,
390 f_path, start_idx, nb_steps,
391 verbose_level);
392
393
394 G.end_figure();
395 G.footer();
396 }
398
399 cout << "written file " << fname_full << " of size "
400 << Fio.file_size(fname_full) << endl;
401 if (f_v) {
402 cout << "draw_grid done" << endl;
403 }
404
405}
406
407
409 int f_with_grid, int f_with_points, int point_density,
410 int f_path, int start_idx, int nb_steps,
411 int verbose_level)
412{
413 int f_v = (verbose_level >= 1);
414 int a, b, c, d;
415 int x1, x2, x3;
416
417 //int rad = 10000;
418 int i, h;
419
420 double *Dx, *Dy;
421 int *Px, *Py;
422 int dx = G.in_xmax() / q;
423 int dy = G.in_ymax() / q;
424 int N = 1000;
425
426
427 Px = NEW_int(N);
428 Py = NEW_int(N);
429 Dx = new double[N];
430 Dy = new double[N];
431
432
433 if (f_v) {
434 cout << "elliptic_curve::draw_grid2" << endl;
435 cout << "dx=" << dx << " dy=" << dy << endl;
436 }
437
438
439
440
441 if (f_v) {
442 cout << "elliptic_curve::draw_grid2 drawing grid" << endl;
443 }
444
445
446#if 0
447 if (f_with_grid) {
449 0., (double)(q - 1), 0., (double)(q - 1),
450 x_stretch, y_stretch,
451 TRUE /* f_x_axis_at_y_min */,
452 TRUE /* f_y_axis_at_x_min */,
453 1 /* x_mod */, 1 /* y_mod */, 1, 1,
454 -2. /* x_labels_offset */,
455 -2. /* y_labels_offset */,
456 0.5 /* x_tick_half_width */,
457 0.5 /* y_tick_half_width */,
458 TRUE /* f_v_lines */, 1 /* subdivide_v */,
459 TRUE /* f_h_lines */, 1 /* subdivide_h */,
460 verbose_level - 1);
461 }
462 else {
464 0., (double)(q - 1), 0., (double)(q - 1),
465 x_stretch, y_stretch,
466 TRUE /* f_x_axis_at_y_min */,
467 TRUE /* f_y_axis_at_x_min */,
468 1 /* x_mod */, 1 /* y_mod */, 1, 1,
469 -2. /* x_labels_offset */,
470 -2. /* y_labels_offset */,
471 0.5 /* x_tick_half_width */,
472 0.5 /* y_tick_half_width */,
473 TRUE /* f_v_lines */, q - 1 /* subdivide_v */,
474 TRUE /* f_h_lines */, q - 1 /* subdivide_h */,
475 verbose_level - 1);
476
477 }
478#endif
479
480
481 if (f_with_points) {
482
483 G.sf_color(1 /* fill_color*/);
484 G.sf_interior(point_density /* fill_interior */);
485 if (f_v) {
486 cout << "drawing points, nb=" << nb << endl;
487 }
488
489 if (nb >= 40) {
490 //rad = 2000;
491 }
492 for (h = 0; h < nb; h++) {
493 x1 = T[3 * h + 0];
494 x2 = T[3 * h + 1];
495 x3 = T[3 * h + 2];
496 //get_ab(q, x1, x2, x3, a, b);
497 make_affine_point(x1, x2, x3, a, b, 0);
498
499
500 Dx[0] = a;
501 Dy[0] = b;
502 Dx[1] = a + 1;
503 Dy[1] = b;
504 Dx[2] = a + 1;
505 Dy[2] = b + 1;
506 Dx[3] = a;
507 Dy[3] = b + 1;
508 Dx[4] = a;
509 Dy[4] = b;
510
511 for (i = 0; i < 5; i++) {
512 Px[i] = Dx[i] * dx;
513 Py[i] = Dy[i] * dy;
514 }
515
516 cout << "point " << h << " : "
517 << x1 << ", " << x2 << ", " << x3
518 << " : " << a << ", " << b
519 << " : " << Px[0] << "," << Py[0]
520 << endl;
521
522 //G.circle(Px[0], Py[0], rad);
523 G.fill_polygon5(Px, Py, 0, 1, 2, 3, 4);
524 }
525
526#if 0
527
528 if (nb < 30) {
529 if (f_v) {
530 cout << "drawing point labels" << endl;
531 }
532 // drawing point labels:
533 for (i = 0; i < nb; i++) {
534 char str[1000];
535 sprintf(str, "%d", i);
536 x1 = T[3 * i + 0];
537 x2 = T[3 * i + 1];
538 x3 = T[3 * i + 2];
539 get_ab(q, x1, x2, x3, a, b);
540 G.aligned_text(Px[a * Q + b], Py[a * Q + b], "", str);
541 }
542 }
543#endif
544
545 }
546 else {
547 cout << "elliptic_curve::draw_grid2 not drawing any points" << endl;
548 }
549
550
551
552 if (f_path) {
553 G.sl_ends(0 /* line_beg_style */, 1 /* line_end_style*/);
554 G.sl_thickness(100 /* line_thickness*/);
555
556 int h, j;
557 int y1, y2, y3;
558
559 if (f_v) {
560 cout << "drawing multiples of point" << endl;
561 }
562 i = start_idx;
563 for (h = 0; h < nb_steps; h++) {
564 x1 = T[3 * i + 0];
565 x2 = T[3 * i + 1];
566 x3 = T[3 * i + 2];
567 j = A[i * nb + start_idx];
568 y1 = T[3 * j + 0];
569 y2 = T[3 * j + 1];
570 y3 = T[3 * j + 2];
571 make_affine_point(x1, x2, x3, a, b, 0);
572 make_affine_point(y1, y2, y3, c, d, 0);
573
574 Dx[0] = a;
575 Dy[0] = b;
576 Dx[1] = c;
577 Dy[1] = d;
578
579 for (i = 0; i < 2; i++) {
580 Px[i] = Dx[i] * dx + dx / 2;
581 Py[i] = Dy[i] * dy + dy / 2;
582 }
583
584 G.polygon2(Px, Py, 0, 1);
585 i = j;
586 }
587 }
588
589
590 // draw the outline box last, so it overlaps all other elements:
591
592 G.sl_ends(0 /* line_beg_style */, 0 /* line_end_style*/);
593
594 G.sl_thickness(100);
595 Dx[0] = 0;
596 Dy[0] = 0;
597 Dx[1] = q + 1;
598 Dy[1] = 0;
599 Dx[2] = q + 1;
600 Dy[2] = q + 1;
601 Dx[3] = 0;
602 Dy[3] = q + 1;
603 Dx[4] = 0;
604 Dy[4] = 0;
605
606 for (i = 0; i < 5; i++) {
607 Px[i] = Dx[i] * dx;
608 Py[i] = Dy[i] * dy;
609 }
610
611
612 G.polygon5(Px, Py, 0, 1, 2, 3, 4);
613
614
615
616#if 0
617 G.sl_udsty(100);
618 a = Xcoord(-1);
619 b = Ycoord(-1);
620 c = Xcoord(q + 1);
621 d = Ycoord(q + 1);
622 cout << a << "," << b << "," << c << "," << d << endl;
623 G.polygon2(Px, Py, a * Q + b, c * Q + d);
624 a = Xcoord(q + 1);
625 b = Ycoord(-1);
626 c = Xcoord(-1);
627 d = Ycoord(q + 1);
628 cout << a << "," << b << "," << c << "," << d << endl;
629 G.polygon2(Px, Py, a * Q + b, c * Q + d);
630
631
632 q2 = q >> 1;
633 if (ODD(q))
634 r = 1;
635 else
636 r = 0;
637
638 a = Xcoord(q2) + r;
639 b = Ycoord(-1);
640 c = Xcoord(q2) + r;
641 d = Ycoord(q + 1);
642 cout << a << "," << b << "," << c << "," << d << endl;
643 G.polygon2(Px, Py, a * Q + b, c * Q + d);
644
645 a = Xcoord(-1);
646 b = Ycoord(q2) + r;
647 c = Xcoord(q + 1);
648 d = Ycoord(q2) + r;
649 cout << a << "," << b << "," << c << "," << d << endl;
650 G.polygon2(Px, Py, a * Q + b, c * Q + d);
651#endif
652
653
654 FREE_int(Px);
655 FREE_int(Py);
656 delete [] Dx;
657 delete [] Dy;
658
659
660
661 if (f_v) {
662 cout << "draw_grid2 done" << endl;
663 }
664}
665
666void elliptic_curve::make_affine_point(int x1, int x2, int x3,
667 int &a, int &b, int verbose_level)
668{
669 if (x3 == 0) {
670 a = q >> 1;
671 b = q;
672 }
673 else {
674 if (x3 != 1) {
675 cout << "x3 != 1" << endl;
676 exit(1);
677 }
678 a = x1;
679 b = x2;
680 }
681}
682
683
684
685#if 0
686int multiple_of_point(elliptic_curve &E, int i, int n)
687{
688 int j, a;
689
690 a = E.nb - 1;
691 for (j = 0; j < n; j++) {
692 a = E.A[a * E.nb + i];
693 }
694 return a;
695}
696#endif
697
699{
700 int f_v = (verbose_level >= 1);
701 //int f_v3 = (verbose_level >= 3);
702 int i, j, k;
703 int x1, x2, x3;
704 int y1, y2, y3;
705 int z1, z2, z3;
706
707 if (f_v) {
708 cout << "elliptic_curve::compute_addition_table" << endl;
709 }
710
711 A = NEW_int(nb * nb);
712 for (i = 0; i < nb; i++) {
713 x1 = T[3 * i + 0];
714 x2 = T[3 * i + 1];
715 x3 = T[3 * i + 2];
716 for (j = 0; j < nb; j++) {
717 y1 = T[3 * j + 0];
718 y2 = T[3 * j + 1];
719 y3 = T[3 * j + 2];
720 if (FALSE) {
721 cout << "add " << i << " " << j << endl;
722 }
723 addition(
724 x1, x2, x3,
725 y1, y2, y3,
726 z1, z2, z3, 0 /*verbose_level - 1*/);
727
728
729 k = index_of_point(z1, z2, z3);
730 A[i * nb + j] = k;
731 }
732 }
733 if (f_v) {
734 cout << "elliptic_curve::compute_addition_table done" << endl;
735 }
736}
737
739{
741
743 L.int_matrix_print_tex(cout, A, nb, nb);
744}
745
746#if 0
747int elliptic_curve::index_of_point(int x1, int x2, int x3)
748{
749 int a, i;
750
751 if (x3 == 0) {
752 return 0;
753 }
754 if (x3 != 1) {
755 a = F->inverse(x3);
756 x1 = F->mult(x1, a);
757 x2 = F->mult(x2, a);
758 x3 = 1;
759 }
760 for (i = 1; i < nb; i++) {
761 if (T[3 * i + 0] == x1 && T[3 * i + 1] == x2) {
762 return i;
763 }
764 }
765 cout << "did not find point "
766 << x1 << "," << x2 << "," << x3 << " in table" << endl;
767 exit(1);
768}
769#endif
770
771int elliptic_curve::index_of_point(int x1, int x2, int x3)
772//int int_vec_search(int *v, int len, int a, int &idx)
773// This function finds the last occurence of the element a.
774// If a is not found, it returns in idx
775// the position where it should be inserted if
776// the vector is assumed to be in increasing order.
777
778{
779 int l, r, m, res, a;
780 int f_found = FALSE;
781 int f_v = FALSE;
782
783 if (nb == 0) {
784 cout << "elliptic_curve::index_of_point "
785 "nb == 0" << endl;
786 exit(1);
787 }
788
789 if (x3 == 0) {
790 return 0;
791 }
792 if (x3 != 1) {
793 a = F->inverse(x3);
794 x1 = F->mult(x1, a);
795 x2 = F->mult(x2, a);
796 x3 = 1;
797 }
798
799 l = 1;
800 r = nb;
801 // invariant:
802 // v[i] <= a for i < l;
803 // v[i] > a for i >= r;
804 // r - l is the length of the area to search in.
805 while (l < r) {
806 m = (l + r) >> 1;
807 // if the length of the search area is even
808 // we examine the element above the middle
809 if (T[3 * m + 0] > x1) {
810 res = 1;
811 }
812 else if (T[3 * m + 0] < x1) {
813 res = -1;
814 }
815 else {
816 if (T[3 * m + 1] > x2) {
817 res = 1;
818 }
819 else if (T[3 * m + 1] < x2) {
820 res = -1;
821 }
822 else {
823 res = 0;
824 }
825 }
826 //res = v[m] - a;
827 if (f_v) {
828 cout << "l=" << l << " r=" << r<< " m=" << m
829 << " T[3 * m + 0]=" << T[3 * m + 0]
830 << " T[3 * m + 1]=" << T[3 * m + 1]
831 << " res=" << res << endl;
832 }
833 //cout << "search l=" << l << " m=" << m << " r="
834 // << r << "a=" << a << " v[m]=" << v[m]
835 // << " res=" << res << endl;
836 // so, res is
837 // positive if v[m] > a,
838 // zero if v[m] == a,
839 // negative if v[m] < a
840 if (res <= 0) {
841 l = m + 1;
842 if (f_v) {
843 cout << "elliptic_curve::index_of_point "
844 "moving to the right" << endl;
845 }
846 if (res == 0) {
847 f_found = TRUE;
848 }
849 }
850 else {
851 if (f_v) {
852 cout << "elliptic_curve::index_of_point "
853 "moving to the left" << endl;
854 }
855 r = m;
856 }
857 }
858 // now: l == r;
859 // and f_found is set accordingly */
860 if (!f_found) {
861 cout << "elliptic_curve::index_of_point "
862 "did not find point" << endl;
863 cout << "x1=" << x1 << " x2=" << x2 << " x3=" << x3 << endl;
864 exit(1);
865 }
866#if 1
867 if (f_found) {
868 l--;
869 }
870#endif
871 return l;
872}
873
875{
876 vector<int> Ord;
877 int *p;
878 int i;
880
882 p = NEW_int(Ord.size());
883 for (i = 0; i < (int) Ord.size(); i++) {
884 p[i] = Ord[i];
885 }
886
887
888 ost << "\\begin{array}{|r|r|r|}" << endl;
889
890 ost << "\\hline" << endl;
891 for (i = 0; i < nb; i++) {
892 ost << i << " & ";
893 if (i) {
894 ost << "(" << T[3 * i + 0] << "," << T[3 * i + 1] << ")";
895 }
896 else {
897 ost << "{\\cal O}";
898 }
899 ost << " & " << p[i];
900 ost << "\\\\";
901 ost << endl;
902 }
903 ost << "\\end{array}" << endl;
904}
905
906
908{
909 vector<int> Ord;
910 int *p;
911 int i;
913
915 p = NEW_int(Ord.size());
916 for (i = 0; i < (int) Ord.size(); i++) {
917 p[i] = Ord[i];
918 }
920 p, Ord.size(), 1, TRUE /* f_tex */);
921 FREE_int(p);
922}
923
925{
926 int i;
927 int ord;
928
929 for (i = 0; i < nb; i++) {
930 ord = order_of_point(i);
931 Ord.push_back(ord);
932 }
933}
934
935
937{
938 int j;
939 int ord;
940
941 j = i;
942 ord = 1;
943 while (j != 0) {
944 j = A[i * nb + j];
945 ord++;
946 }
947 return ord;
948}
949
951{
952 int j;
953 int ord;
954
955 j = i;
956 ord = 1;
957 while (j != 0) {
958 cout << ord << " & " << j << " & (" << T[3 * j + 0]
959 << ", " << T[3 * j + 1] << ", " << T[3 * j + 2]
960 << ")\\\\" << endl;
961 j = A[i * nb + j];
962 ord++;
963 }
964}
965
966}}}
967
968
969
options for drawing an object of type layered_graph
Definition: graphics.h:457
a general 2D graphical output interface (metapost, tikz, postscript)
Definition: graphics.h:545
void aligned_text(int x, int y, const char *alignment, const char *p)
void polygon2(int *Px, int *Py, int i1, int i2)
void init(std::string &file_name, layered_graph_draw_options *Draw_options, int verbose_level)
Definition: mp_graphics.cpp:71
void draw_axes_and_grid(layered_graph_draw_options *O, double x_min, double x_max, double y_min, double y_max, double dx, double dy, int f_x_axis_at_y_min, int f_y_axis_at_x_min, int x_mod, int y_mod, int x_tick_mod, int y_tick_mod, double x_labels_offset, double y_labels_offset, double x_tick_half_width, double y_tick_half_width, int f_v_lines, int subdivide_v, int f_h_lines, int subdivide_h, int verbose_level)
void sl_ends(int line_beg_style, int line_end_style)
void polygon5(int *Px, int *Py, int i1, int i2, int i3, int i4, int i5)
void fill_polygon5(int *Px, int *Py, int i1, int i2, int i3, int i4, int i5)
a fixed elliptic curve in Weierstrass form
Definition: number_theory.h:58
void init(field_theory::finite_field *F, int b, int c, int verbose_level)
void save_incidence_matrix(std::string &fname, int verbose_level)
void draw_grid(std::string &fname, graphics::layered_graph_draw_options *Draw_options, int f_with_grid, int f_with_points, int point_density, int f_path, int start_idx, int nb_steps, int verbose_level)
void make_affine_point(int x1, int x2, int x3, int &a, int &b, int verbose_level)
void addition(int x1, int y1, int z1, int x2, int y2, int z2, int &x3, int &y3, int &z3, int verbose_level)
void draw_grid2(graphics::mp_graphics &G, int f_with_grid, int f_with_points, int point_density, int f_path, int start_idx, int nb_steps, int verbose_level)
void elliptic_curve_addition(field_theory::finite_field *F, int b, int c, int x1, int x2, int x3, int y1, int y2, int y3, int &z1, int &z2, int &z3, int verbose_level)
void int_matrix_write_csv(std::string &fname, int *M, int m, int n)
Definition: file_io.cpp:1300
void int_matrix_print_tex(std::ostream &ost, int *p, int m, int n)
void print_integer_matrix_with_standard_labels(std::ostream &ost, int *p, int m, int n, int f_tex)
#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 Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define ODD(x)
Definition: foundations.h:222
int sqrt_mod_involved(int a, int p, int verbose_level)
Definition: global.cpp:628
the orbiter library for the classification of combinatorial objects