Beispiel #1
0
void mul_aux(mat_ZZ& X, const mat_ZZ& A, const mat_ZZ& B)
{
    long n = A.NumRows();
    long l = A.NumCols();
    long m = B.NumCols();

    if (l != B.NumRows())
        Error("matrix mul: dimension mismatch");

    X.SetDims(n, m);

    long i, j, k;
    ZZ acc, tmp;

    for (i = 1; i <= n; i++) {
        for (j = 1; j <= m; j++) {
            clear(acc);
            for(k = 1; k <= l; k++) {
                mul(tmp, A(i,k), B(k,j));
                add(acc, acc, tmp);
            }
            X(i,j) = acc;
        }
    }
}
Beispiel #2
0
void sub(mat_ZZ& X, const mat_ZZ& A, const mat_ZZ& B)
{
    long n = A.NumRows();
    long m = A.NumCols();

    if (B.NumRows() != n || B.NumCols() != m)
        Error("matrix sub: dimension mismatch");

    X.SetDims(n, m);

    long i, j;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
            sub(X(i,j), A(i,j), B(i,j));
}
Beispiel #3
0
vec_ZZ  GS_reduce(mat_ZZ mat, vec_ZZ vec, ZZ weight)
{
    vec_ZZ          target;
    ZZ_mat<mpz_t>   mat_fp;
    mat_ZZ          mat_exp;
    int             row, col;


    row     =   mat.NumRows();
    col     =   mat.NumCols();
    mat_exp.SetDims(row+1, col+1);

    for(int i=0;i<row;i++)
    {
        for(int j=0;j<col;j++)
        {
            mat_exp[i][j] =   mat[i][j];
        }
    }
    for(int i=0;i<col;i++)
    {
        mat_exp[row][i] =   vec[i];
    }
    mat_exp[row][col]   =   weight;

    mat_fp  =   convert<ZZ_mat<mpz_t> ,mat_ZZ >(mat_exp);
    lllReduction(mat_fp, 0.99,0.51, LM_WRAPPER,FT_DEFAULT, 0, LLL_DEFAULT);
    mat_exp =   convert<mat_ZZ ,ZZ_mat<mpz_t> >(mat_fp);
    target.SetLength(col);
    for (int i=0;i<col;i++)
        target[i]   =   mat_exp[row][i];
//    cout<<target<<endl;
    return target;
}
Beispiel #4
0
static
long image(ZZ& det, mat_ZZ& B, mat_ZZ* U, long verbose)
{
   long m = B.NumRows();
   long n = B.NumCols();

   long force_reduce = 1;

   vec_long P;
   P.SetLength(m);

   vec_ZZ D;
   D.SetLength(m+1);
   D[0] = 1;

   vec_vec_ZZ lam;

   lam.SetLength(m);

   long j;
   for (j = 1; j <= m; j++)
      lam(j).SetLength(m);

   if (U) ident(*U, m);

   long s = 0;

   long k = 1;
   long max_k = 0;


   while (k <= m) {
      if (k > max_k) {
         IncrementalGS(B, P, D, lam, s, k);
         max_k = k;
      }

      if (k == 1) {
         force_reduce = 1;
         k++;
         continue;
      }

      if (force_reduce)
         for (j = k-1; j >= 1; j--)
            reduce(k, j, B, P, D, lam, U);

      if (P(k-1) != 0 && P(k) == 0) {
         force_reduce = swap(k, B, P, D, lam, U, max_k, verbose);
         k--;
      }
      else {
         force_reduce = 1;
         k++;
      }
   }

   det = D[s];
   return s;
}
Beispiel #5
0
void power(mat_ZZ& X, const mat_ZZ& A, const ZZ& e)
{
    if (A.NumRows() != A.NumCols()) Error("power: non-square matrix");

    if (e == 0) {
        ident(X, A.NumRows());
        return;
    }

    mat_ZZ T1, T2;
    long i, k;

    k = NumBits(e);
    T1 = A;

    for (i = k-2; i >= 0; i--) {
        sqr(T2, T1);
        if (bit(e, i))
            mul(T1, T2, A);
        else
            T1 = T2;
    }

    if (e < 0)
        inv(X, T1);
    else
        X = T1;
}
Beispiel #6
0
void transpose(mat_ZZ& X, const mat_ZZ& A)
{
    long n = A.NumRows();
    long m = A.NumCols();

    long i, j;

    if (&X == & A) {
        if (n == m)
            for (i = 1; i <= n; i++)
                for (j = i+1; j <= n; j++)
                    swap(X(i, j), X(j, i));
        else {
            mat_ZZ tmp;
            tmp.SetDims(m, n);
            for (i = 1; i <= n; i++)
                for (j = 1; j <= m; j++)
                    tmp(j, i) = A(i, j);
            X.kill();
            X = tmp;
        }
    }
    else {
        X.SetDims(m, n);
        for (i = 1; i <= n; i++)
            for (j = 1; j <= m; j++)
                X(j, i) = A(i, j);
    }
}
Beispiel #7
0
NTL_START_IMPL


void add(mat_ZZ& X, const mat_ZZ& A, const mat_ZZ& B)  
{  
   long n = A.NumRows();  
   long m = A.NumCols();  
  
   if (B.NumRows() != n || B.NumCols() != m)   
      LogicError("matrix add: dimension mismatch");  
  
   X.SetDims(n, m);  
  
   long i, j;  
   for (i = 1; i <= n; i++)   
      for (j = 1; j <= m; j++)  
         add(X(i,j), A(i,j), B(i,j));  
}  
Beispiel #8
0
void conv(mat_ZZ_p& x, const mat_ZZ& a)
{
    long n = a.NumRows();
    long m = a.NumCols();
    long i;

    x.SetDims(n, m);
    for (i = 0; i < n; i++)
        conv(x[i], a[i]);
}
Beispiel #9
0
static
long MaxBits(const mat_ZZ& A)
{
    long m = 0;
    long i, j;
    for (i = 0; i < A.NumRows(); i++)
        for (j = 0; j < A.NumCols(); j++)
            m = max(m, NumBits(A[i][j]));

    return m;
}
Beispiel #10
0
void mul(mat_ZZ& X, const mat_ZZ& A, long b)
{
    long n = A.NumRows();
    long m = A.NumCols();

    X.SetDims(n, m);

    long i, j;
    for (i = 0; i < n; i++)
        for (j = 0; j < m; j++)
            mul(X[i][j], A[i][j], b);
}
Beispiel #11
0
static
void ExactDiv(mat_ZZ& x, const ZZ& d)
{
    long n = x.NumRows();
    long m = x.NumCols();

    long i, j;

    for (i = 0; i < n; i++)
        for (j = 0; j < m; j++)
            if (!divide(x[i][j], x[i][j], d))
                Error("inexact division");
}
Beispiel #12
0
void negate(mat_ZZ& X, const mat_ZZ& A)
{
    long n = A.NumRows();
    long m = A.NumCols();


    X.SetDims(n, m);

    long i, j;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
            negate(X(i,j), A(i,j));
}
Beispiel #13
0
static
void ComputeGS(mat_ZZ& B, xdouble **B1, xdouble **mu, xdouble *b, 
               xdouble *c, long k, xdouble bound, long st, xdouble *buf)
{
   long n = B.NumCols();
   long i, j;
   xdouble s, t1, y, t;
   ZZ T1;

   xdouble *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++) {
      if (b[k]*b[j] < NTL_FDOUBLE_PRECISION*NTL_FDOUBLE_PRECISION) {
         double z = 0;
         xdouble *B1_k = B1[k];
         xdouble *B1_j = B1[j];

         for (i = 1; i <= n; i++)
            z += B1_k[i].x * B1_j[i].x;

         s = z;
      }
      else {
         s = InnerProduct(B1[k], B1[j], n);
   
         if (s*s <= b[k]*b[j]/bound) {
            InnerProduct(T1, B(k), B(j));
            conv(s, T1);
         }
      }

      xdouble *mu_j = mu[j];

      t1 = 0;
      for (i = 1; i <= j-1; i++)
         MulAdd(t1, t1, mu_j[i], buf[i]);

      mu_k[j] = (buf[j] = (s - t1))/c[j];
   }

   s = 0;
   for (j = 1; j <= k-1; j++)
      MulAdd(s, s, mu_k[j], buf[j]);

   c[k] = b[k] - s;
}
Beispiel #14
0
static
void IncrementalGS(mat_ZZ& B, vec_long& P, vec_ZZ& D, vec_vec_ZZ& lam,
                   long& s, long k)
{
   long n = B.NumCols();
   long m = B.NumRows();

   static ZZ u, t1, t2;

   long i, j;

   for (j = 1; j <= k-1; j++) {
      long posj = P(j);
      if (posj == 0) continue;

      InnerProduct(u, B(k), B(j));
      for (i = 1; i <= posj-1; i++) {
         mul(t1, D[i], u);
         mul(t2, lam(k)(i), lam(j)(i));
         sub(t1, t1, t2);
         div(t1, t1, D[i-1]);
         u = t1;
      }

      lam(k)(posj) = u;
   }

   InnerProduct(u, B(k), B(k));
   for (i = 1; i <= s; i++) {
      mul(t1, D[i], u);
      mul(t2, lam(k)(i), lam(k)(i));
      sub(t1, t1, t2);
      div(t1, t1, D[i-1]);
      u = t1;
   }

   if (u == 0) {
      P(k) = 0;
   }
   else {
      s++;
      P(k) = s;
      D[s] = u;
   }
}
Beispiel #15
0
long IsIdent(const mat_ZZ& A, long n)
{
    if (A.NumRows() != n || A.NumCols() != n)
        return 0;

    long i, j;

    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
            if (i != j) {
                if (!IsZero(A(i, j))) return 0;
            }
            else {
                if (!IsOne(A(i, j))) return 0;
            }

    return 1;
}
Beispiel #16
0
long IsDiag(const mat_ZZ& A, long n, const ZZ& d)
{
    if (A.NumRows() != n || A.NumCols() != n)
        return 0;

    long i, j;

    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
            if (i != j) {
                if (!IsZero(A(i, j))) return 0;
            }
            else {
                if (A(i, j) != d) return 0;
            }

    return 1;
}
Beispiel #17
0
mat_ZZ  mat_expand(mat_ZZ M, vec_ZZ v)
{
    int     len, col, row;
    mat_ZZ  mat_exp;

    len =   v.length();
    col =   M.NumCols();
    row =   M.NumRows();

    if (len!=col)
        cout<<"Incompatible rows"<<endl;

    mat_exp =   M;
    mat_exp.SetDims(row+1, col);
    mat_exp[row] = v;



    return  mat_exp;
}
Beispiel #18
0
static
void mul_aux(vec_ZZ& x, const mat_ZZ& A, const vec_ZZ& b)
{
    long n = A.NumRows();
    long l = A.NumCols();

    if (l != b.length())
        Error("matrix mul: dimension mismatch");

    x.SetLength(n);

    long i, k;
    ZZ acc, tmp;

    for (i = 1; i <= n; i++) {
        clear(acc);
        for (k = 1; k <= l; k++) {
            mul(tmp, A(i,k), b(k));
            add(acc, acc, tmp);
        }
        x(i) = acc;
    }
}
Beispiel #19
0
static
void MixedMul(vec_ZZ& x, const vec_zz_p& a, const mat_ZZ& B)
{
    long n = B.NumRows();
    long l = B.NumCols();

    if (n != a.length())
        Error("matrix mul: dimension mismatch");

    x.SetLength(l);

    long i, k;
    ZZ acc, tmp;

    for (i = 1; i <= l; i++) {
        clear(acc);
        for (k = 1; k <= n; k++) {
            mul(tmp, B(k, i), rep(a(k)));
            add(acc, acc, tmp);
        }
        x(i) = acc;
    }
}
Beispiel #20
0
void Testbench::initMatrix(mat_ZZ & m, int int_size) {
	ZZ n;
	switch (int_size) {
		case 64:
			n = to_ZZ("9999999999999999995");
			break;
		case 128:
			n = to_ZZ("99993749237498237498237493299999999995");
			break;
		case 256:
			n = to_ZZ("99993749237498237498237493299999937129873912873981273129842343242399999799995");
			break;
		case 512:
			n = to_ZZ("9999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995");
			break;
		case 1024:
			n = to_ZZ("99993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995");
			break;
		case 2048:
			n = to_ZZ("9999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995");
			break;
		case 4096:
			n = to_ZZ("99993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995");
			break;
		case 8192:
			n = to_ZZ("9999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995999937492374982374982374932999999371298739128739812731298423432423999997999959999374923749823749823749329999993712987391287398127312984234324239999979999599993749237498237498237493299999937129873912873981273129842343242399999799995");
			break;
		default:
			n = to_ZZ("9999999999999999995");
			break;
	}
	for (int i = 1; i <= m.NumRows(); i++) {
		for (int j = 1; j <= m.NumCols(); j++) {
			m(i,j) = n;
		}
	}
}
Beispiel #21
0
static
long ll_LLL_XD(mat_ZZ& B, mat_ZZ* U, xdouble delta, long deep, 
           LLLCheckFct check, xdouble **B1, xdouble **mu, 
           xdouble *b, xdouble *c,
           long m, long init_k, long &quit)
{
   long n = B.NumCols();

   long i, j, k, Fc1;
   ZZ MU;
   xdouble mu1;

   xdouble t1;
   ZZ T1;
   xdouble *tp;


   NTL_THREAD_LOCAL static xdouble bound = to_xdouble(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;
      }
   }


   xdouble half = to_xdouble(0.5);
   xdouble 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;

   UniqueArray<xdouble> buf_store;
   buf_store.SetLength(m+1);
   xdouble *buf = buf_store.get();

   long rst;
   long counter;

   long trigger_index;
   long small_trigger;
   long cnt;

   long max_k = 0;

   double tt;


   while (k <= m) {

      if (k > max_k) {
         max_k = k;
      }

      if (verbose) {
         tt = GetTime();

         if (tt > LastTime + LLLStatusInterval)
            LLLStatus(max_k, tt, m, B);
      }


      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);
      st[k] = k;

      counter = 0;
      trigger_index = k;
      small_trigger = 0;
      cnt = 0;

      do {
         // size reduction

         counter++;
         if (counter > 10000) {
            cerr << "LLL_XD: warning--possible infinite loop\n";
            counter = 0;
         }


         Fc1 = 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 > 10) {
                        inc_red_fudge();
                        half_plus_fudge = 0.5 + red_fudge;
                        cnt = 0;
                     }
                  }

                  trigger_index = j;
                  small_trigger = (t1 < 4);
               }


               Fc1 = 1;
   
               mu1 = mu[k][j];
               if (mu1 >= 0)
                  mu1 = ceil(mu1-half);
               else
                  mu1 = floor(mu1+half);
   
   
               xdouble *mu_k = mu[k];
               xdouble *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++)
                     MulSub(mu_k[i], mu_k[i], mu1, mu_j[i]);
               }
  
               mu_k[j] -= mu1;

               conv(MU, mu1);

               // cout << j << " " << MU << "\n";
   
               RowTransform(B(k), B(j), MU);
               if (U) RowTransform((*U)(k), (*U)(j), MU);
            }
         }

         if (Fc1) {
            for (i = 1; i <= n; i++)
               conv(B1[k][i], B(k, i));
   
            b[k] = InnerProduct(B1[k], B1[k], n);
            ComputeGS(B, B1, mu, b, c, k, bound, 1, buf);
         }
      } while (Fc1);

      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;
            if (U) swap((*U)(i), (*U)(i+1));
         }

         for (i = k; i <= m+1; i++) st[i] = 1;

         m--;
         if (quit) break;
         continue;
      }

      if (quit) break;

      if (deep > 0) {
         // deep insertions
   
         xdouble 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;
               if (U) swap((*U)(i), (*U)(i-1));
            }
   
            k = l;
            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;
         if (U) swap((*U)(k), (*U)(k-1));

         k--;
         NumSwaps++;

         // cout << "- " << k << "\n";
      }
      else {
         k++;
         // cout << "+ " << k << "\n";
      }
   }

   if (verbose) {
      LLLStatus(m+1, GetTime(), m, B);
   }


   return m;
}
Beispiel #22
0
void solve1(ZZ& d_out, vec_ZZ& x_out, const mat_ZZ& A, const vec_ZZ& b)
{
   long n = A.NumRows();

   if (A.NumCols() != n)
      LogicError("solve1: nonsquare matrix");

   if (b.length() != n)
      LogicError("solve1: dimension mismatch");

   if (n == 0) {
      set(d_out);
      x_out.SetLength(0);
      return;
   }

   ZZ num_bound, den_bound;

   hadamard(num_bound, den_bound, A, b);

   if (den_bound == 0) {
      clear(d_out);
      return;
   }

   zz_pBak zbak;
   zbak.save();

   long i;
   long j;

   ZZ prod;
   prod = 1;

   mat_zz_p B;


   for (i = 0; ; i++) {
      zz_p::FFTInit(i);

      mat_zz_p AA, BB;
      zz_p dd;

      conv(AA, A);
      inv(dd, BB, AA);

      if (dd != 0) {
         transpose(B, BB);
         break;
      }

      mul(prod, prod, zz_p::modulus());
      
      if (prod > den_bound) {
         d_out = 0;
         return;
      }
   }

   long max_A_len = MaxBits(A);

   long use_double_mul1 = 0;
   long use_double_mul2 = 0;
   long double_limit = 0;

   if (max_A_len + NTL_SP_NBITS + NumBits(n) <= NTL_DOUBLE_PRECISION-1)
      use_double_mul1 = 1;

   if (!use_double_mul1 && max_A_len+NTL_SP_NBITS+2 <= NTL_DOUBLE_PRECISION-1) {
      use_double_mul2 = 1;
      double_limit = (1L << (NTL_DOUBLE_PRECISION-1-max_A_len-NTL_SP_NBITS));
   }

   long use_long_mul1 = 0;
   long use_long_mul2 = 0;
   long long_limit = 0;

   if (max_A_len + NTL_SP_NBITS + NumBits(n) <= NTL_BITS_PER_LONG-1)
      use_long_mul1 = 1;

   if (!use_long_mul1 && max_A_len+NTL_SP_NBITS+2 <= NTL_BITS_PER_LONG-1) {
      use_long_mul2 = 1;
      long_limit = (1L << (NTL_BITS_PER_LONG-1-max_A_len-NTL_SP_NBITS));
   }



   if (use_double_mul1 && use_long_mul1)
      use_long_mul1 = 0;
   else if (use_double_mul1 && use_long_mul2)
      use_long_mul2 = 0;
   else if (use_double_mul2 && use_long_mul1)
      use_double_mul2 = 0;
   else if (use_double_mul2 && use_long_mul2) {
      if (long_limit > double_limit)
         use_double_mul2 = 0;
      else
         use_long_mul2 = 0;
   }


   double **double_A=0;
   double *double_h=0;

   Unique2DArray<double> double_A_store;
   UniqueArray<double> double_h_store;


   if (use_double_mul1 || use_double_mul2) {
      double_h_store.SetLength(n);
      double_h = double_h_store.get();

      double_A_store.SetDims(n, n);
      double_A = double_A_store.get();

      for (i = 0; i < n; i++)
         for (j = 0; j < n; j++)
            double_A[j][i] = to_double(A[i][j]);
   }

   long **long_A=0;
   long *long_h=0;

   Unique2DArray<long> long_A_store;
   UniqueArray<long> long_h_store;


   if (use_long_mul1 || use_long_mul2) {
      long_h_store.SetLength(n);
      long_h = long_h_store.get();

      long_A_store.SetDims(n, n);
      long_A = long_A_store.get();

      for (i = 0; i < n; i++)
         for (j = 0; j < n; j++)
            long_A[j][i] = to_long(A[i][j]);
   }


   vec_ZZ x;
   x.SetLength(n);

   vec_zz_p h;
   h.SetLength(n);

   vec_ZZ e;
   e = b;

   vec_zz_p ee;

   vec_ZZ t;
   t.SetLength(n);

   prod = 1;

   ZZ bound1;
   mul(bound1, num_bound, den_bound);
   mul(bound1, bound1, 2);

   while (prod <= bound1) {
      conv(ee, e);

      mul(h, B, ee);

      if (use_double_mul1) {
         for (i = 0; i < n; i++)
            double_h[i] = to_double(rep(h[i]));

         double_MixedMul1(t, double_h, double_A, n);
      }
      else if (use_double_mul2) {
         for (i = 0; i < n; i++)
            double_h[i] = to_double(rep(h[i]));

         double_MixedMul2(t, double_h, double_A, n, double_limit);
      }
      else if (use_long_mul1) {
         for (i = 0; i < n; i++)
            long_h[i] = to_long(rep(h[i]));

         long_MixedMul1(t, long_h, long_A, n);
      }
      else if (use_long_mul2) {
         for (i = 0; i < n; i++)
            long_h[i] = to_long(rep(h[i]));

         long_MixedMul2(t, long_h, long_A, n, long_limit);
      }
      else
         MixedMul(t, h, A); // t = h*A

      SubDiv(e, t, zz_p::modulus()); // e = (e-t)/p
      MulAdd(x, prod, h);  // x = x + prod*h

      mul(prod, prod, zz_p::modulus());
   }

   vec_ZZ num, denom;
   ZZ d, d_mod_prod, tmp1;

   num.SetLength(n);
   denom.SetLength(n);
 
   d = 1;
   d_mod_prod = 1;

   for (i = 0; i < n; i++) {
      rem(x[i], x[i], prod);
      MulMod(x[i], x[i], d_mod_prod, prod);

      if (!ReconstructRational(num[i], denom[i], x[i], prod, 
           num_bound, den_bound))
          LogicError("solve1 internal error: rat recon failed!");

      mul(d, d, denom[i]);

      if (i != n-1) {
         if (denom[i] != 1) {
            div(den_bound, den_bound, denom[i]); 
            mul(bound1, num_bound, den_bound);
            mul(bound1, bound1, 2);

            div(tmp1, prod, zz_p::modulus());
            while (tmp1 > bound1) {
               prod = tmp1;
               div(tmp1, prod, zz_p::modulus());
            }

            rem(tmp1, denom[i], prod);
            rem(d_mod_prod, d_mod_prod, prod);
            MulMod(d_mod_prod, d_mod_prod, tmp1, prod);
         }
      }
   }

   tmp1 = 1;
   for (i = n-1; i >= 0; i--) {
      mul(num[i], num[i], tmp1);
      mul(tmp1, tmp1, denom[i]);
   }
   
   x_out.SetLength(n);

   for (i = 0; i < n; i++) {
      x_out[i] = num[i];
   }

   d_out = d;
}
Beispiel #23
0
static
long LLL_XD(mat_ZZ& B, mat_ZZ* U, xdouble delta, long deep, 
           LLLCheckFct check)
{
   long m = B.NumRows();
   long n = B.NumCols();

   long i, j;
   long new_m, dep, quit;
   xdouble s;
   ZZ MU;
   xdouble mu1;

   xdouble t1;
   ZZ T1;

   init_red_fudge();

   if (U) ident(*U, m);

   xdouble **B1;  // approximates B

   typedef xdouble *xdoubleptr;

   B1 = NTL_NEW_OP xdoubleptr[m+1];
   if (!B1) Error("LLL_XD: out of memory");

   for (i = 1; i <= m; i++) {
      B1[i] = NTL_NEW_OP xdouble[n+1];
      if (!B1[i]) Error("LLL_XD: out of memory");
   }

   xdouble **mu;
   mu = NTL_NEW_OP xdoubleptr[m+1];
   if (!mu) Error("LLL_XD: out of memory");

   for (i = 1; i <= m; i++) {
      mu[i] = NTL_NEW_OP xdouble[m+1];
      if (!mu[i]) Error("LLL_XD: out of memory");
   }

   xdouble *c; // squared lengths of Gramm-Schmidt basis vectors

   c = NTL_NEW_OP xdouble[m+1];
   if (!c) Error("LLL_XD: out of memory");

   xdouble *b; // squared lengths of basis vectors

   b = NTL_NEW_OP xdouble[m+1];
   if (!b) Error("LLL_XD: 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);
   }


   new_m = ll_LLL_XD(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+dep; i++) {
      delete [] B1[i];
   }

   delete [] B1;

   for (i = 1; i <= m+dep; i++) {
      delete [] mu[i];
   }

   delete [] mu;

   delete [] c;

   delete [] b;

   return m;
}
void CharPoly(ZZX& gg, const mat_ZZ& a, long deterministic)
{
   long n = a.NumRows();
   if (a.NumCols() != n)
      LogicError("CharPoly: nonsquare matrix");

   if (n == 0) {
      set(gg);
      return;
   }


   if (n == 1) {
      ZZ t;
      SetX(gg);
      negate(t, a(1, 1));
      SetCoeff(gg, 0, t);
      return;
   }

   long bound = 2 + CharPolyBound(a);

   zz_pBak bak;
   bak.save();

   ZZ_pBak bak1;
   bak1.save();

   ZZX g;
   ZZ prod;

   clear(g);
   set(prod);

   long i;

   long instable = 1;

   long gp_cnt = 0;

   for (i = 0; ; i++) {
      if (NumBits(prod) > bound)
         break;

      if (!deterministic &&
          !instable && bound > 1000 && NumBits(prod) < 0.25*bound) {
         long plen = 90 + NumBits(max(bound, MaxBits(g)));

         ZZ P;

         GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++));

         ZZ_p::init(P);
         mat_ZZ_p A;
         ZZ_pX G;
         conv(A, a);
         CharPoly(G, A);

         if (CRT(g, prod, G))
            instable = 1;
         else
            break;
      }

      zz_p::FFTInit(i);

      mat_zz_p A;
      zz_pX G;
      conv(A, a);
      CharPoly(G, A);
      instable = CRT(g, prod, G);
   }

   gg = g;

   bak.restore();
   bak1.restore();
}
Beispiel #25
0
void solve1(ZZ& d_out, vec_ZZ& x_out, const mat_ZZ& A, const vec_ZZ& b)
{
    long n = A.NumRows();

    if (A.NumCols() != n)
        Error("solve1: nonsquare matrix");

    if (b.length() != n)
        Error("solve1: dimension mismatch");

    if (n == 0) {
        set(d_out);
        x_out.SetLength(0);
        return;
    }

    ZZ num_bound, den_bound;

    hadamard(num_bound, den_bound, A, b);

    if (den_bound == 0) {
        clear(d_out);
        return;
    }

    zz_pBak zbak;
    zbak.save();

    long i;
    long j;

    ZZ prod;
    prod = 1;

    mat_zz_p B;


    for (i = 0; ; i++) {
        zz_p::FFTInit(i);

        mat_zz_p AA, BB;
        zz_p dd;

        conv(AA, A);
        inv(dd, BB, AA);

        if (dd != 0) {
            transpose(B, BB);
            break;
        }

        mul(prod, prod, zz_p::modulus());

        if (prod > den_bound) {
            d_out = 0;
            return;
        }
    }

    long max_A_len = MaxBits(A);

    long use_double_mul1 = 0;
    long use_double_mul2 = 0;
    long double_limit = 0;

    if (max_A_len + NTL_SP_NBITS + NumBits(n) <= NTL_DOUBLE_PRECISION-1)
        use_double_mul1 = 1;

    if (!use_double_mul1 && max_A_len+NTL_SP_NBITS+2 <= NTL_DOUBLE_PRECISION-1) {
        use_double_mul2 = 1;
        double_limit = (1L << (NTL_DOUBLE_PRECISION-1-max_A_len-NTL_SP_NBITS));
    }

    long use_long_mul1 = 0;
    long use_long_mul2 = 0;
    long long_limit = 0;

    if (max_A_len + NTL_SP_NBITS + NumBits(n) <= NTL_BITS_PER_LONG-1)
        use_long_mul1 = 1;

    if (!use_long_mul1 && max_A_len+NTL_SP_NBITS+2 <= NTL_BITS_PER_LONG-1) {
        use_long_mul2 = 1;
        long_limit = (1L << (NTL_BITS_PER_LONG-1-max_A_len-NTL_SP_NBITS));
    }



    if (use_double_mul1 && use_long_mul1)
        use_long_mul1 = 0;
    else if (use_double_mul1 && use_long_mul2)
        use_long_mul2 = 0;
    else if (use_double_mul2 && use_long_mul1)
        use_double_mul2 = 0;
    else if (use_double_mul2 && use_long_mul2) {
        if (long_limit > double_limit)
            use_double_mul2 = 0;
        else
            use_long_mul2 = 0;
    }


    double **double_A;
    double *double_h;

    typedef double *double_ptr;

    if (use_double_mul1 || use_double_mul2) {
        double_h = NTL_NEW_OP double[n];
        double_A = NTL_NEW_OP double_ptr[n];
        if (!double_h || !double_A) Error("solve1: out of mem");

        for (i = 0; i < n; i++) {
            double_A[i] = NTL_NEW_OP double[n];
            if (!double_A[i]) Error("solve1: out of mem");
        }

        for (i = 0; i < n; i++)
            for (j = 0; j < n; j++)
                double_A[j][i] = to_double(A[i][j]);
    }
Beispiel #26
0
void determinant(ZZ& rres, const mat_ZZ& a, long deterministic)
{
    long n = a.NumRows();
    if (a.NumCols() != n)
        Error("determinant: nonsquare matrix");

    if (n == 0) {
        set(rres);
        return;
    }

    zz_pBak zbak;
    zbak.save();

    ZZ_pBak Zbak;
    Zbak.save();

    long instable = 1;

    long gp_cnt = 0;

    long bound = 2+DetBound(a);

    ZZ res, prod;

    clear(res);
    set(prod);


    long i;
    for (i = 0; ; i++) {
        if (NumBits(prod) > bound)
            break;

        if (!deterministic &&
                !instable && bound > 1000 && NumBits(prod) < 0.25*bound) {
            ZZ P;


            long plen = 90 + NumBits(max(bound, NumBits(res)));
            GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++));

            ZZ_p::init(P);

            mat_ZZ_p A;
            conv(A, a);

            ZZ_p t;
            determinant(t, A);

            if (CRT(res, prod, rep(t), P))
                instable = 1;
            else
                break;
        }


        zz_p::FFTInit(i);
        long p = zz_p::modulus();

        mat_zz_p A;
        conv(A, a);

        zz_p t;
        determinant(t, A);

        instable = CRT(res, prod, rep(t), p);
    }

    rres = res;

    zbak.restore();
    Zbak.restore();
}
Beispiel #27
0
static
long LLL_XD(mat_ZZ& B, mat_ZZ* U, xdouble delta, long deep, 
           LLLCheckFct check)
{
   long m = B.NumRows();
   long n = B.NumCols();

   long i, j;
   long new_m, dep, quit;
   xdouble s;
   ZZ MU;
   xdouble mu1;

   xdouble t1;
   ZZ T1;

   init_red_fudge();

   if (U) ident(*U, m);

   Unique2DArray<xdouble> B1_store;
   B1_store.SetDimsFrom1(m+1, n+1);
   xdouble **B1 = B1_store.get();  // approximates B


   Unique2DArray<xdouble> mu_store;
   mu_store.SetDimsFrom1(m+1, m+1);
   xdouble **mu = mu_store.get();

   UniqueArray<xdouble> c_store;
   c_store.SetLength(m+1);
   xdouble *c = c_store.get(); // squared lengths of Gramm-Schmidt basis vectors

   UniqueArray<xdouble> b_store;
   b_store.SetLength(m+1);
   xdouble *b = b_store.get(); // squared lengths of basis vectors

   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);
   }


   new_m = ll_LLL_XD(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));
      }
   }

   return m;
}
Beispiel #28
0
void inv(ZZ& d_out, mat_ZZ& x_out, const mat_ZZ& A, long deterministic)
{
    long n = A.NumRows();

    if (A.NumCols() != n)
        Error("solve: nonsquare matrix");

    if (n == 0) {
        set(d_out);
        x_out.SetDims(0, 0);
        return;
    }

    zz_pBak zbak;
    zbak.save();

    ZZ_pBak Zbak;
    Zbak.save();

    mat_ZZ x(INIT_SIZE, n, n);
    ZZ d, d1;

    ZZ d_prod, x_prod;
    set(d_prod);
    set(x_prod);

    long d_instable = 1;
    long x_instable = 1;

    long gp_cnt = 0;

    long check = 0;


    mat_ZZ y;

    long i;
    long bound = 2+DetBound(A);

    for (i = 0; ; i++) {
        if ((check || IsZero(d)) && !d_instable) {
            if (NumBits(d_prod) > bound) {
                break;
            }
            else if (!deterministic &&
                     bound > 1000 && NumBits(d_prod) < 0.25*bound) {

                ZZ P;

                long plen = 90 + NumBits(max(bound, NumBits(d)));
                GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++));

                ZZ_p::init(P);

                mat_ZZ_p AA;
                conv(AA, A);

                ZZ_p dd;
                determinant(dd, AA);

                if (CRT(d, d_prod, rep(dd), P))
                    d_instable = 1;
                else
                    break;
            }
        }


        zz_p::FFTInit(i);
        long p = zz_p::modulus();

        mat_zz_p AA;
        conv(AA, A);

        if (!check) {
            mat_zz_p xx;

            zz_p dd;

            inv(dd, xx, AA);

            d_instable = CRT(d, d_prod, rep(dd), p);
            if (!IsZero(dd)) {
                mul(xx, xx, dd);
                x_instable = CRT(x, x_prod, xx);
            }
            else
                x_instable = 1;

            if (!d_instable && !x_instable) {
                mul(y, x, A);
                if (IsDiag(y, n, d)) {
                    d1 = d;
                    check = 1;
                }
            }
        }
        else {
            zz_p dd;
            determinant(dd, AA);
            d_instable = CRT(d, d_prod, rep(dd), p);
        }
    }

    if (check && d1 != d) {
        mul(x, x, d);
        ExactDiv(x, d1);
    }

    d_out = d;
    if (check) x_out = x;

    zbak.restore();
    Zbak.restore();
}
Beispiel #29
0
static
long BKZ_XD(mat_ZZ& BB, mat_ZZ* UU, xdouble delta, 
         long beta, long prune, LLLCheckFct check)
{
   long m = BB.NumRows();
   long n = BB.NumCols();
   long m_orig = m;
   
   long i, j;
   ZZ MU;

   xdouble t1;
   ZZ T1;
   xdouble *tp;

   init_red_fudge();

   mat_ZZ B;
   B = BB;

   B.SetDims(m+1, n);

   Unique2DArray<xdouble> B1_store;
   B1_store.SetDimsFrom1(m+2, n+1);
   xdouble **B1 = B1_store.get();  // approximates B


   Unique2DArray<xdouble> mu_store;
   mu_store.SetDimsFrom1(m+2, m+1);
   xdouble **mu = mu_store.get();

   UniqueArray<xdouble> c_store;
   c_store.SetLength(m+2);
   xdouble *c = c_store.get(); // squared lengths of Gramm-Schmidt basis vectors

   UniqueArray<xdouble> b_store;
   b_store.SetLength(m+2);
   xdouble *b = b_store.get(); // squared lengths of basis vectors

   xdouble cbar;


   UniqueArray<xdouble> ctilda_store;
   ctilda_store.SetLength(m+2);
   xdouble *ctilda = ctilda_store.get();


   UniqueArray<xdouble> vvec_store;
   vvec_store.SetLength(m+2);
   xdouble *vvec = vvec_store.get();

   UniqueArray<xdouble> yvec_store;
   yvec_store.SetLength(m+2);
   xdouble *yvec = yvec_store.get();

   UniqueArray<xdouble> uvec_store;
   uvec_store.SetLength(m+2);
   xdouble *uvec = uvec_store.get();

   UniqueArray<xdouble> utildavec_store;
   utildavec_store.SetLength(m+2);
   xdouble *utildavec = utildavec_store.get();

   UniqueArray<long> Deltavec_store;
   Deltavec_store.SetLength(m+2);
   long *Deltavec = Deltavec_store.get();

   UniqueArray<long> deltavec_store;
   deltavec_store.SetLength(m+2);
   long *deltavec = deltavec_store.get();;



   mat_ZZ Ulocal;
   mat_ZZ *U;

   if (UU) {
      Ulocal.SetDims(m+1, m);
      for (i = 1; i <= m; i++)
         conv(Ulocal(i, i), 1);
      U = &Ulocal;
   }
   else
      U = 0;

   long quit;
   long new_m;
   long z, jj, kk;
   long s, t;
   long h;
   xdouble eta;


   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);
   }

   // cerr << "\n";
   // cerr << "first LLL\n";

   m = ll_LLL_XD(B, U, delta, 0, check, B1, mu, b, c, m, 1, quit);

   double tt;

   double enum_time = 0;
   unsigned long NumIterations = 0;
   unsigned long NumTrivial = 0;
   unsigned long NumNonTrivial = 0;
   unsigned long NumNoOps = 0;

   long verb = verbose;

   verbose = 0;



   if (m < m_orig) {
      for (i = m_orig+1; i >= m+2; i--) {
         // swap i, i-1

         swap(B(i), B(i-1));
         if (U) swap((*U)(i), (*U)(i-1));
      }
   }

   long clean = 1;

   if (!quit && m > 1) {
      // cerr << "continuing\n";
      if (beta > m) beta = m;

      if (prune > 0)
         ComputeBKZConstant(beta, prune);

      z = 0;
      jj = 0;
   
      while (z < m-1) {
         jj++;
         kk = min(jj+beta-1, m);
   
         if (jj == m) {
            jj = 1;
            kk = beta;
            clean = 1;
         }

         if (verb) {
            tt = GetTime();
            if (tt > LastTime + LLLStatusInterval)
               BKZStatus(tt, enum_time, NumIterations, NumTrivial,
                         NumNonTrivial, NumNoOps, m, B);
         }

         // ENUM

         double tt1;

         if (verb) {
            tt1 = GetTime();
         }

         if (prune > 0)
            ComputeBKZThresh(&c[jj], kk-jj+1);

         cbar = c[jj];
         utildavec[jj] = uvec[jj] = 1;
   
         yvec[jj] = vvec[jj] = 0;
         Deltavec[jj] = 0;
   
   
         s = t = jj;
         deltavec[jj] = 1;
   
         for (i = jj+1; i <= kk+1; i++) {
            ctilda[i] = uvec[i] = utildavec[i] = yvec[i] = 0;
            Deltavec[i] = 0;
            vvec[i] = 0;
            deltavec[i] = 1;
         }

         long enum_cnt = 0;
   
         while (t <= kk) {
            if (verb) {
               enum_cnt++;
               if (enum_cnt > 100000) {
                  enum_cnt = 0;
                  tt = GetTime();
                  if (tt > LastTime + LLLStatusInterval) {
                     enum_time += tt - tt1;
                     tt1 = tt;
                     BKZStatus(tt, enum_time, NumIterations, NumTrivial,
                               NumNonTrivial, NumNoOps, m, B);
                  }
               }
            }


            ctilda[t] = ctilda[t+1] + 
               (yvec[t]+utildavec[t])*(yvec[t]+utildavec[t])*c[t];

            if (prune > 0 && t > jj) {
               eta = BKZThresh(t-jj);
            }
            else
               eta = 0;
   
            if (ctilda[t] < cbar - eta) {
               if (t > jj) {
                  t--;
                  t1 = 0;
                  for (i = t+1; i <= s; i++) {
                     t1 += utildavec[i]*mu[i][t];
                  }


                  yvec[t] = t1;
                  t1 = -t1;
                  if (t1 >= 0)
                     t1 = ceil(t1-0.5);
                  else
                     t1 = floor(t1+0.5);

                  utildavec[t] = vvec[t] = t1;
                  Deltavec[t] = 0;
                  if (utildavec[t] > -yvec[t]) 
                     deltavec[t] = -1;
                  else
                     deltavec[t] = 1;
               }
               else {
                  cbar = ctilda[jj];
                  for (i = jj; i <= kk; i++) {
                     uvec[i] = utildavec[i];
                  }
               }
            }
            else {
               t++;
               s = max(s, t);
               if (t < s) Deltavec[t] = -Deltavec[t];
               if (Deltavec[t]*deltavec[t] >= 0) Deltavec[t] += deltavec[t];
               utildavec[t] = vvec[t] + Deltavec[t];
            }
         }
         
         if (verb) {
            tt1 = GetTime() - tt1;
            enum_time += tt1;
         }

         NumIterations++;

         h = min(kk+1, m);
   
         if ((delta-8*red_fudge)*c[jj] > cbar) {

            clean = 0;

            // we treat the case that the new vector is b_s (jj < s <= kk)
            // as a special case that appears to occur most of the time.
   
            s = 0;
            for (i = jj+1; i <= kk; i++) {
               if (uvec[i] != 0) {
                  if (s == 0)
                     s = i;
                  else
                     s = -1;
               }
            }
   
            if (s == 0) LogicError("BKZ_XD: internal error");
   
            if (s > 0) {
               // special case

               NumTrivial++;
   
               for (i = s; i > jj; i--) {
                  // swap i, i-1
                  swap(B(i-1), B(i));
                  if (U) swap((*U)(i-1), (*U)(i));
                  tp = B1[i-1]; B1[i-1] = B1[i]; B1[i] = tp;
                  t1 = b[i-1]; b[i-1] = b[i]; b[i] = t1;
               }
   
               // cerr << "special case\n";
               new_m = ll_LLL_XD(B, U, delta, 0, check, 
                                B1, mu, b, c, h, jj, quit);
               if (new_m != h) LogicError("BKZ_XD: internal error");
               if (quit) break;
            }
            else {
               // the general case

               NumNonTrivial++;
   
               for (i = 1; i <= n; i++) conv(B(m+1, i), 0);

               if (U) {
                  for (i = 1; i <= m_orig; i++)
                     conv((*U)(m+1, i), 0);
               }

               for (i = jj; i <= kk; i++) {
                  if (uvec[i] == 0) continue;
                  conv(MU, uvec[i]);
                  RowTransform2(B(m+1), B(i), MU);
                  if (U) RowTransform2((*U)(m+1), (*U)(i), MU);
               }
      
               for (i = m+1; i >= jj+1; i--) {
                  // swap i, i-1
                  swap(B(i-1), B(i));
                  if (U) swap((*U)(i-1), (*U)(i));
                  tp = B1[i-1]; B1[i-1] = B1[i]; B1[i] = tp;
                  t1 = b[i-1]; b[i-1] = b[i]; b[i] = t1;
               }
      
               for (i = 1; i <= n; i++)
                  conv(B1[jj][i], B(jj, i));
      
               b[jj] = InnerProduct(B1[jj], B1[jj], n);
      
               if (b[jj] == 0) LogicError("BKZ_XD: internal error"); 
      
               // remove linear dependencies
   
               // cerr << "general case\n";
               new_m = ll_LLL_XD(B, U, delta, 0, 0, B1, mu, b, c, kk+1, jj, quit);
              
               if (new_m != kk) LogicError("BKZ_XD: internal error"); 

               // remove zero vector
      
               for (i = kk+2; i <= m+1; i++) {
                  // swap i, i-1
                  swap(B(i-1), B(i));
                  if (U) swap((*U)(i-1), (*U)(i));
                  tp = B1[i-1]; B1[i-1] = B1[i]; B1[i] = tp;
                  t1 = b[i-1]; b[i-1] = b[i]; b[i] = t1;
               }
      
               quit = 0;
               if (check) {
                  for (i = 1; i <= kk; i++)
                     if ((*check)(B(i))) {
                        quit = 1;
                        break;
                     }
               }

               if (quit) break;
   
               if (h > kk) {
                  // extend reduced basis
   
                  new_m = ll_LLL_XD(B, U, delta, 0, check, 
                                   B1, mu, b, c, h, h, quit);
   
                  if (new_m != h) LogicError("BKZ_XD: internal error");
                  if (quit) break;
               }
            }
   
            z = 0;
         }
         else {
            // LLL_XD
            // cerr << "progress\n";

            NumNoOps++;

            if (!clean) {
               new_m = 
                  ll_LLL_XD(B, U, delta, 0, check, B1, mu, b, c, h, h, quit);
               if (new_m != h) LogicError("BKZ_XD: internal error");
               if (quit) break;
            }
   
            z++;
         }
      }
   }

   if (verb) {
      BKZStatus(GetTime(), enum_time, NumIterations, NumTrivial, NumNonTrivial,
                NumNoOps, m, B);
   }


   // clean up

   if (m_orig > m) {
      // for consistency, we move zero vectors to the front

      for (i = m+1; i <= m_orig; i++) {
         swap(B(i), B(i+1));
         if (U) swap((*U)(i), (*U)(i+1));
      }

      for (i = 0; i < m; i++) {
         swap(B(m_orig-i), B(m-i));
         if (U) swap((*U)(m_orig-i), (*U)(m-i));
      }
   }

   B.SetDims(m_orig, n);
   BB = B;

   if (U) {
      U->SetDims(m_orig, m_orig);
      *UU = *U;
   }

   return m;
}
Beispiel #30
0
long CRT(mat_ZZ& gg, ZZ& a, const mat_zz_p& G)
{
    long n = gg.NumRows();
    long m = gg.NumCols();

    if (G.NumRows() != n || G.NumCols() != m)
        Error("CRT: dimension mismatch");

    long p = zz_p::modulus();

    ZZ new_a;
    mul(new_a, a, p);

    long a_inv;
    a_inv = rem(a, p);
    a_inv = InvMod(a_inv, p);

    long p1;
    p1 = p >> 1;

    ZZ a1;
    RightShift(a1, a, 1);

    long p_odd = (p & 1);

    long modified = 0;

    long h;

    ZZ g;
    long i, j;

    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            if (!CRTInRange(gg[i][j], a)) {
                modified = 1;
                rem(g, gg[i][j], a);
                if (g > a1) sub(g, g, a);
            }
            else
                g = gg[i][j];

            h = rem(g, p);
            h = SubMod(rep(G[i][j]), h, p);
            h = MulMod(h, a_inv, p);
            if (h > p1)
                h = h - p;

            if (h != 0) {
                modified = 1;

                if (!p_odd && g > 0 && (h == p1))
                    MulSubFrom(g, a, h);
                else
                    MulAddTo(g, a, h);

            }

            gg[i][j] = g;
        }
    }

    a = new_a;

    return modified;

}