void mul(ZZ_p* x, const ZZ_p* a, const ZZ_p* b, long n)
{
   NTL_ZZRegister(t);
   NTL_ZZRegister(accum);

   long i, j, jmin, jmax;

   long d = 2*n-1;

   for (i = 0; i <= d; i++) {
      jmin = max(0, i-(n-1));
      jmax = min(n-1, i);
      clear(accum);
      for (j = jmin; j <= jmax; j++) {
         mul(t, rep(a[j]), rep(b[i-j]));
         add(accum, accum, t);
      }
      if (i >= n) {
         add(accum, accum, rep(a[i-n]));
         add(accum, accum, rep(b[i-n]));
      }

      conv(x[i], accum);
   }
}
Beispiel #2
0
static void RowTransform2(vec_ZZ& A, vec_ZZ& B, const ZZ& MU1)
// x = x + y*MU
{
   NTL_ZZRegister(T);
   NTL_ZZRegister(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);
      }
   }
}
Beispiel #3
0
void InnerProduct(ZZ_p& x, const vec_ZZ_p& a, const vec_ZZ_p& b)
{
    long n = min(a.length(), b.length());
    long i;
    NTL_ZZRegister(accum);
    NTL_ZZRegister(t);

    clear(accum);
    for (i = 0; i < n; i++) {
        mul(t, rep(a[i]), rep(b[i]));
        add(accum, accum, t);
    }

    conv(x, accum);
}
void InnerProduct(ZZ_pX& x, const vec_ZZ_p& v, long low, long high, 
                   const vec_ZZ_pX& H, long n, ZZVec& t)
{
   NTL_ZZRegister(s);
   long i, j;

   for (j = 0; j < n; j++)
      clear(t[j]);

   high = min(high, v.length()-1);
   for (i = low; i <= high; i++) {
      const vec_ZZ_p& h = H[i-low].rep;
      long m = h.length();
      const ZZ& w = rep(v[i]);

      for (j = 0; j < m; j++) {
         mul(s, w, rep(h[j]));
         add(t[j], t[j], s);
      }
   }

   x.rep.SetLength(n);
   for (j = 0; j < n; j++)
      conv(x.rep[j], t[j]);
   x.normalize();
}
Beispiel #5
0
void conv(quad_float& z, const ZZ& a)
{
   double xhi, xlo;

   conv(xhi, a);

   if (!IsFinite(&xhi)) {
      z.hi = xhi;
      z.lo = 0;
      return;
   }

   NTL_ZZRegister(t);

   conv(t, xhi);
   sub(t, a, t);

   conv(xlo, t);

   normalize(z, xhi, xlo);

   // The following is just paranoia.
   if (fabs(z.hi) < NTL_FDOUBLE_PRECISION && z.lo != 0)
      LogicError("internal error: ZZ to quad_float conversion");
} 
Beispiel #6
0
void InnerProduct(ZZ_p& x, const vec_ZZ_p& a, const vec_ZZ_p& b,
                  long offset)
{
    if (offset < 0) LogicError("InnerProduct: negative offset");
    if (NTL_OVERFLOW(offset, 1, 0))
        ResourceError("InnerProduct: offset too big");

    long n = min(a.length(), b.length()+offset);
    long i;
    NTL_ZZRegister(accum);
    NTL_ZZRegister(t);

    clear(accum);
    for (i = offset; i < n; i++) {
        mul(t, rep(a[i]), rep(b[i-offset]));
        add(accum, accum, t);
    }

    conv(x, accum);
}
Beispiel #7
0
void conv(ZZ& z, const quad_float& x)
{ 
   NTL_ZZRegister(t1);
   NTL_ZZRegister(t2);
   NTL_ZZRegister(t3);

   double fhi, flo;

   fhi = floor(x.hi);

   if (fhi == x.hi) {
      flo = floor(x.lo);

      conv(t1, fhi);
      conv(t2, flo);

      add(z, t1, t2);
   }
   else
      conv(z, fhi);
}
Beispiel #8
0
void conv(ZZ_p& x, long a)
{
   if (a == 0)
      clear(x);
   else if (a == 1)
      set(x);
   else {
      NTL_ZZRegister(y);

      conv(y, a);
      conv(x, y);
   }
}
Beispiel #9
0
void div(RR& z, const RR& a, const RR& b)
{
   if (IsZero(b))
      ArithmeticError("RR: division by zero");

   if (IsZero(a)) {
      clear(z);
      return;
   }

   long la = NumBits(a.x);
   long lb = NumBits(b.x);

   long neg = (sign(a) != sign(b));

   long k = RR::prec - la + lb + 1;
   if (k < 0) k = 0;

   NTL_TLS_LOCAL(RR, t);
   NTL_ZZRegister(A);
   NTL_ZZRegister(B);
   NTL_ZZRegister(R);

   abs(A, a.x);
   LeftShift(A, A, k);

   abs(B, b.x);
   DivRem(t.x, R, A, B);

   t.e = a.e - b.e - k;

   normalize(z, t, !IsZero(R));

   if (neg)
      negate(z.x, z.x);
}
Beispiel #10
0
void conv(RR& z, unsigned long a)
{
   if (a == 0) {
      clear(z);
      return;
   }

   if (a == 1) {
      set(z);
      return;
   }

   NTL_ZZRegister(t);
   conv(t, a);
   conv(z, t);
}
Beispiel #11
0
void conv(RR& z, long a)
{
   if (a == 0) {
      clear(z);
      return;
   }

   if (a == 1) {
      set(z);
      return;
   }

   NTL_ZZRegister(t);
   t = a;
   conv(z, t);
}
Beispiel #12
0
void power(xdouble& z, const xdouble& a, long e)
{
   NTL_ZZRegister(E);
   E = e;
   power(z, a, E);
}
void mul(ZZ_pX& U, ZZ_pX& V, const ZZ_pXMatrix& M)
// (U, V)^T = M*(U, V)^T
{
   long d = deg(U) - deg(M(1,1));
   long k = NextPowerOfTwo(d - 1);

   // When the GCD algorithm is run on polynomials of degree n, n-1, 
   // where n is a power of two, then d-1 is likely to be a power of two.
   // It would be more natural to set k = NextPowerOfTwo(d+1), but this
   // would be much less efficient in this case.

   // We optimize this case, as it does sometimes arise naturally
   // in some situations.

   long n = (1L << k);
   long xx;
   ZZ_p a0, a1, b0, b1, c0, d0, u0, u1, v0, v1, nu0, nu1, nv0;
   NTL_ZZRegister(t1);
   NTL_ZZRegister(t2);

   if (n == d-1)
      xx = 1;
   else if (n == d)
      xx = 2;
   else 
      xx = 3;

   switch (xx) {
   case 1:
      GetCoeff(a0, M(0,0), 0);
      GetCoeff(a1, M(0,0), 1);
      GetCoeff(b0, M(0,1), 0);
      GetCoeff(b1, M(0,1), 1);
      GetCoeff(c0, M(1,0), 0);
      GetCoeff(d0, M(1,1), 0);

      GetCoeff(u0, U, 0);
      GetCoeff(u1, U, 1);
      GetCoeff(v0, V, 0);
      GetCoeff(v1, V, 1);

      mul(t1, rep(a0), rep(u0));
      mul(t2, rep(b0), rep(v0));
      add(t1, t1, t2); 
      conv(nu0, t1);

      mul(t1, rep(a1), rep(u0));
      mul(t2, rep(a0), rep(u1));
      add(t1, t1, t2);
      mul(t2, rep(b1), rep(v0));
      add(t1, t1, t2);
      mul(t2, rep(b0), rep(v1));
      add(t1, t1, t2);
      conv(nu1, t1);

      mul(t1, rep(c0), rep(u0));
      mul(t2, rep(d0), rep(v0));
      add (t1, t1, t2);
      conv(nv0, t1);
   
      break;

   case 2:
      GetCoeff(a0, M(0,0), 0);
      GetCoeff(b0, M(0,1), 0);

      GetCoeff(u0, U, 0);
      GetCoeff(v0, V, 0);

      mul(t1, rep(a0), rep(u0));
      mul(t2, rep(b0), rep(v0));
      add(t1, t1, t2); 
      conv(nu0, t1);

      break;

   case 3:
      break;

   }

   FFTRep RU(INIT_SIZE, k), RV(INIT_SIZE, k), R1(INIT_SIZE, k), 
          R2(INIT_SIZE, k);

   ToFFTRep(RU, U, k);  
   ToFFTRep(RV, V, k);  

   ToFFTRep(R1, M(0,0), k);
   mul(R1, R1, RU);
   ToFFTRep(R2, M(0,1), k);
   mul(R2, R2, RV);
   add(R1, R1, R2);
   FromFFTRep(U, R1, 0, d);

   ToFFTRep(R1, M(1,0), k);
   mul(R1, R1, RU);
   ToFFTRep(R2, M(1,1), k);
   mul(R2, R2, RV);
   add(R1, R1, R2);
   FromFFTRep(V, R1, 0, d-1);

   // now fix-up results

   switch (xx) {
   case 1:
      GetCoeff(u0, U, 0);
      sub(u0, u0, nu0);
      SetCoeff(U, d-1, u0);
      SetCoeff(U, 0, nu0);

      GetCoeff(u1, U, 1);
      sub(u1, u1, nu1);
      SetCoeff(U, d, u1);
      SetCoeff(U, 1, nu1);

      GetCoeff(v0, V, 0);
      sub(v0, v0, nv0);
      SetCoeff(V, d-1, v0);
      SetCoeff(V, 0, nv0);

      break;
      

   case 2:
      GetCoeff(u0, U, 0);
      sub(u0, u0, nu0);
      SetCoeff(U, d, u0);
      SetCoeff(U, 0, nu0);

      break;

   }
}