Import ntl_6.2.1.orig.tar.gz
Julien Puydt
9 years ago
0 | NTL -- a library for doing numbery theory -- version 6.2 | |
1 | Release date: 2014.08.21 | |
0 | NTL -- a library for doing numbery theory -- version 6.2.1 | |
1 | Release date: 2014.08.26 | |
2 | 2 | |
3 | 3 | Author: Victor Shoup (victor@shoup.net) |
4 | 4 |
3 | 3 | A Tour of NTL: Acknowledgements </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | |
8 | 7 | <center> |
9 | 8 | <a href="tour-changes.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
3 | 3 | A Tour of NTL: Summary of Changes </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-roadmap.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
18 | 17 | |
19 | 18 | <p> <hr> <p> |
20 | 19 | <h3> |
20 | 2014.8.26: Changes between NTL 6.2 and 6.2.1 | |
21 | </h3> | |
22 | ||
23 | <ul> | |
24 | <li> | |
25 | Fixed syntax problem in <tt>NTL/vector.h</tt> | |
26 | </ul> | |
27 | ||
28 | <p> <hr> <p> | |
29 | <h3> | |
21 | 30 | 2014.8.21: Changes between NTL 6.1 and 6.2 |
22 | 31 | </h3> |
23 | 32 | |
27 | 36 | <li> |
28 | 37 | I added <i>explicit</i> constructors corresponding to promotions. |
29 | 38 | For example: |
30 | <pre> | |
39 | <!-- STARTPLAIN | |
31 | 40 | ZZ w = ZZ(1); // legal |
32 | 41 | ZZ w(1); // legal |
33 | 42 | ZZ w{1}; // legal in C++11 |
34 | 43 | ZZ w = 1; // not legal |
35 | </pre> | |
44 | ENDPLAIN --> | |
45 | <!-- STARTPRETTY {{{ --> | |
46 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
47 | <font face="monospace"> | |
48 | ZZ w = ZZ(<font color="#ff8c00">1</font>); <font color="#0000ee"><i>// legal</i></font><br> | |
49 | ZZ w(<font color="#ff8c00">1</font>); <font color="#0000ee"><i>// legal</i></font><br> | |
50 | ZZ w{<font color="#ff8c00">1</font>}; <font color="#0000ee"><i>// legal in C++11</i></font><br> | |
51 | ZZ w = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// not legal</i></font><br> | |
52 | </font> | |
53 | </font></td></tr></table><p><p> | |
54 | <!-- }}} ENDPRETTY --> | |
55 | ||
36 | 56 | <p> |
37 | 57 | Also added new names for the "monomial constructors", e.g., |
38 | 58 | <tt>ZZX(INIT_MONO, i, c)</tt> is now preferred to <tt>ZZX(i, c)</tt>, |
94 | 114 | <tt>zz_pPush</tt>, <tt>zz_pEPush</tt>, <tt>GF2EPush</tt>. |
95 | 115 | These allow one to conveniently backup and optionally install |
96 | 116 | a new modulus in one step: |
97 | <pre> | |
117 | <!-- STARTPLAIN | |
98 | 118 | { ZZ_pPush push(p); ... } |
99 | </pre> | |
119 | ENDPLAIN --> | |
120 | <!-- STARTPRETTY {{{ --> | |
121 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
122 | <font face="monospace"> | |
123 | { ZZ_pPush push(p); ... }<br> | |
124 | </font> | |
125 | </font></td></tr></table><p><p> | |
126 | <!-- }}} ENDPRETTY --> | |
127 | ||
100 | 128 | will save the current modulus and install <tt>p</tt> as the |
101 | 129 | new modulus; when the destructor for <tt>push</tt> is invoked, |
102 | 130 | the old modulus will be re-installed. |
178 | 206 | <li> |
179 | 207 | Added support for "user defined" FFT primes for <tt>zz_p</tt>. |
180 | 208 | See the functions |
181 | <pre> | |
209 | <!-- STARTPLAIN | |
182 | 210 | static void zz_p::UserFFTInit(long p); |
183 | 211 | zz_pContext::zz_pContext(INIT_USER_FFT_TYPE, long p); |
184 | </pre> | |
212 | ENDPLAIN --> | |
213 | <!-- STARTPRETTY {{{ --> | |
214 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
215 | <font face="monospace"> | |
216 | <font color="#008b00"><b>static</b></font> <font color="#008b00"><b>void</b></font> zz_p::UserFFTInit(<font color="#008b00"><b>long</b></font> p);<br> | |
217 | zz_pContext::zz_pContext(INIT_USER_FFT_TYPE, <font color="#008b00"><b>long</b></font> p);<br> | |
218 | </font> | |
219 | </font></td></tr></table><p><p> | |
220 | <!-- }}} ENDPRETTY --> | |
221 | ||
185 | 222 | in the <tt>lzz_p</tt> module. |
186 | 223 | |
187 | 224 | </ul> |
275 | 312 | In the case where <tt>b</tt> is a <tt>long</tt>, |
276 | 313 | this may be much faster than writing |
277 | 314 | <tt>mul(t, a, b); add(x, x, t)</tt>. |
278 | See <a href="ZZ.txt">ZZ.txt</a> for details. | |
315 | See <a href="ZZ.cpp.html">ZZ.txt</a> for details. | |
279 | 316 | |
280 | 317 | These new routines are used in a number of places in |
281 | 318 | NTL to get faster algorithms (for example, the <tt>LLL</tt> routine). |
338 | 375 | |
339 | 376 | <li> |
340 | 377 | Added a callback mechanism to NTL's error reporting function. |
341 | See <tt>ErrorCallback</tt> in <a href="tools.txt">tools.txt</a>. | |
378 | See <tt>ErrorCallback</tt> in <a href="tools.cpp.html">tools.txt</a>. | |
342 | 379 | |
343 | 380 | <li> |
344 | 381 | Added support for the <tt>gf2x</tt> library for speeding up |
525 | 562 | <li> |
526 | 563 | Added functions <tt>IsWhiteSpace</tt>, <tt>CharToIntVal</tt>, |
527 | 564 | and <tt>IntValToChar</tt> to the <tt>tools</tt> module |
528 | <a href="tools.txt">[more details]</a>. | |
565 | <a href="tools.cpp.html">[more details]</a>. | |
529 | 566 | |
530 | 567 | <p> |
531 | 568 | <li> |
532 | 569 | Added methods <tt>allocated</tt>, <tt>position1</tt> to generic vector classes |
533 | <a href="vector.txt">[more details]</a>. | |
570 | <a href="vector.cpp.html">[more details]</a>. | |
534 | 571 | |
535 | 572 | <p> |
536 | 573 | <li> |
537 | 574 | Added method <tt>allocated</tt> to the class <tt>vec_GF2</tt> |
538 | <a href="vec_GF2.txt">[more details]</a>. | |
575 | <a href="vec_GF2.cpp.html">[more details]</a>. | |
539 | 576 | |
540 | 577 | <p> |
541 | 578 | <li> |
547 | 584 | Added routines <tt>AddPrec</tt>, <tt>SubPrec</tt>, etc., to the <tt>RR</tt> |
548 | 585 | module, and declared the practice of directly assigning to the variable |
549 | 586 | <tt>RR::prec</tt> obsolete |
550 | <a href="RR.txt">[more details]</a>. | |
587 | <a href="RR.cpp.html">[more details]</a>. | |
551 | 588 | |
552 | 589 | <p> |
553 | 590 | <li> |
572 | 609 | used by NTL, and is the default (one can switch back to the old algorithm |
573 | 610 | with a run-time switch). |
574 | 611 | <p> |
575 | <a href="ZZXFactoring.txt">[documentation]</a> | |
612 | <a href="ZZXFactoring.cpp.html">[documentation]</a> | |
576 | 613 | <p> |
577 | 614 | <a href="tour-time.html">[performance measurements]</a> |
578 | 615 | <p> |
582 | 619 | <tt>LLL</tt> routines, except that they return the exact values of the |
583 | 620 | squared lengths of the Gramm-Schmidt basis vectors. |
584 | 621 | This is useful in implementing van Hoeij's algorithm. |
585 | <a href="LLL.txt">[more details]</a>. | |
622 | <a href="LLL.cpp.html">[more details]</a>. | |
586 | 623 | <p> |
587 | 624 | |
588 | 625 | <li> |
607 | 644 | Any small bug fixes to this version will be named "5.2.1", "5.2.2", etc. |
608 | 645 | Also, macros are now defined so that the numerical components |
609 | 646 | of the version number are available to the programmer. |
610 | <a href="version.txt">[more details]</a>. | |
647 | <a href="version.cpp.html">[more details]</a>. | |
611 | 648 | |
612 | 649 | |
613 | 650 | </ul> |
629 | 666 | <li> |
630 | 667 | Added a routine <tt>LatticeSolve()</tt> for finding integer |
631 | 668 | solutions to linear systems of integer equations. |
632 | <a href="LLL.txt">[more details]</a> | |
669 | <a href="LLL.cpp.html">[more details]</a> | |
633 | 670 | |
634 | 671 | <p> |
635 | 672 | <li> |
636 | 673 | Modified the stragey used by the <tt>LLL()</tt> and <tt>image()</tt> |
637 | routines in the <a href="LLL.txt">LLL package</a> to deal | |
674 | routines in the <a href="LLL.cpp.html">LLL package</a> to deal | |
638 | 675 | with linear dependencies. |
639 | 676 | The new strategy guarantees better worst-case bounds on the |
640 | 677 | sizes of intermediate values. |
808 | 845 | <li> |
809 | 846 | Added function <tt>GenGermainPrime</tt> |
810 | 847 | to efficiently generate random Germain primes, i.e., primes <i>p</i> |
811 | such that <i>2p+1</i> is also prime. <a href="ZZ.txt">[more details]</a> | |
848 | such that <i>2p+1</i> is also prime. <a href="ZZ.cpp.html">[more details]</a> | |
812 | 849 | <li> |
813 | 850 | Added a function <tt>random</tt> to generate random <tt>quad_floats</tt>. |
814 | <a href="quad_float.txt">[more details]</a> | |
851 | <a href="quad_float.cpp.html">[more details]</a> | |
815 | 852 | <li> |
816 | 853 | Added an <tt>ifdef</tt> in <tt>tools.h</tt> that allows |
817 | 854 | one to suppress the declaration of <tt>min</tt> and <tt>max</tt> |
901 | 938 | <ul> |
902 | 939 | <li> |
903 | 940 | Improved time and space efficiency of the HNF routine |
904 | (see <a href="HNF.txt"><tt>HNF.txt</tt></a>). | |
941 | (see <a href="HNF.cpp.html"><tt>HNF.txt</tt></a>). | |
905 | 942 | The old version was based on the description in Henri Cohen's book, |
906 | 943 | which was not really properly optimized. |
907 | 944 | </ul> |
948 | 985 | RoundToPrecision, MakeRR |
949 | 986 | random |
950 | 987 | </pre> |
951 | See <a href="RR.txt"><tt>RR.txt</tt></a> for details. | |
988 | See <a href="RR.cpp.html"><tt>RR.txt</tt></a> for details. | |
952 | 989 | |
953 | 990 | <li> |
954 | 991 | Improved the accuracy of <tt>quad_float</tt> input/output, |
984 | 1021 | <li> |
985 | 1022 | Tightened up some size checks, so that now some nice "size invariants" |
986 | 1023 | are guaranteed, e.g., for a <tt>ZZ</tt> <tt>n</tt>, |
987 | <pre> | |
988 | NumBits(NumBits(n)) <= NTL_BITS_PER_LONG-4 | |
989 | </pre> | |
1024 | <!-- STARTPLAIN | |
1025 | NumBits(NumBits(n)) <= NTL_BITS_PER_LONG-4 | |
1026 | ENDPLAIN --> | |
1027 | <!-- STARTPRETTY {{{ --> | |
1028 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1029 | <font face="monospace"> | |
1030 | NumBits(NumBits(n)) <= NTL_BITS_PER_LONG-<font color="#ff8c00">4</font><br> | |
1031 | </font> | |
1032 | </font></td></tr></table><p><p> | |
1033 | <!-- }}} ENDPRETTY --> | |
1034 | ||
990 | 1035 | Similarly for the type <tt>GF2X</tt>. |
991 | 1036 | Of course, on most platforms, one will run out of memory before |
992 | 1037 | these bounds are exceeded, but they are nevertheless convenient. |
1015 | 1060 | for conversion between byte vectors and polynomials over <tt>GF(2)</tt>, |
1016 | 1061 | along with routines <tt>NumBits</tt> and <tt>NumBytes</tt> |
1017 | 1062 | for such polynomials. |
1018 | See <a href="GF2X.txt"><tt>GF2X.txt</tt></a> for details. | |
1063 | See <a href="GF2X.cpp.html"><tt>GF2X.txt</tt></a> for details. | |
1019 | 1064 | |
1020 | 1065 | <li> |
1021 | 1066 | Added a hack in the <tt>ZZX</tt> factorizer |
1022 | 1067 | to exploit polynomials of the form <tt>g(x^k)</tt>. |
1023 | 1068 | This can be disabled by setting the variable <tt>ZZXFac_PowerHack</tt> |
1024 | 1069 | to zero. |
1025 | See <a href="ZZXFactoring.txt"><tt>ZZXFactoring.txt</tt></a> | |
1070 | See <a href="ZZXFactoring.cpp.html"><tt>ZZXFactoring.txt</tt></a> | |
1026 | 1071 | for details. |
1027 | 1072 | |
1028 | 1073 | <li> |
1029 | 1074 | Improved the hensel system solver <tt>solve1</tt>. |
1030 | See <a href="mat_ZZ.txt"><tt>mat_ZZ.txt</tt></a> for details. | |
1075 | See <a href="mat_ZZ.cpp.html"><tt>mat_ZZ.txt</tt></a> for details. | |
1031 | 1076 | |
1032 | 1077 | <li> |
1033 | 1078 | Changed documentation for <tt>RationalReconstruction</tt> |
1034 | 1079 | to reflect the Wang, Guy, Davenport bounds. |
1035 | See <a href="ZZ.txt"><tt>ZZ.txt</tt></a> for details. | |
1080 | See <a href="ZZ.cpp.html"><tt>ZZ.txt</tt></a> for details. | |
1036 | 1081 | |
1037 | 1082 | <li> |
1038 | 1083 | Improved the routine <tt>GenPrime</tt> a bit. |
1059 | 1104 | <ul> |
1060 | 1105 | <li> |
1061 | 1106 | Added a "rational reconstruction" routine. |
1062 | See the routine <tt>ReconstructRational</tt> in <a href="ZZ.txt">ZZ.txt</a>. | |
1107 | See the routine <tt>ReconstructRational</tt> in <a href="ZZ.cpp.html">ZZ.txt</a>. | |
1063 | 1108 | <li> |
1064 | 1109 | Added another routine for solving linear systems over <tt>ZZ</tt> |
1065 | 1110 | that is based on Hensel lifting, rather than Chinese Remaindering. |
1066 | 1111 | It can be significantly faster in some cases. |
1067 | See the routine <tt>solve1</tt> in <a href="mat_ZZ.txt">mat_ZZ.txt</a>). | |
1112 | See the routine <tt>solve1</tt> in <a href="mat_ZZ.cpp.html">mat_ZZ.txt</a>). | |
1068 | 1113 | <li> |
1069 | 1114 | Some performace tuning, especially CRT and polynomial interpolation code. |
1070 | 1115 | <li> |
1200 | 1245 | The names of header files themeselves pollute another (extra-linguitsic) namespace. |
1201 | 1246 | To alleviate this problem, the header files have been renamed. |
1202 | 1247 | Instead of |
1203 | <pre> | |
1248 | <!-- STARTPLAIN | |
1204 | 1249 | #include "foo.h" |
1205 | </pre> | |
1250 | ENDPLAIN --> | |
1251 | <!-- STARTPRETTY {{{ --> | |
1252 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1253 | <font face="monospace"> | |
1254 | <font color="#1874cd"> #include </font><font color="#4a708b">"foo.h"</font><br> | |
1255 | </font> | |
1256 | </font></td></tr></table><p><p> | |
1257 | <!-- }}} ENDPRETTY --> | |
1258 | ||
1206 | 1259 | one now should write |
1207 | <pre> | |
1208 | #include <NTL/foo.h> | |
1209 | </pre> | |
1260 | <!-- STARTPLAIN | |
1261 | #include <NTL/foo.h> | |
1262 | ENDPLAIN --> | |
1263 | <!-- STARTPRETTY {{{ --> | |
1264 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1265 | <font face="monospace"> | |
1266 | <font color="#1874cd"> #include </font><font color="#4a708b"><NTL/foo.h></font><br> | |
1267 | </font> | |
1268 | </font></td></tr></table><p><p> | |
1269 | <!-- }}} ENDPRETTY --> | |
1270 | ||
1210 | 1271 | The only exceptions are the old header files "ntl_vector.h", |
1211 | 1272 | "ntl_matrix.h", and "ntl_pair.h", which are now called |
1212 | 1273 | <tt><NTL/vector.h></tt>, <tt><NTL/matrix.h></tt>, and |
1282 | 1343 | Added floating point LLL routines based on Givens rotations, |
1283 | 1344 | instead of classical Gramm-Schmidt orthogonalization. |
1284 | 1345 | This is a more stable, but somewhat slower, method. |
1285 | See <a href="LLL.txt">LLL.txt</a> for details. | |
1346 | See <a href="LLL.cpp.html">LLL.txt</a> for details. | |
1286 | 1347 | |
1287 | 1348 | <li> |
1288 | 1349 | Added support for irreducible trinomials and pentanomials |
1488 | 1549 | <li> |
1489 | 1550 | The conversion operator "<tt><<</tt>" has been retired. |
1490 | 1551 | Now instead of |
1491 | <pre> | |
1492 | x << a; | |
1493 | </pre> | |
1552 | <!-- STARTPLAIN | |
1553 | x << a; | |
1554 | ENDPLAIN --> | |
1555 | <!-- STARTPRETTY {{{ --> | |
1556 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1557 | <font face="monospace"> | |
1558 | x << a; <br> | |
1559 | </font> | |
1560 | </font></td></tr></table><p><p> | |
1561 | <!-- }}} ENDPRETTY --> | |
1562 | ||
1494 | 1563 | one writes |
1495 | <pre> | |
1564 | <!-- STARTPLAIN | |
1496 | 1565 | conv(x, a); |
1497 | </pre> | |
1566 | ENDPLAIN --> | |
1567 | <!-- STARTPRETTY {{{ --> | |
1568 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1569 | <font face="monospace"> | |
1570 | conv(x, a);<br> | |
1571 | </font> | |
1572 | </font></td></tr></table><p><p> | |
1573 | <!-- }}} ENDPRETTY --> | |
1574 | ||
1498 | 1575 | <p> |
1499 | 1576 | Operator "<tt><<</tt>" is now used for shift operations. |
1500 | 1577 | <li> |
1502 | 1579 | which has the name <tt>to_T</tt>, where <tt>T</tt> is the result type. |
1503 | 1580 | These new names replace old names that were less consistent. |
1504 | 1581 | So instead of |
1505 | <pre> | |
1582 | <!-- STARTPLAIN | |
1506 | 1583 | x = Long(a); |
1507 | </pre> | |
1584 | ENDPLAIN --> | |
1585 | <!-- STARTPRETTY {{{ --> | |
1586 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1587 | <font face="monospace"> | |
1588 | x = Long(a);<br> | |
1589 | </font> | |
1590 | </font></td></tr></table><p><p> | |
1591 | <!-- }}} ENDPRETTY --> | |
1592 | ||
1508 | 1593 | one writes |
1509 | <pre> | |
1594 | <!-- STARTPLAIN | |
1510 | 1595 | x = to_long(a); |
1511 | </pre> | |
1596 | ENDPLAIN --> | |
1597 | <!-- STARTPRETTY {{{ --> | |
1598 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1599 | <font face="monospace"> | |
1600 | x = to_long(a);<br> | |
1601 | </font> | |
1602 | </font></td></tr></table><p><p> | |
1603 | <!-- }}} ENDPRETTY --> | |
1604 | ||
1512 | 1605 | |
1513 | 1606 | |
1514 | 1607 | <li> |
1635 | 1728 | A more consistent and natural interface, including arithmetic operators |
1636 | 1729 | and a disciplined use of automatic conversion. |
1637 | 1730 | So now one can write |
1638 | <pre> | |
1731 | <!-- STARTPLAIN | |
1639 | 1732 | x = a * b + c; |
1640 | </pre> | |
1733 | ENDPLAIN --> | |
1734 | <!-- STARTPRETTY {{{ --> | |
1735 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1736 | <font face="monospace"> | |
1737 | x = a * b + c;<br> | |
1738 | </font> | |
1739 | </font></td></tr></table><p><p> | |
1740 | <!-- }}} ENDPRETTY --> | |
1741 | ||
1641 | 1742 | instead of |
1642 | <pre> | |
1743 | <!-- STARTPLAIN | |
1643 | 1744 | mul(x, a, b); |
1644 | 1745 | add(x, x, c); |
1645 | </pre> | |
1746 | ENDPLAIN --> | |
1747 | <!-- STARTPRETTY {{{ --> | |
1748 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1749 | <font face="monospace"> | |
1750 | mul(x, a, b);<br> | |
1751 | add(x, x, c);<br> | |
1752 | </font> | |
1753 | </font></td></tr></table><p><p> | |
1754 | <!-- }}} ENDPRETTY --> | |
1755 | ||
1646 | 1756 | as one must in older versions of NTL. |
1647 | 1757 | The operator notation leads to somewhat less efficient code, |
1648 | 1758 | and one can always use the old notation in situations |
3 | 3 | A Tour of NTL: Examples: Big Integers </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | |
8 | 7 | <center> |
9 | 8 | <img src="arrow1.gif" alt="[Previous]" align=bottom> |
26 | 25 | This program reads two big integers <tt>a</tt> and <tt>b</tt>, |
27 | 26 | and prints <tt>(a+1)*(b+1)</tt>. |
28 | 27 | |
29 | <p> | |
30 | <pre> | |
31 | #include <NTL/ZZ.h> | |
28 | <!-- STARTPLAIN | |
29 | #include <NTL/ZZ.h> | |
32 | 30 | |
33 | 31 | using namespace std; |
34 | 32 | using namespace NTL; |
37 | 35 | { |
38 | 36 | ZZ a, b, c; |
39 | 37 | |
40 | cin >> a; | |
41 | cin >> b; | |
38 | cin >> a; | |
39 | cin >> b; | |
42 | 40 | c = (a+1)*(b+1); |
43 | cout << c << "\n"; | |
41 | cout << c << "\n"; | |
44 | 42 | } |
45 | </pre> | |
46 | ||
47 | <p> | |
43 | ENDPLAIN --> | |
44 | <!-- STARTPRETTY {{{ --> | |
45 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
46 | <font face="monospace"> | |
47 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
48 | <br> | |
49 | using namespace std;<br> | |
50 | using namespace NTL;<br> | |
51 | <br> | |
52 | <font color="#008b00"><b>int</b></font> main()<br> | |
53 | {<br> | |
54 | ZZ a, b, c; <br> | |
55 | <br> | |
56 | cin >> a; <br> | |
57 | cin >> b; <br> | |
58 | c = (a+<font color="#ff8c00">1</font>)*(b+<font color="#ff8c00">1</font>);<br> | |
59 | cout << c << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
60 | }<br> | |
61 | </font> | |
62 | </font></td></tr></table><p><p> | |
63 | <!-- }}} ENDPRETTY --> | |
64 | ||
65 | ||
48 | 66 | |
49 | 67 | This program declares three variables <tt>a</tt>, <tt>b</tt>, |
50 | 68 | and <tt>c</tt> of type <tt>ZZ</tt>. |
77 | 95 | Here's a program that reads a list of integers from standard |
78 | 96 | input and prints the sum of their squares. |
79 | 97 | |
80 | <p> | |
81 | <pre> | |
82 | #include <NTL/ZZ.h> | |
98 | <!-- STARTPLAIN | |
99 | #include <NTL/ZZ.h> | |
83 | 100 | |
84 | 101 | |
85 | 102 | using namespace std; |
92 | 109 | |
93 | 110 | acc = 0; |
94 | 111 | while (SkipWhiteSpace(cin)) { |
95 | cin >> val; | |
112 | cin >> val; | |
96 | 113 | acc += val*val; |
97 | 114 | } |
98 | 115 | |
99 | cout << acc << "\n"; | |
116 | cout << acc << "\n"; | |
100 | 117 | } |
101 | </pre> | |
102 | ||
103 | <p> | |
118 | ENDPLAIN --> | |
119 | <!-- STARTPRETTY {{{ --> | |
120 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
121 | <font face="monospace"> | |
122 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
123 | <br> | |
124 | <br> | |
125 | using namespace std;<br> | |
126 | using namespace NTL;<br> | |
127 | <br> | |
128 | <br> | |
129 | <font color="#008b00"><b>int</b></font> main()<br> | |
130 | {<br> | |
131 | ZZ acc, val;<br> | |
132 | <br> | |
133 | acc = <font color="#ff8c00">0</font>;<br> | |
134 | <font color="#b03060"><b>while</b></font> (SkipWhiteSpace(cin)) {<br> | |
135 | cin >> val;<br> | |
136 | acc += val*val;<br> | |
137 | }<br> | |
138 | <br> | |
139 | cout << acc << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
140 | }<br> | |
141 | </font> | |
142 | </font></td></tr></table><p><p> | |
143 | <!-- }}} ENDPRETTY --> | |
144 | ||
145 | ||
104 | 146 | |
105 | 147 | The function <tt>SkipWhiteSpace</tt> is defined by NTL. |
106 | 148 | It skips over white space, and returns 1 if there is something |
126 | 168 | <tt>a^e mod n</tt>. |
127 | 169 | NTL already provides a more sophisticated one, though. |
128 | 170 | |
129 | <p> | |
130 | <pre> | |
131 | ZZ PowerMod(const ZZ& a, const ZZ& e, const ZZ& n) | |
171 | <!-- STARTPLAIN | |
172 | ZZ PowerMod(const ZZ& a, const ZZ& e, const ZZ& n) | |
132 | 173 | { |
133 | 174 | if (e == 0) return ZZ(1); |
134 | 175 | |
137 | 178 | ZZ res; |
138 | 179 | res = 1; |
139 | 180 | |
140 | for (long i = k-1; i >= 0; i--) { | |
181 | for (long i = k-1; i >= 0; i~~) { | |
141 | 182 | res = (res*res) % n; |
142 | 183 | if (bit(e, i) == 1) res = (res*a) % n; |
143 | 184 | } |
144 | 185 | |
145 | if (e < 0) | |
186 | if (e < 0) | |
146 | 187 | return InvMod(res, n); |
147 | 188 | else |
148 | 189 | return res; |
149 | 190 | } |
150 | </pre> | |
151 | <p> | |
191 | ENDPLAIN --> | |
192 | <!-- STARTPRETTY {{{ --> | |
193 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
194 | <font face="monospace"> | |
195 | ZZ PowerMod(<font color="#008b00"><b>const</b></font> ZZ& a, <font color="#008b00"><b>const</b></font> ZZ& e, <font color="#008b00"><b>const</b></font> ZZ& n)<br> | |
196 | {<br> | |
197 | <font color="#b03060"><b>if</b></font> (e == <font color="#ff8c00">0</font>) <font color="#b03060"><b>return</b></font> ZZ(<font color="#ff8c00">1</font>);<br> | |
198 | <br> | |
199 | <font color="#008b00"><b>long</b></font> k = NumBits(e);<br> | |
200 | <br> | |
201 | ZZ res;<br> | |
202 | res = <font color="#ff8c00">1</font>;<br> | |
203 | <br> | |
204 | <font color="#b03060"><b>for</b></font> (<font color="#008b00"><b>long</b></font> i = k-<font color="#ff8c00">1</font>; i >= <font color="#ff8c00">0</font>; i--) {<br> | |
205 | res = (res*res) % n;<br> | |
206 | <font color="#b03060"><b>if</b></font> (bit(e, i) == <font color="#ff8c00">1</font>) res = (res*a) % n;<br> | |
207 | }<br> | |
208 | <br> | |
209 | <font color="#b03060"><b>if</b></font> (e < <font color="#ff8c00">0</font>)<br> | |
210 | <font color="#b03060"><b>return</b></font> InvMod(res, n);<br> | |
211 | <font color="#b03060"><b>else</b></font><br> | |
212 | <font color="#b03060"><b>return</b></font> res;<br> | |
213 | }<br> | |
214 | </font> | |
215 | </font></td></tr></table><p><p> | |
216 | <!-- }}} ENDPRETTY --> | |
217 | ||
152 | 218 | |
153 | 219 | Note that as an alternative, we could implement the inner loop |
154 | 220 | as follows: |
155 | 221 | |
156 | <pre> | |
222 | <!-- STARTPLAIN | |
157 | 223 | res = SqrMod(res, n); |
158 | 224 | if (bit(e, i) == 1) res = MulMod(res, a, n); |
159 | </pre> | |
225 | ENDPLAIN --> | |
226 | <!-- STARTPRETTY {{{ --> | |
227 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
228 | <font face="monospace"> | |
229 | res = SqrMod(res, n);<br> | |
230 | <font color="#b03060"><b>if</b></font> (bit(e, i) == <font color="#ff8c00">1</font>) res = MulMod(res, a, n);<br> | |
231 | </font> | |
232 | </font></td></tr></table><p><p> | |
233 | <!-- }}} ENDPRETTY --> | |
234 | ||
160 | 235 | |
161 | 236 | We could also write this as: |
162 | 237 | |
163 | <pre> | |
238 | <!-- STARTPLAIN | |
164 | 239 | SqrMod(res, res, n); |
165 | 240 | if (bit(e, i) == 1) MulMod(res, res, a, n); |
166 | </pre> | |
241 | ENDPLAIN --> | |
242 | <!-- STARTPRETTY {{{ --> | |
243 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
244 | <font face="monospace"> | |
245 | SqrMod(res, res, n);<br> | |
246 | <font color="#b03060"><b>if</b></font> (bit(e, i) == <font color="#ff8c00">1</font>) MulMod(res, res, a, n);<br> | |
247 | </font> | |
248 | </font></td></tr></table><p><p> | |
249 | <!-- }}} ENDPRETTY --> | |
250 | ||
167 | 251 | |
168 | 252 | This illustrates an important point about NTL's programming interface. |
169 | 253 | For every function in NTL, there is a procedural version that |
192 | 276 | While we are taking about temporaries, consider the first version |
193 | 277 | of the inner loop. |
194 | 278 | Execution of the statement |
195 | <pre> | |
279 | <!-- STARTPLAIN | |
196 | 280 | res = (res*res) % n; |
197 | </pre> | |
281 | ENDPLAIN --> | |
282 | <!-- STARTPRETTY {{{ --> | |
283 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
284 | <font face="monospace"> | |
285 | res = (res*res) % n;<br> | |
286 | </font> | |
287 | </font></td></tr></table><p><p> | |
288 | <!-- }}} ENDPRETTY --> | |
289 | ||
198 | 290 | will result in the creation of two temporary objects, |
199 | 291 | one for the product, and one for the result of the mod operation, |
200 | 292 | whose value is copied into <tt>res</tt>. |
211 | 303 | Note that NTL already provides a slightly more sophisticated |
212 | 304 | primality test. |
213 | 305 | |
214 | <p> | |
215 | <pre> | |
216 | #include <NTL/ZZ.h> | |
306 | <!-- STARTPLAIN | |
307 | #include <NTL/ZZ.h> | |
217 | 308 | |
218 | 309 | using namespace std; |
219 | 310 | using namespace NTL; |
220 | 311 | |
221 | long witness(const ZZ& n, const ZZ& x) | |
312 | long witness(const ZZ& n, const ZZ& x) | |
222 | 313 | { |
223 | 314 | ZZ m, y, z; |
224 | 315 | long j, k; |
242 | 333 | y = z; |
243 | 334 | z = (y*y) % n; |
244 | 335 | j++; |
245 | } while (j < k && z != 1); | |
336 | } while (j < k && z != 1); | |
246 | 337 | |
247 | 338 | return z != 1 || y != n-1; |
248 | 339 | } |
249 | 340 | |
250 | 341 | |
251 | long PrimeTest(const ZZ& n, long t) | |
342 | long PrimeTest(const ZZ& n, long t) | |
252 | 343 | { |
253 | if (n <= 1) return 0; | |
344 | if (n <= 1) return 0; | |
254 | 345 | |
255 | 346 | // first, perform trial division by primes up to 2000 |
256 | 347 | |
268 | 359 | ZZ x; |
269 | 360 | long i; |
270 | 361 | |
271 | for (i = 0; i < t; i++) { | |
362 | for (i = 0; i < t; i++) { | |
272 | 363 | x = RandomBnd(n); // random number between 0 and n-1 |
273 | 364 | |
274 | 365 | if (witness(n, x)) |
282 | 373 | { |
283 | 374 | ZZ n; |
284 | 375 | |
285 | cout << "n: "; | |
286 | cin >> n; | |
376 | cout << "n: "; | |
377 | cin >> n; | |
287 | 378 | |
288 | 379 | if (PrimeTest(n, 10)) |
289 | cout << n << " is probably prime\n"; | |
380 | cout << n << " is probably prime\n"; | |
290 | 381 | else |
291 | cout << n << " is composite\n"; | |
382 | cout << n << " is composite\n"; | |
292 | 383 | } |
293 | </pre> | |
294 | <p> | |
384 | ENDPLAIN --> | |
385 | <!-- STARTPRETTY {{{ --> | |
386 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
387 | <font face="monospace"> | |
388 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
389 | <br> | |
390 | <font color="#b03060"><b>using</b></font> <font color="#008b00"><b>namespace</b></font> std;<br> | |
391 | <font color="#b03060"><b>using</b></font> <font color="#008b00"><b>namespace</b></font> NTL;<br> | |
392 | <br> | |
393 | <font color="#008b00"><b>long</b></font> witness(<font color="#008b00"><b>const</b></font> ZZ& n, <font color="#008b00"><b>const</b></font> ZZ& x)<br> | |
394 | {<br> | |
395 | ZZ m, y, z;<br> | |
396 | <font color="#008b00"><b>long</b></font> j, k;<br> | |
397 | <br> | |
398 | <font color="#b03060"><b>if</b></font> (x == <font color="#ff8c00">0</font>) <font color="#b03060"><b>return</b></font> <font color="#ff8c00">0</font>;<br> | |
399 | <br> | |
400 | <font color="#0000ee"><i>// compute m, k such that n-1 = 2^k * m, m odd:</i></font><br> | |
401 | <br> | |
402 | k = <font color="#ff8c00">1</font>;<br> | |
403 | m = n/<font color="#ff8c00">2</font>;<br> | |
404 | <font color="#b03060"><b>while</b></font> (m % <font color="#ff8c00">2</font> == <font color="#ff8c00">0</font>) {<br> | |
405 | k++;<br> | |
406 | m /= <font color="#ff8c00">2</font>;<br> | |
407 | }<br> | |
408 | <br> | |
409 | z = PowerMod(x, m, n); <font color="#0000ee"><i>// z = x^m % n</i></font><br> | |
410 | <font color="#b03060"><b>if</b></font> (z == <font color="#ff8c00">1</font>) <font color="#b03060"><b>return</b></font> <font color="#ff8c00">0</font>;<br> | |
411 | <br> | |
412 | j = <font color="#ff8c00">0</font>;<br> | |
413 | <font color="#b03060"><b>do</b></font> {<br> | |
414 | y = z;<br> | |
415 | z = (y*y) % n; <br> | |
416 | j++;<br> | |
417 | } <font color="#b03060"><b>while</b></font> (j < k && z != <font color="#ff8c00">1</font>);<br> | |
418 | <br> | |
419 | <font color="#b03060"><b>return</b></font> z != <font color="#ff8c00">1</font> || y != n-<font color="#ff8c00">1</font>;<br> | |
420 | }<br> | |
421 | <br> | |
422 | <br> | |
423 | <font color="#008b00"><b>long</b></font> PrimeTest(<font color="#008b00"><b>const</b></font> ZZ& n, <font color="#008b00"><b>long</b></font> t)<br> | |
424 | {<br> | |
425 | <font color="#b03060"><b>if</b></font> (n <= <font color="#ff8c00">1</font>) <font color="#b03060"><b>return</b></font> <font color="#ff8c00">0</font>;<br> | |
426 | <br> | |
427 | <font color="#0000ee"><i>// first, perform trial division by primes up to 2000</i></font><br> | |
428 | <br> | |
429 | PrimeSeq s; <font color="#0000ee"><i>// a class for quickly generating primes in sequence</i></font><br> | |
430 | <font color="#008b00"><b>long</b></font> p;<br> | |
431 | <br> | |
432 | p = s.next(); <font color="#0000ee"><i>// first prime is always 2</i></font><br> | |
433 | <font color="#b03060"><b>while</b></font> (p && p < <font color="#ff8c00">2000</font>) {<br> | |
434 | <font color="#b03060"><b>if</b></font> ((n % p) == <font color="#ff8c00">0</font>) <font color="#b03060"><b>return</b></font> (n == p);<br> | |
435 | p = s.next(); <br> | |
436 | }<br> | |
437 | <br> | |
438 | <font color="#0000ee"><i>// second, perform t Miller-Rabin tests</i></font><br> | |
439 | <br> | |
440 | ZZ x;<br> | |
441 | <font color="#008b00"><b>long</b></font> i;<br> | |
442 | <br> | |
443 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">0</font>; i < t; i++) {<br> | |
444 | x = RandomBnd(n); <font color="#0000ee"><i>// random number between 0 and n-1</i></font><br> | |
445 | <br> | |
446 | <font color="#b03060"><b>if</b></font> (witness(n, x)) <br> | |
447 | <font color="#b03060"><b>return</b></font> <font color="#ff8c00">0</font>;<br> | |
448 | }<br> | |
449 | <br> | |
450 | <font color="#b03060"><b>return</b></font> <font color="#ff8c00">1</font>;<br> | |
451 | }<br> | |
452 | <br> | |
453 | <font color="#008b00"><b>int</b></font> main()<br> | |
454 | {<br> | |
455 | ZZ n;<br> | |
456 | <br> | |
457 | cout << <font color="#4a708b">"n: "</font>;<br> | |
458 | cin >> n;<br> | |
459 | <br> | |
460 | <font color="#b03060"><b>if</b></font> (PrimeTest(n, <font color="#ff8c00">10</font>))<br> | |
461 | cout << n << <font color="#4a708b">" is probably prime</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
462 | <font color="#b03060"><b>else</b></font><br> | |
463 | cout << n << <font color="#4a708b">" is composite</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
464 | }<br> | |
465 | </font> | |
466 | </font></td></tr></table><p><p> | |
467 | <!-- }}} ENDPRETTY --> | |
468 | ||
295 | 469 | |
296 | 470 | Note that in NTL, there are typically a number of ways to |
297 | 471 | compute the same thing. |
299 | 473 | in function <tt>witness</tt>. |
300 | 474 | We could have written it thusly: |
301 | 475 | |
302 | <pre> | |
476 | <!-- STARTPLAIN | |
303 | 477 | k = 1; |
304 | m = n >> 1; | |
478 | m = n >> 1; | |
305 | 479 | while (!IsOdd(m)) { |
306 | 480 | k++; |
307 | m >>= 1; | |
481 | m >>= 1; | |
308 | 482 | } |
309 | </pre> | |
483 | ENDPLAIN --> | |
484 | <!-- STARTPRETTY {{{ --> | |
485 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
486 | <font face="monospace"> | |
487 | k = <font color="#ff8c00">1</font>;<br> | |
488 | m = n >> <font color="#ff8c00">1</font>;<br> | |
489 | <font color="#b03060"><b>while</b></font> (!IsOdd(m)) {<br> | |
490 | k++;<br> | |
491 | m >>= <font color="#ff8c00">1</font>;<br> | |
492 | }<br> | |
493 | </font> | |
494 | </font></td></tr></table><p><p> | |
495 | <!-- }}} ENDPRETTY --> | |
496 | ||
310 | 497 | |
311 | 498 | It turns out that this is actually not significantly more |
312 | 499 | efficient than the original version, because the implementation |
316 | 503 | |
317 | 504 | The following is more efficient: |
318 | 505 | |
319 | <pre> | |
506 | <!-- STARTPLAIN | |
320 | 507 | k = 1; |
321 | 508 | while (bit(n, k) == 0) k++; |
322 | m = n >> k; | |
323 | </pre> | |
509 | m = n >> k; | |
510 | ENDPLAIN --> | |
511 | <!-- STARTPRETTY {{{ --> | |
512 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
513 | <font face="monospace"> | |
514 | k = <font color="#ff8c00">1</font>;<br> | |
515 | <font color="#b03060"><b>while</b></font> (bit(n, k) == <font color="#ff8c00">0</font>) k++;<br> | |
516 | m = n >> k;<br> | |
517 | </font> | |
518 | </font></td></tr></table><p><p> | |
519 | <!-- }}} ENDPRETTY --> | |
520 | ||
324 | 521 | |
325 | 522 | As it happens, there is a built-in NTL routine that does just what we want: |
326 | 523 | |
327 | <pre> | |
524 | <!-- STARTPLAIN | |
328 | 525 | m = n-1; |
329 | 526 | k = MakeOdd(m); |
330 | </pre> | |
527 | ENDPLAIN --> | |
528 | <!-- STARTPRETTY {{{ --> | |
529 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
530 | <font face="monospace"> | |
531 | m = n-<font color="#ff8c00">1</font>;<br> | |
532 | k = MakeOdd(m);<br> | |
533 | </font> | |
534 | </font></td></tr></table><p><p> | |
535 | <!-- }}} ENDPRETTY --> | |
536 | ||
331 | 537 | |
332 | 538 | |
333 | 539 | |
356 | 562 | |
357 | 563 | <p> |
358 | 564 | One can also assign a value of type <tt>long</tt> to a <tt>ZZ</tt>: |
359 | <pre> | |
565 | <!-- STARTPLAIN | |
360 | 566 | ZZ x; |
361 | 567 | x = 1; |
362 | </pre> | |
568 | ENDPLAIN --> | |
569 | <!-- STARTPRETTY {{{ --> | |
570 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
571 | <font face="monospace"> | |
572 | ZZ x;<br> | |
573 | x = <font color="#ff8c00">1</font>;<br> | |
574 | </font> | |
575 | </font></td></tr></table><p><p> | |
576 | <!-- }}} ENDPRETTY --> | |
577 | ||
363 | 578 | |
364 | 579 | <p> |
365 | 580 | Note that one cannot write |
366 | <pre> | |
581 | <!-- STARTPLAIN | |
367 | 582 | ZZ x = 1; // error |
368 | </pre> | |
583 | ENDPLAIN --> | |
584 | <!-- STARTPRETTY {{{ --> | |
585 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
586 | <font face="monospace"> | |
587 | ZZ x = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// error</i></font><br> | |
588 | </font> | |
589 | </font></td></tr></table><p><p> | |
590 | <!-- }}} ENDPRETTY --> | |
591 | ||
369 | 592 | to initialize a <tt>ZZ</tt>. |
370 | 593 | Instead, one could write |
371 | <pre> | |
594 | <!-- STARTPLAIN | |
372 | 595 | ZZ x = ZZ(1); |
373 | 596 | ZZ y(1); |
374 | 597 | ZZ z{1}; // C++11 only |
375 | </pre> | |
598 | ENDPLAIN --> | |
599 | <!-- STARTPRETTY {{{ --> | |
600 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
601 | <font face="monospace"> | |
602 | ZZ x = ZZ(<font color="#ff8c00">1</font>);<br> | |
603 | ZZ y(<font color="#ff8c00">1</font>);<br> | |
604 | ZZ z{<font color="#ff8c00">1</font>}; <font color="#0000ee"><i>// C++11 only</i></font><br> | |
605 | </font> | |
606 | </font></td></tr></table><p><p> | |
607 | <!-- }}} ENDPRETTY --> | |
608 | ||
376 | 609 | Using the comstructor that allows one to <i>explicitly</i> |
377 | 610 | construct a <tt>ZZ</tt> from a <tt>long</tt>. |
378 | 611 | |
379 | 612 | <p> |
380 | 613 | Alternatively, one could write this as: |
381 | <pre> | |
382 | ZZ x = conv<ZZ>(1); | |
383 | </pre> | |
614 | <!-- STARTPLAIN | |
615 | ZZ x = conv<ZZ>(1); | |
616 | ENDPLAIN --> | |
617 | <!-- STARTPRETTY {{{ --> | |
618 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
619 | <font face="monospace"> | |
620 | ZZ x = conv<ZZ>(<font color="#ff8c00">1</font>);<br> | |
621 | </font> | |
622 | </font></td></tr></table><p><p> | |
623 | <!-- }}} ENDPRETTY --> | |
624 | ||
384 | 625 | This is an example of one of NTL's conversion routines. |
385 | 626 | For very large constants, one can write: |
386 | <pre> | |
387 | ZZ x = conv<ZZ>("99999999999999999999"); | |
388 | </pre> | |
627 | <!-- STARTPLAIN | |
628 | ZZ x = conv<ZZ>("99999999999999999999"); | |
629 | ENDPLAIN --> | |
630 | <!-- STARTPRETTY {{{ --> | |
631 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
632 | <font face="monospace"> | |
633 | ZZ x = conv<ZZ>(<font color="#4a708b">"99999999999999999999"</font>);<br> | |
634 | </font> | |
635 | </font></td></tr></table><p><p> | |
636 | <!-- }}} ENDPRETTY --> | |
637 | ||
389 | 638 | These examples illustrate conversion rountines in their |
390 | 639 | functional forms. |
391 | <pre> | |
640 | <!-- STARTPLAIN | |
392 | 641 | ZZ x; |
393 | 642 | conv(x, 1); |
394 | 643 | conv(x, "99999999999999999999"); |
395 | </pre> | |
644 | ENDPLAIN --> | |
645 | <!-- STARTPRETTY {{{ --> | |
646 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
647 | <font face="monospace"> | |
648 | ZZ x;<br> | |
649 | conv(x, <font color="#ff8c00">1</font>);<br> | |
650 | conv(x, <font color="#4a708b">"99999999999999999999"</font>);<br> | |
651 | </font> | |
652 | </font></td></tr></table><p><p> | |
653 | <!-- }}} ENDPRETTY --> | |
654 | ||
396 | 655 | |
397 | 656 | <p> |
398 | 657 | <b> |
466 | 725 | |
467 | 726 | <p> |
468 | 727 | There are other functions as well. |
469 | See <a href="ZZ.txt"><tt>ZZ.txt</tt></a> for complete details. | |
470 | Also see <a href="tools.txt"><tt>tools.txt</tt></a> for some basic | |
728 | See <a href="ZZ.cpp.html"><tt>ZZ.txt</tt></a> for complete details. | |
729 | Also see <a href="tools.cpp.html"><tt>tools.txt</tt></a> for some basic | |
471 | 730 | services provided by NTL. |
472 | 731 | |
473 | 732 |
3 | 3 | A Tour of NTL: Examples: Vectors and Matrices </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-ex1.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour-examples.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
24 | 23 | The following routine sums up the |
25 | 24 | numbers in a vector of <tt>ZZ</tt>'s. |
26 | 25 | |
27 | <pre> | |
28 | #include <NTL/ZZ.h> | |
29 | #include <NTL/vector.h> | |
26 | <!-- STARTPLAIN | |
27 | #include <NTL/ZZ.h> | |
28 | #include <NTL/vector.h> | |
30 | 29 | |
31 | 30 | using namespace std; |
32 | 31 | using namespace NTL; |
33 | 32 | |
34 | ZZ sum(const Vec<ZZ>& v) | |
33 | ZZ sum(const Vec<ZZ>& v) | |
35 | 34 | { |
36 | 35 | ZZ acc; |
37 | 36 | |
38 | 37 | acc = 0; |
39 | 38 | |
40 | for (long i = 0; i < v.length(); i++) | |
39 | for (long i = 0; i < v.length(); i++) | |
41 | 40 | acc += v[i]; |
42 | 41 | |
43 | 42 | return acc; |
44 | 43 | } |
45 | </pre> | |
44 | ENDPLAIN --> | |
45 | <!-- STARTPRETTY {{{ --> | |
46 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
47 | <font face="monospace"> | |
48 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
49 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/vector.h></font><br> | |
50 | <br> | |
51 | using namespace std;<br> | |
52 | using namespace NTL;<br> | |
53 | <br> | |
54 | ZZ sum(<font color="#008b00"><b>const</b></font> Vec<ZZ>& v)<br> | |
55 | {<br> | |
56 | ZZ acc;<br> | |
57 | <br> | |
58 | acc = <font color="#ff8c00">0</font>;<br> | |
59 | <br> | |
60 | <font color="#b03060"><b>for</b></font> (<font color="#008b00"><b>long</b></font> i = <font color="#ff8c00">0</font>; i < v.length(); i++)<br> | |
61 | acc += v[i];<br> | |
62 | <br> | |
63 | <font color="#b03060"><b>return</b></font> acc;<br> | |
64 | }<br> | |
65 | </font> | |
66 | </font></td></tr></table><p><p> | |
67 | <!-- }}} ENDPRETTY --> | |
68 | ||
46 | 69 | |
47 | 70 | <p> |
48 | 71 | The class <tt>Vec<ZZ></tt> is a dynamic-length array of <tt>ZZ</tt>s; |
67 | 90 | The generic vector class allows for this; |
68 | 91 | the above example could be written as follows. |
69 | 92 | |
70 | <pre> | |
71 | #include <NTL/ZZ.h> | |
72 | #include <NTL/vector.h> | |
93 | <!-- STARTPLAIN | |
94 | #include <NTL/ZZ.h> | |
95 | #include <NTL/vector.h> | |
73 | 96 | |
74 | 97 | using namespace std; |
75 | 98 | using namespace NTL; |
76 | 99 | |
77 | ZZ sum(ZZ& s, const Vec<ZZ>& v) | |
100 | ZZ sum(ZZ& s, const Vec<ZZ>& v) | |
78 | 101 | { |
79 | 102 | ZZ acc; |
80 | 103 | |
81 | 104 | acc = 0; |
82 | 105 | |
83 | for (long i = 1; i <= v.length(); i++) | |
106 | for (long i = 1; i <= v.length(); i++) | |
84 | 107 | acc += v(i); |
85 | 108 | |
86 | 109 | return acc; |
87 | 110 | } |
88 | </pre> | |
111 | ENDPLAIN --> | |
112 | <!-- STARTPRETTY {{{ --> | |
113 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
114 | <font face="monospace"> | |
115 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
116 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/vector.h></font><br> | |
117 | <br> | |
118 | using namespace std;<br> | |
119 | using namespace NTL;<br> | |
120 | <br> | |
121 | ZZ sum(ZZ& s, <font color="#008b00"><b>const</b></font> Vec<ZZ>& v)<br> | |
122 | {<br> | |
123 | ZZ acc;<br> | |
124 | <br> | |
125 | acc = <font color="#ff8c00">0</font>;<br> | |
126 | <br> | |
127 | <font color="#b03060"><b>for</b></font> (<font color="#008b00"><b>long</b></font> i = <font color="#ff8c00">1</font>; i <= v.length(); i++)<br> | |
128 | acc += v(i); <br> | |
129 | <br> | |
130 | <font color="#b03060"><b>return</b></font> acc;<br> | |
131 | }<br> | |
132 | </font> | |
133 | </font></td></tr></table><p><p> | |
134 | <!-- }}} ENDPRETTY --> | |
135 | ||
89 | 136 | |
90 | 137 | <p> |
91 | 138 | Note that by default, NTL does not perform range checks on |
101 | 148 | This program reads a <tt>Vec<ZZ></tt>, |
102 | 149 | and then creates and prints a "palindrome". |
103 | 150 | |
104 | <pre> | |
105 | #include <NTL/ZZ.h> | |
106 | #include <NTL/vector.h> | |
151 | <!-- STARTPLAIN | |
152 | #include <NTL/ZZ.h> | |
153 | #include <NTL/vector.h> | |
107 | 154 | |
108 | 155 | using namespace std; |
109 | 156 | using namespace NTL; |
110 | 157 | |
111 | 158 | int main() |
112 | 159 | { |
113 | Vec<ZZ> v; | |
114 | cin >> v; | |
160 | Vec<ZZ> v; | |
161 | cin >> v; | |
115 | 162 | |
116 | 163 | long n = v.length(); |
117 | 164 | v.SetLength(2*n); |
120 | 167 | for (i = 0 ; i < n; i++) |
121 | 168 | v[n+i] = v[n-1-i]; |
122 | 169 | |
123 | cout << v << "\n"; | |
170 | cout << v << "\n"; | |
124 | 171 | } |
125 | </pre> | |
172 | ENDPLAIN --> | |
173 | <!-- STARTPRETTY {{{ --> | |
174 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
175 | <font face="monospace"> | |
176 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
177 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/vector.h></font><br> | |
178 | <br> | |
179 | using namespace std;<br> | |
180 | using namespace NTL;<br> | |
181 | <br> | |
182 | <font color="#008b00"><b>int</b></font> main()<br> | |
183 | {<br> | |
184 | Vec<ZZ> v;<br> | |
185 | cin >> v;<br> | |
186 | <br> | |
187 | <font color="#008b00"><b>long</b></font> n = v.length();<br> | |
188 | v.SetLength(<font color="#ff8c00">2</font>*n);<br> | |
189 | <br> | |
190 | <font color="#008b00"><b>long</b></font> i;<br> | |
191 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">0</font> ; i < n; i++)<br> | |
192 | v[n+i] = v[n-<font color="#ff8c00">1</font>-i];<br> | |
193 | <br> | |
194 | cout << v <&lt <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
195 | }<br> | |
196 | </font> | |
197 | </font></td></tr></table><p><p> | |
198 | <!-- }}} ENDPRETTY --> | |
199 | ||
126 | 200 | |
127 | 201 | <p> |
128 | 202 | |
143 | 217 | |
144 | 218 | <p> |
145 | 219 | |
146 | See <a href="vector.txt"><tt>vector.txt</tt></a> for | |
220 | See <a href="vector.cpp.html"><tt>vector.txt</tt></a> for | |
147 | 221 | complete details of NTL's generic vector mechanism. |
148 | 222 | |
149 | 223 | Also note that for several fundamental vector types, such as |
152 | 226 | a number of basic arithmetic operations, |
153 | 227 | as well as provides the typedef |
154 | 228 | typedef <tt>vec_ZZ</tt> for backward compatibilty. |
155 | See <a href="vec_ZZ.txt"><tt>vec_ZZ.txt</tt></a> for | |
229 | See <a href="vec_ZZ.cpp.html"><tt>vec_ZZ.txt</tt></a> for | |
156 | 230 | complete details on the arithmetic operations for <tt>Vec<ZZ></tt>'s |
157 | 231 | provided by NTL. |
158 | 232 | |
176 | 250 | Here is a matrix multiplication routine, |
177 | 251 | which in fact is already provided by NTL. |
178 | 252 | |
179 | <pre> | |
180 | #include <NTL/ZZ.h> | |
181 | #include <NTL/matrix.h> | |
253 | <!-- STARTPLAIN | |
254 | #include <NTL/ZZ.h> | |
255 | #include <NTL/matrix.h> | |
182 | 256 | |
183 | 257 | using namespace std; |
184 | 258 | using namespace NTL; |
185 | 259 | |
186 | void mul(Mat<ZZ>& X, const Mat<ZZ>& A, const Mat<ZZ>& B) | |
260 | void mul(Mat<ZZ>& X, const Mat<ZZ>& A, const Mat<ZZ>& B) | |
187 | 261 | { |
188 | 262 | long n = A.NumRows(); |
189 | 263 | long l = A.NumCols(); |
197 | 271 | long i, j, k; |
198 | 272 | ZZ acc, tmp; |
199 | 273 | |
200 | for (i = 1; i <= n; i++) { | |
201 | for (j = 1; j <= m; j++) { | |
274 | for (i = 1; i <= n; i++) { | |
275 | for (j = 1; j <= m; j++) { | |
202 | 276 | acc = 0; |
203 | for(k = 1; k <= l; k++) { | |
277 | for(k = 1; k <= l; k++) { | |
204 | 278 | mul(tmp, A(i,k), B(k,j)); |
205 | 279 | add(acc, acc, tmp); |
206 | 280 | } |
208 | 282 | } |
209 | 283 | } |
210 | 284 | } |
211 | </pre> | |
285 | ENDPLAIN --> | |
286 | <!-- STARTPRETTY {{{ --> | |
287 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
288 | <font face="monospace"> | |
289 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
290 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/matrix.h></font><br> | |
291 | <br> | |
292 | using namespace std;<br> | |
293 | using namespace NTL;<br> | |
294 | <br> | |
295 | <font color="#008b00"><b>void</b></font> mul(Mat<ZZ>& X, <font color="#008b00"><b>const</b></font> Mat<ZZ>& A, <font color="#008b00"><b>const</b></font> Mat<ZZ>& B)<br> | |
296 | {<br> | |
297 | <font color="#008b00"><b>long</b></font> n = A.NumRows();<br> | |
298 | <font color="#008b00"><b>long</b></font> l = A.NumCols();<br> | |
299 | <font color="#008b00"><b>long</b></font> m = B.NumCols();<br> | |
300 | <br> | |
301 | <font color="#b03060"><b>if</b></font> (l != B.NumRows())<br> | |
302 | Error(<font color="#4a708b">"matrix mul: dimension mismatch"</font>);<br> | |
303 | <br> | |
304 | X.SetDims(n, m); <font color="#0000ee"><i>// make X have n rows and m columns</i></font><br> | |
305 | <br> | |
306 | <font color="#008b00"><b>long</b></font> i, j, k;<br> | |
307 | ZZ acc, tmp;<br> | |
308 | <br> | |
309 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">1</font>; i <= n; i++) {<br> | |
310 | <font color="#b03060"><b>for</b></font> (j = <font color="#ff8c00">1</font>; j <= m; j++) {<br> | |
311 | acc = <font color="#ff8c00">0</font>;<br> | |
312 | <font color="#b03060"><b>for</b></font>(k = <font color="#ff8c00">1</font>; k <= l; k++) {<br> | |
313 | mul(tmp, A(i,k), B(k,j));<br> | |
314 | add(acc, acc, tmp);<br> | |
315 | }<br> | |
316 | X(i,j) = acc;<br> | |
317 | }<br> | |
318 | }<br> | |
319 | }<br> | |
320 | </font> | |
321 | </font></td></tr></table><p><p> | |
322 | <!-- }}} ENDPRETTY --> | |
323 | ||
212 | 324 | |
213 | 325 | <p> |
214 | 326 | In case of a dimension mismatch, the routine calls the |
235 | 347 | |
236 | 348 | <p> |
237 | 349 | NTL provides several matrix types. |
238 | See <a href="matrix.txt"><tt>matrix.txt</tt></a> | |
350 | See <a href="matrix.cpp.html"><tt>matrix.txt</tt></a> | |
239 | 351 | for complete details on NTL's generic matrix mechanism. |
240 | Also see <a href="mat_ZZ.txt"><tt>mat_ZZ.txt</tt></a> for | |
352 | Also see <a href="mat_ZZ.cpp.html"><tt>mat_ZZ.txt</tt></a> for | |
241 | 353 | complete details on the arithmetic operations for <tt>Mat<ZZ></tt>'s |
242 | 354 | provideed by NTL (including basic linear algebra). |
243 | Also see <a href="LLL.txt"><tt>LLL.txt</tt></a> | |
355 | Also see <a href="LLL.cpp.html"><tt>LLL.txt</tt></a> | |
244 | 356 | for details on routines for lattice basis reduction |
245 | 357 | (as well as routines for finding the kernel and image of a matrix). |
246 | 358 |
3 | 3 | A Tour of NTL: Examples: Polynomials </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | |
8 | 7 | <center> |
9 | 8 | <a href="tour-ex2.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
29 | 28 | The following program reads a polynomial, |
30 | 29 | factors it, and prints the factorization. |
31 | 30 | |
32 | <p> | |
33 | <pre> | |
34 | #include <NTL/ZZXFactoring.h> | |
31 | <!-- STARTPLAIN | |
32 | #include <NTL/ZZXFactoring.h> | |
35 | 33 | |
36 | 34 | using namespace std; |
37 | 35 | using namespace NTL; |
40 | 38 | { |
41 | 39 | ZZX f; |
42 | 40 | |
43 | cin >> f; | |
44 | ||
45 | Vec< Pair< ZZX, long > > factors; | |
41 | cin >> f; | |
42 | ||
43 | Vec< Pair< ZZX, long > > factors; | |
46 | 44 | ZZ c; |
47 | 45 | |
48 | 46 | factor(c, factors, f); |
49 | 47 | |
50 | cout << c << "\n"; | |
51 | cout << factors << "\n"; | |
48 | cout << c << "\n"; | |
49 | cout << factors << "\n"; | |
52 | 50 | } |
53 | </pre> | |
54 | <p> | |
51 | ENDPLAIN --> | |
52 | <!-- STARTPRETTY {{{ --> | |
53 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
54 | <font face="monospace"> | |
55 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZXFactoring.h></font><br> | |
56 | <br> | |
57 | using namespace std;<br> | |
58 | using namespace NTL;<br> | |
59 | <br> | |
60 | <font color="#008b00"><b>int</b></font> main()<br> | |
61 | {<br> | |
62 | ZZX f;<br> | |
63 | <br> | |
64 | cin >> f;<br> | |
65 | <br> | |
66 | Vec< Pair< ZZX, <font color="#008b00"><b>long</b></font> > > factors;<br> | |
67 | ZZ c;<br> | |
68 | <br> | |
69 | factor(c, factors, f);<br> | |
70 | <br> | |
71 | cout << c << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
72 | cout << factors << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
73 | }<br> | |
74 | </font> | |
75 | </font></td></tr></table><p><p> | |
76 | <!-- }}} ENDPRETTY --> | |
77 | ||
55 | 78 | |
56 | 79 | When this program is compiled an run on input |
57 | 80 | |
89 | 112 | is an NTL vector whose base type is <tt>Pair< ZZX, long ></tt>. |
90 | 113 | The type <tt>Pair< ZZX, long ></tt> is the instantiation |
91 | 114 | of a template "pair" type defined by NTL. |
92 | See <a href="pair.txt"><tt>pair.txt</tt></a> for more details. | |
115 | See <a href="pair.cpp.html"><tt>pair.txt</tt></a> for more details. | |
93 | 116 | |
94 | 117 | |
95 | 118 | |
98 | 121 | Here is another example. |
99 | 122 | The following program prints out the first 100 cyclotomic polynomials. |
100 | 123 | |
101 | <pre> | |
102 | ||
103 | #include <NTL/ZZX.h> | |
124 | <!-- STARTPLAIN | |
125 | ||
126 | #include <NTL/ZZX.h> | |
104 | 127 | |
105 | 128 | using namespace std; |
106 | 129 | using namespace NTL; |
107 | 130 | |
108 | 131 | int main() |
109 | 132 | { |
110 | Vec<ZZX> phi(INIT_SIZE, 100); | |
111 | ||
112 | for (long i = 1; i <= 100; i++) { | |
133 | Vec<ZZX> phi(INIT_SIZE, 100); | |
134 | ||
135 | for (long i = 1; i <= 100; i++) { | |
113 | 136 | ZZX t; |
114 | 137 | t = 1; |
115 | 138 | |
116 | for (long j = 1; j <= i-1; j++) | |
139 | for (long j = 1; j <= i-1; j++) | |
117 | 140 | if (i % j == 0) |
118 | 141 | t *= phi(j); |
119 | 142 | |
120 | 143 | phi(i) = (ZZX(INIT_MONO, i) - 1)/t; |
121 | 144 | |
122 | cout << phi(i) << "\n"; | |
145 | cout << phi(i) << "\n"; | |
123 | 146 | } |
124 | 147 | } |
125 | </pre> | |
148 | ENDPLAIN --> | |
149 | <!-- STARTPRETTY {{{ --> | |
150 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
151 | <font face="monospace"> | |
152 | <br> | |
153 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZX.h></font><br> | |
154 | <br> | |
155 | using namespace std;<br> | |
156 | using namespace NTL;<br> | |
157 | <br> | |
158 | <font color="#008b00"><b>int</b></font> main()<br> | |
159 | {<br> | |
160 | Vec<ZZX> phi(INIT_SIZE, <font color="#ff8c00">100</font>); <br> | |
161 | <br> | |
162 | <font color="#b03060"><b>for</b></font> (<font color="#008b00"><b>long</b></font> i = <font color="#ff8c00">1</font>; i <= <font color="#ff8c00">100</font>; i++) {<br> | |
163 | ZZX t;<br> | |
164 | t = <font color="#ff8c00">1</font>;<br> | |
165 | <br> | |
166 | <font color="#b03060"><b>for</b></font> (<font color="#008b00"><b>long</b></font> j = <font color="#ff8c00">1</font>; j <= i-<font color="#ff8c00">1</font>; j++)<br> | |
167 | <font color="#b03060"><b>if</b></font> (i % j == <font color="#ff8c00">0</font>)<br> | |
168 | t *= phi(j);<br> | |
169 | <br> | |
170 | phi(i) = (ZZX(INIT_MONO, i) - <font color="#ff8c00">1</font>)/t; <br> | |
171 | <br> | |
172 | cout << phi(i) << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
173 | }<br> | |
174 | }<br> | |
175 | </font> | |
176 | </font></td></tr></table><p><p> | |
177 | <!-- }}} ENDPRETTY --> | |
178 | ||
126 | 179 | |
127 | 180 | <p> |
128 | 181 | To illustrate more of the NTL interface, let's look at alternative ways |
130 | 183 | |
131 | 184 | <p> |
132 | 185 | First, instead of |
133 | <pre> | |
134 | Vec<ZZX> phi(INIT_SIZE, 100); | |
135 | </pre> | |
186 | <!-- STARTPLAIN | |
187 | Vec<ZZX> phi(INIT_SIZE, 100); | |
188 | ENDPLAIN --> | |
189 | <!-- STARTPRETTY {{{ --> | |
190 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
191 | <font face="monospace"> | |
192 | Vec<ZZX> phi(INIT_SIZE, <font color="#ff8c00">100</font>); <br> | |
193 | </font> | |
194 | </font></td></tr></table><p><p> | |
195 | <!-- }}} ENDPRETTY --> | |
196 | ||
136 | 197 | one can write |
137 | <pre> | |
138 | Vec<ZZX> phi; | |
198 | <!-- STARTPLAIN | |
199 | Vec<ZZX> phi; | |
139 | 200 | phi.SetLength(100); |
140 | </pre> | |
201 | ENDPLAIN --> | |
202 | <!-- STARTPRETTY {{{ --> | |
203 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
204 | <font face="monospace"> | |
205 | Vec<ZZX> phi;<br> | |
206 | phi.SetLength(<font color="#ff8c00">100</font>);<br> | |
207 | </font> | |
208 | </font></td></tr></table><p><p> | |
209 | <!-- }}} ENDPRETTY --> | |
210 | ||
141 | 211 | |
142 | 212 | <p> |
143 | 213 | Second, |
144 | 214 | instead of |
145 | <pre> | |
215 | <!-- STARTPLAIN | |
146 | 216 | t *= phi(j); |
147 | </pre> | |
217 | ENDPLAIN --> | |
218 | <!-- STARTPRETTY {{{ --> | |
219 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
220 | <font face="monospace"> | |
221 | t *= phi(j);<br> | |
222 | </font> | |
223 | </font></td></tr></table><p><p> | |
224 | <!-- }}} ENDPRETTY --> | |
225 | ||
148 | 226 | one can write this as |
149 | <pre> | |
227 | <!-- STARTPLAIN | |
150 | 228 | mul(t, t, phi(j)); |
151 | </pre> | |
229 | ENDPLAIN --> | |
230 | <!-- STARTPRETTY {{{ --> | |
231 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
232 | <font face="monospace"> | |
233 | mul(t, t, phi(j));<br> | |
234 | </font> | |
235 | </font></td></tr></table><p><p> | |
236 | <!-- }}} ENDPRETTY --> | |
237 | ||
152 | 238 | or |
153 | <pre> | |
239 | <!-- STARTPLAIN | |
154 | 240 | t = t * phi(j); |
155 | </pre> | |
241 | ENDPLAIN --> | |
242 | <!-- STARTPRETTY {{{ --> | |
243 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
244 | <font face="monospace"> | |
245 | t = t * phi(j);<br> | |
246 | </font> | |
247 | </font></td></tr></table><p><p> | |
248 | <!-- }}} ENDPRETTY --> | |
249 | ||
156 | 250 | Also, one can write <tt>phi[j-1]</tt> in place of <tt>phi(j)</tt>. |
157 | 251 | |
158 | 252 | <p> |
159 | 253 | Third, instead of |
160 | <pre> | |
254 | <!-- STARTPLAIN | |
161 | 255 | phi(i) = (ZZX(INIT_MONO, i) - 1)/t; |
162 | </pre> | |
256 | ENDPLAIN --> | |
257 | <!-- STARTPRETTY {{{ --> | |
258 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
259 | <font face="monospace"> | |
260 | phi(i) = (ZZX(INIT_MONO, i) - <font color="#ff8c00">1</font>)/t; <br> | |
261 | </font> | |
262 | </font></td></tr></table><p><p> | |
263 | <!-- }}} ENDPRETTY --> | |
264 | ||
163 | 265 | one can write |
164 | <pre> | |
266 | <!-- STARTPLAIN | |
165 | 267 | ZZX t1; |
166 | 268 | SetCoeff(t1, i); |
167 | 269 | SetCoeff(t1, 0, -1); |
168 | 270 | div(phi(i), t1, t); |
169 | </pre> | |
271 | ENDPLAIN --> | |
272 | <!-- STARTPRETTY {{{ --> | |
273 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
274 | <font face="monospace"> | |
275 | ZZX t1;<br> | |
276 | SetCoeff(t1, i);<br> | |
277 | SetCoeff(t1, <font color="#ff8c00">0</font>, -<font color="#ff8c00">1</font>);<br> | |
278 | div(phi(i), t1, t);<br> | |
279 | </font> | |
280 | </font></td></tr></table><p><p> | |
281 | <!-- }}} ENDPRETTY --> | |
282 | ||
170 | 283 | Alternatively, one could directly access the coefficient vector as follows: |
171 | <pre> | |
284 | <!-- STARTPLAIN | |
172 | 285 | ZZX t1; |
173 | 286 | t1.SetLength(i+1); // all vector elements are initialized to zero |
174 | 287 | t1[i] = 1; |
175 | 288 | t1[0] = -1; |
176 | 289 | t1.normalize(); // not necessary here, but good practice in general |
177 | 290 | div(phi(i), t1, t); |
178 | </pre> | |
291 | ENDPLAIN --> | |
292 | <!-- STARTPRETTY {{{ --> | |
293 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
294 | <font face="monospace"> | |
295 | ZZX t1;<br> | |
296 | t1.SetLength(i+<font color="#ff8c00">1</font>); <font color="#0000ee"><i>// all vector elements are initialized to zero</i></font><br> | |
297 | t1[i] = <font color="#ff8c00">1</font>;<br> | |
298 | t1[<font color="#ff8c00">0</font>] = -<font color="#ff8c00">1</font>;<br> | |
299 | t1.normalize(); <font color="#0000ee"><i>// not necessary here, but good practice in general</i></font><br> | |
300 | div(phi(i), t1, t);<br> | |
301 | </font> | |
302 | </font></td></tr></table><p><p> | |
303 | <!-- }}} ENDPRETTY --> | |
304 | ||
179 | 305 | Generally, you can freely access the coefficient vector |
180 | 306 | of a polynomial, as above. |
181 | 307 | However, after fiddling with this vector, you should "normalize" |
187 | 313 | You can always use the <tt>SetCoeff</tt> routine above to set or |
188 | 314 | change coefficients, and you can always read the value of a coefficient |
189 | 315 | using the routine <tt>coeff</tt>, e.g., |
190 | <pre> | |
316 | <!-- STARTPLAIN | |
191 | 317 | ... f[i] == 1 ... |
192 | </pre> | |
318 | ENDPLAIN --> | |
319 | <!-- STARTPRETTY {{{ --> | |
320 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
321 | <font face="monospace"> | |
322 | ... f[i] == <font color="#ff8c00">1</font> ...<br> | |
323 | </font> | |
324 | </font></td></tr></table><p><p> | |
325 | <!-- }}} ENDPRETTY --> | |
326 | ||
193 | 327 | is equivalent to |
194 | <pre> | |
328 | <!-- STARTPLAIN | |
195 | 329 | ... coeff(f, i) == 1 ... |
196 | </pre> | |
330 | ENDPLAIN --> | |
331 | <!-- STARTPRETTY {{{ --> | |
332 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
333 | <font face="monospace"> | |
334 | ... coeff(f, i) == <font color="#ff8c00">1</font> ...<br> | |
335 | </font> | |
336 | </font></td></tr></table><p><p> | |
337 | <!-- }}} ENDPRETTY --> | |
338 | ||
197 | 339 | except that in the latter case, a read-only reference to zero is returned |
198 | 340 | if the index <tt>i</tt> is out of range. |
199 | 341 | There are also special-purpose read-only access routines <tt>LeadCoeff(f)</tt> |
206 | 348 | All of the basic operations support a "promotion logic" similar |
207 | 349 | to that for <tt>ZZ</tt>, except that inputs of <i>both</i> types |
208 | 350 | <tt>long</tt> and <tt>ZZ</tt> are promoted to <tt>ZZX</tt>. |
209 | See <a href="ZZX.txt"><tt>ZZX.txt</tt></a> for details, | |
210 | and see <a href="ZZXFactoring.txt"><tt>ZZXFactoring.txt</tt></a> for details | |
351 | See <a href="ZZX.cpp.html"><tt>ZZX.txt</tt></a> for details, | |
352 | and see <a href="ZZXFactoring.cpp.html"><tt>ZZXFactoring.txt</tt></a> for details | |
211 | 353 | on the polynomial factoring routines. |
212 | 354 | |
213 | 355 | <p> |
3 | 3 | A Tour of NTL: Examples: Modular Arithmetic </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-ex3.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour-examples.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
34 | 33 | Here is a program that reads a prime number <tt>p</tt>, |
35 | 34 | and a polynomial <tt>f</tt> modulo <tt>p</tt>, and factors it. |
36 | 35 | |
37 | <p> | |
38 | <pre> | |
39 | #include <NTL/ZZ_pXFactoring.h> | |
36 | <!-- STARTPLAIN | |
37 | #include <NTL/ZZ_pXFactoring.h> | |
40 | 38 | |
41 | 39 | using namespace std; |
42 | 40 | using namespace NTL; |
44 | 42 | int main() |
45 | 43 | { |
46 | 44 | ZZ p; |
47 | cin >> p; | |
45 | cin >> p; | |
48 | 46 | ZZ_p::init(p); |
49 | 47 | |
50 | 48 | ZZ_pX f; |
51 | cin >> f; | |
52 | ||
53 | Vec< Pair< ZZ_pX, long > > factors; | |
49 | cin >> f; | |
50 | ||
51 | Vec< Pair< ZZ_pX, long > > factors; | |
54 | 52 | |
55 | 53 | CanZass(factors, f); // calls "Cantor/Zassenhaus" algorithm |
56 | 54 | |
57 | cout << factors << "\n"; | |
55 | cout << factors << "\n"; | |
58 | 56 | |
59 | 57 | } |
60 | </pre> | |
58 | ENDPLAIN --> | |
59 | <!-- STARTPRETTY {{{ --> | |
60 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
61 | <font face="monospace"> | |
62 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ_pXFactoring.h></font><br> | |
63 | <br> | |
64 | using namespace std;<br> | |
65 | using namespace NTL;<br> | |
66 | <br> | |
67 | <font color="#008b00"><b>int</b></font> main()<br> | |
68 | {<br> | |
69 | ZZ p;<br> | |
70 | cin >> p;<br> | |
71 | ZZ_p::init(p);<br> | |
72 | <br> | |
73 | ZZ_pX f;<br> | |
74 | cin >> f;<br> | |
75 | <br> | |
76 | Vec< Pair< ZZ_pX, <font color="#008b00"><b>long</b></font> > > factors;<br> | |
77 | <br> | |
78 | CanZass(factors, f); <font color="#0000ee"><i>// calls "Cantor/Zassenhaus" algorithm</i></font><br> | |
79 | <br> | |
80 | cout << factors << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
81 | <br> | |
82 | }<br> | |
83 | </font> | |
84 | </font></td></tr></table><p><p> | |
85 | <!-- }}} ENDPRETTY --> | |
86 | ||
61 | 87 | |
62 | 88 | <p> |
63 | 89 | As a program is running, NTL keeps track of a "current modulus" |
81 | 107 | classes. |
82 | 108 | The first is a vector addition routine (already supplied by NTL): |
83 | 109 | |
84 | <p> | |
85 | <pre> | |
86 | #include <NTL/ZZ_p.h> | |
110 | <!-- STARTPLAIN | |
111 | #include <NTL/ZZ_p.h> | |
87 | 112 | |
88 | 113 | using namespace std; |
89 | 114 | using namespace NTL; |
90 | 115 | |
91 | void add(Vec<ZZ_p>& x, const Vec<ZZ_p>& a, const Vec<ZZ_p>& b) | |
116 | void add(Vec<ZZ_p>& x, const Vec<ZZ_p>& a, const Vec<ZZ_p>& b) | |
92 | 117 | { |
93 | 118 | long n = a.length(); |
94 | 119 | if (b.length() != n) Error("vector add: dimension mismatch"); |
98 | 123 | for (i = 0; i < n; i++) |
99 | 124 | add(x[i], a[i], b[i]); |
100 | 125 | } |
101 | </pre> | |
126 | ENDPLAIN --> | |
127 | <!-- STARTPRETTY {{{ --> | |
128 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
129 | <font face="monospace"> | |
130 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ_p.h></font><br> | |
131 | <br> | |
132 | using namespace std;<br> | |
133 | using namespace NTL;<br> | |
134 | <br> | |
135 | <font color="#008b00"><b>void</b></font> add(Vec<ZZ_p>& x, <font color="#008b00"><b>const</b></font> Vec<ZZ_p>& a, <font color="#008b00"><b>const</b></font> Vec<ZZ_p>& b)<br> | |
136 | {<br> | |
137 | <font color="#008b00"><b>long</b></font> n = a.length();<br> | |
138 | <font color="#b03060"><b>if</b></font> (b.length() != n) Error(<font color="#4a708b">"vector add: dimension mismatch"</font>);<br> | |
139 | <br> | |
140 | x.SetLength(n);<br> | |
141 | <font color="#008b00"><b>long</b></font> i;<br> | |
142 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">0</font>; i < n; i++)<br> | |
143 | add(x[i], a[i], b[i]);<br> | |
144 | }<br> | |
145 | </font> | |
146 | </font></td></tr></table><p><p> | |
147 | <!-- }}} ENDPRETTY --> | |
148 | ||
102 | 149 | |
103 | 150 | <p> |
104 | 151 | |
105 | 152 | The second example is an inner product routine (also supplied by NTL): |
106 | 153 | |
107 | <p> | |
108 | <pre> | |
109 | #include <NTL/ZZ_p.h> | |
154 | <!-- STARTPLAIN | |
155 | #include <NTL/ZZ_p.h> | |
110 | 156 | |
111 | 157 | using namespace std; |
112 | 158 | using namespace NTL; |
113 | 159 | |
114 | void InnerProduct(ZZ_p& x, const Vec<ZZ_p>& a, const Vec<ZZ_p>& b) | |
160 | void InnerProduct(ZZ_p& x, const Vec<ZZ_p>& a, const Vec<ZZ_p>& b) | |
115 | 161 | { |
116 | 162 | long n = min(a.length(), b.length()); |
117 | 163 | long i; |
118 | 164 | ZZ accum, t; |
119 | 165 | |
120 | 166 | accum = 0; |
121 | for (i = 0; i < n; i++) { | |
167 | for (i = 0; i < n; i++) { | |
122 | 168 | mul(t, rep(a[i]), rep(b[i])); |
123 | 169 | add(accum, accum, t); |
124 | 170 | } |
125 | 171 | |
126 | 172 | conv(x, accum); |
127 | 173 | } |
128 | </pre> | |
129 | ||
130 | <p> | |
174 | ENDPLAIN --> | |
175 | <!-- STARTPRETTY {{{ --> | |
176 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
177 | <font face="monospace"> | |
178 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ_p.h></font><br> | |
179 | <br> | |
180 | using namespace std;<br> | |
181 | using namespace NTL;<br> | |
182 | <br> | |
183 | <font color="#008b00"><b>void</b></font> InnerProduct(ZZ_p& x, <font color="#008b00"><b>const</b></font> Vec<ZZ_p>& a, <font color="#008b00"><b>const</b></font> Vec<ZZ_p>& b)<br> | |
184 | {<br> | |
185 | <font color="#008b00"><b>long</b></font> n = min(a.length(), b.length());<br> | |
186 | <font color="#008b00"><b>long</b></font> i;<br> | |
187 | ZZ accum, t;<br> | |
188 | <br> | |
189 | accum = <font color="#ff8c00">0</font>;<br> | |
190 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">0</font>; i < n; i++) {<br> | |
191 | mul(t, rep(a[i]), rep(b[i]));<br> | |
192 | add(accum, accum, t);<br> | |
193 | }<br> | |
194 | <br> | |
195 | conv(x, accum);<br> | |
196 | }<br> | |
197 | </font> | |
198 | </font></td></tr></table><p><p> | |
199 | <!-- }}} ENDPRETTY --> | |
200 | ||
201 | ||
131 | 202 | This second example illustrates two things. |
132 | 203 | First, it illustrates the use of function <tt>rep</tt> which |
133 | 204 | returns a read-only reference to the representation of a <tt>ZZ_p</tt> |
161 | 232 | promoting both <tt>long</tt> and <tt>ZZ_p</tt> to <tt>ZZ_pX</tt>. |
162 | 233 | |
163 | 234 | <p> |
164 | See <a href="ZZ_p.txt"><tt>ZZ_p.txt</tt></a> for details on <tt>ZZ_p</tt>; | |
165 | see <a href="ZZ_pX.txt"><tt>ZZ_pX.txt</tt></a> for details on <tt>ZZ_pX</tt>; | |
166 | see <a href="ZZ_pXFactoring.txt"><tt>ZZ_pXFactoring.txt</tt></a> for details on | |
235 | See <a href="ZZ_p.cpp.html"><tt>ZZ_p.txt</tt></a> for details on <tt>ZZ_p</tt>; | |
236 | see <a href="ZZ_pX.cpp.html"><tt>ZZ_pX.txt</tt></a> for details on <tt>ZZ_pX</tt>; | |
237 | see <a href="ZZ_pXFactoring.cpp.html"><tt>ZZ_pXFactoring.txt</tt></a> for details on | |
167 | 238 | the routines for factoring polynomials over <tt>ZZ_p</tt>; |
168 | see <a href="vec_ZZ_p.txt"><tt>vec_ZZ_p.txt</tt></a> for details | |
239 | see <a href="vec_ZZ_p.cpp.html"><tt>vec_ZZ_p.txt</tt></a> for details | |
169 | 240 | on mathematical operations on <tt>Vec<ZZ_p></tt>'s; |
170 | see <a href="mat_ZZ_p.txt"><tt>mat_ZZ_p.txt</tt></a> for details on | |
241 | see <a href="mat_ZZ_p.cpp.html"><tt>mat_ZZ_p.txt</tt></a> for details on | |
171 | 242 | mathematical operations on <tt>Mat<ZZ_p></tt>'s. |
172 | 243 | |
173 | 244 | <p> <hr> <p> |
178 | 249 | and a prime, and tests if the polynomial is irreducible modulo |
179 | 250 | the prime. |
180 | 251 | |
181 | <p> | |
182 | <pre> | |
183 | #include <NTL/ZZX.h> | |
184 | #include <NTL/ZZ_pXFactoring.h> | |
252 | <!-- STARTPLAIN | |
253 | #include <NTL/ZZX.h> | |
254 | #include <NTL/ZZ_pXFactoring.h> | |
185 | 255 | |
186 | 256 | using namespace std; |
187 | 257 | using namespace NTL; |
188 | 258 | |
189 | long IrredTestMod(const ZZX& f, const ZZ& p) | |
259 | long IrredTestMod(const ZZX& f, const ZZ& p) | |
190 | 260 | { |
191 | 261 | ZZ_pPush push(p); // save current modulus and install p |
192 | 262 | // as current modulus |
193 | 263 | |
194 | return DetIrredTest(conv<ZZ_pX>(f)); | |
264 | return DetIrredTest(conv<ZZ_pX>(f)); | |
195 | 265 | |
196 | 266 | // old modulus is restored automatically when push is destroyed |
197 | 267 | // upon return |
198 | 268 | } |
199 | </pre> | |
200 | ||
201 | <p> | |
269 | ENDPLAIN --> | |
270 | <!-- STARTPRETTY {{{ --> | |
271 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
272 | <font face="monospace"> | |
273 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZX.h></font><br> | |
274 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ_pXFactoring.h></font><br> | |
275 | <br> | |
276 | using namespace std;<br> | |
277 | using namespace NTL;<br> | |
278 | <br> | |
279 | <font color="#008b00"><b>long</b></font> IrredTestMod(<font color="#008b00"><b>const</b></font> ZZX& f, <font color="#008b00"><b>const</b></font> ZZ& p)<br> | |
280 | {<br> | |
281 | ZZ_pPush push(p); <font color="#0000ee"><i>// save current modulus and install p</i></font><br> | |
282 | <font color="#0000ee"><i>// as current modulus</i></font><br> | |
283 | <br> | |
284 | <font color="#b03060"><b>return</b></font> DetIrredTest(conv<ZZ_pX>(f));<br> | |
285 | <br> | |
286 | <font color="#0000ee"><i>// old modulus is restored automatically when push is destroyed</i></font><br> | |
287 | <font color="#0000ee"><i>// upon return</i></font><br> | |
288 | }<br> | |
289 | </font> | |
290 | </font></td></tr></table><p><p> | |
291 | <!-- }}} ENDPRETTY --> | |
292 | ||
293 | ||
202 | 294 | The modulus switching mechanism is actually quite a bit |
203 | 295 | more general and flexible than this example illustrates. |
204 | 296 | |
206 | 298 | Noe the use of the conversion function |
207 | 299 | <tt>conv<ZZ_pX></tt>. |
208 | 300 | We could also have used the equivalent procedural form: |
209 | <pre> | |
301 | <!-- STARTPLAIN | |
210 | 302 | ZZ_pX f1; |
211 | 303 | conv(f1, f); |
212 | 304 | return DetIrredTest(f1); |
213 | </pre> | |
214 | ||
215 | ||
216 | ||
305 | ENDPLAIN --> | |
306 | <!-- STARTPRETTY {{{ --> | |
307 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
308 | <font face="monospace"> | |
309 | ZZ_pX f1;<br> | |
310 | conv(f1, f);<br> | |
311 | <font color="#b03060"><b>return</b></font> DetIrredTest(f1);<br> | |
312 | </font> | |
313 | </font></td></tr></table><p><p> | |
314 | <!-- }}} ENDPRETTY --> | |
217 | 315 | |
218 | 316 | |
219 | 317 | |
234 | 332 | as follows. |
235 | 333 | |
236 | 334 | |
237 | <p> | |
238 | <pre> | |
239 | #include <NTL/ZZX.h> | |
240 | #include <NTL/lzz_pXFactoring.h> | |
335 | <!-- STARTPLAIN | |
336 | #include <NTL/ZZX.h> | |
337 | #include <NTL/lzz_pXFactoring.h> | |
241 | 338 | |
242 | 339 | using namespace std; |
243 | 340 | using namespace NTL; |
244 | 341 | |
245 | long IrredTestMod(const ZZX& f, long p) | |
342 | long IrredTestMod(const ZZX& f, long p) | |
246 | 343 | { |
247 | 344 | zz_pPush push(p); |
248 | return DetIrredTest(conv<zz_pX>(f)); | |
345 | return DetIrredTest(conv<zz_pX>(f)); | |
249 | 346 | } |
250 | </pre> | |
347 | ENDPLAIN --> | |
348 | <!-- STARTPRETTY {{{ --> | |
349 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
350 | <font face="monospace"> | |
351 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZX.h></font><br> | |
352 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/lzz_pXFactoring.h></font><br> | |
353 | <br> | |
354 | using namespace std;<br> | |
355 | using namespace NTL;<br> | |
356 | <br> | |
357 | <font color="#008b00"><b>long</b></font> IrredTestMod(<font color="#008b00"><b>const</b></font> ZZX& f, <font color="#008b00"><b>long</b></font> p)<br> | |
358 | {<br> | |
359 | zz_pPush push(p);<br> | |
360 | <font color="#b03060"><b>return</b></font> DetIrredTest(conv<zz_pX>(f));<br> | |
361 | }<br> | |
362 | </font> | |
363 | </font></td></tr></table><p><p> | |
364 | <!-- }}} ENDPRETTY --> | |
365 | ||
251 | 366 | |
252 | 367 | <p> <hr> <p> |
253 | 368 | |
258 | 373 | The small primes are specially chosen "FFT primes", which are of |
259 | 374 | a special form that allows for particular fast polynomial arithmetic. |
260 | 375 | |
261 | <p> | |
262 | <pre> | |
263 | #include <NTL/ZZX.h> | |
376 | <!-- STARTPLAIN | |
377 | #include <NTL/ZZX.h> | |
264 | 378 | |
265 | 379 | using namespace std; |
266 | 380 | using namespace NTL; |
267 | 381 | |
268 | void GCD(ZZX& d, const ZZX& a, const ZZX& b) | |
382 | void GCD(ZZX& d, const ZZX& a, const ZZX& b) | |
269 | 383 | { |
270 | 384 | if (a == 0) { |
271 | 385 | d = b; |
272 | if (LeadCoeff(d) < 0) negate(d, d); | |
386 | if (LeadCoeff(d) < 0) negate(d, d); | |
273 | 387 | return; |
274 | 388 | } |
275 | 389 | |
276 | 390 | if (b == 0) { |
277 | 391 | d = a; |
278 | if (LeadCoeff(d) < 0) negate(d, d); | |
392 | if (LeadCoeff(d) < 0) negate(d, d); | |
279 | 393 | return; |
280 | 394 | } |
281 | 395 | |
324 | 438 | break; |
325 | 439 | } |
326 | 440 | |
327 | if (FirstTime || deg(G) < deg(g)) { | |
441 | if (FirstTime || deg(G) < deg(g)) { | |
328 | 442 | prod = 1; |
329 | 443 | g = 0; |
330 | 444 | FirstTime = 0; |
331 | 445 | } |
332 | else if (deg(G) > deg(g)) { | |
446 | else if (deg(G) > deg(g)) { | |
333 | 447 | continue; |
334 | 448 | } |
335 | 449 | |
336 | 450 | if (!CRT(g, prod, G)) { |
337 | 451 | PrimitivePart(res, g); |
338 | if (divide(f1, res) && divide(f2, res)) | |
452 | if (divide(f1, res) && divide(f2, res)) | |
339 | 453 | break; |
340 | 454 | } |
341 | 455 | |
342 | 456 | } |
343 | 457 | |
344 | 458 | mul(d, res, c); |
345 | if (LeadCoeff(d) < 0) negate(d, d); | |
459 | if (LeadCoeff(d) < 0) negate(d, d); | |
346 | 460 | } |
347 | </pre> | |
348 | ||
349 | ||
350 | <p> | |
351 | See <a href="lzz_p.txt"><tt>lzz_p.txt</tt></a> for details on <tt>zz_p</tt>; | |
352 | see <a href="lzz_pX.txt"><tt>lzz_pX.txt</tt></a> for details on <tt>zz_pX</tt>; | |
353 | see <a href="lzz_pXFactoring.txt"><tt>lzz_pXFactoring.txt</tt></a> for details on | |
461 | ENDPLAIN --> | |
462 | <!-- STARTPRETTY {{{ --> | |
463 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
464 | <font face="monospace"> | |
465 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZX.h></font><br> | |
466 | <br> | |
467 | using namespace std;<br> | |
468 | using namespace NTL;<br> | |
469 | <br> | |
470 | <font color="#008b00"><b>void</b></font> GCD(ZZX& d, <font color="#008b00"><b>const</b></font> ZZX& a, <font color="#008b00"><b>const</b></font> ZZX& b)<br> | |
471 | {<br> | |
472 | <font color="#b03060"><b>if</b></font> (a == <font color="#ff8c00">0</font>) {<br> | |
473 | d = b;<br> | |
474 | <font color="#b03060"><b>if</b></font> (LeadCoeff(d) < <font color="#ff8c00">0</font>) negate(d, d);<br> | |
475 | <font color="#b03060"><b>return</b></font>;<br> | |
476 | }<br> | |
477 | <br> | |
478 | <font color="#b03060"><b>if</b></font> (b == <font color="#ff8c00">0</font>) {<br> | |
479 | d = a;<br> | |
480 | <font color="#b03060"><b>if</b></font> (LeadCoeff(d) < <font color="#ff8c00">0</font>) negate(d, d);<br> | |
481 | <font color="#b03060"><b>return</b></font>;<br> | |
482 | }<br> | |
483 | <br> | |
484 | ZZ c1, c2, c;<br> | |
485 | ZZX f1, f2;<br> | |
486 | <br> | |
487 | content(c1, a);<br> | |
488 | divide(f1, a, c1);<br> | |
489 | <br> | |
490 | content(c2, b);<br> | |
491 | divide(f2, b, c2);<br> | |
492 | <br> | |
493 | GCD(c, c1, c2);<br> | |
494 | <br> | |
495 | ZZ ld;<br> | |
496 | GCD(ld, LeadCoeff(f1), LeadCoeff(f2));<br> | |
497 | <br> | |
498 | ZZX g, res;<br> | |
499 | <br> | |
500 | ZZ prod;<br> | |
501 | <br> | |
502 | zz_pPush push(); <font color="#0000ee"><i>// save current modulus, restore upon return</i></font><br> | |
503 | <br> | |
504 | <font color="#008b00"><b>long</b></font> FirstTime = <font color="#ff8c00">1</font>;<br> | |
505 | <br> | |
506 | <font color="#008b00"><b>long</b></font> i;<br> | |
507 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">0</font>; ;i++) {<br> | |
508 | zz_p::FFTInit(i);<br> | |
509 | <font color="#008b00"><b>long</b></font> p = zz_p::modulus();<br> | |
510 | <br> | |
511 | <font color="#b03060"><b>if</b></font> (divide(LeadCoeff(f1), p) || divide(LeadCoeff(f2), p)) <font color="#b03060"><b>continue</b></font>;<br> | |
512 | <br> | |
513 | zz_pX G, F1, F2;<br> | |
514 | zz_p LD;<br> | |
515 | <br> | |
516 | conv(F1, f1);<br> | |
517 | conv(F2, f2);<br> | |
518 | conv(LD, ld);<br> | |
519 | <br> | |
520 | GCD(G, F1, F2);<br> | |
521 | mul(G, G, LD);<br> | |
522 | <br> | |
523 | <br> | |
524 | <font color="#b03060"><b>if</b></font> (deg(G) == <font color="#ff8c00">0</font>) { <br> | |
525 | res = <font color="#ff8c00">1</font>;<br> | |
526 | <font color="#b03060"><b>break</b></font>;<br> | |
527 | }<br> | |
528 | <br> | |
529 | <font color="#b03060"><b>if</b></font> (FirstTime || deg(G) < deg(g)) {<br> | |
530 | prod = <font color="#ff8c00">1</font>;<br> | |
531 | g = <font color="#ff8c00">0</font>;<br> | |
532 | FirstTime = <font color="#ff8c00">0</font>;<br> | |
533 | }<br> | |
534 | <font color="#b03060"><b>else</b></font> <font color="#b03060"><b>if</b></font> (deg(G) > deg(g)) {<br> | |
535 | <font color="#b03060"><b>continue</b></font>;<br> | |
536 | }<br> | |
537 | <br> | |
538 | <font color="#b03060"><b>if</b></font> (!CRT(g, prod, G)) {<br> | |
539 | PrimitivePart(res, g);<br> | |
540 | <font color="#b03060"><b>if</b></font> (divide(f1, res) && divide(f2, res))<br> | |
541 | <font color="#b03060"><b>break</b></font>;<br> | |
542 | }<br> | |
543 | <br> | |
544 | }<br> | |
545 | <br> | |
546 | mul(d, res, c);<br> | |
547 | <font color="#b03060"><b>if</b></font> (LeadCoeff(d) < <font color="#ff8c00">0</font>) negate(d, d);<br> | |
548 | }<br> | |
549 | </font> | |
550 | </font></td></tr></table><p><p> | |
551 | <!-- }}} ENDPRETTY --> | |
552 | ||
553 | ||
554 | ||
555 | <p> | |
556 | See <a href="lzz_p.cpp.html"><tt>lzz_p.txt</tt></a> for details on <tt>zz_p</tt>; | |
557 | see <a href="lzz_pX.cpp.html"><tt>lzz_pX.txt</tt></a> for details on <tt>zz_pX</tt>; | |
558 | see <a href="lzz_pXFactoring.cpp.html"><tt>lzz_pXFactoring.txt</tt></a> for details on | |
354 | 559 | the routines for factoring polynomials over <tt>zz_p</tt>; |
355 | see <a href="vec_lzz_p.txt"><tt>vec_lzz_p.txt</tt></a> for details on <tt>vec_zz_p</tt>; | |
356 | see <a href="mat_lzz_p.txt"><tt>mat_lzz_p.txt</tt></a> for details on <tt>mat_zz_p</tt>. | |
560 | see <a href="vec_lzz_p.cpp.html"><tt>vec_lzz_p.txt</tt></a> for details on <tt>vec_zz_p</tt>; | |
561 | see <a href="mat_lzz_p.cpp.html"><tt>mat_lzz_p.txt</tt></a> for details on <tt>mat_zz_p</tt>. | |
357 | 562 | |
358 | 563 | |
359 | 564 | <p> <hr> <p> |
398 | 603 | is irreducible using linear algebra. |
399 | 604 | NTL's built-in irreducibility test is to be preferred, however. |
400 | 605 | |
401 | <pre> | |
402 | ||
403 | #include <NTL/GF2X.h> | |
404 | #include <NTL/mat_GF2.h> | |
606 | <!-- STARTPLAIN | |
607 | #include <NTL/GF2X.h> | |
608 | #include <NTL/mat_GF2.h> | |
405 | 609 | |
406 | 610 | using namespace std; |
407 | 611 | using namespace NTL; |
408 | 612 | |
409 | long MatIrredTest(const GF2X& f) | |
613 | long MatIrredTest(const GF2X& f) | |
410 | 614 | { |
411 | 615 | long n = deg(f); |
412 | 616 | |
413 | if (n <= 0) return 0; | |
617 | if (n <= 0) return 0; | |
414 | 618 | if (n == 1) return 1; |
415 | 619 | |
416 | 620 | if (GCD(f, diff(f)) != 1) return 0; |
417 | 621 | |
418 | Mat<GF2> M; | |
622 | Mat<GF2> M; | |
419 | 623 | |
420 | 624 | M.SetDims(n, n); |
421 | 625 | |
424 | 628 | GF2X g; |
425 | 629 | g = 1; |
426 | 630 | |
427 | for (long i = 0; i < n; i++) { | |
631 | for (long i = 0; i < n; i++) { | |
428 | 632 | VectorCopy(M[i], g, n); |
429 | 633 | M[i][i] += 1; |
430 | 634 | g = (g * x_squared) % f; |
437 | 641 | else |
438 | 642 | return 0; |
439 | 643 | } |
440 | </pre> | |
644 | ENDPLAIN --> | |
645 | <!-- STARTPRETTY {{{ --> | |
646 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
647 | <font face="monospace"> | |
648 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/GF2X.h></font><br> | |
649 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/mat_GF2.h></font><br> | |
650 | <br> | |
651 | using namespace std;<br> | |
652 | using namespace NTL;<br> | |
653 | <br> | |
654 | <font color="#008b00"><b>long</b></font> MatIrredTest(<font color="#008b00"><b>const</b></font> GF2X& f)<br> | |
655 | {<br> | |
656 | <font color="#008b00"><b>long</b></font> n = deg(f);<br> | |
657 | <br> | |
658 | <font color="#b03060"><b>if</b></font> (n <= <font color="#ff8c00">0</font>) <font color="#b03060"><b>return</b></font> <font color="#ff8c00">0</font>;<br> | |
659 | <font color="#b03060"><b>if</b></font> (n == <font color="#ff8c00">1</font>) <font color="#b03060"><b>return</b></font> <font color="#ff8c00">1</font>;<br> | |
660 | <br> | |
661 | <font color="#b03060"><b>if</b></font> (GCD(f, diff(f)) != <font color="#ff8c00">1</font>) <font color="#b03060"><b>return</b></font> <font color="#ff8c00">0</font>;<br> | |
662 | <br> | |
663 | Mat<GF2> M;<br> | |
664 | <br> | |
665 | M.SetDims(n, n);<br> | |
666 | <br> | |
667 | GF2X x_squared = GF2X(INIT_MONO, <font color="#ff8c00">2</font>);<br> | |
668 | <br> | |
669 | GF2X g;<br> | |
670 | g = <font color="#ff8c00">1</font>;<br> | |
671 | <br> | |
672 | <font color="#b03060"><b>for</b></font> (<font color="#008b00"><b>long</b></font> i = <font color="#ff8c00">0</font>; i < n; i++) {<br> | |
673 | VectorCopy(M[i], g, n);<br> | |
674 | M[i][i] += <font color="#ff8c00">1</font>;<br> | |
675 | g = (g * x_squared) % f;<br> | |
676 | }<br> | |
677 | <br> | |
678 | <font color="#008b00"><b>long</b></font> rank = gauss(M);<br> | |
679 | <br> | |
680 | <font color="#b03060"><b>if</b></font> (rank == n-<font color="#ff8c00">1</font>)<br> | |
681 | <font color="#b03060"><b>return</b></font> <font color="#ff8c00">1</font>;<br> | |
682 | <font color="#b03060"><b>else</b></font><br> | |
683 | <font color="#b03060"><b>return</b></font> <font color="#ff8c00">0</font>;<br> | |
684 | }<br> | |
685 | </font> | |
686 | </font></td></tr></table><p><p> | |
687 | <!-- }}} ENDPRETTY --> | |
688 | ||
441 | 689 | |
442 | 690 | <p> |
443 | 691 | Note that the statement |
444 | <pre> | |
692 | <!-- STARTPLAIN | |
445 | 693 | g = (g * x_squared) % f; |
446 | </pre> | |
694 | ENDPLAIN --> | |
695 | <!-- STARTPRETTY {{{ --> | |
696 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
697 | <font face="monospace"> | |
698 | g = (g * x_squared) % f;<br> | |
699 | </font> | |
700 | </font></td></tr></table><p><p> | |
701 | <!-- }}} ENDPRETTY --> | |
702 | ||
447 | 703 | could be replace d by the more efficient code sequence |
448 | <pre> | |
704 | <!-- STARTPLAIN | |
449 | 705 | MulByXMod(g, g, f); |
450 | 706 | MulByXMod(g, g, f); |
451 | </pre> | |
707 | ENDPLAIN --> | |
708 | <!-- STARTPRETTY {{{ --> | |
709 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
710 | <font face="monospace"> | |
711 | MulByXMod(g, g, f);<br> | |
712 | MulByXMod(g, g, f);<br> | |
713 | </font> | |
714 | </font></td></tr></table><p><p> | |
715 | <!-- }}} ENDPRETTY --> | |
716 | ||
452 | 717 | but this would not significantly impact the overall |
453 | 718 | running time, since it is the Gaussian elimination that |
454 | 719 | dominates the running time. |
455 | 720 | |
456 | 721 | <p> |
457 | See <a href="GF2.txt"><tt>GF2.txt</tt></a> for details on <tt>GF2</tt>; | |
458 | see <a href="GF2X.txt"><tt>GF2X.txt</tt></a> for details on <tt>GF2X</tt>; | |
459 | see <a href="GF2XFactoring.txt"><tt>GF2XFactoring.txt</tt></a> for details on | |
722 | See <a href="GF2.cpp.html"><tt>GF2.txt</tt></a> for details on <tt>GF2</tt>; | |
723 | see <a href="GF2X.cpp.html"><tt>GF2X.txt</tt></a> for details on <tt>GF2X</tt>; | |
724 | see <a href="GF2XFactoring.cpp.html"><tt>GF2XFactoring.txt</tt></a> for details on | |
460 | 725 | the routines for factoring polynomials over <tt>GF2</tt>; |
461 | see <a href="vec_GF2.txt"><tt>vec_GF2.txt</tt></a> for details on <tt>vec_GF2</tt>; | |
462 | see <a href="mat_GF2.txt"><tt>mat_GF2.txt</tt></a> for details on <tt>mat_GF2</tt>. | |
726 | see <a href="vec_GF2.cpp.html"><tt>vec_GF2.txt</tt></a> for details on <tt>vec_GF2</tt>; | |
727 | see <a href="mat_GF2.cpp.html"><tt>mat_GF2.txt</tt></a> for details on <tt>mat_GF2</tt>. | |
463 | 728 | |
464 | 729 | <p> |
465 | 730 |
3 | 3 | A Tour of NTL: Examples: Extension Rings and Fields </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-ex4.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour-examples.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
22 | 21 | and polynomial arithmetic over such extensions. |
23 | 22 | Here is a little program that illustrates this. |
24 | 23 | |
25 | <p> | |
26 | <pre> | |
27 | #include <NTL/ZZ_pXFactoring.h> | |
28 | #include <NTL/ZZ_pEX.h> | |
24 | <!-- STARTPLAIN | |
25 | #include <NTL/ZZ_pXFactoring.h> | |
26 | #include <NTL/ZZ_pEX.h> | |
29 | 27 | |
30 | 28 | NTL_CLIENT |
31 | 29 | |
53 | 51 | if (CompMod(g, h, f) != 0) // check that g(h) = 0 mod f |
54 | 52 | Error("oops (2)"); |
55 | 53 | } |
56 | </pre> | |
54 | ENDPLAIN --> | |
55 | <!-- STARTPRETTY {{{ --> | |
56 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
57 | <font face="monospace"> | |
58 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ_pXFactoring.h></font><br> | |
59 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ_pEX.h></font><br> | |
60 | <br> | |
61 | NTL_CLIENT<br> | |
62 | <br> | |
63 | <font color="#008b00"><b>int</b></font> main()<br> | |
64 | {<br> | |
65 | ZZ_p::init(ZZ(<font color="#ff8c00">17</font>)); <font color="#0000ee"><i>// define GF(17)</i></font><br> | |
66 | <br> | |
67 | ZZ_pX P;<br> | |
68 | BuildIrred(P, <font color="#ff8c00">10</font>); <font color="#0000ee"><i>// generate an irreducible polynomial P</i></font><br> | |
69 | <font color="#0000ee"><i>// of degree 10 over GF(17)</i></font><br> | |
70 | <br> | |
71 | ZZ_pE::init(P); <font color="#0000ee"><i>// define GF(17^10)</i></font><br> | |
72 | <br> | |
73 | ZZ_pEX f, g, h; <font color="#0000ee"><i>// declare polynomials over GF(17^10)</i></font><br> | |
74 | <br> | |
75 | random(f, <font color="#ff8c00">20</font>); <font color="#0000ee"><i>// f is a random, monic polynomial of degree 20</i></font><br> | |
76 | SetCoeff(f, <font color="#ff8c00">20</font>);<br> | |
77 | <br> | |
78 | random(h, <font color="#ff8c00">20</font>); <font color="#0000ee"><i>// h is a random polynomial of degree less than 20</i></font><br> | |
79 | <br> | |
80 | g = MinPolyMod(h, f); <font color="#0000ee"><i>// compute the minimum polynomial of h modulo f</i></font><br> | |
81 | <br> | |
82 | <font color="#b03060"><b>if</b></font> (g == <font color="#ff8c00">0</font>) Error(<font color="#4a708b">"oops (1)"</font>); <font color="#0000ee"><i>// check that g != 0</i></font><br> | |
83 | <br> | |
84 | <font color="#b03060"><b>if</b></font> (CompMod(g, h, f) != <font color="#ff8c00">0</font>) <font color="#0000ee"><i>// check that g(h) = 0 mod f</i></font><br> | |
85 | Error(<font color="#4a708b">"oops (2)"</font>);<br> | |
86 | }<br> | |
87 | </font> | |
88 | </font></td></tr></table><p><p> | |
89 | <!-- }}} ENDPRETTY --> | |
90 | ||
57 | 91 | |
58 | 92 | <p> |
59 | 93 | This example illustrates building extension rings over <tt>ZZ_p</tt>. |
61 | 95 | the syntax is exactly the same. |
62 | 96 | |
63 | 97 | <p> |
64 | See <a href="ZZ_pE.txt"><tt>ZZ_pE.txt</tt></a> for the basics of the extension | |
98 | See <a href="ZZ_pE.cpp.html"><tt>ZZ_pE.txt</tt></a> for the basics of the extension | |
65 | 99 | ring <tt>ZZ_pE</tt> over <tt>ZZ_p</tt>. |
66 | Also see <a href="ZZ_pEX.txt"><tt>ZZ_pEX.txt</tt></a> for polynomial | |
100 | Also see <a href="ZZ_pEX.cpp.html"><tt>ZZ_pEX.txt</tt></a> for polynomial | |
67 | 101 | arithmetic over <tt>ZZ_pE</tt>, and |
68 | <a href="ZZ_pEXFactoring.txt"><tt>ZZ_pEXFactoring.txt</tt></a> for factoring | |
102 | <a href="ZZ_pEXFactoring.cpp.html"><tt>ZZ_pEXFactoring.txt</tt></a> for factoring | |
69 | 103 | routines over <tt>ZZ_pE</tt>. |
70 | See <a href="vec_ZZ_pE.txt"><tt>vec_ZZ_pE.txt</tt></a> for vectors over <tt>ZZ_pE</tt>, | |
71 | and <a href="mat_ZZ_pE.txt"><tt>mat_ZZ_pE.txt</tt></a> for matrices over <tt>ZZ_pE</tt>. | |
104 | See <a href="vec_ZZ_pE.cpp.html"><tt>vec_ZZ_pE.txt</tt></a> for vectors over <tt>ZZ_pE</tt>, | |
105 | and <a href="mat_ZZ_pE.cpp.html"><tt>mat_ZZ_pE.txt</tt></a> for matrices over <tt>ZZ_pE</tt>. | |
72 | 106 | |
73 | 107 | <p> |
74 | See <a href="lzz_pE.txt"><tt>lzz_pE.txt</tt></a> for the basics of the extension | |
108 | See <a href="lzz_pE.cpp.html"><tt>lzz_pE.txt</tt></a> for the basics of the extension | |
75 | 109 | ring <tt>zz_pE</tt> over <tt>zz_p</tt>. |
76 | Also see <a href="lzz_pEX.txt"><tt>lzz_pEX.txt</tt></a> for polynomial | |
110 | Also see <a href="lzz_pEX.cpp.html"><tt>lzz_pEX.txt</tt></a> for polynomial | |
77 | 111 | arithmetic over <tt>zz_pE</tt>, and |
78 | <a href="lzz_pEXFactoring.txt"><tt>lzz_pEXFactoring.txt</tt></a> for factoring | |
112 | <a href="lzz_pEXFactoring.cpp.html"><tt>lzz_pEXFactoring.txt</tt></a> for factoring | |
79 | 113 | routines over <tt>zz_pE</tt>. |
80 | See <a href="vec_lzz_pE.txt"><tt>vec_lzz_pE.txt</tt></a> for vectors over <tt>zz_pE</tt>, | |
81 | and <a href="mat_lzz_pE.txt"><tt>mat_lzz_pE.txt</tt></a> for matrices over <tt>zz_pE</tt>. | |
114 | See <a href="vec_lzz_pE.cpp.html"><tt>vec_lzz_pE.txt</tt></a> for vectors over <tt>zz_pE</tt>, | |
115 | and <a href="mat_lzz_pE.cpp.html"><tt>mat_lzz_pE.txt</tt></a> for matrices over <tt>zz_pE</tt>. | |
82 | 116 | |
83 | 117 | <p> |
84 | See <a href="GF2E.txt"><tt>GF2E.txt</tt></a> for the basics of the extension | |
118 | See <a href="GF2E.cpp.html"><tt>GF2E.txt</tt></a> for the basics of the extension | |
85 | 119 | ring <tt>GF2E</tt> over <tt>GF2</tt>. |
86 | Also see <a href="GF2EX.txt"><tt>GF2EX.txt</tt></a> for polynomial | |
120 | Also see <a href="GF2EX.cpp.html"><tt>GF2EX.txt</tt></a> for polynomial | |
87 | 121 | arithmetic over <tt>GF2E</tt>, and |
88 | <a href="GF2EXFactoring.txt"><tt>GF2EXFactoring.txt</tt></a> for factoring | |
122 | <a href="GF2EXFactoring.cpp.html"><tt>GF2EXFactoring.txt</tt></a> for factoring | |
89 | 123 | routines over <tt>GF2E</tt>. |
90 | See <a href="vec_GF2E.txt"><tt>vec_GF2E.txt</tt></a> for vectors over <tt>GF2E</tt>, | |
91 | and <a href="mat_GF2E.txt"><tt>mat_GF2E.txt</tt></a> for matrices over <tt>GF2E</tt>. | |
124 | See <a href="vec_GF2E.cpp.html"><tt>vec_GF2E.txt</tt></a> for vectors over <tt>GF2E</tt>, | |
125 | and <a href="mat_GF2E.cpp.html"><tt>mat_GF2E.txt</tt></a> for matrices over <tt>GF2E</tt>. | |
92 | 126 | |
93 | 127 | |
94 | 128 | <center> |
3 | 3 | A Tour of NTL: Examples: Floating Point Classes </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-ex5.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour-examples.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
31 | 30 | |
32 | 31 | Here again is a program that reads a list of numbers from the input, |
33 | 32 | and outputs the sum of their squares, using the class <tt>RR</tt>. |
34 | <p> | |
35 | 33 | |
36 | <pre> | |
37 | #include <NTL/RR.h> | |
34 | <!-- STARTPLAIN | |
35 | #include <NTL/RR.h> | |
38 | 36 | |
39 | 37 | int main() |
40 | 38 | { |
42 | 40 | |
43 | 41 | acc = 0; |
44 | 42 | while (SkipWhiteSpace(cin)) { |
45 | cin >> val; | |
43 | cin >> val; | |
46 | 44 | acc += val*val; |
47 | 45 | } |
48 | 46 | |
49 | cout << acc << "\n"; | |
47 | cout << acc << "\n"; | |
50 | 48 | } |
51 | </pre> | |
49 | ENDPLAIN --> | |
50 | <!-- STARTPRETTY {{{ --> | |
51 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
52 | <font face="monospace"> | |
53 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/RR.h></font><br> | |
54 | <br> | |
55 | <font color="#008b00"><b>int</b></font> main()<br> | |
56 | {<br> | |
57 | RR acc, val;<br> | |
58 | <br> | |
59 | acc = <font color="#ff8c00">0</font>;<br> | |
60 | <font color="#b03060"><b>while</b></font> (SkipWhiteSpace(cin)) {<br> | |
61 | cin >> val;<br> | |
62 | acc += val*val;<br> | |
63 | }<br> | |
64 | <br> | |
65 | cout << acc << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
66 | }<br> | |
67 | </font> | |
68 | </font></td></tr></table><p><p> | |
69 | <!-- }}} ENDPRETTY --> | |
70 | ||
52 | 71 | |
53 | 72 | <p> |
54 | 73 | |
55 | 74 | The precision used for the computation can be set by executing |
56 | <pre> | |
75 | <!-- STARTPLAIN | |
57 | 76 | RR::SetPrecision(p); |
58 | </pre> | |
77 | ENDPLAIN --> | |
78 | <!-- STARTPRETTY {{{ --> | |
79 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
80 | <font face="monospace"> | |
81 | RR::SetPrecision(p);<br> | |
82 | </font> | |
83 | </font></td></tr></table><p><p> | |
84 | <!-- }}} ENDPRETTY --> | |
85 | ||
59 | 86 | which sets the effective precision to <tt>p</tt> bits. |
60 | 87 | By default, <tt>p=150</tt>. |
61 | 88 | All of the basic arithmetic operations compute their results |
68 | 95 | |
69 | 96 | The number of <i>decimal</i> digits of precision that are used when |
70 | 97 | printing an <tt>RR</tt> can be set be executing |
71 | <pre> | |
98 | <!-- STARTPLAIN | |
72 | 99 | RR::SetOutputPrecision(d); |
73 | </pre> | |
100 | ENDPLAIN --> | |
101 | <!-- STARTPRETTY {{{ --> | |
102 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
103 | <font face="monospace"> | |
104 | RR::SetOutputPrecision(d);<br> | |
105 | </font> | |
106 | </font></td></tr></table><p><p> | |
107 | <!-- }}} ENDPRETTY --> | |
108 | ||
74 | 109 | which sets the output precision to <tt>d</tt>. |
75 | 110 | By default, <tt>d=10</tt>. |
76 | 111 | |
77 | 112 | <p> |
78 | See <a href="RR.txt"><tt>RR.txt</tt></a> for details. | |
113 | See <a href="RR.cpp.html"><tt>RR.txt</tt></a> for details. | |
79 | 114 | |
80 | 115 | <p> |
81 | 116 | |
84 | 119 | other floating point classes. |
85 | 120 | The output precision for these two classes can be controlled just |
86 | 121 | as with <tt>RR</tt>. |
87 | See <a href="quad_float.txt"><tt>quad_float.txt</tt></a> and | |
88 | <a href="xdouble.txt"><tt>xdouble.txt</tt></a> | |
122 | See <a href="quad_float.cpp.html"><tt>quad_float.txt</tt></a> and | |
123 | <a href="xdouble.cpp.html"><tt>xdouble.txt</tt></a> | |
89 | 124 | for details. |
90 | 125 | |
91 | 126 | <p> |
3 | 3 | A Tour of NTL: Examples </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-intro.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
3 | 3 | A Tour of NTL: Using NTL with the gf2x library </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | |
8 | 7 | <center> |
9 | 8 | <a href="tour-gmp.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
33 | 32 | for very large degree polynomials. |
34 | 33 | If you use NTL if the <tt>gf2x</tt> library, |
35 | 34 | then multiplication, division, GCD, and minimum polynomal |
36 | calculations for the <a href="GF2X.txt">GF2X</a> class will | |
35 | calculations for the <a href="GF2X.cpp.html">GF2X</a> class will | |
37 | 36 | be faster for large degree polymials. |
38 | 37 | |
39 | 38 |
3 | 3 | A Tour of NTL: Using NTL with GMP </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | |
8 | 7 | <center> |
9 | 8 | <a href="tour-impl.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
3 | 3 | A Tour of NTL: NTL Implementation and Portability </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-tips.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
232 | 231 | for the <tt>quad_float</tt> module, where some desperate hacks, |
233 | 232 | including assembly code, may be used |
234 | 233 | to try to work around problems created by "loose" IEEE floating point |
235 | <a href="quad_float.txt">[more details]</a>. | |
234 | <a href="quad_float.cpp.html">[more details]</a>. | |
236 | 235 | But note that even if the <tt>quad_float</tt> package does not work correctly |
237 | 236 | because of these problems, the only other routines that are affected |
238 | 237 | are the <tt>LLL_QP</tt> routines in the <tt>LLL</tt> module -- the |
3 | 3 | A Tour of NTL: Introduction </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | |
8 | 7 | <center> |
9 | 8 | <img src="arrow1.gif" alt="[Previous]" align=bottom> |
3 | 3 | A Tour of NTL: Summary of NTL's Main Modules </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-struct.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
3 | 3 | A Tour of NTL: NTL past, present, and future </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-time.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
3 | 3 | A Tour of NTL: Traditional and ISO Modes </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-modules.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
156 | 155 | <p> |
157 | 156 | |
158 | 157 | Here is a simple example to illustrate namespaces. |
159 | <p> | |
160 | <pre> | |
158 | <!-- STARTPLAIN | |
161 | 159 | |
162 | 160 | namespace N { |
163 | 161 | void f(int); |
172 | 170 | x = 1; // the global x |
173 | 171 | N::x = 0; // the x in namespace N |
174 | 172 | N::f(0); // the f in namespace N |
175 | g(1); // error -- g is not visible here | |
176 | } | |
177 | ||
178 | </pre> | |
173 | g(1); // error ~~ g is not visible here | |
174 | } | |
175 | ||
176 | ENDPLAIN --> | |
177 | <!-- STARTPRETTY {{{ --> | |
178 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
179 | <font face="monospace"> | |
180 | <br> | |
181 | namespace N {<br> | |
182 | <font color="#008b00"><b>void</b></font> f(<font color="#008b00"><b>int</b></font>);<br> | |
183 | <font color="#008b00"><b>void</b></font> g(<font color="#008b00"><b>int</b></font>);<br> | |
184 | <font color="#008b00"><b>int</b></font> x;<br> | |
185 | }<br> | |
186 | <br> | |
187 | <font color="#008b00"><b>int</b></font> x;<br> | |
188 | <br> | |
189 | <font color="#008b00"><b>void</b></font> h()<br> | |
190 | {<br> | |
191 | x = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// the global x</i></font><br> | |
192 | N::x = <font color="#ff8c00">0</font>; <font color="#0000ee"><i>// the x in namespace N</i></font><br> | |
193 | N::f(<font color="#ff8c00">0</font>); <font color="#0000ee"><i>// the f in namespace N</i></font><br> | |
194 | g(<font color="#ff8c00">1</font>); <font color="#0000ee"><i>// error -- g is not visible here</i></font><br> | |
195 | }<br> | |
196 | <br> | |
197 | </font> | |
198 | </font></td></tr></table><p><p> | |
199 | <!-- }}} ENDPRETTY --> | |
200 | ||
179 | 201 | |
180 | 202 | <p> |
181 | 203 | All of this explicit qualification business |
187 | 209 | |
188 | 210 | Here is a variation on the previous example, with a using directive. |
189 | 211 | |
190 | <p> | |
191 | <pre> | |
192 | ||
212 | <!-- STARTPLAIN | |
193 | 213 | namespace N { |
194 | 214 | void f(int); |
195 | 215 | void g(int); |
202 | 222 | |
203 | 223 | void h() |
204 | 224 | { |
205 | x = 1; // error -- ambiguous: the global x or the x in namespace N? | |
225 | x = 1; // error ~~ ambiguous: the global x or the x in namespace N? | |
206 | 226 | ::x = 1; // the global x |
207 | 227 | N::x = 0; // the x in namespace N |
208 | 228 | N::f(0); // the f in namespace N |
209 | f(0); // OK -- N::f(int) is visible here | |
210 | g(1); // OK -- N::g(int) is visible here | |
211 | } | |
212 | ||
213 | </pre> | |
229 | f(0); // OK ~~ N::f(int) is visible here | |
230 | g(1); // OK ~~ N::g(int) is visible here | |
231 | } | |
232 | ||
233 | ENDPLAIN --> | |
234 | <!-- STARTPRETTY {{{ --> | |
235 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
236 | <font face="monospace"> | |
237 | namespace N {<br> | |
238 | <font color="#008b00"><b>void</b></font> f(<font color="#008b00"><b>int</b></font>);<br> | |
239 | <font color="#008b00"><b>void</b></font> g(<font color="#008b00"><b>int</b></font>);<br> | |
240 | <font color="#008b00"><b>int</b></font> x;<br> | |
241 | }<br> | |
242 | <br> | |
243 | <font color="#008b00"><b>int</b></font> x;<br> | |
244 | <br> | |
245 | using namespace N;<br> | |
246 | <br> | |
247 | <font color="#008b00"><b>void</b></font> h()<br> | |
248 | {<br> | |
249 | x = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// error -- ambiguous: the global x or the x in namespace N?</i></font><br> | |
250 | ::x = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// the global x</i></font><br> | |
251 | N::x = <font color="#ff8c00">0</font>; <font color="#0000ee"><i>// the x in namespace N</i></font><br> | |
252 | N::f(<font color="#ff8c00">0</font>); <font color="#0000ee"><i>// the f in namespace N</i></font><br> | |
253 | f(<font color="#ff8c00">0</font>); <font color="#0000ee"><i>// OK -- N::f(int) is visible here</i></font><br> | |
254 | g(<font color="#ff8c00">1</font>); <font color="#0000ee"><i>// OK -- N::g(int) is visible here</i></font><br> | |
255 | }<br> | |
256 | <br> | |
257 | </font> | |
258 | </font></td></tr></table><p><p> | |
259 | <!-- }}} ENDPRETTY --> | |
260 | ||
214 | 261 | |
215 | 262 | <p> |
216 | 263 | Here is another example. |
217 | 264 | |
218 | <p> | |
219 | <pre> | |
265 | <!-- STARTPLAIN | |
220 | 266 | |
221 | 267 | namespace N1 { |
222 | 268 | int x; |
236 | 282 | |
237 | 283 | void h() |
238 | 284 | { |
239 | x = 1; // error -- ambiguous: N1::x or N2::x? | |
285 | x = 1; // error ~~ ambiguous: N1::x or N2::x? | |
240 | 286 | N1::x = 1; // OK |
241 | 287 | N2::x = 1; // OK |
242 | y = 1; // OK -- this is N2::y | |
243 | g(0); // error -- ambiguous: N1::g(int) or N2::g(int)? | |
244 | f(0); // OK -- N1::f(int), because it is the "best" match | |
245 | f(0.0); // OK -- N2::f(double), because it is the "best" match | |
246 | } | |
247 | ||
248 | </pre> | |
288 | y = 1; // OK ~~ this is N2::y | |
289 | g(0); // error ~~ ambiguous: N1::g(int) or N2::g(int)? | |
290 | f(0); // OK ~~ N1::f(int), because it is the "best" match | |
291 | f(0.0); // OK ~~ N2::f(double), because it is the "best" match | |
292 | } | |
293 | ||
294 | ENDPLAIN --> | |
295 | <!-- STARTPRETTY {{{ --> | |
296 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
297 | <font face="monospace"> | |
298 | <br> | |
299 | namespace N1 {<br> | |
300 | <font color="#008b00"><b>int</b></font> x;<br> | |
301 | <font color="#008b00"><b>void</b></font> f(<font color="#008b00"><b>int</b></font>);<br> | |
302 | <font color="#008b00"><b>void</b></font> g(<font color="#008b00"><b>int</b></font>);<br> | |
303 | }<br> | |
304 | <br> | |
305 | namespace N2 {<br> | |
306 | <font color="#008b00"><b>int</b></font> x;<br> | |
307 | <font color="#008b00"><b>int</b></font> y;<br> | |
308 | <font color="#008b00"><b>void</b></font> f(<font color="#008b00"><b>double</b></font>);<br> | |
309 | <font color="#008b00"><b>void</b></font> g(<font color="#008b00"><b>int</b></font>);<br> | |
310 | }<br> | |
311 | <br> | |
312 | using namespace N1;<br> | |
313 | using namespace N2;<br> | |
314 | <br> | |
315 | <font color="#008b00"><b>void</b></font> h()<br> | |
316 | {<br> | |
317 | x = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// error -- ambiguous: N1::x or N2::x?</i></font><br> | |
318 | N1::x = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// OK</i></font><br> | |
319 | N2::x = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// OK</i></font><br> | |
320 | y = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// OK -- this is N2::y</i></font><br> | |
321 | g(<font color="#ff8c00">0</font>); <font color="#0000ee"><i>// error -- ambiguous: N1::g(int) or N2::g(int)?</i></font><br> | |
322 | f(<font color="#ff8c00">0</font>); <font color="#0000ee"><i>// OK -- N1::f(int), because it is the "best" match </i></font><br> | |
323 | f(<font color="#ff8c00">0.0</font>); <font color="#0000ee"><i>// OK -- N2::f(double), because it is the "best" match</i></font><br> | |
324 | }<br> | |
325 | <br> | |
326 | </font> | |
327 | </font></td></tr></table><p><p> | |
328 | <!-- }}} ENDPRETTY --> | |
329 | ||
249 | 330 | |
250 | 331 | <p> |
251 | 332 | This example illustrates the interaction between using declarations |
271 | 352 | and NTL is "wrapped" in namespace <tt>NTL</tt>. |
272 | 353 | Thus, the header file <tt><NTL/ZZ.h></tt> in ISO mode looks |
273 | 354 | something like this: |
274 | <pre> | |
275 | ||
355 | ||
356 | <!-- STARTPLAIN | |
276 | 357 | namespace NTL { |
277 | 358 | |
278 | 359 | // ... |
281 | 362 | |
282 | 363 | // ... |
283 | 364 | |
284 | ZZ operator+(const ZZ& a, const ZZ& b); | |
285 | ZZ operator*(const ZZ& a, const ZZ& b); | |
286 | ||
287 | std::istream& operator>>(std::istream& s, ZZ& x); | |
288 | std::ostream& operator<<(std::ostream& s, const ZZ& a); | |
365 | ZZ operator+(const ZZ& a, const ZZ& b); | |
366 | ZZ operator*(const ZZ& a, const ZZ& b); | |
367 | ||
368 | std::istream& operator>>(std::istream& s, ZZ& x); | |
369 | std::ostream& operator<<(std::ostream& s, const ZZ& a); | |
289 | 370 | |
290 | 371 | // ... |
291 | 372 | |
292 | 373 | |
293 | 374 | } |
294 | 375 | |
295 | </pre> | |
376 | ENDPLAIN --> | |
377 | <!-- STARTPRETTY {{{ --> | |
378 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
379 | <font face="monospace"> | |
380 | namespace NTL {<br> | |
381 | <br> | |
382 | <font color="#0000ee"><i>// ...</i></font><br> | |
383 | <br> | |
384 | class ZZ { <font color="#0000ee"><i>/*</i></font><font color="#0000ee"><i> ... </i></font><font color="#0000ee"><i>*/</i></font> };<br> | |
385 | <br> | |
386 | <font color="#0000ee"><i>// ...</i></font><br> | |
387 | <br> | |
388 | ZZ operator+(<font color="#008b00"><b>const</b></font> ZZ& a, <font color="#008b00"><b>const</b></font> ZZ& b);<br> | |
389 | ZZ operator*(<font color="#008b00"><b>const</b></font> ZZ& a, <font color="#008b00"><b>const</b></font> ZZ& b);<br> | |
390 | <br> | |
391 | std::istream& operator>>(std::istream& s, ZZ& x);<br> | |
392 | std::ostream& operator<<(std::ostream& s, <font color="#008b00"><b>const</b></font> ZZ& a);<br> | |
393 | <br> | |
394 | <font color="#0000ee"><i>// ...</i></font><br> | |
395 | <br> | |
396 | <br> | |
397 | }<br> | |
398 | <br> | |
399 | </font> | |
400 | </font></td></tr></table><p><p> | |
401 | <!-- }}} ENDPRETTY --> | |
402 | ||
296 | 403 | |
297 | 404 | Therefore, one must explicitly qualify all names, or use appropriate |
298 | 405 | using directives. |
300 | 407 | of the tour in |
301 | 408 | ISO mode. |
302 | 409 | |
303 | <pre> | |
304 | ||
305 | #include <NTL/ZZ.h> | |
410 | <!-- STARTPLAIN | |
411 | #include <NTL/ZZ.h> | |
306 | 412 | |
307 | 413 | int main() |
308 | 414 | { |
309 | 415 | NTL::ZZ a, b, c; |
310 | 416 | |
311 | std::cin >> a; | |
312 | std::cin >> b; | |
417 | std::cin >> a; | |
418 | std::cin >> b; | |
313 | 419 | c = (a+1)*(b+1); |
314 | std::cout << c << "\n"; | |
315 | } | |
316 | ||
317 | </pre> | |
420 | std::cout << c << "\n"; | |
421 | } | |
422 | ||
423 | ENDPLAIN --> | |
424 | <!-- STARTPRETTY {{{ --> | |
425 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
426 | <font face="monospace"> | |
427 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
428 | <br> | |
429 | <font color="#008b00"><b>int</b></font> main()<br> | |
430 | {<br> | |
431 | NTL::ZZ a, b, c; <br> | |
432 | <br> | |
433 | std::cin >> a; <br> | |
434 | std::cin >> b; <br> | |
435 | c = (a+<font color="#ff8c00">1</font>)*(b+<font color="#ff8c00">1</font>);<br> | |
436 | std::cout << c << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
437 | }<br> | |
438 | <br> | |
439 | </font> | |
440 | </font></td></tr></table><p><p> | |
441 | <!-- }}} ENDPRETTY --> | |
442 | ||
318 | 443 | |
319 | 444 | <p> |
320 | 445 | Notice how everything is explicitly qualified. |
331 | 456 | be a bit tedious. |
332 | 457 | Here is the same example, this time with using directives. |
333 | 458 | |
334 | <pre> | |
335 | ||
336 | #include <NTL/ZZ.h> | |
459 | <!-- STARTPLAIN | |
460 | #include <NTL/ZZ.h> | |
337 | 461 | |
338 | 462 | using namespace NTL; |
339 | 463 | using namespace std; |
342 | 466 | { |
343 | 467 | ZZ a, b, c; |
344 | 468 | |
345 | cin >> a; | |
346 | cin >> b; | |
469 | cin >> a; | |
470 | cin >> b; | |
347 | 471 | c = (a+1)*(b+1); |
348 | cout << c << "\n"; | |
349 | } | |
350 | ||
351 | </pre> | |
472 | cout << c << "\n"; | |
473 | } | |
474 | ||
475 | ENDPLAIN --> | |
476 | <!-- STARTPRETTY {{{ --> | |
477 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
478 | <font face="monospace"> | |
479 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
480 | <br> | |
481 | using namespace NTL;<br> | |
482 | using namespace std;<br> | |
483 | <br> | |
484 | <font color="#008b00"><b>int</b></font> main()<br> | |
485 | {<br> | |
486 | ZZ a, b, c; <br> | |
487 | <br> | |
488 | cin >> a; <br> | |
489 | cin >> b; <br> | |
490 | c = (a+<font color="#ff8c00">1</font>)*(b+<font color="#ff8c00">1</font>);<br> | |
491 | cout << c << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
492 | }<br> | |
493 | <br> | |
494 | </font> | |
495 | </font></td></tr></table><p><p> | |
496 | <!-- }}} ENDPRETTY --> | |
497 | ||
352 | 498 | |
353 | 499 | To write NTL client code that will compile smoothly in either |
354 | 500 | Traditional or ISO mode, one simply does the following: |
355 | 501 | |
356 | <pre> | |
357 | ||
358 | #include <NTL/ZZ.h> | |
502 | <!-- STARTPLAIN | |
503 | #include <NTL/ZZ.h> | |
359 | 504 | |
360 | 505 | NTL_CLIENT |
361 | 506 | |
363 | 508 | { |
364 | 509 | ZZ a, b, c; |
365 | 510 | |
366 | cin >> a; | |
367 | cin >> b; | |
511 | cin >> a; | |
512 | cin >> b; | |
368 | 513 | c = (a+1)*(b+1); |
369 | cout << c << "\n"; | |
370 | } | |
371 | ||
372 | </pre> | |
514 | cout << c << "\n"; | |
515 | } | |
516 | ||
517 | ENDPLAIN --> | |
518 | <!-- STARTPRETTY {{{ --> | |
519 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
520 | <font face="monospace"> | |
521 | <font color="#1874cd">#include </font><font color="#4a708b"><NTL/ZZ.h></font><br> | |
522 | <br> | |
523 | NTL_CLIENT<br> | |
524 | <br> | |
525 | <font color="#008b00"><b>int</b></font> main()<br> | |
526 | {<br> | |
527 | ZZ a, b, c; <br> | |
528 | <br> | |
529 | cin >> a; <br> | |
530 | cin >> b; <br> | |
531 | c = (a+<font color="#ff8c00">1</font>)*(b+<font color="#ff8c00">1</font>);<br> | |
532 | cout << c << <font color="#4a708b">"</font><font color="#8a2be2">\n</font><font color="#4a708b">"</font>;<br> | |
533 | }<br> | |
534 | <br> | |
535 | </font> | |
536 | </font></td></tr></table><p><p> | |
537 | <!-- }}} ENDPRETTY --> | |
538 | ||
373 | 539 | |
374 | 540 | <p> |
375 | 541 | Here, <tt>NTL_CLIENT</tt> is a macro defined by NTL |
378 | 544 | <tt>NTL_PSTD_NNS</tt>, and <tt>NTL_PSTD_NHF</tt>. |
379 | 545 | Alternatively, instead of using the <tt>NTL_CLIENT</tt> macro, |
380 | 546 | you can write: |
381 | <p> | |
382 | ||
383 | <pre> | |
547 | ||
548 | <!-- STARTPLAIN | |
384 | 549 | #if (defined(NTL_PSTD_NNS) || defined(NTL_STD_CXX)) |
385 | 550 | using namespace NTL; |
386 | 551 | #endif |
388 | 553 | #if (defined(NTL_PSTD_NHF) || defined(NTL_STD_CXX)) |
389 | 554 | using namespace std; |
390 | 555 | #endif |
391 | </pre> | |
556 | ENDPLAIN --> | |
557 | <!-- STARTPRETTY {{{ --> | |
558 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
559 | <font face="monospace"> | |
560 | <font color="#1874cd">#if (defined(NTL_PSTD_NNS) || defined(NTL_STD_CXX))</font><br> | |
561 | using namespace NTL;<br> | |
562 | <font color="#1874cd">#endif</font><br> | |
563 | <br> | |
564 | <font color="#1874cd">#if (defined(NTL_PSTD_NHF) || defined(NTL_STD_CXX))</font><br> | |
565 | using namespace std;<br> | |
566 | <font color="#1874cd">#endif</font><br> | |
567 | </font> | |
568 | </font></td></tr></table><p><p> | |
569 | <!-- }}} ENDPRETTY --> | |
570 | ||
392 | 571 | |
393 | 572 | Typically, |
394 | 573 | when writing a program that uses NTL, |
477 | 656 | Specifically, the new header files declare several overloaded versions |
478 | 657 | of some functions. |
479 | 658 | For example, in the old header files, there was one function |
480 | <pre> | |
659 | <!-- STARTPLAIN | |
481 | 660 | int abs(int); |
482 | </pre> | |
661 | ENDPLAIN --> | |
662 | <!-- STARTPRETTY {{{ --> | |
663 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
664 | <font face="monospace"> | |
665 | <font color="#008b00"><b>int</b></font> abs(<font color="#008b00"><b>int</b></font>);<br> | |
666 | </font> | |
667 | </font></td></tr></table><p><p> | |
668 | <!-- }}} ENDPRETTY --> | |
669 | ||
483 | 670 | Now there are several, including: |
484 | <pre> | |
671 | <!-- STARTPLAIN | |
485 | 672 | int abs(int); |
486 | 673 | long abs(long); |
487 | 674 | float abs(float); |
488 | 675 | double abs(double); |
489 | 676 | long double abs(long double); |
490 | </pre> | |
677 | ENDPLAIN --> | |
678 | <!-- STARTPRETTY {{{ --> | |
679 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
680 | <font face="monospace"> | |
681 | <font color="#008b00"><b>int</b></font> abs(<font color="#008b00"><b>int</b></font>);<br> | |
682 | <font color="#008b00"><b>long</b></font> abs(<font color="#008b00"><b>long</b></font>);<br> | |
683 | <font color="#008b00"><b>float</b></font> abs(<font color="#008b00"><b>float</b></font>);<br> | |
684 | <font color="#008b00"><b>double</b></font> abs(<font color="#008b00"><b>double</b></font>);<br> | |
685 | <font color="#008b00"><b>long</b></font> <font color="#008b00"><b>double</b></font> abs(<font color="#008b00"><b>long</b></font> <font color="#008b00"><b>double</b></font>);<br> | |
686 | </font> | |
687 | </font></td></tr></table><p><p> | |
688 | <!-- }}} ENDPRETTY --> | |
689 | ||
491 | 690 | Also, functions like <tt>log</tt> and <tt>sqrt</tt> are also overloaded. |
492 | 691 | So instead of just |
493 | <pre> | |
692 | <!-- STARTPLAIN | |
494 | 693 | double log(double); |
495 | </pre> | |
694 | ENDPLAIN --> | |
695 | <!-- STARTPRETTY {{{ --> | |
696 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
697 | <font face="monospace"> | |
698 | <font color="#008b00"><b>double</b></font> log(<font color="#008b00"><b>double</b></font>);<br> | |
699 | </font> | |
700 | </font></td></tr></table><p><p> | |
701 | <!-- }}} ENDPRETTY --> | |
702 | ||
496 | 703 | there are |
497 | <pre> | |
704 | <!-- STARTPLAIN | |
498 | 705 | float log(float); |
499 | 706 | double log(double); |
500 | 707 | long double log(long double); |
501 | </pre> | |
708 | ENDPLAIN --> | |
709 | <!-- STARTPRETTY {{{ --> | |
710 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
711 | <font face="monospace"> | |
712 | <font color="#008b00"><b>float</b></font> log(<font color="#008b00"><b>float</b></font>);<br> | |
713 | <font color="#008b00"><b>double</b></font> log(<font color="#008b00"><b>double</b></font>);<br> | |
714 | <font color="#008b00"><b>long</b></font> <font color="#008b00"><b>double</b></font> log(<font color="#008b00"><b>long</b></font> <font color="#008b00"><b>double</b></font>);<br> | |
715 | </font> | |
716 | </font></td></tr></table><p><p> | |
717 | <!-- }}} ENDPRETTY --> | |
718 | ||
502 | 719 | |
503 | 720 | <p> |
504 | 721 | This can lead to compile-time errors in some old codes, such as: |
505 | <pre> | |
722 | <!-- STARTPLAIN | |
506 | 723 | double log_2 = log(2); |
507 | </pre> | |
724 | ENDPLAIN --> | |
725 | <!-- STARTPRETTY {{{ --> | |
726 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
727 | <font face="monospace"> | |
728 | <font color="#008b00"><b>double</b></font> log_2 = log(<font color="#ff8c00">2</font>);<br> | |
729 | </font> | |
730 | </font></td></tr></table><p><p> | |
731 | <!-- }}} ENDPRETTY --> | |
732 | ||
508 | 733 | |
509 | 734 | <p> |
510 | 735 | With the old header files, the <tt>int</tt> value 2 would have |
511 | 736 | been converted to a <tt>double</tt>, and the function |
512 | <pre> | |
737 | <!-- STARTPLAIN | |
513 | 738 | double log(double); |
514 | </pre> | |
739 | ENDPLAIN --> | |
740 | <!-- STARTPRETTY {{{ --> | |
741 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
742 | <font face="monospace"> | |
743 | <font color="#008b00"><b>double</b></font> log(<font color="#008b00"><b>double</b></font>);<br> | |
744 | </font> | |
745 | </font></td></tr></table><p><p> | |
746 | <!-- }}} ENDPRETTY --> | |
747 | ||
515 | 748 | would have been called. |
516 | 749 | <p> |
517 | 750 | With the new header files, the compiler would raise an error, |
518 | 751 | because the function call is now ambiguous. |
519 | 752 | <p> |
520 | 753 | Of course, the fix is trivial: |
521 | <pre> | |
754 | <!-- STARTPLAIN | |
522 | 755 | double log_2 = log(2.0); |
523 | </pre> | |
756 | ENDPLAIN --> | |
757 | <!-- STARTPRETTY {{{ --> | |
758 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
759 | <font face="monospace"> | |
760 | <font color="#008b00"><b>double</b></font> log_2 = log(<font color="#ff8c00">2.0</font>);<br> | |
761 | </font> | |
762 | </font></td></tr></table><p><p> | |
763 | <!-- }}} ENDPRETTY --> | |
764 | ||
524 | 765 | This will compile correctly with either old or new header files. |
525 | 766 | |
526 | 767 | <p> |
3 | 3 | A Tour of NTL: Programming Interface </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-examples.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
137 | 136 | a functional form, and a procedural form. |
138 | 137 | For example: |
139 | 138 | |
140 | <pre> | |
139 | <!-- STARTPLAIN | |
141 | 140 | ZZ x, a, n; |
142 | 141 | x = InvMod(a, n); // functional form |
143 | 142 | InvMod(x, a, n); // procedural form |
144 | </pre> | |
143 | ENDPLAIN --> | |
144 | <!-- STARTPRETTY {{{ --> | |
145 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
146 | <font face="monospace"> | |
147 | ZZ x, a, n;<br> | |
148 | x = InvMod(a, n); <font color="#0000ee"><i>// functional form</i></font><br> | |
149 | InvMod(x, a, n); <font color="#0000ee"><i>// procedural form</i></font><br> | |
150 | </font> | |
151 | </font></td></tr></table><p><p> | |
152 | <!-- }}} ENDPRETTY --> | |
153 | ||
145 | 154 | |
146 | 155 | <p> |
147 | 156 | This example illustrates the normal way these two forms differ |
151 | 160 | First, if there is a operator that can play the role of the |
152 | 161 | functional form, that is the notation used: |
153 | 162 | |
154 | <pre> | |
163 | <!-- STARTPLAIN | |
155 | 164 | ZZ x, a, b; |
156 | 165 | x = a + b; // functional form |
157 | 166 | add(x, a, b); // procedural form |
158 | </pre> | |
167 | ENDPLAIN --> | |
168 | <!-- STARTPRETTY {{{ --> | |
169 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
170 | <font face="monospace"> | |
171 | ZZ x, a, b;<br> | |
172 | x = a + b; <font color="#0000ee"><i>// functional form</i></font><br> | |
173 | add(x, a, b); <font color="#0000ee"><i>// procedural form</i></font><br> | |
174 | </font> | |
175 | </font></td></tr></table><p><p> | |
176 | <!-- }}} ENDPRETTY --> | |
177 | ||
159 | 178 | |
160 | 179 | Second, if the functional form's name would be ambiguous, |
161 | 180 | the return type is simply appended to its name: |
162 | 181 | |
163 | <pre> | |
182 | <!-- STARTPLAIN | |
164 | 183 | ZZ_p x; |
165 | 184 | x = random_ZZ_p(); // functional form |
166 | 185 | random(x); // procedural form |
167 | </pre> | |
186 | ENDPLAIN --> | |
187 | <!-- STARTPRETTY {{{ --> | |
188 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
189 | <font face="monospace"> | |
190 | ZZ_p x;<br> | |
191 | x = random_ZZ_p(); <font color="#0000ee"><i>// functional form</i></font><br> | |
192 | random(x); <font color="#0000ee"><i>// procedural form</i></font><br> | |
193 | </font> | |
194 | </font></td></tr></table><p><p> | |
195 | <!-- }}} ENDPRETTY --> | |
196 | ||
168 | 197 | |
169 | 198 | Third, there are a number of conversion functions (see below), whose name |
170 | 199 | in procedural form is <tt>conv</tt>, but whose name in |
171 | 200 | functional form is <tt>conv<T></tt>, where <tt>T</tt> is the return type: |
172 | 201 | |
173 | <pre> | |
202 | <!-- STARTPLAIN | |
174 | 203 | ZZ x; |
175 | 204 | double a; |
176 | 205 | |
177 | x = conv<ZZ>(a); // functional form | |
206 | x = conv<ZZ>(a); // functional form | |
178 | 207 | conv(x, a); // procedural form |
179 | </pre> | |
208 | ENDPLAIN --> | |
209 | <!-- STARTPRETTY {{{ --> | |
210 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
211 | <font face="monospace"> | |
212 | ZZ x; <br> | |
213 | <font color="#008b00"><b>double</b></font> a;<br> | |
214 | <br> | |
215 | x = conv<ZZ>(a); <font color="#0000ee"><i>// functional form</i></font><br> | |
216 | conv(x, a); <font color="#0000ee"><i>// procedural form</i></font><br> | |
217 | </font> | |
218 | </font></td></tr></table><p><p> | |
219 | <!-- }}} ENDPRETTY --> | |
220 | ||
180 | 221 | |
181 | 222 | |
182 | 223 | |
234 | 275 | to get the effect of automatic "promotions". |
235 | 276 | For example: |
236 | 277 | |
237 | <pre> | |
278 | <!-- STARTPLAIN | |
238 | 279 | ZZ x, a; |
239 | 280 | |
240 | 281 | x = a + 1; |
241 | if (x < 0) | |
282 | if (x < 0) | |
242 | 283 | mul(x, 2, a); |
243 | 284 | else |
244 | 285 | x = -1; |
245 | </pre> | |
286 | ENDPLAIN --> | |
287 | <!-- STARTPRETTY {{{ --> | |
288 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
289 | <font face="monospace"> | |
290 | ZZ x, a;<br> | |
291 | <br> | |
292 | x = a + <font color="#ff8c00">1</font>;<br> | |
293 | <font color="#b03060"><b>if</b></font> (x < <font color="#ff8c00">0</font>) <br> | |
294 | mul(x, <font color="#ff8c00">2</font>, a);<br> | |
295 | <font color="#b03060"><b>else</b></font><br> | |
296 | x = -<font color="#ff8c00">1</font>;<br> | |
297 | </font> | |
298 | </font></td></tr></table><p><p> | |
299 | <!-- }}} ENDPRETTY --> | |
300 | ||
246 | 301 | |
247 | 302 | <p> |
248 | 303 | |
250 | 305 | usually using a kind of "short hand" notation. |
251 | 306 | For example: |
252 | 307 | |
253 | <pre> | |
254 | ZZ operator+(const ZZ& a, const ZZ& b); | |
308 | <!-- STARTPLAIN | |
309 | ZZ operator+(const ZZ& a, const ZZ& b); | |
255 | 310 | |
256 | 311 | // PROMOTIONS: operator + promotes long to ZZ on (a, b). |
257 | </pre> | |
312 | ENDPLAIN --> | |
313 | <!-- STARTPRETTY {{{ --> | |
314 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
315 | <font face="monospace"> | |
316 | ZZ operator+(<font color="#008b00"><b>const</b></font> ZZ& a, <font color="#008b00"><b>const</b></font> ZZ& b);<br> | |
317 | <br> | |
318 | <font color="#0000ee"><i>// PROMOTIONS: operator + promotes long to ZZ on (a, b).</i></font><br> | |
319 | </font> | |
320 | </font></td></tr></table><p><p> | |
321 | <!-- }}} ENDPRETTY --> | |
322 | ||
258 | 323 | |
259 | 324 | This means that in addition to the declared function, there |
260 | 325 | are two other functions that are logically equivalent to the following: |
261 | <pre> | |
262 | ZZ operator+(long a, const ZZ& b) { return ZZ(a) + b; } | |
263 | ZZ operator+(const ZZ& a, long b) { return a + ZZ(b); } | |
264 | </pre> | |
326 | <!-- STARTPLAIN | |
327 | ZZ operator+(long a, const ZZ& b) { return ZZ(a) + b; } | |
328 | ZZ operator+(const ZZ& a, long b) { return a + ZZ(b); } | |
329 | ENDPLAIN --> | |
330 | <!-- STARTPRETTY {{{ --> | |
331 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
332 | <font face="monospace"> | |
333 | ZZ operator+(<font color="#008b00"><b>long</b></font> a, <font color="#008b00"><b>const</b></font> ZZ& b) { <font color="#b03060"><b>return</b></font> ZZ(a) + b; }<br> | |
334 | ZZ operator+(<font color="#008b00"><b>const</b></font> ZZ& a, <font color="#008b00"><b>long</b></font> b) { <font color="#b03060"><b>return</b></font> a + ZZ(b); }<br> | |
335 | </font> | |
336 | </font></td></tr></table><p><p> | |
337 | <!-- }}} ENDPRETTY --> | |
338 | ||
265 | 339 | |
266 | 340 | <p> |
267 | 341 | Note that this is not how NTL actually implements these functions. |
268 | 342 | It is in generally more efficient to write |
269 | <pre> | |
343 | <!-- STARTPLAIN | |
270 | 344 | x = y + 2; |
271 | </pre> | |
345 | ENDPLAIN --> | |
346 | <!-- STARTPRETTY {{{ --> | |
347 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
348 | <font face="monospace"> | |
349 | x = y + <font color="#ff8c00">2</font>;<br> | |
350 | </font> | |
351 | </font></td></tr></table><p><p> | |
352 | <!-- }}} ENDPRETTY --> | |
353 | ||
272 | 354 | than it is to write |
273 | <pre> | |
355 | <!-- STARTPLAIN | |
274 | 356 | x = y + ZZ(2); |
275 | </pre> | |
357 | ENDPLAIN --> | |
358 | <!-- STARTPRETTY {{{ --> | |
359 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
360 | <font face="monospace"> | |
361 | x = y + ZZ(<font color="#ff8c00">2</font>);<br> | |
362 | </font> | |
363 | </font></td></tr></table><p><p> | |
364 | <!-- }}} ENDPRETTY --> | |
365 | ||
276 | 366 | The former notation avoids the creation and destruction |
277 | 367 | of a temporary <tt>ZZ</tt> |
278 | 368 | object to hold the value 2. |
279 | 369 | |
280 | 370 | <p> |
281 | 371 | Also, don't have any inhibitions about writing tests like |
282 | <pre> | |
372 | <!-- STARTPLAIN | |
283 | 373 | if (x == 0) ... |
284 | </pre> | |
374 | ENDPLAIN --> | |
375 | <!-- STARTPRETTY {{{ --> | |
376 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
377 | <font face="monospace"> | |
378 | <font color="#b03060"><b>if</b></font> (x == <font color="#ff8c00">0</font>) ...<br> | |
379 | </font> | |
380 | </font></td></tr></table><p><p> | |
381 | <!-- }}} ENDPRETTY --> | |
382 | ||
285 | 383 | and assignments like |
286 | <pre> | |
384 | <!-- STARTPLAIN | |
287 | 385 | x = 1; |
288 | </pre> | |
386 | ENDPLAIN --> | |
387 | <!-- STARTPRETTY {{{ --> | |
388 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
389 | <font face="monospace"> | |
390 | x = <font color="#ff8c00">1</font>; <br> | |
391 | </font> | |
392 | </font></td></tr></table><p><p> | |
393 | <!-- }}} ENDPRETTY --> | |
394 | ||
289 | 395 | These are all optimized, and do not execute significaltly slower |
290 | 396 | than the "lower level" (and much less natural) |
291 | <pre> | |
397 | <!-- STARTPLAIN | |
292 | 398 | if (IsZero(x)) ... |
293 | </pre> | |
399 | ENDPLAIN --> | |
400 | <!-- STARTPRETTY {{{ --> | |
401 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
402 | <font face="monospace"> | |
403 | <font color="#b03060"><b>if</b></font> (IsZero(x)) ...<br> | |
404 | </font> | |
405 | </font></td></tr></table><p><p> | |
406 | <!-- }}} ENDPRETTY --> | |
407 | ||
294 | 408 | and |
295 | <pre> | |
409 | <!-- STARTPLAIN | |
296 | 410 | set(x); |
297 | </pre> | |
411 | ENDPLAIN --> | |
412 | <!-- STARTPRETTY {{{ --> | |
413 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
414 | <font face="monospace"> | |
415 | set(x);<br> | |
416 | </font> | |
417 | </font></td></tr></table><p><p> | |
418 | <!-- }}} ENDPRETTY --> | |
419 | ||
298 | 420 | |
299 | 421 | <p> |
300 | 422 | Some types have even more promotions. |
318 | 440 | For a given type, there is a natural, fixed set of types |
319 | 441 | that promote to it. |
320 | 442 | Here is the complete list: |
321 | <pre> | |
322 | destination: source | |
443 | <!-- STARTPLAIN | |
444 | destination source | |
323 | 445 | |
324 | xdouble: double | |
325 | quad_float: double | |
326 | RR: double | |
327 | ZZ: long | |
328 | ZZ_p: long | |
329 | ZZ_pX: long, ZZ_p | |
330 | zz_p: long | |
331 | zz_pX: long, zz_p | |
332 | ZZX: long, ZZ | |
333 | GF2: long | |
334 | GF2X: long, GF2 | |
335 | GF2E: long, GF2 | |
336 | GF2EX: long, GF2, GF2E | |
337 | ZZ_pE: long, ZZ_p | |
338 | ZZ_pEX: long, ZZ_p, ZZ_pE | |
339 | zz_pE: long, zz_p | |
340 | zz_pEX: long, zz_p, zz_pE | |
341 | </pre> | |
446 | xdouble double | |
447 | quad_float double | |
448 | RR double | |
449 | ZZ long | |
450 | ZZ_p long | |
451 | ZZ_pX long, ZZ_p | |
452 | zz_p long | |
453 | zz_pX long, zz_p | |
454 | ZZX long, ZZ | |
455 | GF2 long | |
456 | GF2X long, GF2 | |
457 | GF2E long, GF2 | |
458 | GF2EX long, GF2, GF2E | |
459 | ZZ_pE long, ZZ_p | |
460 | ZZ_pEX long, ZZ_p, ZZ_pE | |
461 | zz_pE long, zz_p | |
462 | zz_pEX long, zz_p, zz_pE | |
463 | ENDPLAIN --> | |
464 | <!-- STARTPRETTY {{{ --> | |
465 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
466 | <font face="monospace"> | |
467 | destination source<br> | |
468 | <br> | |
469 | xdouble <font color="#008b00"><b>double</b></font><br> | |
470 | quad_float <font color="#008b00"><b>double</b></font><br> | |
471 | RR <font color="#008b00"><b>double</b></font><br> | |
472 | ZZ <font color="#008b00"><b>long</b></font><br> | |
473 | ZZ_p <font color="#008b00"><b>long</b></font><br> | |
474 | ZZ_pX <font color="#008b00"><b>long</b></font>, ZZ_p<br> | |
475 | zz_p <font color="#008b00"><b>long</b></font><br> | |
476 | zz_pX <font color="#008b00"><b>long</b></font>, zz_p<br> | |
477 | ZZX <font color="#008b00"><b>long</b></font>, ZZ<br> | |
478 | GF2 <font color="#008b00"><b>long</b></font><br> | |
479 | GF2X <font color="#008b00"><b>long</b></font>, GF2<br> | |
480 | GF2E <font color="#008b00"><b>long</b></font>, GF2<br> | |
481 | GF2EX <font color="#008b00"><b>long</b></font>, GF2, GF2E<br> | |
482 | ZZ_pE <font color="#008b00"><b>long</b></font>, ZZ_p<br> | |
483 | ZZ_pEX <font color="#008b00"><b>long</b></font>, ZZ_p, ZZ_pE<br> | |
484 | zz_pE <font color="#008b00"><b>long</b></font>, zz_p<br> | |
485 | zz_pEX <font color="#008b00"><b>long</b></font>, zz_p, zz_pE<br> | |
486 | </font> | |
487 | </font></td></tr></table><p><p> | |
488 | <!-- }}} ENDPRETTY --> | |
489 | ||
342 | 490 | |
343 | 491 | <p> |
344 | 492 | All the promotions are documented, but here |
349 | 497 | <li> |
350 | 498 | All classes provide explicit constructors for promoted types. |
351 | 499 | For example, |
352 | <pre> | |
500 | <!-- STARTPLAIN | |
353 | 501 | ZZ w = ZZ(1); |
354 | 502 | ZZ x(1); // allowed |
355 | 503 | ZZ y{1}; // allowed in C++11 |
356 | 504 | ZZ z = 1; // not allowed |
357 | </pre> | |
505 | ENDPLAIN --> | |
506 | <!-- STARTPRETTY {{{ --> | |
507 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
508 | <font face="monospace"> | |
509 | ZZ w = ZZ(<font color="#ff8c00">1</font>);<br> | |
510 | ZZ x(<font color="#ff8c00">1</font>); <font color="#0000ee"><i>// allowed</i></font><br> | |
511 | ZZ y{<font color="#ff8c00">1</font>}; <font color="#0000ee"><i>// allowed in C++11</i></font><br> | |
512 | ZZ z = <font color="#ff8c00">1</font>; <font color="#0000ee"><i>// not allowed</i></font><br> | |
513 | </font> | |
514 | </font></td></tr></table><p><p> | |
515 | <!-- }}} ENDPRETTY --> | |
516 | ||
358 | 517 | |
359 | 518 | <li> |
360 | 519 | Promotions apply uniformly to both procedural and functional |
361 | 520 | forms, as well as to the corresponding assignment operator forms. |
362 | 521 | E.g., |
363 | <pre> | |
522 | <!-- STARTPLAIN | |
364 | 523 | x = x + 2; |
365 | 524 | add(x, x, 2); |
366 | 525 | x += 2; |
367 | </pre> | |
526 | ENDPLAIN --> | |
527 | <!-- STARTPRETTY {{{ --> | |
528 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
529 | <font face="monospace"> | |
530 | x = x + <font color="#ff8c00">2</font>;<br> | |
531 | add(x, x, <font color="#ff8c00">2</font>);<br> | |
532 | x += <font color="#ff8c00">2</font>;<br> | |
533 | </font> | |
534 | </font></td></tr></table><p><p> | |
535 | <!-- }}} ENDPRETTY --> | |
536 | ||
368 | 537 | |
369 | 538 | <li> |
370 | 539 | The addition, subtraction, multiplication, equality and comparison |
371 | 540 | routines always promote both arguments. E.g., |
372 | <pre> | |
541 | <!-- STARTPLAIN | |
373 | 542 | x = 2 + y; |
374 | 543 | add(x, 2, y); |
375 | if (3 > x || y == 5) ... | |
376 | </pre> | |
544 | if (3 > x || y == 5) ... | |
545 | ENDPLAIN --> | |
546 | <!-- STARTPRETTY {{{ --> | |
547 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
548 | <font face="monospace"> | |
549 | x = <font color="#ff8c00">2</font> + y;<br> | |
550 | add(x, <font color="#ff8c00">2</font>, y);<br> | |
551 | <font color="#b03060"><b>if</b></font> (<font color="#ff8c00">3</font> > x || y == <font color="#ff8c00">5</font>) ...<br> | |
552 | </font> | |
553 | </font></td></tr></table><p><p> | |
554 | <!-- }}} ENDPRETTY --> | |
555 | ||
377 | 556 | |
378 | 557 | <li> |
379 | 558 | The assignment operator always promotes the right-hand side. |
380 | 559 | E.g., |
381 | <pre> | |
560 | <!-- STARTPLAIN | |
382 | 561 | x = 2; |
383 | </pre> | |
562 | ENDPLAIN --> | |
563 | <!-- STARTPRETTY {{{ --> | |
564 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
565 | <font face="monospace"> | |
566 | x = <font color="#ff8c00">2</font>;<br> | |
567 | </font> | |
568 | </font></td></tr></table><p><p> | |
569 | <!-- }}} ENDPRETTY --> | |
570 | ||
384 | 571 | |
385 | 572 | <li> |
386 | 573 | For non-integer, non-polynomial types, the division routine |
387 | 574 | promotes both arguments. |
388 | 575 | E.g., |
389 | <pre> | |
576 | <!-- STARTPLAIN | |
390 | 577 | RR x, y, z; |
391 | 578 | ... |
392 | 579 | x = 1.0/y; |
393 | 580 | z = y/2.0; |
394 | </pre> | |
581 | ENDPLAIN --> | |
582 | <!-- STARTPRETTY {{{ --> | |
583 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
584 | <font face="monospace"> | |
585 | RR x, y, z;<br> | |
586 | ...<br> | |
587 | x = <font color="#ff8c00">1.0</font>/y;<br> | |
588 | z = y/<font color="#ff8c00">2.0</font>;<br> | |
589 | </font> | |
590 | </font></td></tr></table><p><p> | |
591 | <!-- }}} ENDPRETTY --> | |
592 | ||
395 | 593 | |
396 | 594 | For integer or polynomial types, the division routine |
397 | 595 | promotes the denominator only. E.g., |
405 | 603 | <li> |
406 | 604 | Matrix by scalar and vector by scalar multiplication promote the scalar. |
407 | 605 | E.g., |
408 | <pre> | |
409 | Vec<ZZ> v, w; | |
606 | <!-- STARTPLAIN | |
607 | Vec<ZZ> v, w; | |
410 | 608 | ... |
411 | 609 | v = w*2; |
412 | 610 | v = 2*w; |
413 | 611 | v *= 2; |
414 | </pre> | |
612 | ENDPLAIN --> | |
613 | <!-- STARTPRETTY {{{ --> | |
614 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
615 | <font face="monospace"> | |
616 | Vec<ZZ> v, w;<br> | |
617 | ...<br> | |
618 | v = w*<font color="#ff8c00">2</font>;<br> | |
619 | v = <font color="#ff8c00">2</font>*w;<br> | |
620 | v *= <font color="#ff8c00">2</font>;<br> | |
621 | </font> | |
622 | </font></td></tr></table><p><p> | |
623 | <!-- }}} ENDPRETTY --> | |
624 | ||
415 | 625 | |
416 | 626 | |
417 | 627 | <li> |
419 | 629 | and the corresponding <tt>SetCoeff</tt> routines |
420 | 630 | promote the coefficient argument. |
421 | 631 | E.g., |
422 | <pre> | |
632 | <!-- STARTPLAIN | |
423 | 633 | ZZX f; |
424 | 634 | f = ZZX(INIT_MONO, 3, 5); // f == 5*X^3 |
425 | 635 | SetCoeff(f, 0, 2); // f == 5*x^3 + 2; |
426 | </pre> | |
636 | ENDPLAIN --> | |
637 | <!-- STARTPRETTY {{{ --> | |
638 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
639 | <font face="monospace"> | |
640 | ZZX f;<br> | |
641 | f = ZZX(INIT_MONO, <font color="#ff8c00">3</font>, <font color="#ff8c00">5</font>); <font color="#0000ee"><i>// f == 5*X^3</i></font><br> | |
642 | SetCoeff(f, <font color="#ff8c00">0</font>, <font color="#ff8c00">2</font>); <font color="#0000ee"><i>// f == 5*x^3 + 2;</i></font><br> | |
643 | </font> | |
644 | </font></td></tr></table><p><p> | |
645 | <!-- }}} ENDPRETTY --> | |
646 | ||
427 | 647 | |
428 | 648 | <li> |
429 | 649 | In module <tt>ZZ</tt>, the modular arithmetic routines, as well as |
431 | 651 | There are also several other routines in module <tt>ZZ</tt> |
432 | 652 | that have both <tt>ZZ</tt> and <tt>long</tt> versions, e.g., |
433 | 653 | <tt>NumBits</tt>, <tt>bit</tt>, <tt>weight</tt>. |
434 | Check the documentation in <a href="ZZ.txt"><tt>ZZ.txt</tt></a> | |
654 | Check the documentation in <a href="ZZ.cpp.html"><tt>ZZ.cpp.html</tt></a> | |
435 | 655 | for complete details. |
436 | 656 | |
437 | 657 | </ul> |
457 | 677 | The safest way to do this is to apply an explicit conversion operator, |
458 | 678 | and not to rely on promotions. |
459 | 679 | For example, consider |
460 | <pre> | |
680 | <!-- STARTPLAIN | |
461 | 681 | ZZ a; double x; |
462 | 682 | |
463 | 683 | a = a + x; |
464 | </pre> | |
684 | ENDPLAIN --> | |
685 | <!-- STARTPRETTY {{{ --> | |
686 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
687 | <font face="monospace"> | |
688 | ZZ a; <font color="#008b00"><b>double</b></font> x;<br> | |
689 | <br> | |
690 | a = a + x;<br> | |
691 | </font> | |
692 | </font></td></tr></table><p><p> | |
693 | <!-- }}} ENDPRETTY --> | |
694 | ||
465 | 695 | This is equivialent to |
466 | <pre> | |
696 | <!-- STARTPLAIN | |
467 | 697 | a = a + long(x); |
468 | </pre> | |
698 | ENDPLAIN --> | |
699 | <!-- STARTPRETTY {{{ --> | |
700 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
701 | <font face="monospace"> | |
702 | a = a + <font color="#008b00"><b>long</b></font>(x);<br> | |
703 | </font> | |
704 | </font></td></tr></table><p><p> | |
705 | <!-- }}} ENDPRETTY --> | |
706 | ||
469 | 707 | and to |
470 | <pre> | |
708 | <!-- STARTPLAIN | |
471 | 709 | a = a + ZZ(x); |
472 | </pre> | |
710 | ENDPLAIN --> | |
711 | <!-- STARTPRETTY {{{ --> | |
712 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
713 | <font face="monospace"> | |
714 | a = a + ZZ(x);<br> | |
715 | </font> | |
716 | </font></td></tr></table><p><p> | |
717 | <!-- }}} ENDPRETTY --> | |
718 | ||
473 | 719 | One could also use an explicit conversion function: |
474 | <pre> | |
475 | a = a + conv<ZZ>(x); | |
476 | </pre> | |
720 | <!-- STARTPLAIN | |
721 | a = a + conv<ZZ>(x); | |
722 | ENDPLAIN --> | |
723 | <!-- STARTPRETTY {{{ --> | |
724 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
725 | <font face="monospace"> | |
726 | a = a + conv<ZZ>(x);<br> | |
727 | </font> | |
728 | </font></td></tr></table><p><p> | |
729 | <!-- }}} ENDPRETTY --> | |
730 | ||
477 | 731 | This last version guarantees that there is no loss of precision, |
478 | 732 | and also guarantees that the floor of <tt>x</tt> is computed. |
479 | 733 | With the first version, one may lose precision when <tt>x</tt> |
503 | 757 | Another pitfall too avoid is initialzing <tt>ZZ</tt>'s |
504 | 758 | with integer constants that are too big. |
505 | 759 | Consider the following: |
506 | <pre> | |
760 | <!-- STARTPLAIN | |
507 | 761 | ZZ x; |
508 | 762 | x = 1234567890123456789012; |
509 | </pre> | |
763 | ENDPLAIN --> | |
764 | <!-- STARTPRETTY {{{ --> | |
765 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
766 | <font face="monospace"> | |
767 | ZZ x;<br> | |
768 | x = <font color="#ff8c00">1234567890123456789012</font>;<br> | |
769 | </font> | |
770 | </font></td></tr></table><p><p> | |
771 | <!-- }}} ENDPRETTY --> | |
772 | ||
510 | 773 | This integer constant is too big, and this overflow |
511 | 774 | condition may or may not cause your compiler to give |
512 | 775 | you a warning or an error. |
513 | 776 | The easiest way to introduce such large constants into your |
514 | 777 | program is as follows: |
515 | <pre> | |
778 | <!-- STARTPLAIN | |
516 | 779 | ZZ x; |
517 | x = conv<ZZ>("1234567890123456789012"); | |
518 | </pre> | |
780 | x = conv<ZZ>("1234567890123456789012"); | |
781 | ENDPLAIN --> | |
782 | <!-- STARTPRETTY {{{ --> | |
783 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
784 | <font face="monospace"> | |
785 | ZZ x;<br> | |
786 | x = conv<ZZ>(<font color="#4a708b">"1234567890123456789012"</font>);<br> | |
787 | </font> | |
788 | </font></td></tr></table><p><p> | |
789 | <!-- }}} ENDPRETTY --> | |
790 | ||
519 | 791 | Conversion functions are provided for converting <tt>C</tt> character strings |
520 | 792 | to the types <tt>ZZ</tt>, <tt>RR</tt>, <tt>quad_float</tt>, |
521 | 793 | and <tt>xdouble</tt>. |
590 | 862 | It is safe to declare global objects of any NTL type |
591 | 863 | as long as one uses only the default constructor. |
592 | 864 | For example, the global declarations |
593 | <pre> | |
865 | <!-- STARTPLAIN | |
594 | 866 | ZZ global_integer; |
595 | Vec<ZZ_p> global_vector; | |
596 | </pre> | |
867 | Vec<ZZ_p> global_vector; | |
868 | ENDPLAIN --> | |
869 | <!-- STARTPRETTY {{{ --> | |
870 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
871 | <font face="monospace"> | |
872 | ZZ global_integer;<br> | |
873 | Vec<ZZ_p> global_vector;<br> | |
874 | </font> | |
875 | </font></td></tr></table><p><p> | |
876 | <!-- }}} ENDPRETTY --> | |
877 | ||
597 | 878 | should always work, since their initialization only involves |
598 | 879 | setting a pointer to 0. |
599 | 880 | However, |
612 | 893 | should not matter too much. |
613 | 894 | There is, however, one possible exception to this. |
614 | 895 | A programmer might want to have a global constant initialized like this: |
615 | <pre> | |
616 | const quad_float Pi = conv<quad_float>("3.1415926535897932384626433832795029"); | |
617 | </pre> | |
896 | <!-- STARTPLAIN | |
897 | const quad_float Pi = conv<quad_float>("3.1415926535897932384626433832795029"); | |
898 | ENDPLAIN --> | |
899 | <!-- STARTPRETTY {{{ --> | |
900 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
901 | <font face="monospace"> | |
902 | <font color="#008b00"><b>const</b></font> quad_float Pi = conv<quad_float>(<font color="#4a708b">"3.1415926535897932384626433832795029"</font>);<br> | |
903 | </font> | |
904 | </font></td></tr></table><p><p> | |
905 | <!-- }}} ENDPRETTY --> | |
906 | ||
618 | 907 | While this probably will work fine on most platforms, |
619 | 908 | it may not be an entirely portable construction, |
620 | 909 | since it will involve a non-trivial computation before |
622 | 911 | A more portable strategy |
623 | 912 | is to define a function returning a read-only |
624 | 913 | reference: |
625 | <pre> | |
626 | const quad_float& Pi() | |
914 | <!-- STARTPLAIN | |
915 | const quad_float& Pi() | |
627 | 916 | { |
628 | 917 | static quad_float pi = |
629 | conv<quad_float>("3.1415926535897932384626433832795029"); | |
918 | conv<quad_float>("3.1415926535897932384626433832795029"); | |
630 | 919 | return pi; |
631 | 920 | } |
632 | </pre> | |
921 | ENDPLAIN --> | |
922 | <!-- STARTPRETTY {{{ --> | |
923 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
924 | <font face="monospace"> | |
925 | <font color="#008b00"><b>const</b></font> quad_float& Pi()<br> | |
926 | {<br> | |
927 | <font color="#008b00"><b>static</b></font> quad_float pi = <br> | |
928 | conv<quad_float>(<font color="#4a708b">"3.1415926535897932384626433832795029"</font>);<br> | |
929 | <font color="#b03060"><b>return</b></font> pi;<br> | |
930 | }<br> | |
931 | </font> | |
932 | </font></td></tr></table><p><p> | |
933 | <!-- }}} ENDPRETTY --> | |
934 | ||
633 | 935 | and then call the function <tt>Pi()</tt> to get a read-only reference |
634 | 936 | to this constant value: |
635 | <pre> | |
937 | <!-- STARTPLAIN | |
636 | 938 | area = Pi()*r*r; |
637 | </pre> | |
939 | ENDPLAIN --> | |
940 | <!-- STARTPRETTY {{{ --> | |
941 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
942 | <font face="monospace"> | |
943 | area = Pi()*r*r;<br> | |
944 | </font> | |
945 | </font></td></tr></table><p><p> | |
946 | <!-- }}} ENDPRETTY --> | |
947 | ||
638 | 948 | The initialization will then take place the first time <tt>Pi()</tt> |
639 | 949 | is called, which is presumably after <tt>main()</tt> starts, |
640 | 950 | and so everything should work fine. |
662 | 972 | residue class types. |
663 | 973 | For example, for <tt>ZZ_p</tt>, you can set the current modulus to <tt>p</tt> |
664 | 974 | as follows: |
665 | <pre> | |
975 | <!-- STARTPLAIN | |
666 | 976 | ZZ_p::init(p); |
667 | </pre> | |
977 | ENDPLAIN --> | |
978 | <!-- STARTPRETTY {{{ --> | |
979 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
980 | <font face="monospace"> | |
981 | ZZ_p::init(p);<br> | |
982 | </font> | |
983 | </font></td></tr></table><p><p> | |
984 | <!-- }}} ENDPRETTY --> | |
985 | ||
668 | 986 | The current modulus <i>must</i> be initialized before any operations |
669 | 987 | on <tt>ZZ_p</tt>'s are performed. The modulus may be changed, and a mechanism is provided |
670 | 988 | for saving and restoring a modulus. |
673 | 991 | Here is what you do to save the current modulus, temporarily |
674 | 992 | set it to p, and automatically restore it: |
675 | 993 | |
676 | <pre> | |
994 | <!-- STARTPLAIN | |
677 | 995 | { |
678 | 996 | ZZ_pPush push(p); |
679 | 997 | |
680 | 998 | ... |
681 | 999 | |
682 | 1000 | } |
683 | </pre> | |
1001 | ENDPLAIN --> | |
1002 | <!-- STARTPRETTY {{{ --> | |
1003 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1004 | <font face="monospace"> | |
1005 | { <br> | |
1006 | ZZ_pPush push(p); <br> | |
1007 | <br> | |
1008 | ...<br> | |
1009 | <br> | |
1010 | }<br> | |
1011 | </font> | |
1012 | </font></td></tr></table><p><p> | |
1013 | <!-- }}} ENDPRETTY --> | |
1014 | ||
684 | 1015 | |
685 | 1016 | The constructor for push will save the current modulus, and install <tt>p</tt> as the |
686 | 1017 | current modulus. The destructor for push will restore the old modulus when the |
690 | 1021 | <p> |
691 | 1022 | You could also do the following: |
692 | 1023 | |
693 | <pre> | |
1024 | <!-- STARTPLAIN | |
694 | 1025 | { |
695 | 1026 | ZZ_pPush push(); // just backup current modulus |
696 | 1027 | |
704 | 1035 | |
705 | 1036 | // reinstall original modulus as close of scope |
706 | 1037 | } |
707 | </pre> | |
1038 | ENDPLAIN --> | |
1039 | <!-- STARTPRETTY {{{ --> | |
1040 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
1041 | <font face="monospace"> | |
1042 | {<br> | |
1043 | ZZ_pPush push(); <font color="#0000ee"><i>// just backup current modulus</i></font><br> | |
1044 | <br> | |
1045 | ...<br> | |
1046 | <br> | |
1047 | ZZ_p::init(p1); <font color="#0000ee"><i>// install p1 </i></font><br> | |
1048 | <br> | |
1049 | ...<br> | |
1050 | <br> | |
1051 | ZZ_p::init(p2); <font color="#0000ee"><i>// install p2</i></font><br> | |
1052 | <br> | |
1053 | <font color="#0000ee"><i>// reinstall original modulus as close of scope</i></font><br> | |
1054 | }<br> | |
1055 | </font> | |
1056 | </font></td></tr></table><p><p> | |
1057 | <!-- }}} ENDPRETTY --> | |
1058 | ||
708 | 1059 | |
709 | 1060 | |
710 | 1061 | <p> |
3 | 3 | A Tour of NTL: Some Performance Data </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | |
8 | 7 | <center> |
9 | 8 | <a href="tour-gf2x.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
4 | 4 | </title> |
5 | 5 | </head> |
6 | 6 | |
7 | <body bgcolor="#fff9e6"> | |
8 | 7 | <center> |
9 | 8 | <a href="tour-win.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
10 | 9 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
64 | 63 | In time-critical code, avoid creating unnecessary temporary |
65 | 64 | objects. |
66 | 65 | For example, instead of |
67 | <pre> | |
66 | <!-- STARTPLAIN | |
68 | 67 | ZZ InnerProduct(const ZZ *a, const ZZ *b, long n) |
69 | 68 | { |
70 | 69 | long i; |
73 | 72 | res += a[i] * b[i]; |
74 | 73 | return res; |
75 | 74 | } |
76 | </pre> | |
75 | ENDPLAIN --> | |
76 | <!-- STARTPRETTY {{{ --> | |
77 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
78 | <font face="monospace"> | |
79 | ZZ InnerProduct(<font color="#008b00"><b>const</b></font> ZZ *a, <font color="#008b00"><b>const</b></font> ZZ *b, <font color="#008b00"><b>long</b></font> n)<br> | |
80 | {<br> | |
81 | <font color="#008b00"><b>long</b></font> i;<br> | |
82 | ZZ res;<br> | |
83 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">0</font>; i < n; i++)<br> | |
84 | res += a[i] * b[i];<br> | |
85 | <font color="#b03060"><b>return</b></font> res;<br> | |
86 | }<br> | |
87 | </font> | |
88 | </font></td></tr></table><p><p> | |
89 | <!-- }}} ENDPRETTY --> | |
90 | ||
77 | 91 | write this as |
78 | <pre> | |
92 | <!-- STARTPLAIN | |
79 | 93 | ZZ InnerProduct(const ZZ *a, const ZZ *b, long n) |
80 | 94 | { |
81 | 95 | long i; |
86 | 100 | } |
87 | 101 | return res; |
88 | 102 | } |
89 | </pre> | |
103 | ENDPLAIN --> | |
104 | <!-- STARTPRETTY {{{ --> | |
105 | <p><p><table cellPadding=10px><tr><td><font color="#000000"> | |
106 | <font face="monospace"> | |
107 | ZZ InnerProduct(<font color="#008b00"><b>const</b></font> ZZ *a, <font color="#008b00"><b>const</b></font> ZZ *b, <font color="#008b00"><b>long</b></font> n)<br> | |
108 | {<br> | |
109 | <font color="#008b00"><b>long</b></font> i;<br> | |
110 | ZZ res, t;<br> | |
111 | <font color="#b03060"><b>for</b></font> (i = <font color="#ff8c00">0</font>; i < n; i++) {<br> | |
112 | mul(t, a[i], b[i]);<br> | |
113 | add(res, res, t);<br> | |
114 | }<br> | |
115 | <font color="#b03060"><b>return</b></font> res;<br> | |
116 | }<br> | |
117 | </font> | |
118 | </font></td></tr></table><p><p> | |
119 | <!-- }}} ENDPRETTY --> | |
120 | ||
90 | 121 | The first version of <tt>InnerProduct</tt> |
91 | 122 | creates and destroys a temporary object, holding the value |
92 | 123 | <tt>a[i]*b[i]</tt>, in every loop iteration. |
101 | 132 | too often, as this can be a rather expensive operation. |
102 | 133 | If you <i>must</i> switch the modulus often, |
103 | 134 | use the class <tt>ZZ_pContext</tt> to save the information |
104 | associated with the modulus (see <a href="ZZ_p.txt">ZZ_p.txt</a>). | |
135 | associated with the modulus (see <a href="ZZ_p.cpp.html">ZZ_p.txt</a>). | |
105 | 136 | |
106 | 137 | |
107 | 138 |
3 | 3 | A Tour of NTL: Obtaining and Installing NTL for UNIX </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <center> |
8 | 7 | <a href="tour-stdcxx.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
9 | 8 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
4 | 4 | and other Platforms </title> |
5 | 5 | </head> |
6 | 6 | |
7 | <body bgcolor="#fff9e6"> | |
8 | 7 | <center> |
9 | 8 | <a href="tour-unix.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> |
10 | 9 | <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> |
3 | 3 | A Tour of NTL </title> |
4 | 4 | </head> |
5 | 5 | |
6 | <body bgcolor="#fff9e6"> | |
7 | 6 | <h1> |
8 | 7 | <p align=center> |
9 | 8 | A Tour of NTL |
0 | ||
1 | // TODO: add constructor that uses BlockConstructFromObj | |
2 | 0 | |
3 | 1 | #ifndef NTL_vector__H |
4 | 2 | #define NTL_vector__H |
423 | 421 | if (n >= allocated()) pos = position(a); |
424 | 422 | AllocateTo(n); |
425 | 423 | if (pos != -1) src = elts() + pos; |
426 | Init(n, a, *src); | |
424 | Init(n, *src); | |
427 | 425 | AdjustLength(n); |
428 | 426 | } |
429 | 427 |
5 | 5 | |
6 | 6 | #define NTL_MAJOR_VERSION (6) |
7 | 7 | #define NTL_MINOR_VERSION (2) |
8 | #define NTL_REVISION (0) | |
8 | #define NTL_REVISION (1) | |
9 | 9 | |
10 | 10 | #endif |
11 | 11 |