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

📄 lll_fp.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <NTL/LLL.h>#include <NTL/fileio.h>#include <NTL/vec_double.h>#include <NTL/new.h>NTL_START_IMPLstatic double InnerProduct(double *a, double *b, long n){   double s;   long i;   s = 0;   for (i = 1; i <= n; i++)       s += a[i]*b[i];   return s;}static void RowTransform(vec_ZZ& A, vec_ZZ& B, const ZZ& MU1)// x = x - y*MU{   static ZZ T, MU;   long k;   long n = A.length();   long i;   MU = MU1;   if (MU == 1) {      for (i = 1; i <= n; i++)         sub(A(i), A(i), B(i));      return;   }   if (MU == -1) {      for (i = 1; i <= n; i++)         add(A(i), A(i), B(i));      return;   }   if (MU == 0) return;   if (NumTwos(MU) >= NTL_ZZ_NBITS)       k = MakeOdd(MU);   else      k = 0;   if (MU.WideSinglePrecision()) {      long mu1;      conv(mu1, MU);      for (i = 1; i <= n; i++) {         mul(T, B(i), mu1);         if (k > 0) LeftShift(T, T, k);         sub(A(i), A(i), T);      }   }   else {      for (i = 1; i <= n; i++) {         mul(T, B(i), MU);         if (k > 0) LeftShift(T, T, k);         sub(A(i), A(i), T);      }   }}#define TR_BND (NTL_FDOUBLE_PRECISION/2.0)// Just to be safe!!static double max_abs(double *v, long n){   long i;   double res, t;   res = 0;   for (i = 1; i <= n; i++) {      t = fabs(v[i]);      if (t > res) res = t;   }   return res;}static void RowTransformStart(double *a, long *in_a, long& in_float, long n){   long i;   long inf = 1;   for (i = 1; i <= n; i++) {      in_a[i] = (a[i] < TR_BND && a[i] > -TR_BND);      inf = inf & in_a[i];   }   in_float = inf;}static void RowTransformFinish(vec_ZZ& A, double *a, long *in_a){   long n = A.length();   long i;   for (i = 1; i <= n; i++) {      if (in_a[i])  {         conv(A(i), a[i]);      }      else {         conv(a[i], A(i));      }   }}static void RowTransform(vec_ZZ& A, vec_ZZ& B, const ZZ& MU1,                          double mu, double *a, double *b, long *in_a,                         double& max_a, double max_b, long& in_float)// x = x - y*MU{   static ZZ T, MU;   long k;   long n = A.length();   long i;   if (in_float) {      max_a += fabs(mu)*max_b;      if (max_a >= TR_BND) {         in_float = 0;      }   }   if (in_float) {      if (mu == 1) {         for (i = 1; i <= n; i++)            a[i] -= b[i];         return;      }      if (mu == -1) {         for (i = 1; i <= n; i++)            a[i] += b[i];         return;      }      if (mu == 0) return;      for (i = 1; i <= n; i++)         a[i] -= mu*b[i];      return;   }   MU = MU1;   if (MU == 1) {      for (i = 1; i <= n; i++) {         if (in_a[i] && a[i] < TR_BND && a[i] > -TR_BND &&             b[i] < TR_BND && b[i] > -TR_BND) {            a[i] -= b[i];         }         else {            if (in_a[i]) {               conv(A(i), a[i]);               in_a[i] = 0;            }                     sub(A(i), A(i), B(i));         }      }      return;   }   if (MU == -1) {      for (i = 1; i <= n; i++) {         if (in_a[i] && a[i] < TR_BND && a[i] > -TR_BND &&             b[i] < TR_BND && b[i] > -TR_BND) {            a[i] += b[i];         }         else {            if (in_a[i]) {               conv(A(i), a[i]);               in_a[i] = 0;            }                     add(A(i), A(i), B(i));         }      }      return;   }   if (MU == 0) return;   double b_bnd = fabs(TR_BND/mu) - 1;   if (b_bnd < 0) b_bnd = 0;    if (NumTwos(MU) >= NTL_ZZ_NBITS)       k = MakeOdd(MU);   else      k = 0;   if (MU.WideSinglePrecision()) {      long mu1;      conv(mu1, MU);      if (k > 0) {         for (i = 1; i <= n; i++) {            if (in_a[i]) {               conv(A(i), a[i]);               in_a[i] = 0;            }            mul(T, B(i), mu1);            LeftShift(T, T, k);            sub(A(i), A(i), T);         }      }      else {         for (i = 1; i <= n; i++) {            if (in_a[i] && a[i] < TR_BND && a[i] > -TR_BND &&                b[i] < b_bnd && b[i] > -b_bnd) {                  a[i] -= b[i]*mu;            }            else {               if (in_a[i]) {                  conv(A(i), a[i]);                  in_a[i] = 0;               }               mul(T, B(i), mu1);               sub(A(i), A(i), T);            }         }      }   }   else {      for (i = 1; i <= n; i++) {         if (in_a[i]) {            conv(A(i), a[i]);            in_a[i] = 0;         }         mul(T, B(i), MU);         if (k > 0) LeftShift(T, T, k);         sub(A(i), A(i), T);      }   }}static void RowTransform2(vec_ZZ& A, vec_ZZ& B, const ZZ& MU1)// x = x + y*MU{   static ZZ T, MU;   long k;   long n = A.length();   long i;   MU = MU1;   if (MU == 1) {      for (i = 1; i <= n; i++)         add(A(i), A(i), B(i));      return;   }   if (MU == -1) {      for (i = 1; i <= n; i++)         sub(A(i), A(i), B(i));      return;   }   if (MU == 0) return;   if (NumTwos(MU) >= NTL_ZZ_NBITS)       k = MakeOdd(MU);   else      k = 0;   if (MU.WideSinglePrecision()) {      long mu1;      conv(mu1, MU);      for (i = 1; i <= n; i++) {         mul(T, B(i), mu1);         if (k > 0) LeftShift(T, T, k);         add(A(i), A(i), T);      }   }   else {      for (i = 1; i <= n; i++) {         mul(T, B(i), MU);         if (k > 0) LeftShift(T, T, k);         add(A(i), A(i), T);      }   }}staticvoid ComputeGS(mat_ZZ& B, double **B1, double **mu, double *b,               double *c, long k, double bound, long st, double *buf){   long n = B.NumCols();   long i, j;   double s, t1, y, t;   ZZ T1;   long test;   double *mu_k = mu[k];   if (st < k) {      for (i = 1; i < st; i++)         buf[i] = mu_k[i]*c[i];   }   for (j = st; j <= k-1; j++) {      s = InnerProduct(B1[k], B1[j], n);      // test = b[k]*b[j] >= NTL_FDOUBLE_PRECISION^2      test = (b[k]/NTL_FDOUBLE_PRECISION >= NTL_FDOUBLE_PRECISION/b[j]);      // test = test && s^2 <= b[k]*b[j]/bound,      // but we compute it in a strange way to avoid overflow      if (test && (y = fabs(s)) != 0) {         t = y/b[j];         t1 = b[k]/y;         if (t <= 1)            test = (t*bound <= t1);         else if (t1 >= 1)            test = (t <= t1/bound);         else            test = 0;      }      if (test) {         InnerProduct(T1, B(k), B(j));         conv(s, T1);      }      double *mu_j = mu[j];      t1 = 0;      for (i = 1; i <= j-1; i++) {         t1 += mu_j[i]*buf[i];      }        mu_k[j] = (buf[j] = (s - t1))/c[j];   }#if (!NTL_EXT_DOUBLE)   // Kahan summation    double c1;   s = c1 = 0;   for (j = 1; j <= k-1; j++) {      y = mu_k[j]*buf[j] - c1;      t = s+y;      c1 = t-s;      c1 = c1-y;      s = t;   }#else   s = 0;   for (j = 1; j <= k-1; j++)      s += mu_k[j]*buf[j];#endif   c[k] = b[k] - s;}static double red_fudge = 0;static long log_red = 0;static long verbose = 0;double LLLStatusInterval = 900.0;char *LLLDumpFile = 0;static unsigned long NumSwaps = 0;static double RR_GS_time = 0;static double StartTime = 0;static double LastTime = 0;static void LLLStatus(long max_k, double t, long m, const mat_ZZ& B){   cerr << "---- LLL_FP status ----\n";   cerr << "elapsed time: ";   PrintTime(cerr, t-StartTime);   cerr << ", stage: " << max_k;   cerr << ", rank: " << m;   cerr << ", swaps: " << NumSwaps << "\n";   ZZ t1;   long i;   double prodlen = 0;   for (i = 1; i <= m; i++) {      InnerProduct(t1, B(i), B(i));      if (!IsZero(t1))         prodlen += log(t1);   }   cerr << "log of prod of lengths: " << prodlen/(2.0*log(2.0)) << "\n";   if (LLLDumpFile) {      cerr << "dumping to " << LLLDumpFile << "...";      ofstream f;      OpenWrite(f, LLLDumpFile);            f << "[";      for (i = 1; i <= m; i++) {         f << B(i) << "\n";      }      f << "]\n";      f.close();      cerr << "\n";   }   LastTime = t;   }static void init_red_fudge(){   long i;   log_red = long(0.50*NTL_DOUBLE_PRECISION);   red_fudge = 1;   for (i = log_red; i > 0; i--)      red_fudge = red_fudge*0.5;}static void inc_red_fudge(){   red_fudge = red_fudge * 2;   log_red--;      cerr << "LLL_FP: warning--relaxing reduction (" << log_red << ")\n";   if (log_red < 4)      Error("LLL_FP: too much loss of precision...stop!");}#if 0static void print_mus(double **mu, long k){   long i;   for (i = k-1; i >= 1; i--)      cerr << mu[k][i] << " ";   cerr << "\n";}#endifvoid ComputeGS(const mat_ZZ& B, mat_RR& B1,                mat_RR& mu, vec_RR& b,               vec_RR& c, long k, const RR& bound, long st,               vec_RR& buf, const RR& bound2);static void RR_GS(mat_ZZ& B, double **B1, double **mu,                   double *b, double *c, double *buf, long prec,                  long rr_st, long k, long m_orig,                  mat_RR& rr_B1, mat_RR& rr_mu,                   vec_RR& rr_b, vec_RR& rr_c){   double tt;   cerr << "LLL_FP: RR refresh " << rr_st << "..." << k << "...";   tt = GetTime();   if (rr_st > k) Error("LLL_FP: can not continue!!!");   long old_p = RR::precision();   RR::SetPrecision(prec);   long n = B.NumCols();   rr_B1.SetDims(k, n);   rr_mu.SetDims(k, m_orig);   rr_b.SetLength(k);   rr_c.SetLength(k);   vec_RR rr_buf;   rr_buf.SetLength(k);   long i, j;   for (i = rr_st; i <= k; i++)      for (j = 1; j <= n; j++)         conv(rr_B1(i, j), B(i, j));   for (i = rr_st; i <= k; i++)      InnerProduct(rr_b(i), rr_B1(i), rr_B1(i));      RR bound;   power2(bound, 2*long(0.15*RR::precision()));   RR bound2;   power2(bound2, 2*RR::precision());   for (i = rr_st; i <= k; i++)      ComputeGS(B, rr_B1, rr_mu, rr_b, rr_c, i, bound, 1, rr_buf, bound2);   for (i = rr_st; i <= k; i++)      for (j = 1; j <= n; j++)          conv(B1[i][j], rr_B1(i,j));   for (i = rr_st; i <= k; i++)      for (j = 1; j <= i-1; j++) {         conv(mu[i][j], rr_mu(i,j));         if (!IsFinite(&mu[i][j]))             Error("LLL_FP: numbers too big...use LLL_XD");      }   for (i = rr_st; i <= k; i++) {      conv(b[i], rr_b(i));      if (!IsFinite(&b[i])) Error("LLL_FP: numbers too big...use LLL_XD");   }      for (i = rr_st; i <= k; i++) {      conv(c[i], rr_c(i));      if (!IsFinite(&c[i])) Error("LLL_FP: numbers too big...use LLL_XD");   }   for (i = 1; i <= k-1; i++) {      conv(buf[i], rr_buf[i]);   }   RR::SetPrecision(old_p);   tt = GetTime()-tt;

⌨️ 快捷键说明

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