27 #include <NTL/ZZ_pX.h>
28 #include <NTL/GF2EX.h>
32 #define FTXY FXY<F,FX,vec_FX>
52 template <
class F,
class FX,
class vec_FX>
57 typedef vec_FX VectorBaseType;
76 FXY(INIT_SIZE_TYPE,
long n) { rep.SetMaxLength(n); }
78 FXY(
const FXY& a) : rep(a.rep) { }
82 FXY& operator=(
const FXY& a)
83 { rep = a.rep;
return *
this; }
104 while (n > 0 && IsZero(*--p)) {
110 void SetMaxLength(
long n)
114 { rep.SetMaxLength(n); }
122 static const FXY& zero() {
128 FXY(
FXY& x, INIT_TRANS_TYPE) : rep(x.rep, INIT_TRANS) { }
130 inline FXY(
long i,
const FX& c);
131 inline FXY(
long i,
const F& c);
132 inline FXY(
long i,
long c);
134 FXY& operator=(
long a) { conv(*
this, a);
return *
this; }
135 FXY& operator=(
const F& a) { conv(*
this, a);
return *
this; }
136 FXY& operator=(
const FX& a) { conv(*
this, a);
return *
this; }
161 template <
class F,
class FX,
class vec_FX>
169 template <
class F,
class FX,
class vec_FX>
170 NTL_SNS ostream& operator<<(NTL_SNS ostream& s, const FXY<F,FX,vec_FX>& a)
186 template <
class F,
class FX,
class vec_FX>
191 template <
class F,
class FX,
class vec_FX>
198 template <
class F,
class FX,
class vec_FX>
206 long degY = a.rep.length() - 1;
210 degX = deg(a.rep[0]);
211 for(
long i = 1; i <= degY; i++){
212 if( deg(a.rep[i]) > degX )
213 degX = deg(a.rep[i]);
225 template <
class F,
class FX,
class vec_FX>
228 if (i < 0 || i > deg(a))
235 template <
class F,
class FX,
class vec_FX>
238 if (i < 0 || i > deg(a))
245 template <
class F,
class FX,
class vec_FX>
251 return a.rep[deg(a)];
255 template <
class F,
class FX,
class vec_FX>
265 template <
class F,
class FX,
class vec_FX>
271 Error(
"SetCoeff: negative index");
273 if (NTL_OVERFLOW(i, 1, 0))
274 Error(
"overflow in SetCoeff");
282 long alloc = x.rep.allocated();
284 if (alloc > 0 && i >= alloc) {
285 FXTemp aa_tmp; FX& aa = aa_tmp.val();
287 x.rep.SetLength(i+1);
292 x.rep.SetLength(i+1);
293 SetCoeff(x.rep[i], j, a);
298 for (k = m+1; k < i; k++)
302 SetCoeff(x.rep[i], j, a);
308 template <
class F,
class FX,
class vec_FX>
314 Error(
"SetCoeff: negative index");
316 if (NTL_OVERFLOW(i, 1, 0))
317 Error(
"overflow in SetCoeff");
325 long alloc = x.rep.allocated();
327 if (alloc > 0 && i >= alloc) {
328 FXTemp aa_tmp; FX& aa = aa_tmp.val();
330 x.rep.SetLength(i+1);
335 x.rep.SetLength(i+1);
341 for (j = m+1; j < i; j++)
350 template <
class F,
class FX,
class vec_FX>
363 template <
class F,
class FX,
class vec_FX>
369 Error(
"coefficient index out of range");
371 if (NTL_OVERFLOW(i, 1, 0))
372 Error(
"overflow in SetCoeff");
377 x.rep.SetLength(i+1);
378 for (j = m+1; j < i; j++)
385 template <
class F,
class FX,
class vec_FX>
387 { SetCoeff(*
this, i, a); }
389 template <
class F,
class FX,
class vec_FX>
391 { SetCoeff(*
this, i, a); }
394 template <
class F,
class FX,
class vec_FX>
402 template <
class F,
class FX,
class vec_FX>
405 return deg(a) == 1 && IsOne(LeadCoeff(a)) && IsZero(ConstTerm(a));
408 template <
class F,
class FX,
class vec_FX>
412 { x.rep.SetLength(0); }
414 template <
class F,
class FX,
class vec_FX>
418 { x.rep.SetLength(1); set(x.rep[0]); }
420 template <
class F,
class FX,
class vec_FX>
424 { swap(x.rep, y.rep); }
426 template <
class F,
class FX,
class vec_FX>
428 template <
class F,
class FX,
class vec_FX>
433 template <
class F,
class FX,
class vec_FX>
437 template <
class F,
class FX,
class vec_FX>
441 template <
class F,
class FX,
class vec_FX>
445 template <
class F,
class FX,
class vec_FX>
449 template <
class F,
class FX,
class vec_FX>
453 template <
class F,
class FX,
class vec_FX>
458 template <
class F,
class FX,
class vec_FX>
459 FX shiftX(
const FX& P,
long n)
464 long deg = P.rep.length()-1;
467 x.rep.SetLength( deg+1+n );
469 for(
long i = 0; i < n; i++){
472 for(
long i = 0; i <= deg; i++){
473 x.rep[i+n] = P.rep[i];
479 template <
class F,
class FX,
class vec_FX>
484 long deg = P.rep.length() - 1;
488 x.rep.SetLength( deg+1 );
490 for(
long i = 0; i <= deg; i++){
491 if( IsZero(P.rep[i]) ){
494 degX = (P.rep[i].rep.length()-1)-n;
495 x.rep[i].rep.SetLength( degX + 1);
496 for(
long j = 0; j <= degX; j++){
497 x.rep[i].rep[j] = P.rep[i].rep[j+n];
505 #ifndef NTL_TRANSITION
507 template <
class F,
class FX,
class vec_FX>
511 template <
class F,
class FX,
class vec_FX>
515 template <
class F,
class FX,
class vec_FX>
517 { LeftShift(x, x, n);
return x; }
519 template <
class F,
class FX,
class vec_FX>
521 { RightShift(x, x, n);
return x; }
527 template <
class F,
class FX,
class vec_FX>
531 template <
class F,
class FX,
class vec_FX>
536 template <
class F,
class FX,
class vec_FX>
542 F lc = LeadCoeff(LeadCoeff(x));
551 template <
class F,
class FX,
class vec_FX>
554 template <
class F,
class FX,
class vec_FX>
558 template <
class F,
class FX,
class vec_FX>
560 { reverse(c, a, deg(a)); }
562 template <
class F,
class FX,
class vec_FX>
568 template <
class F,
class FX,
class vec_FX>
571 long max_degree = -1;
572 for (
long i = 0; i < a.rep.length(); ++i) {
573 long d = deg(a.rep[i]);
574 if (d >= max_degree) {
582 template <
class F,
class FX,
class vec_FX>
585 for (
long i = 0; i < a.rep.length(); ++i) {
586 for (
long j = 0; j <= deg(a.rep[i]); ++j) {
587 if (j > deg(new_a)) {
588 SetCoeff(new_a, j, FX(i, coeff(a.rep[i], j)));
590 SetCoeff(new_a.rep[j], i, coeff(a.rep[i], j));
597 template <
class F,
class FX,
class vec_FX>
600 for (
long i = 0; i < a.rep.length(); ++i) {
601 result += power(x, i) * a.rep[i];
615 template <
class F,
class FX,
class vec_FX>
629 template <
class F,
class FX,
class vec_FX>
641 template <
class F,
class FX,
class vec_FX>
655 template <
class F,
class FX,
class vec_FX>
662 template <
class F,
class FX,
class vec_FX>
666 template <
class F,
class FX,
class vec_FX>
670 template <
class F,
class FX,
class vec_FX>
674 template <
class F,
class FX,
class vec_FX>
686 template <
class F,
class FX,
class vec_FX>
689 return a.rep.length() == 0;
692 template <
class F,
class FX,
class vec_FX>
695 return a.rep.length() == 1 && IsOne(a.rep[0]);
698 template <
class F,
class FX,
class vec_FX>
701 return a.rep == b.rep;
704 template <
class F,
class FX,
class vec_FX>
710 template <
class F,
class FX,
class vec_FX>
730 return a.rep[0] == bb;
733 template <
class F,
class FX,
class vec_FX>
744 return a.rep[0] == b;
747 template <
class F,
class FX,
class vec_FX>
758 return a.rep[0] == b;
761 template <
class F,
class FX,
class vec_FX>
762 inline long operator==(
long a,
const FXY<F,FX,vec_FX>& b) {
return b == a; }
763 template <
class F,
class FX,
class vec_FX>
764 inline long operator==(
const F& a,
const FXY<F,FX,vec_FX>& b) {
return b == a; }
765 template <
class F,
class FX,
class vec_FX>
766 inline long operator==(
const FX& a,
const FXY<F,FX,vec_FX>& b) {
return b == a; }
768 template <
class F,
class FX,
class vec_FX>
769 inline long operator!=(
const FXY<F,FX,vec_FX>& a,
long b) {
return !(a == b); }
770 template <
class F,
class FX,
class vec_FX>
771 inline long operator!=(
const FXY<F,FX,vec_FX>& a,
const F& b) {
return !(a == b); }
772 template <
class F,
class FX,
class vec_FX>
773 inline long operator!=(
const FXY<F,FX,vec_FX>& a,
const FX& b) {
return !(a == b); }
775 template <
class F,
class FX,
class vec_FX>
776 inline long operator!=(
long a,
const FXY<F,FX,vec_FX>& b) {
return !(a == b); }
777 template <
class F,
class FX,
class vec_FX>
778 inline long operator!=(
const F& a,
const FXY<F,FX,vec_FX>& b) {
return !(a == b); }
779 template <
class F,
class FX,
class vec_FX>
780 inline long operator!=(
const FX& a,
const FXY<F,FX,vec_FX>& b) {
return !(a == b); }
792 template <
class F,
class FX,
class vec_FX>
797 long minab = min(degYa, degYb);
798 long maxab = max(degYa, degYb);
799 x.rep.SetLength(maxab+1);
805 for (i = minab+1, ap = a.rep.elts(), bp = b.rep.elts(), xp = x.rep.elts();
806 i; i--, ap++, bp++, xp++)
807 add(*xp, (*ap), (*bp));
809 if (degYa > minab && &x != &a)
810 for (i = degYa-minab; i; i--, xp++, ap++)
812 else if (degYb > minab && &x != &b)
813 for (i = degYb-minab; i; i--, xp++, bp++)
819 template <
class F,
class FX,
class vec_FX>
822 long n = a.rep.length();
827 add(x.rep[0], a.rep[0], b);
830 else if (x.rep.MaxLength() == 0) {
832 add(x.rep[0], a.rep[0], b);
838 FX *xp = x.rep.elts();
839 add(xp[0], a.rep[0], b);
842 const FX *ap = a.rep.elts();
844 for (i = 1; i < n; i++)
850 template <
class F,
class FX,
class vec_FX>
853 if (a.rep.length() == 0) {
858 add(x.rep[0], x.rep[0], b);
863 template <
class F,
class FX,
class vec_FX>
866 if (a.rep.length() == 0) {
871 add(x.rep[0], x.rep[0], b);
876 template <
class F,
class FX,
class vec_FX>
878 template <
class F,
class FX,
class vec_FX>
880 template <
class F,
class FX,
class vec_FX>
887 template <
class F,
class FX,
class vec_FX>
892 long minab = min(da, db);
893 long maxab = max(da, db);
894 x.rep.SetLength(maxab+1);
900 for (i = minab+1, ap = a.rep.elts(), bp = b.rep.elts(), xp = x.rep.elts();
901 i; i--, ap++, bp++, xp++)
902 sub(*xp, (*ap), (*bp));
904 if (da > minab && &x != &a)
905 for (i = da-minab; i; i--, xp++, ap++)
908 for (i = db-minab; i; i--, xp++, bp++)
915 template <
class F,
class FX,
class vec_FX>
918 long n = a.rep.length();
924 sub(x.rep[0], a.rep[0], b);
927 else if (x.rep.MaxLength() == 0) {
929 sub(x.rep[0], a.rep[0], b);
935 FX *xp = x.rep.elts();
936 sub(xp[0], a.rep[0], b);
939 const FX *ap = a.rep.elts();
941 for (i = 1; i < n; i++)
947 template <
class F,
class FX,
class vec_FX>
955 if (a.rep.length() == 0) {
958 negate(x.rep[0], x.rep[0]);
962 sub(x.rep[0], x.rep[0], b);
967 template <
class F,
class FX,
class vec_FX>
975 if (a.rep.length() == 0) {
978 negate(x.rep[0], x.rep[0]);
982 sub(x.rep[0], x.rep[0], b);
987 template <
class F,
class FX,
class vec_FX>
997 template <
class F,
class FX,
class vec_FX>
1007 template <
class F,
class FX,
class vec_FX>
1021 template <
class F,
class FX,
class vec_FX>
1024 long n = a.rep.length();
1027 const FX* ap = a.rep.elts();
1028 FX* xp = x.rep.elts();
1031 for (i = n; i; i--, ap++, xp++)
1032 negate((*xp), (*ap));
1040 template <
class F,
class FX,
class vec_FX>
1044 template <
class F,
class FX,
class vec_FX>
1048 template <
class F,
class FX,
class vec_FX>
1052 template <
class F,
class FX,
class vec_FX>
1056 template <
class F,
class FX,
class vec_FX>
1060 template <
class F,
class FX,
class vec_FX>
1064 template <
class F,
class FX,
class vec_FX>
1069 template <
class F,
class FX,
class vec_FX>
1073 template <
class F,
class FX,
class vec_FX>
1077 template <
class F,
class FX,
class vec_FX>
1081 template <
class F,
class FX,
class vec_FX>
1086 template <
class F,
class FX,
class vec_FX>
1090 template <
class F,
class FX,
class vec_FX>
1094 template <
class F,
class FX,
class vec_FX>
1099 template <
class F,
class FX,
class vec_FX>
1101 { add(x, x, b);
return x; }
1103 template <
class F,
class FX,
class vec_FX>
1105 { add(x, x, b);
return x; }
1107 template <
class F,
class FX,
class vec_FX>
1109 { add(x, x, b);
return x; }
1111 template <
class F,
class FX,
class vec_FX>
1113 { add(x, x, b);
return x; }
1116 template <
class F,
class FX,
class vec_FX>
1118 { sub(x, x, b);
return x; }
1120 template <
class F,
class FX,
class vec_FX>
1122 { sub(x, x, b);
return x; }
1124 template <
class F,
class FX,
class vec_FX>
1126 { sub(x, x, b);
return x; }
1128 template <
class F,
class FX,
class vec_FX>
1130 { sub(x, x, b);
return x; }
1133 template <
class F,
class FX,
class vec_FX>
1137 template <
class F,
class FX,
class vec_FX>
1139 { add(x, x, 1);
return x; }
1141 template <
class F,
class FX,
class vec_FX>
1145 template <
class F,
class FX,
class vec_FX>
1147 { sub(x, x, 1);
return x; }
1149 template <
class F,
class FX,
class vec_FX>
1161 ZZ comb(
long n,
long k);
1163 template <
class F,
class FX,
class vec_FX>
1164 void mul(FX &x,
const FX &a,
const ZZ &b)
1174 template <
class F,
class FX,
class vec_FX>
1183 if( deg(Q) < 1 )
return Q;
1194 temp.rep.SetLength( degY + 1 );
1206 for(
long i = 0; i <= degY; i++){
1209 for(
long j = i; j <= degY; j++){
1214 mul(coef2, Q.rep[j], aa);
1216 mul<F,FX,vec_FX>(coef2, coef2, comb(j,i));
1218 add(coef1,coef1,coef2);
1225 coef1 = shiftX<F,FX,vec_FX>(coef1, i);
1227 temp.rep[i] = coef1;
1234 temp = backShiftX(temp, minX(temp));
1241 template <
class F,
class vec_F,
class FX,
class vec_FX,
class vec_pair_FX_
long>
1242 vec_F findroots_FX(
const FX &P)
1262 vec_pair_FX_long sqrfreeQ = SquareFreeDecomp(Q);
1267 for(
long i = 0; i < sqrfreeQ.length(); i++){
1268 factor = sqrfreeQ[i].a;
1271 factors = SFBerlekamp(factor);
1272 nfactors = factors.length();
1276 for(
long j = 0; j < nfactors; j++){
1278 if( deg(factors[j]) == 1 ){
1279 root = FindRoot( factors[j] );
1281 append(roots, root);
1295 template <
class F,
class FX,
class vec_FX>
1296 long minDegX(
const FX& P,
long max)
1302 if( IsZero(P) )
return max;
1305 while( IsZero(P.rep[min]) ){
1311 template <
class F,
class FX,
class vec_FX>
1318 if( IsZero(Q) )
return 0;
1321 long minX = minDegX<F,FX,vec_FX>(Q.rep[0],max);
1322 long degreeY = deg(Q);
1325 for(
long i = 1; i <= degreeY; i++){
1326 currentMinX = minDegX<F,FX,vec_FX>(Q.rep[i], max);
1327 if( currentMinX < minX)
1334 template <
class F,
class FX,
class vec_FX>
1343 Error(
"multiply: multiplier smaller than 1");
1346 if ( IsOne(Q) || a == 1) {
1364 res.SetMaxLength(dQ + 1);
1367 long k = NumBits(a);
1371 for (i = k - 1; i >= 0; i--) {
1380 template <
class F,
class FX,
class vec_FX>
1381 void multiply(FX& x,
const FX& Q,
long a)
1389 Error(
"multiply: multiplier smaller than 1");
1392 if ( IsOne(Q) || a == 1) {
1410 res.SetMaxLength(dQ + 1);
1413 long k = NumBits(a);
1416 for (i = k - 1; i >= 0; i--) {
1425 template <
class F,
class FX,
class vec_FX>
1426 void multiply(FX& x,
const FX& Q, ZZ a)
1433 if( a < to_ZZ(1) ) {
1434 Error(
"multiply: multiplier smaller than 1");
1437 if( IsOne(Q) || IsOne(a) ) {
1455 res.SetMaxLength(dQ + 1);
1458 long k = NumBits(a);
1461 for (i = k - 1; i >= 0; i--) {
1481 template <
class F,
class FX,
class vec_FX>
1489 if (da < 0 || db < 0){
1494 if (da == 0 && db == 0){
1496 mul( x.rep[0], a.rep[0], b.rep[0] );
1515 template <
class F,
class FX,
class vec_FX>
1523 if (da < 0 || db < 0){
1529 x.rep.SetLength(da+1);
1530 mul( x.rep[0], a.rep[0], b );
1535 mul(x, a, b.rep[0]);
1542 for(
long i = 0; i <= da; i++){
1543 mul(x.rep[i],a.rep[i],b);
1549 template <
class F,
class FX,
class vec_FX>
1571 x.rep.SetLength(da+1);
1575 for (i = 0; i <= da; i++)
1576 mul(xp[i], ap[i], t);
1581 template <
class F,
class FX,
class vec_FX>
1590 template <
class F,
class FX,
class vec_FX>
1596 template <
class F,
class FX,
class vec_FX>
1604 template <
class F,
class FX,
class vec_FX>
1612 template <
class F,
class FX,
class vec_FX>
1623 template <
class F,
class FX,
class vec_FX>
1628 Error(
"power: negative exponent");
1636 if (a == 0 || a == 1 || e == 1) {
1649 x = power(ConstTerm(a), e);
1653 if (da > (NTL_MAX_LONG-1)/e)
1654 Error(
"overflow in power");
1657 res.SetMaxLength(da*e + 1);
1660 long k = NumBits(e);
1663 for (i = k - 1; i >= 0; i--) {
1676 template <
class F,
class FX,
class vec_FX>
1680 template <
class F,
class FX,
class vec_FX>
1689 template <
class F,
class FX,
class vec_FX>
1693 template <
class F,
class FX,
class vec_FX>
1697 template <
class F,
class FX,
class vec_FX>
1704 template <
class F,
class FX,
class vec_FX>
1708 template <
class F,
class FX,
class vec_FX>
1712 template <
class F,
class FX,
class vec_FX>
1716 template <
class F,
class FX,
class vec_FX>
1721 template <
class F,
class FX,
class vec_FX>
1725 template <
class F,
class FX,
class vec_FX>
1729 template <
class F,
class FX,
class vec_FX>
1735 template <
class F,
class FX,
class vec_FX>
1737 { mul(x, x, b);
return x; }
1739 template <
class F,
class FX,
class vec_FX>
1741 { mul(x, x, b);
return x; }
1743 template <
class F,
class FX,
class vec_FX>
1745 { mul(x, x, b);
return x; }
1747 template <
class F,
class FX,
class vec_FX>
1749 { mul(x, x, b);
return x; }
1760 template <
class F,
class FX,
class vec_FX>
1768 if (da < 0 || db < 0){
1773 if (da == 0 && db == 0){
1775 mul( x.rep[0], a.rep[0], b.rep[0] );
1797 x.rep.SetLength(d+1);
1799 long i, j, jmin, jmax;
1802 for (i = 0; i <= d; i++) {
1803 jmin = max(0, i-db);
1806 for (j = jmin; j <= jmax; j++) {
1807 mul(t, la.rep[j], lb.rep[i-j]);
1809 add(accum, accum, t);
1811 SetCoeff( x, i, accum);