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

📄 lll_fp.c

📁 数值算法库for Unix
💻 C
📖 第 1 页 / 共 3 页
字号:
   RR_GS_time += tt;   cerr << tt << " (" << RR_GS_time << ")\n";}void ComputeGS(const mat_ZZ& B, mat_RR& mu, vec_RR& c){   long n = B.NumCols();   long k = B.NumRows();   mat_RR B1;   vec_RR b;   B1.SetDims(k, n);   mu.SetDims(k, k);   b.SetLength(k);   c.SetLength(k);   vec_RR buf;   buf.SetLength(k);   long i, j;   for (i = 1; i <= k; i++)      for (j = 1; j <= n; j++)         conv(B1(i, j), B(i, j));   for (i = 1; i <= k; i++)      InnerProduct(b(i), B1(i), B1(i));      RR bound;   power2(bound, 2*long(0.15*RR::precision()));   RR bound2;   power2(bound2, 2*RR::precision());   for (i = 1; i <= k; i++)      ComputeGS(B, B1, mu, b, c, i, bound, 1, buf, bound2);}staticlong ll_LLL_FP(mat_ZZ& B, mat_ZZ* U, double delta, long deep,            LLLCheckFct check, double **B1, double **mu,            double *b, double *c,           long m, long init_k, long &quit){   long n = B.NumCols();   long i, j, k, Fc1;   ZZ MU;   double mu1;   double t1;   ZZ T1;   double *tp;   static double bound = 0;   if (bound == 0) {      // we tolerate a 15% loss of precision in computing      // inner products in ComputeGS.      bound = 1;      for (i = 2*long(0.15*NTL_DOUBLE_PRECISION); i > 0; i--)         bound = bound * 2;   }   double half_plus_fudge = 0.5 + red_fudge;   quit = 0;   k = init_k;   vec_long st_mem;   st_mem.SetLength(m+2);   long *st = st_mem.elts();   for (i = 1; i < k; i++)      st[i] = i;   for (i = k; i <= m+1; i++)      st[i] = 1;   double *buf;   buf = NTL_NEW_OP double [m+1];   if (!buf) Error("out of memory in lll_LLL_FP");   vec_long in_vec_mem;   in_vec_mem.SetLength(n+1);   long *in_vec = in_vec_mem.elts();   double *max_b;   max_b = NTL_NEW_OP double [m+1];   if (!max_b) Error("out of memory in lll_LLL_FP");   for (i = 1; i <= m; i++)      max_b[i] = max_abs(B1[i], n);   long in_float;   long rst;   long counter;   long start_over;   long trigger_index;   long small_trigger;   long cnt;   mat_RR rr_B1;   mat_RR rr_mu;   vec_RR rr_c;   vec_RR rr_b;   long m_orig = m;   long rr_st = 1;   long max_k = 0;   long prec = RR::precision();   double tt;   long swap_cnt = 0;   while (k <= m) {      if (k > max_k) {         max_k = k;         swap_cnt = 0;      }      if (verbose) {         tt = GetTime();         if (tt > LastTime + LLLStatusInterval)            LLLStatus(max_k, tt, m, B);      }      if (k < rr_st) rr_st = k;      if (st[k] == k)         rst = 1;      else         rst = k;      if (st[k] < st[k+1]) st[k+1] = st[k];      ComputeGS(B, B1, mu, b, c, k, bound, st[k], buf);      if (!IsFinite(&c[k])) Error("LLL_FP: numbers too big...use LLL_XD");      st[k] = k;      if (swap_cnt > 200000) {         cerr << "LLL_FP: swap loop?\n";         RR_GS(B, B1, mu, b, c, buf, prec,               rr_st, k, m_orig, rr_B1, rr_mu, rr_b, rr_c);         if (rr_st < st[k+1]) st[k+1] = rr_st;         rr_st = k+1;         rst = k;         swap_cnt = 0;      }      counter = 0;      trigger_index = k;      small_trigger = 0;      cnt = 0;      long thresh = 10;      long sz=0, new_sz;      long did_rr_gs = 0;      do {         // size reduction         counter++;         if ((counter & 127) == 0) {            new_sz = 0;            for (j = 1; j <= n; j++)               new_sz += NumBits(B(k,j));            if ((counter >> 7) == 1 || new_sz < sz) {               sz = new_sz;            }            else {               cerr << "LLL_FP: warning--infinite loop?\n";            }         }         Fc1 = 0;         start_over = 0;            for (j = rst-1; j >= 1; j--) {            t1 = fabs(mu[k][j]);            if (t1 > half_plus_fudge) {                if (!Fc1) {                  if (j > trigger_index ||                       (j == trigger_index && small_trigger)) {                     cnt++;                     if (cnt > thresh) {                        if (log_red <= 15) {                            while (log_red > 10)                              inc_red_fudge();                           half_plus_fudge = 0.5 + red_fudge;                           if (!did_rr_gs) {                              RR_GS(B, B1, mu, b, c, buf, prec,                                    rr_st, k, m_orig, rr_B1, rr_mu, rr_b, rr_c);                              if (rr_st < st[k+1]) st[k+1] = rr_st;                              rr_st = k+1;                              did_rr_gs = 1;                              rst = k;                              trigger_index = k;                              small_trigger = 0;                              start_over = 1;                              break;                           }                        }                        else {                           inc_red_fudge();                           half_plus_fudge = 0.5 + red_fudge;                           cnt = 0;                        }                     }                  }                  trigger_index = j;                  small_trigger = (t1 < 4);                  Fc1 = 1;                  if (k < rr_st) rr_st = k;                  RowTransformStart(B1[k], in_vec, in_float, n);               }                                 mu1 = mu[k][j];               if (mu1 >= 0)                  mu1 = ceil(mu1-0.5);               else                  mu1 = floor(mu1+0.5);                  double *mu_k = mu[k];               double *mu_j = mu[j];                  if (mu1 == 1) {                  for (i = 1; i <= j-1; i++)                     mu_k[i] -= mu_j[i];               }               else if (mu1 == -1) {                  for (i = 1; i <= j-1; i++)                     mu_k[i] += mu_j[i];               }               else {                  for (i = 1; i <= j-1; i++)                     mu_k[i] -= mu1*mu_j[i];               }                  mu_k[j] -= mu1;                  conv(MU, mu1);               RowTransform(B(k), B(j), MU, mu1, B1[k], B1[j], in_vec,                            max_b[k], max_b[j], in_float);               if (U) RowTransform((*U)(k), (*U)(j), MU);            }         }         if (Fc1) {            RowTransformFinish(B(k), B1[k], in_vec);            max_b[k] = max_abs(B1[k], n);               if (!did_rr_gs) {               b[k] = InnerProduct(B1[k], B1[k], n);               ComputeGS(B, B1, mu, b, c, k, bound, 1, buf);            }            else {               RR_GS(B, B1, mu, b, c, buf, prec,                     rr_st, k, m_orig, rr_B1, rr_mu, rr_b, rr_c);               rr_st = k+1;            }            if (!IsFinite(&b[k]))               Error("LLL_FP: numbers too big...use LLL_XD");            if (!IsFinite(&c[k]))               Error("LLL_FP: numbers too big...use LLL_XD");            rst = k;         }      } while (Fc1 || start_over);      if (check && (*check)(B(k)))          quit = 1;      if (b[k] == 0) {         for (i = k; i < m; i++) {            // swap i, i+1            swap(B(i), B(i+1));            tp = B1[i]; B1[i] = B1[i+1]; B1[i+1] = tp;            t1 = b[i]; b[i] = b[i+1]; b[i+1] = t1;            t1 = max_b[i]; max_b[i] = max_b[i+1]; max_b[i+1] = t1;            if (U) swap((*U)(i), (*U)(i+1));         }         for (i = k; i <= m+1; i++) st[i] = 1;         if (k < rr_st) rr_st = k;         m--;         if (quit) break;         continue;      }      if (quit) break;      if (deep > 0) {         // deep insertions         double cc = b[k];         long l = 1;         while (l <= k-1 && delta*c[l] <= cc) {            cc = cc - mu[k][l]*mu[k][l]*c[l];            l++;         }            if (l <= k-1 && (l <= deep || k-l <= deep)) {            // deep insertion at position l               for (i = k; i > l; i--) {               // swap rows i, i-1               swap(B(i), B(i-1));               tp = B1[i]; B1[i] = B1[i-1]; B1[i-1] = tp;               tp = mu[i]; mu[i] = mu[i-1]; mu[i-1] = tp;               t1 = b[i]; b[i] = b[i-1]; b[i-1] = t1;               t1 = max_b[i]; max_b[i] = max_b[i-1]; max_b[i-1] = t1;               if (U) swap((*U)(i), (*U)(i-1));            }               k = l;            NumSwaps++;            swap_cnt++;            continue;         }      } // end deep insertions      // test LLL reduction condition      if (k > 1 && delta*c[k-1] > c[k] + mu[k][k-1]*mu[k][k-1]*c[k-1]) {         // swap rows k, k-1         swap(B(k), B(k-1));         tp = B1[k]; B1[k] = B1[k-1]; B1[k-1] = tp;         tp = mu[k]; mu[k] = mu[k-1]; mu[k-1] = tp;         t1 = b[k]; b[k] = b[k-1]; b[k-1] = t1;         t1 = max_b[k]; max_b[k] = max_b[k-1]; max_b[k-1] = t1;         if (U) swap((*U)(k), (*U)(k-1));         k--;         NumSwaps++;         swap_cnt++;         // cout << "-\n";      }      else {         k++;         // cout << "+\n";      }   }   if (verbose) {      LLLStatus(m+1, GetTime(), m, B);   }   delete [] buf;   delete [] max_b;   return m;}staticlong LLL_FP(mat_ZZ& B, mat_ZZ* U, double delta, long deep,            LLLCheckFct check){   long m = B.NumRows();   long n = B.NumCols();   long i, j;   long new_m, dep, quit;   ZZ MU;   ZZ T1;   init_red_fudge();   if (U) ident(*U, m);   double **B1;  // approximates B   typedef double *doubleptr;   B1 = NTL_NEW_OP doubleptr[m+1];   if (!B1) Error("LLL_FP: out of memory");   for (i = 1; i <= m; i++) {      B1[i] = NTL_NEW_OP double[n+1];      if (!B1[i]) Error("LLL_FP: out of memory");   }   double **mu;   mu = NTL_NEW_OP doubleptr[m+1];   if (!mu) Error("LLL_FP: out of memory");   for (i = 1; i <= m; i++) {      mu[i] = NTL_NEW_OP double[m+1];      if (!mu[i]) Error("LLL_FP: out of memory");   }   double *c; // squared lengths of Gramm-Schmidt basis vectors   c = NTL_NEW_OP double[m+1];   if (!c) Error("LLL_FP: out of memory");   double *b; // squared lengths of basis vectors   b = NTL_NEW_OP double[m+1];   if (!b) Error("LLL_FP: out of memory");   for (i = 1; i <=m; i++)      for (j = 1; j <= n; j++)          conv(B1[i][j], B(i, j));            for (i = 1; i <= m; i++) {      b[i] = InnerProduct(B1[i], B1[i], n);      if (!IsFinite(&b[i]))          Error("LLL_FP: numbers too big...use LLL_XD");   }   new_m = ll_LLL_FP(B, U, delta, deep, check, B1, mu, b, c, m, 1, quit);   dep = m - new_m;   m = new_m;   if (dep > 0) {      // for consistency, we move all of the zero rows to the front      for (i = 0; i < m; i++) {         swap(B(m+dep-i), B(m-i));         if (U) swap((*U)(m+dep-i), (*U)(m-i));      }   }   // clean-up   for (i = 1; i <= m; i++) {      delete [] B1[i];   }   delete [] B1;   for (i = 1; i <= m; i++) {      delete [] mu[i];   }   delete [] mu;   delete [] c;   delete [] b;   return m;}         long LLL_FP(mat_ZZ& B, double delta, long deep, LLLCheckFct check,            long verb){   verbose = verb;   RR_GS_time = 0;   NumSwaps = 0;   if (verbose) {      StartTime = GetTime();      LastTime = StartTime;   }   if (delta < 0.50 || delta >= 1) Error("LLL_FP: bad delta");   if (deep < 0) Error("LLL_FP: bad deep");   return LLL_FP(B, 0, delta, deep, check);}long LLL_FP(mat_ZZ& B, mat_ZZ& U, double delta, long deep,            LLLCheckFct check, long verb){   verbose = verb;   RR_GS_time = 0;   NumSwaps = 0;   if (verbose) {      StartTime = GetTime();      LastTime = StartTime;   }   if (delta < 0.50 || delta >= 1) Error("LLL_FP: bad delta");   if (deep < 0) Error("LLL_FP: bad deep");   return LLL_FP(B, &U, delta, deep, check);}static vec_double BKZConstant;staticvoid ComputeBKZConstant(long beta, long p){   const double c_PI = 3.14159265358979323846264338328;   const double LogPI = 1.14472988584940017414342735135;   BKZConstant.SetLength(beta-1);   vec_double Log;   Log.SetLength(beta);   long i, j, k;   double x, y;   for (j = 1; j <= beta; j++)      Log(j) = log(double(j));   for (i = 1; i <= beta-1; i++) {      // First, we compute x = gamma(i/2)^{2/i}      k = i/2;      if ((i & 1) == 0) { // i even         x = 0;         for (j = 1; j <= k; j++)            x = x + Log(j);                   x = x * (1/double(k));         x = exp(x);      }      else { // i odd         x = 0;         for (j = k + 2; j <= 2*k + 2; j++)            x = x + Log(j);         x = 0.5*LogPI + x - 2*(k+1)*Log(2);         x = x * (2.0/double(i));         x = exp(x);      }      // Second, we compute y = 2^{2*p/i}

⌨️ 快捷键说明

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