⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzz_pex.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <NTL/lzz_pEX.h>#include <NTL/vec_vec_lzz_p.h>#include <NTL/new.h>NTL_START_IMPLconst zz_pEX& zz_pEX::zero(){   static zz_pEX z;   return z;}istream& operator>>(istream& s, zz_pEX& x){   s >> x.rep;   x.normalize();   return s;}ostream& operator<<(ostream& s, const zz_pEX& a){   return s << a.rep;}void zz_pEX::normalize(){   long n;   const zz_pE* p;   n = rep.length();   if (n == 0) return;   p = rep.elts() + (n-1);   while (n > 0 && IsZero(*p)) {      p--;       n--;   }   rep.SetLength(n);}long IsZero(const zz_pEX& a){   return a.rep.length() == 0;}long IsOne(const zz_pEX& a){    return a.rep.length() == 1 && IsOne(a.rep[0]);}long operator==(const zz_pEX& a, long b){   if (b == 0)      return IsZero(a);   if (b == 1)      return IsOne(a);   long da = deg(a);   if (da > 0) return 0;   NTL_zz_pRegister(bb);   bb = b;   if (da < 0)      return IsZero(bb);   return a.rep[0] == bb;}long operator==(const zz_pEX& a, const zz_p& b){   if (IsZero(b))      return IsZero(a);   long da = deg(a);   if (da != 0)      return 0;   return a.rep[0] == b;}long operator==(const zz_pEX& a, const zz_pE& b){   if (IsZero(b))      return IsZero(a);   long da = deg(a);   if (da != 0)      return 0;   return a.rep[0] == b;}void SetCoeff(zz_pEX& x, long i, const zz_pE& a){   long j, m;   if (i < 0)       Error("SetCoeff: negative index");   if (i >= (1L << (NTL_BITS_PER_LONG-4)))      Error("overflow in SetCoeff");   m = deg(x);   if (i > m) {      long pos = x.rep.position(a);      x.rep.SetLength(i+1);      if (pos != -1)         x.rep[i] = x.rep.RawGet(pos);      else         x.rep[i] = a;      for (j = m+1; j < i; j++)         clear(x.rep[j]);   }   else      x.rep[i] = a;   x.normalize();}void SetCoeff(zz_pEX& x, long i, const zz_p& aa){   long j, m;   if (i < 0)      Error("SetCoeff: negative index");   if (i >= (1L << (NTL_BITS_PER_LONG-4)))      Error("overflow in SetCoeff");   NTL_zz_pRegister(a);  // watch out for aliases!   a = aa;   m = deg(x);   if (i > m) {      x.rep.SetLength(i+1);      for (j = m+1; j < i; j++)         clear(x.rep[j]);   }   x.rep[i] = a;   x.normalize();}void SetCoeff(zz_pEX& x, long i, long a){   if (a == 1)      SetCoeff(x, i);   else {      NTL_zz_pRegister(T);      T = a;      SetCoeff(x, i, T);   }}void SetCoeff(zz_pEX& x, long i){   long j, m;   if (i < 0)       Error("coefficient index out of range");   if (i >= (1L << (NTL_BITS_PER_LONG-4)))      Error("overflow in SetCoeff");   m = deg(x);   if (i > m) {      x.rep.SetLength(i+1);      for (j = m+1; j < i; j++)         clear(x.rep[j]);   }   set(x.rep[i]);   x.normalize();}void SetX(zz_pEX& x){   clear(x);   SetCoeff(x, 1);}long IsX(const zz_pEX& a){   return deg(a) == 1 && IsOne(LeadCoeff(a)) && IsZero(ConstTerm(a));}            const zz_pE& coeff(const zz_pEX& a, long i){   if (i < 0 || i > deg(a))      return zz_pE::zero();   else      return a.rep[i];}const zz_pE& LeadCoeff(const zz_pEX& a){   if (IsZero(a))      return zz_pE::zero();   else      return a.rep[deg(a)];}const zz_pE& ConstTerm(const zz_pEX& a){   if (IsZero(a))      return zz_pE::zero();   else      return a.rep[0];}void conv(zz_pEX& x, const zz_pE& a){   if (IsZero(a))      x.rep.SetLength(0);   else {      x.rep.SetLength(1);      x.rep[0] = a;   }}void conv(zz_pEX& x, long a){   if (a == 0)       clear(x);   else if (a == 1)      set(x);   else {      NTL_zz_pRegister(T);      T = a;      conv(x, T);   }}void conv(zz_pEX& x, const ZZ& a){   NTL_zz_pRegister(T);   conv(T, a);   conv(x, T);}void conv(zz_pEX& x, const zz_p& a){   if (IsZero(a))       clear(x);   else if (IsOne(a))      set(x);   else {      x.rep.SetLength(1);      conv(x.rep[0], a);      x.normalize();   }}void conv(zz_pEX& x, const zz_pX& aa){   zz_pX a = aa; // in case a aliases the rep of a coefficient of x   long n = deg(a)+1;   long i;   x.rep.SetLength(n);   for (i = 0; i < n; i++)      conv(x.rep[i], coeff(a, i));}void conv(zz_pEX& x, const vec_zz_pE& a){   x.rep = a;   x.normalize();}void add(zz_pEX& x, const zz_pEX& a, const zz_pEX& b){   long da = deg(a);   long db = deg(b);   long minab = min(da, db);   long maxab = max(da, db);   x.rep.SetLength(maxab+1);   long i;   const zz_pE *ap, *bp;    zz_pE* xp;   for (i = minab+1, ap = a.rep.elts(), bp = b.rep.elts(), xp = x.rep.elts();        i; i--, ap++, bp++, xp++)      add(*xp, (*ap), (*bp));   if (da > minab && &x != &a)      for (i = da-minab; i; i--, xp++, ap++)         *xp = *ap;   else if (db > minab && &x != &b)      for (i = db-minab; i; i--, xp++, bp++)         *xp = *bp;   else      x.normalize();}void add(zz_pEX& x, const zz_pEX& a, const zz_pE& b){   long n = a.rep.length();   if (n == 0) {      conv(x, b);   }   else if (&x == &a) {      add(x.rep[0], a.rep[0], b);      x.normalize();   }   else if (x.rep.MaxLength() == 0) {      x = a;      add(x.rep[0], a.rep[0], b);      x.normalize();   }   else {      // ugly...b could alias a coeff of x      zz_pE *xp = x.rep.elts();      add(xp[0], a.rep[0], b);      x.rep.SetLength(n);      xp = x.rep.elts();      const zz_pE *ap = a.rep.elts();      long i;      for (i = 1; i < n; i++)         xp[i] = ap[i];      x.normalize();   }}void add(zz_pEX& x, const zz_pEX& a, const zz_p& b){   long n = a.rep.length();   if (n == 0) {      conv(x, b);   }   else if (&x == &a) {      add(x.rep[0], a.rep[0], b);      x.normalize();   }   else if (x.rep.MaxLength() == 0) {      x = a;      add(x.rep[0], a.rep[0], b);      x.normalize();   }   else {      // ugly...b could alias a coeff of x      zz_pE *xp = x.rep.elts();      add(xp[0], a.rep[0], b);      x.rep.SetLength(n);      xp = x.rep.elts();      const zz_pE *ap = a.rep.elts();      long i;      for (i = 1; i < n; i++)         xp[i] = ap[i];      x.normalize();   }}void add(zz_pEX& x, const zz_pEX& a, long b){   if (a.rep.length() == 0) {      conv(x, b);   }   else {      if (&x != &a) x = a;      add(x.rep[0], x.rep[0], b);      x.normalize();   }}void sub(zz_pEX& x, const zz_pEX& a, const zz_pEX& b){   long da = deg(a);   long db = deg(b);   long minab = min(da, db);   long maxab = max(da, db);   x.rep.SetLength(maxab+1);   long i;   const zz_pE *ap, *bp;    zz_pE* xp;   for (i = minab+1, ap = a.rep.elts(), bp = b.rep.elts(), xp = x.rep.elts();        i; i--, ap++, bp++, xp++)      sub(*xp, (*ap), (*bp));   if (da > minab && &x != &a)      for (i = da-minab; i; i--, xp++, ap++)         *xp = *ap;   else if (db > minab)      for (i = db-minab; i; i--, xp++, bp++)         negate(*xp, *bp);   else      x.normalize();}void sub(zz_pEX& x, const zz_pEX& a, const zz_pE& b){   long n = a.rep.length();   if (n == 0) {      conv(x, b);      negate(x, x);   }   else if (&x == &a) {      sub(x.rep[0], a.rep[0], b);      x.normalize();   }   else if (x.rep.MaxLength() == 0) {      x = a;      sub(x.rep[0], a.rep[0], b);      x.normalize();   }   else {      // ugly...b could alias a coeff of x      zz_pE *xp = x.rep.elts();      sub(xp[0], a.rep[0], b);      x.rep.SetLength(n);      xp = x.rep.elts();      const zz_pE *ap = a.rep.elts();      long i;      for (i = 1; i < n; i++)         xp[i] = ap[i];      x.normalize();   }}void sub(zz_pEX& x, const zz_pEX& a, const zz_p& b){   long n = a.rep.length();   if (n == 0) {      conv(x, b);      negate(x, x);   }   else if (&x == &a) {      sub(x.rep[0], a.rep[0], b);      x.normalize();   }   else if (x.rep.MaxLength() == 0) {      x = a;      sub(x.rep[0], a.rep[0], b);      x.normalize();   }   else {      // ugly...b could alias a coeff of x      zz_pE *xp = x.rep.elts();      sub(xp[0], a.rep[0], b);      x.rep.SetLength(n);      xp = x.rep.elts();      const zz_pE *ap = a.rep.elts();      long i;      for (i = 1; i < n; i++)         xp[i] = ap[i];      x.normalize();   }}void sub(zz_pEX& x, const zz_pEX& a, long b){   if (a.rep.length() == 0) {      conv(x, b);      negate(x, x);   }   else {      if (&x != &a) x = a;      sub(x.rep[0], x.rep[0], b);      x.normalize();   }}void sub(zz_pEX& x, const zz_pE& b, const zz_pEX& a){   long n = a.rep.length();   if (n == 0) {      conv(x, b);   }   else if (x.rep.MaxLength() == 0) {      negate(x, a);      add(x.rep[0], a.rep[0], b);      x.normalize();   }   else {      // ugly...b could alias a coeff of x      zz_pE *xp = x.rep.elts();      sub(xp[0], b, a.rep[0]);      x.rep.SetLength(n);      xp = x.rep.elts();      const zz_pE *ap = a.rep.elts();      long i;      for (i = 1; i < n; i++)         negate(xp[i], ap[i]);      x.normalize();   }}void sub(zz_pEX& x, const zz_p& a, const zz_pEX& b){   NTL_zz_pRegister(T);   // avoids aliasing problems   T = a;   negate(x, b);   add(x, x, T);}void sub(zz_pEX& x, long a, const zz_pEX& b){   NTL_zz_pRegister(T);    T = a;   negate(x, b);   add(x, x, T);}void mul(zz_pEX& c, const zz_pEX& a, const zz_pEX& b){   if (&a == &b) {      sqr(c, a);      return;   }   if (IsZero(a) || IsZero(b)) {      clear(c);      return;   }   if (deg(a) == 0) {      mul(c, b, ConstTerm(a));      return;   }    if (deg(b) == 0) {      mul(c, a, ConstTerm(b));      return;   }   // general case...Kronecker subst   zz_pX A, B, C;   long da = deg(a);   long db = deg(b);   long n = zz_pE::degree();   long n2 = 2*n-1;   if (da+db+1 >= (1L << (NTL_BITS_PER_LONG-4))/n2)      Error("overflow in zz_pEX mul");   long i, j;   A.rep.SetLength((da+1)*n2);   for (i = 0; i <= da; i++) {      const zz_pX& coeff = rep(a.rep[i]);      long dcoeff = deg(coeff);      for (j = 0; j <= dcoeff; j++)         A.rep[n2*i + j] = coeff.rep[j];    }   A.normalize();   B.rep.SetLength((db+1)*n2);   for (i = 0; i <= db; i++) {      const zz_pX& coeff = rep(b.rep[i]);      long dcoeff = deg(coeff);      for (j = 0; j <= dcoeff; j++)         B.rep[n2*i + j] = coeff.rep[j];    }   B.normalize();   mul(C, A, B);   long Clen = C.rep.length();   long lc = (Clen + n2 - 1)/n2;   long dc = lc - 1;   c.rep.SetLength(dc+1);   zz_pX tmp;      for (i = 0; i <= dc; i++) {      tmp.rep.SetLength(n2);      for (j = 0; j < n2 && n2*i + j < Clen; j++)         tmp.rep[j] = C.rep[n2*i + j];      for (; j < n2; j++)         clear(tmp.rep[j]);      tmp.normalize();      conv(c.rep[i], tmp);   }     c.normalize();}void mul(zz_pEX& x, const zz_pEX& a, const zz_pE& b){   if (IsZero(b)) {      clear(x);      return;   }   zz_pE t;   t = b;   long i, da;   const zz_pE *ap;   zz_pE* xp;   da = deg(a);   x.rep.SetLength(da+1);   ap = a.rep.elts();   xp = x.rep.elts();   for (i = 0; i <= da; i++)      mul(xp[i], ap[i], t);   x.normalize();}void mul(zz_pEX& x, const zz_pEX& a, const zz_p& b){   if (IsZero(b)) {      clear(x);      return;   }   NTL_zz_pRegister(t);   t = b;   long i, da;   const zz_pE *ap;   zz_pE* xp;   da = deg(a);   x.rep.SetLength(da+1);   ap = a.rep.elts();   xp = x.rep.elts();   for (i = 0; i <= da; i++)      mul(xp[i], ap[i], t);   x.normalize();}void mul(zz_pEX& x, const zz_pEX& a, long b){   NTL_zz_pRegister(t);   t = b;   mul(x, a, t);}void sqr(zz_pEX& c, const zz_pEX& a){   if (IsZero(a)) {      clear(c);      return;   }   if (deg(a) == 0) {      zz_pE res;      sqr(res, ConstTerm(a));      conv(c, res);      return;   }    // general case...Kronecker subst   zz_pX A, C;   long da = deg(a);   long n = zz_pE::degree();   long n2 = 2*n-1;   if (2*da+1 >= (1L << (NTL_BITS_PER_LONG-4))/n2)      Error("overflow in zz_pEX sqr");   long i, j;   A.rep.SetLength((da+1)*n2);   for (i = 0; i <= da; i++) {      const zz_pX& coeff = rep(a.rep[i]);      long dcoeff = deg(coeff);      for (j = 0; j <= dcoeff; j++)         A.rep[n2*i + j] = coeff.rep[j];    }   A.normalize();   sqr(C, A);   long Clen = C.rep.length();   long lc = (Clen + n2 - 1)/n2;   long dc = lc - 1;   c.rep.SetLength(dc+1);   zz_pX tmp;      for (i = 0; i <= dc; i++) {      tmp.rep.SetLength(n2);      for (j = 0; j < n2 && n2*i + j < Clen; j++)         tmp.rep[j] = C.rep[n2*i + j];      for (; j < n2; j++)         clear(tmp.rep[j]);      tmp.normalize();      conv(c.rep[i], tmp);   }       c.normalize();}void MulTrunc(zz_pEX& x, const zz_pEX& a, const zz_pEX& b, long n){   if (n < 0) Error("MulTrunc: bad args");   zz_pEX t;   mul(t, a, b);   trunc(x, t, n);}void SqrTrunc(zz_pEX& x, const zz_pEX& a, long n){   if (n < 0) Error("SqrTrunc: bad args");   zz_pEX t;   sqr(t, a);   trunc(x, t, n);}void CopyReverse(zz_pEX& x, const zz_pEX& a, long hi)   // x[0..hi] = reverse(a[0..hi]), with zero fill   // input may not alias output{   long i, j, n, m;   n = hi+1;   m = a.rep.length();   x.rep.SetLength(n);   const zz_pE* ap = a.rep.elts();   zz_pE* xp = x.rep.elts();   for (i = 0; i < n; i++) {      j = hi-i;      if (j < 0 || j >= m)         clear(xp[i]);      else         xp[i] = ap[j];   }   x.normalize();} void trunc(zz_pEX& x, const zz_pEX& a, long m)// x = a % X^m, output may alias input {   if (m < 0) Error("trunc: bad args");   if (&x == &a) {      if (x.rep.length() > m) {         x.rep.SetLength(m);         x.normalize();      }   }   else {      long n;      long i;      zz_pE* xp;      const zz_pE* ap;      n = min(a.rep.length(), m);      x.rep.SetLength(n);      xp = x.rep.elts();      ap = a.rep.elts();      for (i = 0; i < n; i++) xp[i] = ap[i];      x.normalize();   }}void random(zz_pEX& x, long n){   long i;   x.rep.SetLength(n);   for (i = 0; i < n; i++)      random(x.rep[i]);   x.normalize();}void negate(zz_pEX& x, const zz_pEX& a)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -