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

📄 lzz_pexfactoring.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <NTL/lzz_pEXFactoring.h>#include <NTL/FacVec.h>#include <NTL/fileio.h>#include <stdio.h>#include <NTL/new.h>NTL_START_IMPLstaticvoid IterPower(zz_pE& c, const zz_pE& a, long n){   zz_pE res;   long i;   res = a;   for (i = 0; i < n; i++)      power(res, res, zz_p::modulus());   c = res;}   void SquareFreeDecomp(vec_pair_zz_pEX_long& u, const zz_pEX& ff){   zz_pEX f = ff;   if (!IsOne(LeadCoeff(f)))      Error("SquareFreeDecomp: bad args");   zz_pEX r, t, v, tmp1;   long m, j, finished, done;   u.SetLength(0);   if (deg(f) == 0)      return;   m = 1;   finished = 0;   do {      j = 1;      diff(tmp1, f);      GCD(r, f, tmp1);      div(t, f, r);      if (deg(t) > 0) {         done = 0;         do {            GCD(v, r, t);            div(tmp1, t, v);            if (deg(tmp1) > 0) append(u, cons(tmp1, j*m));            if (deg(v) > 0) {               div(r, r, v);               t = v;               j++;            }            else               done = 1;         } while (!done);         if (deg(r) == 0) finished = 1;      }      if (!finished) {         /* r is a p-th power */         long k, d;         long p = to_long(zz_p::modulus());          d = deg(r)/p;         f.rep.SetLength(d+1);         for (k = 0; k <= d; k++)             IterPower(f.rep[k], r.rep[k*p], zz_pE::degree()-1);         m = m*p;      }   } while (!finished);}         staticvoid AbsTraceMap(zz_pEX& h, const zz_pEX& a, const zz_pEXModulus& F){   zz_pEX res, tmp;   long k = NumBits(zz_pE::cardinality())-1;   res = a;   tmp = a;   long i;   for (i = 0; i < k-1; i++) {      SqrMod(tmp, tmp, F);      add(res, res, tmp);   }   h = res;}void FrobeniusMap(zz_pEX& h, const zz_pEXModulus& F){   PowerXMod(h, zz_pE::cardinality(), F);}staticvoid RecFindRoots(vec_zz_pE& x, const zz_pEX& f){   if (deg(f) == 0) return;   if (deg(f) == 1) {      long k = x.length();      x.SetLength(k+1);      negate(x[k], ConstTerm(f));      return;   }         zz_pEX h;   zz_pEX r;      {      zz_pEXModulus F;      build(F, f);      do {         random(r, deg(F));         if (IsOdd(zz_pE::cardinality())) {            PowerMod(h, r, RightShift(zz_pE::cardinality(), 1), F);            sub(h, h, 1);         }         else {            AbsTraceMap(h, r, F);         }         GCD(h, h, f);      } while (deg(h) <= 0 || deg(h) == deg(f));   }   RecFindRoots(x, h);   div(h, f, h);    RecFindRoots(x, h);}void FindRoots(vec_zz_pE& x, const zz_pEX& ff){   zz_pEX f = ff;   if (!IsOne(LeadCoeff(f)))      Error("FindRoots: bad args");   x.SetMaxLength(deg(f));   x.SetLength(0);   RecFindRoots(x, f);}void split(zz_pEX& f1, zz_pEX& g1, zz_pEX& f2, zz_pEX& g2,           const zz_pEX& f, const zz_pEX& g,            const vec_zz_pE& roots, long lo, long mid){   long r = mid-lo+1;   zz_pEXModulus F;   build(F, f);   vec_zz_pE lroots(INIT_SIZE, r);   long i;   for (i = 0; i < r; i++)      lroots[i] = roots[lo+i];   zz_pEX h, a, d;   BuildFromRoots(h, lroots);   CompMod(a, h, g, F);   GCD(f1, a, f);      div(f2, f, f1);   rem(g1, g, f1);   rem(g2, g, f2);}void RecFindFactors(vec_zz_pEX& factors, const zz_pEX& f, const zz_pEX& g,                    const vec_zz_pE& roots, long lo, long hi){   long r = hi-lo+1;   if (r == 0) return;   if (r == 1) {      append(factors, f);      return;   }   zz_pEX f1, g1, f2, g2;   long mid = (lo+hi)/2;   split(f1, g1, f2, g2, f, g, roots, lo, mid);   RecFindFactors(factors, f1, g1, roots, lo, mid);   RecFindFactors(factors, f2, g2, roots, mid+1, hi);}void FindFactors(vec_zz_pEX& factors, const zz_pEX& f, const zz_pEX& g,                 const vec_zz_pE& roots){   long r = roots.length();   factors.SetMaxLength(r);   factors.SetLength(0);   RecFindFactors(factors, f, g, roots, 0, r-1);}void IterFindFactors(vec_zz_pEX& factors, const zz_pEX& f,                     const zz_pEX& g, const vec_zz_pE& roots){   long r = roots.length();   long i;   zz_pEX h;   factors.SetLength(r);   for (i = 0; i < r; i++) {      sub(h, g, roots[i]);      GCD(factors[i], f, h);   }}void TraceMap(zz_pEX& w, const zz_pEX& a, long d, const zz_pEXModulus& F,               const zz_pEX& b){   if (d < 0) Error("TraceMap: bad args");   zz_pEX y, z, t;   z = b;   y = a;   clear(w);   while (d) {      if (d == 1) {         if (IsZero(w))             w = y;         else {            CompMod(w, w, z, F);            add(w, w, y);         }      }      else if ((d & 1) == 0) {         Comp2Mod(z, t, z, y, z, F);         add(y, t, y);      }      else if (IsZero(w)) {         w = y;         Comp2Mod(z, t, z, y, z, F);         add(y, t, y);      }      else {         Comp3Mod(z, t, w, z, y, w, z, F);         add(w, w, y);         add(y, t, y);      }      d = d >> 1;   }}void PowerCompose(zz_pEX& y, const zz_pEX& h, long q, const zz_pEXModulus& F){   if (q < 0) Error("PowerCompose: bad args");   zz_pEX z(INIT_SIZE, F.n);   long sw;   z = h;   SetX(y);   while (q) {      sw = 0;      if (q > 1) sw = 2;      if (q & 1) {         if (IsX(y))            y = z;         else            sw = sw | 1;      }      switch (sw) {      case 0:         break;      case 1:         CompMod(y, y, z, F);         break;      case 2:         CompMod(z, z, z, F);         break;      case 3:         Comp2Mod(y, z, y, z, z, F);         break;      }      q = q >> 1;   }}long ProbIrredTest(const zz_pEX& f, long iter){   long n = deg(f);   if (n <= 0) return 0;   if (n == 1) return 1;   zz_pEXModulus F;   build(F, f);   zz_pEX b, r, s;   FrobeniusMap(b, F);   long all_zero = 1;   long i;   for (i = 0; i < iter; i++) {      random(r, n);      TraceMap(s, r, n, F, b);      all_zero = all_zero && IsZero(s);      if (deg(s) > 0) return 0;   }   if (!all_zero || (n & 1)) return 1;   PowerCompose(s, b, n/2, F);   return !IsX(s);}long zz_pEX_BlockingFactor = 10;void RootEDF(vec_zz_pEX& factors, const zz_pEX& f, long verbose){   vec_zz_pE roots;   double t;   if (verbose) { cerr << "finding roots..."; t = GetTime(); }   FindRoots(roots, f);   if (verbose) { cerr << (GetTime()-t) << "\n"; }   long r = roots.length();   factors.SetLength(r);   for (long j = 0; j < r; j++) {      SetX(factors[j]);      sub(factors[j], factors[j], roots[j]);   }}void EDFSplit(vec_zz_pEX& v, const zz_pEX& f, const zz_pEX& b, long d){   zz_pEX a, g, h;   zz_pEXModulus F;   vec_zz_pE roots;      build(F, f);   long n = F.n;   long r = n/d;   random(a, n);   TraceMap(g, a, d, F, b);   MinPolyMod(h, g, F, r);   FindRoots(roots, h);   FindFactors(v, f, g, roots);}void RecEDF(vec_zz_pEX& factors, const zz_pEX& f, const zz_pEX& b, long d,            long verbose){   vec_zz_pEX v;   long i;   zz_pEX bb;   if (verbose) cerr << "+";   EDFSplit(v, f, b, d);   for (i = 0; i < v.length(); i++) {      if (deg(v[i]) == d) {         append(factors, v[i]);      }      else {         zz_pEX bb;         rem(bb, b, v[i]);         RecEDF(factors, v[i], bb, d, verbose);      }   }}         void EDF(vec_zz_pEX& factors, const zz_pEX& ff, const zz_pEX& bb,         long d, long verbose){   zz_pEX f = ff;   zz_pEX b = bb;   if (!IsOne(LeadCoeff(f)))      Error("EDF: bad args");   long n = deg(f);   long r = n/d;   if (r == 0) {      factors.SetLength(0);      return;   }   if (r == 1) {      factors.SetLength(1);      factors[0] = f;      return;   }   if (d == 1) {      RootEDF(factors, f, verbose);      return;   }      double t;   if (verbose) {       cerr << "computing EDF(" << d << "," << r << ")...";       t = GetTime();    }   factors.SetLength(0);   RecEDF(factors, f, b, d, verbose);   if (verbose) cerr << (GetTime()-t) << "\n";}void SFCanZass(vec_zz_pEX& factors, const zz_pEX& ff, long verbose){   zz_pEX f = ff;   if (!IsOne(LeadCoeff(f)))      Error("SFCanZass: bad args");   if (deg(f) == 0) {      factors.SetLength(0);      return;   }   if (deg(f) == 1) {      factors.SetLength(1);      factors[0] = f;      return;   }   factors.SetLength(0);   double t;      zz_pEXModulus F;   build(F, f);   zz_pEX h;   if (verbose) { cerr << "computing X^p..."; t = GetTime(); }   FrobeniusMap(h, F);   if (verbose) { cerr << (GetTime()-t) << "\n"; }   vec_pair_zz_pEX_long u;   if (verbose) { cerr << "computing DDF..."; t = GetTime(); }   NewDDF(u, f, h, verbose);   if (verbose) {       t = GetTime()-t;       cerr << "DDF time: " << t << "\n";   }   zz_pEX hh;   vec_zz_pEX v;   long i;   for (i = 0; i < u.length(); i++) {      const zz_pEX& g = u[i].a;      long d = u[i].b;      long r = deg(g)/d;      if (r == 1) {         // g is already irreducible         append(factors, g);      }      else {         // must perform EDF         if (d == 1) {            // root finding            RootEDF(v, g, verbose);            append(factors, v);         }         else {            // general case            rem(hh, h, g);            EDF(v, g, hh, d, verbose);            append(factors, v);         }      }   }}   void CanZass(vec_pair_zz_pEX_long& factors, const zz_pEX& f, long verbose){   if (!IsOne(LeadCoeff(f)))      Error("CanZass: bad args");   double t;   vec_pair_zz_pEX_long sfd;   vec_zz_pEX x;      if (verbose) { cerr << "square-free decomposition..."; t = GetTime(); }   SquareFreeDecomp(sfd, f);   if (verbose) cerr << (GetTime()-t) << "\n";   factors.SetLength(0);   long i, j;   for (i = 0; i < sfd.length(); i++) {      if (verbose) {         cerr << "factoring multiplicity " << sfd[i].b               << ", deg = " << deg(sfd[i].a) << "\n";      }      SFCanZass(x, sfd[i].a, verbose);      for (j = 0; j < x.length(); j++)         append(factors, cons(x[j], sfd[i].b));   }}void mul(zz_pEX& f, const vec_pair_zz_pEX_long& v){   long i, j, n;   n = 0;   for (i = 0; i < v.length(); i++)      n += v[i].b*deg(v[i].a);   zz_pEX g(INIT_SIZE, n+1);   set(g);   for (i = 0; i < v.length(); i++)      for (j = 0; j < v[i].b; j++) {         mul(g, g, v[i].a);      }   f = g;}long BaseCase(const zz_pEX& h, long q, long a, const zz_pEXModulus& F){   long b, e;   zz_pEX lh(INIT_SIZE, F.n);   lh = h;   b = 1;   e = 0;   while (e < a-1 && !IsX(lh)) {      e++;      b *= q;      PowerCompose(lh, lh, q, F);   }   if (!IsX(lh)) b *= q;   return b;}void TandemPowerCompose(zz_pEX& y1, zz_pEX& y2, const zz_pEX& h,                         long q1, long q2, const zz_pEXModulus& F){   zz_pEX z(INIT_SIZE, F.n);   long sw;   z = h;   SetX(y1);   SetX(y2);   while (q1 || q2) {      sw = 0;      if (q1 > 1 || q2 > 1) sw = 4;      if (q1 & 1) {         if (IsX(y1))            y1 = z;         else            sw = sw | 2;      }      if (q2 & 1) {         if (IsX(y2))            y2 = z;         else            sw = sw | 1;      }      switch (sw) {      case 0:         break;      case 1:         CompMod(y2, y2, z, F);         break;      case 2:         CompMod(y1, y1, z, F);         break;      case 3:         Comp2Mod(y1, y2, y1, y2, z, F);         break;      case 4:         CompMod(z, z, z, F);         break;      case 5:         Comp2Mod(z, y2, z, y2, z, F);         break;      case 6:         Comp2Mod(z, y1, z, y1, z, F);         break;      case 7:         Comp3Mod(z, y1, y2, z, y1, y2, z, F);         break;      }      q1 = q1 >> 1;      q2 = q2 >> 1;   }}long RecComputeDegree(long u, const zz_pEX& h, const zz_pEXModulus& F,                      FacVec& fvec){   if (IsX(h)) return 1;   if (fvec[u].link == -1) return BaseCase(h, fvec[u].q, fvec[u].a, F);   zz_pEX h1, h2;   long q1, q2, r1, r2;   q1 = fvec[fvec[u].link].val;    q2 = fvec[fvec[u].link+1].val;   TandemPowerCompose(h1, h2, h, q1, q2, F);   r1 = RecComputeDegree(fvec[u].link, h2, F, fvec);   r2 = RecComputeDegree(fvec[u].link+1, h1, F, fvec);   return r1*r2;}   long RecComputeDegree(const zz_pEX& h, const zz_pEXModulus& F)   // f = F.f is assumed to be an "equal degree" polynomial   // h = X^p mod f   // the common degree of the irreducible factors of f is computed{   if (F.n == 1 || IsX(h))       return 1;   FacVec fvec;   FactorInt(fvec, F.n);   return RecComputeDegree(fvec.length()-1, h, F, fvec);}void FindRoot(zz_pE& root, const zz_pEX& ff)// finds a root of ff.// assumes that ff is monic and splits into distinct linear factors{   zz_pEXModulus F;   zz_pEX h, h1, f;   zz_pEX r;   f = ff;      if (!IsOne(LeadCoeff(f)))      Error("FindRoot: bad args");   if (deg(f) == 0)      Error("FindRoot: bad args");   while (deg(f) > 1) {      build(F, f);      random(r, deg(F));      if (IsOdd(zz_pE::cardinality())) {         PowerMod(h, r, RightShift(zz_pE::cardinality(), 1), F);         sub(h, h, 1);      }      else {         AbsTraceMap(h, r, F);      }      GCD(h, h, f);      if (deg(h) > 0 && deg(h) < deg(f)) {         if (deg(h) > deg(f)/2)            div(f, f, h);         else            f = h;      }   }    negate(root, ConstTerm(f));}staticlong power(long a, long e){   long i, res;   res = 1;   for (i = 1; i <= e; i++)      res = res * a;   return res;}staticlong IrredBaseCase(const zz_pEX& h, long q, long a, const zz_pEXModulus& F){   long e;   zz_pEX X, s, d;   e = power(q, a-1);   PowerCompose(s, h, e, F);   SetX(X);   sub(s, s, X);   GCD(d, F.f, s);   return IsOne(d);}staticlong RecIrredTest(long u, const zz_pEX& h, const zz_pEXModulus& F,                 const FacVec& fvec){   long  q1, q2;   zz_pEX h1, h2;   if (IsX(h)) return 0;   if (fvec[u].link == -1) {      return IrredBaseCase(h, fvec[u].q, fvec[u].a, F);   }   q1 = fvec[fvec[u].link].val;    q2 = fvec[fvec[u].link+1].val;   TandemPowerCompose(h1, h2, h, q1, q2, F);   return RecIrredTest(fvec[u].link, h2, F, fvec)           && RecIrredTest(fvec[u].link+1, h1, F, fvec);}long DetIrredTest(const zz_pEX& f){   if (deg(f) <= 0) return 0;

⌨️ 快捷键说明

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