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

📄 zzxfactoring.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 4 页
字号:
   if (!irred) {      // delete best prime from LocalInfo      swap(LocalInfo.pattern[bestp_index], LocalInfo.pattern[NumPrimes-1]);      LocalInfo.p[bestp_index] = LocalInfo.p[NumPrimes-1];      NumPrimes--;      bestp.restore();      spfactors = NTL_NEW_OP vec_zz_pX;      if (verbose) {         cerr << "p = " << zz_p::modulus() << ", completing factorization...";         t = GetTime();      }      SFCanZass2(*spfactors, *bestfac, *besth, 0);      if (verbose) {         cerr << (GetTime()-t) << "\n";      }   }   delete bestfac;   delete besth;   return spfactors;}staticlong ConstTermTest(const vec_ZZ_pX& W,                   const vec_long& I,                  const ZZ& ct,                  const ZZ_p& lc,                  vec_ZZ_p& prod,                  long& ProdLen) {   long k = I.length();   ZZ_p t;   ZZ t1, t2;   long i;   if (ProdLen == 0) {      mul(prod[0], lc, ConstTerm(W[I[0]]));      ProdLen++;   }   for (i = ProdLen; i < k; i++)      mul(prod[i], prod[i-1], ConstTerm(W[I[i]]));   ProdLen = k-1;   // should make this a routine in ZZ_p   t1 = rep(prod[k-1]);   RightShift(t2, ZZ_p::modulus(), 1);   if (t1 > t2)      sub(t1, t1, ZZ_p::modulus());   return divide(ct, t1);}staticvoid BalCopy(ZZX& g, const ZZ_pX& G){   const ZZ& p = ZZ_p::modulus();   ZZ p2, t;   RightShift(p2, p, 1);   long n = G.rep.length();   long i;   g.rep.SetLength(n);   for (i = 0; i < n; i++) {      t = rep(G.rep[i]);      if (t > p2) sub(t, t, p);      g.rep[i] = t;   }}staticvoid mul(ZZ_pX& g, const vec_ZZ_pX& W, const vec_long& I){   vec_ZZ_pX w;   long k = I.length();   w.SetLength(k);   long i;   for (i = 0; i < k; i++)      w[i] = W[I[i]];   mul(g, w);}staticvoid InvMul(ZZ_pX& g, const vec_ZZ_pX& W, const vec_long& I){   vec_ZZ_pX w;   long k = I.length();   long r = W.length();   w.SetLength(r-k);   long i, j;   i = 0;   for (j = 0; j < r; j++) {      if (i < k && j == I[i])         i++;      else         w[j-i] = W[j];   }    mul(g, w);}staticvoid RemoveFactors(vec_ZZ_pX& W, const vec_long& I){   long k = I.length();   long r = W.length();   long i, j;   i = 0;   for (j = 0; j < r; j++) {      if (i < k && j == I[i])         i++;      else         swap(W[j-i], W[j]);    }   W.SetLength(r-k);}staticvoid unpack(vec_long& x, const ZZ& a, long n){   x.SetLength(n+1);   long i;   for (i = 0; i <= n; i++)      x[i] = bit(a, i);}staticvoid SubPattern(vec_long& p1, const vec_long& p2){   long l = p1.length();   if (p2.length() != l)      Error("SubPattern: bad args");   long i;   for (i = 0; i < l; i++) {      p1[i] -= p2[i];      if (p1[i] < 0)         Error("SubPattern: internal error");   }}staticvoid UpdateLocalInfo(LocalInfoT& LocalInfo, vec_ZZ& pdeg,                     const vec_ZZ_pX& W, const vec_ZZX& factors,                     const ZZX& f, long k, long verbose){   static long cnt = 0;   if (verbose) {      cnt = (cnt + 1) % 100;      if (!cnt) cerr << "#";   }   double t;   long i, j;   if (LocalInfo.NumFactors < factors.length()) {      zz_pBak bak;      bak.save();      vec_long pattern;      pattern.SetLength(LocalInfo.n+1);      ZZ pd;      if (verbose) {         cerr << "updating local info...";         t = GetTime();      }      for (i = 0; i < LocalInfo.NumPrimes; i++) {         zz_p::init(LocalInfo.p[i], NextPowerOfTwo(LocalInfo.n)+1);         for (j = LocalInfo.NumFactors; j < factors.length(); j++) {            vec_pair_zz_pX_long thisfac;            zz_pX thish;             zz_pX ff;            conv(ff, factors[j]);            MakeMonic(ff);            SFCanZass1(thisfac, thish, ff, 0);            RecordPattern(pattern, thisfac);            SubPattern(LocalInfo.pattern[i], pattern);         }         CalcPossibleDegrees(pd, LocalInfo.pattern[i]);         bit_and(LocalInfo.PossibleDegrees, LocalInfo.PossibleDegrees, pd);      }      bak.restore();      LocalInfo.NumFactors = factors.length();      CalcPossibleDegrees(pdeg, W, k);      if (verbose) cerr << (GetTime()-t) << "\n";   }   if (LocalInfo.NumPrimes < ZZXFac_MaxNumPrimes) {      if (verbose)         cerr << "adding a prime\n";      zz_pBak bak;      bak.save();      for (;;) {         long p = LocalInfo.s.next();         if (!p)            Error("UpdateLocalInfo: out of primes");         if (divide(LeadCoeff(f), p)) {            if (verbose) cerr << "skipping " << p << "\n";            continue;         }         zz_p::init(p, NextPowerOfTwo(deg(f))+1);         zz_pX ff, ffp, d;            conv(ff, f);         MakeMonic(ff);         diff(ffp, ff);            GCD(d, ffp, ff);         if (!IsOne(d)) {            if (verbose)  cerr << "skipping " << p << "\n";            continue;         }         vec_pair_zz_pX_long thisfac;         zz_pX thish;         if (verbose) {            cerr << "factoring mod " << p << "...";            t = GetTime();         }         SFCanZass1(thisfac, thish, ff, 0);         LocalInfo.p.SetLength(LocalInfo.NumPrimes+1);         LocalInfo.pattern.SetLength(LocalInfo.NumPrimes+1);         LocalInfo.p[LocalInfo.NumPrimes] = p;         vec_long& pattern = LocalInfo.pattern[LocalInfo.NumPrimes];         pattern.SetLength(LocalInfo.n+1);         RecordPattern(pattern, thisfac);         if (verbose) {            cerr << (GetTime()-t) << "\n";            cerr << "degree sequence: ";            for (i = 0; i <= LocalInfo.n; i++)               if (pattern[i]) {                  cerr << pattern[i] << "*" << i << " ";               }            cerr << "\n";         }         ZZ pd;         CalcPossibleDegrees(pd, pattern);         bit_and(LocalInfo.PossibleDegrees, LocalInfo.PossibleDegrees, pd);         LocalInfo.NumPrimes++;         break;      }      bak.restore();   }}const int ZZX_OVERLIFT = NTL_BITS_PER_LONG;  // number of bits by which we "overlift"....this enables, in particular,  // the "n-1" test.    // Must lie in the range 4..NTL_BITS_PER_LONG.#define EXTRA_BITS (1)// Any small number, like 1, 2 or 3, should be OK.staticvoid CardinalitySearch(vec_ZZX& factors, ZZX& f,                        vec_ZZ_pX& W,                        LocalInfoT& LocalInfo,                        long k,                       long bnd,                       long verbose){   double start_time, end_time;   if (verbose) {      start_time = GetTime();      cerr << "\n************ ";      cerr << "start cardinality " << k << "\n";   }   vec_long I, D;   I.SetLength(k);   D.SetLength(k);   long r = W.length();   vec_ZZ_p prod;   prod.SetLength(k);   long ProdLen;   vec_ZZ pdeg;   CalcPossibleDegrees(pdeg, W, k);   ZZ pd;   vec_long upd;   long i, state;   long cnt = 0;   ZZ ct;   mul(ct, ConstTerm(f), LeadCoeff(f));   ZZ_p lc;   conv(lc, LeadCoeff(f));   ZZ_pX gg;   ZZX g, h;   I[0] = 0;     while (I[0] <= r-k) {      bit_and(pd, pdeg[I[0]], LocalInfo.PossibleDegrees);      if (IsZero(pd)) {         if (verbose) cerr << "skipping\n";         goto done;      }      unpack(upd, pd, LocalInfo.n);      D[0] = deg(W[I[0]]);      i = 1;      state = 0;      ProdLen = 0;      for (;;) {         if (i < ProdLen)            ProdLen = i;         if (i == k) {            // process indices I[0], ..., I[k-1]            if (cnt > 2000000) {                cnt = 0;               UpdateLocalInfo(LocalInfo, pdeg, W, factors, f, k, verbose);               bit_and(pd, pdeg[I[0]], LocalInfo.PossibleDegrees);               if (IsZero(pd)) {                  if (verbose) cerr << "skipping\n";                  goto done;               }               unpack(upd, pd, LocalInfo.n);            }            state = 1;  // default continuation state            if (!upd[D[k-1]]) {               i--;               cnt++;               continue;            }            if (!ConstTermTest(W, I, ct, lc, prod, ProdLen)) {               i--;               cnt += 100;               continue;            }            if (verbose) {               cerr << "+";            }            cnt += 1000;            if (2*D[k-1] <= deg(f)) {               mul(gg, W, I);               mul(gg, gg, lc);               BalCopy(g, gg);               if(MaxBits(g) > bnd) {                  i--;                  continue;               }               if (verbose) {                  cerr << "*";               }               PrimitivePart(g, g);               if (!divide(h, f, g)) {                  i--;                  continue;               }                              // factor found!               append(factors, g);               if (verbose) {                 cerr << "degree " << deg(g) << " factor found\n";               }               f = h;               mul(ct, ConstTerm(f), LeadCoeff(f));               conv(lc, LeadCoeff(f));            }            else {               InvMul(gg, W, I);               mul(gg, gg, lc);               BalCopy(g, gg);               if(MaxBits(g) > bnd) {                  i--;                  continue;               }               if (verbose) {                  cerr << "*";               }               PrimitivePart(g, g);               if (!divide(h, f, g)) {                  i--;                  continue;               }               // factor found!               append(factors, h);               if (verbose) {                 cerr << "degree " << deg(h) << " factor found\n";               }               f = g;               mul(ct, ConstTerm(f), LeadCoeff(f));               conv(lc, LeadCoeff(f));            }            RemoveFactors(W, I);            r = W.length();            cnt = 0;            if (2*k > r)                goto done;            else                break;         }         else if (state == 0) {            I[i] = I[i-1] + 1;            D[i] = D[i-1] + deg(W[I[i]]);            i++;         }         else { // state == 1            I[i]++;            if (i == 0) break;            if (I[i] > r-k+i)               i--;            else {               D[i] = D[i-1] + deg(W[I[i]]);               i++;               state = 0;            }         }      }   }   done:    if (verbose) {      end_time = GetTime();      cerr << "\n************ ";      cerr << "end cardinality " << k << "\n";      cerr << "time: " << (end_time-start_time) << "\n";   }}typedef unsigned long TBL_T;#if (NTL_BITS_PER_LONG >= 64)// for 64-bit machines#define TBL_MSK (63)#define TBL_SHAMT (6)#else// for 32-bit machines#define TBL_MSK (31)#define TBL_SHAMT (5)#endif#if 0// recursive versionstaticvoid RecInitTab(TBL_T ***lookup_tab, long i, const vec_ulong& ratio,              long r, long k, unsigned long thresh1, long **shamt_tab,             unsigned long sum, long card, long j){   if (j >= i || card >= k-1) {      if (card > 1) {         long shamt = shamt_tab[i][card];         unsigned long index1 = ((-sum) >> shamt);         lookup_tab[i][card][index1 >> TBL_SHAMT] |= (1UL << (index1 & TBL_MSK));         unsigned long index2 = ((-sum+thresh1) >> shamt);         if (index1 != index2)            lookup_tab[i][card][index2 >> TBL_SHAMT] |= (1UL << (index2 & TBL_MSK));      }      return;   }   RecInitTab(lookup_tab, i, ratio, r, k, thresh1, shamt_tab, sum, card, j+1);   RecInitTab(lookup_tab, i, ratio, r, k, thresh1, shamt_tab,               sum+ratio[r-1-j], card+1, j+1);}staticvoid DoInitTab(TBL_T ***lookup_tab, long i, const vec_ulong& ratio,                long r, long k, unsigned long thresh1, long **shamt_tab){   RecInitTab(lookup_tab, i, ratio, r, k, thresh1, shamt_tab, 0, 0, 0);}#else// iterative versionstaticvoid DoInitTab(TBL_T ***lookup_tab, long i, const vec_ulong& ratio,               long r, long k, unsigned long thresh1, long **shamt_tab){   vec_long sum_vec, card_vec, location_vec;   sum_vec.SetLength(i+1);   card_vec.SetLength(i+1);   location_vec.SetLength(i+1);   long j = 0;   sum_vec[0] = 0;   card_vec[0] = 0;   unsigned long sum;   long  card, location;   location = 0;   while (j >= 0) {      sum = sum_vec[j];      card = card_vec[j];      switch (location) {      case 0:         if (j >= i || card >= k-1) {            if (card > 1) {               long shamt = shamt_tab[i][card];               unsigned long index1 = ((-sum) >> shamt);               lookup_tab[i][card][index1 >> TBL_SHAMT] |= (1UL << (index1 & TBL_MSK));               unsigned long index2 = ((-sum+thresh1) >> shamt);               if (index1 != index2)                  lookup_tab[i][card][index2 >> TBL_SHAMT] |= (1UL << (index2 & TBL_MSK));                  }                  location = location_vec[j];            j--;            continue;         }         sum_vec[j+1] = sum;         card_vec[j+1] = card;         location_vec[j+1] = 1;         j++;         location = 0;         continue;      case 1:         sum_vec[j+1] = sum+ratio[r-1-j];         card_vec[j+1] = card+1;         location_vec[j+1] = 2;         j++;         location = 0;         continue;        case 2:         location = location_vec[j];         j--;         continue;      }   }}         #endif      staticvoid InitTab(TBL_T ***lookup_tab, const vec_ulong& ratio, long r, long k,             unsigned long thresh1, long **shamt_tab, long pruning){   long i, j, t;   if (pruning) {      for (i = 2; i <= pruning; i++) {         long len = min(k-1, i);         for (j = 2; j <= len; j++) {            long ub = (((1L << (NTL_BITS_PER_LONG-shamt_tab[i][j]))                       + TBL_MSK) >> TBL_SHAMT);             for (t = 0; t < ub; t++)               lookup_tab[i][j][t] = 0;         }            DoInitTab(lookup_tab, i, ratio, r, k, thresh1, shamt_tab);      }   }}staticvoid RatioInit1(vec_ulong& ratio, const vec_ZZ_pX& W, const ZZ_p& lc,                long pruning, TBL_T ***lookup_tab,                 vec_vec_ulong& pair_ratio, long k, unsigned long thresh1,                 long **shamt_tab){   long r = W.length();   long i, j;   ZZ_p a;   ZZ p;   p = ZZ_p::modulus();   ZZ aa;   for (i = 0; i < r; i++) {      long m = deg(W[i]);      mul(a, W[i].rep[m-1], lc);      LeftShift(aa, rep(a), NTL_BITS_PER_LONG);      div(aa, aa, p);

⌨️ 快捷键说明

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