Example #1
0
int count_significance_digit(Float a) {
	for (int i = 0; i < 30; i++) {
		if (roundto(a, i) == a) {
			return i;
		}
	}
	return -1;
}
Example #2
0
void EnumerationDyn<FT>::prepare_enumeration(const vector<enumxt> &subtree, bool solvingsvp,
                                             bool subtree_reset)
{
  is_svp = solvingsvp;

  enumf newdist = 0.0;
  k_end         = d - subtree.size();
  for (k = d - 1; k >= 0 && newdist <= maxdist; --k)
  {
    enumf newcenter = center_partsum[k];
    if (k >= k_end)
    {
      // use subtree
      x[k] = subtree[k - k_end];

      if (x[k] != 0)
        is_svp = false;

      for (int j = 0; j < k; ++j)
        center_partsum[j] -= x[k] * mut[j][k];
    }
    else
    {
      if (dual)
      {
        for (int j = k + 1; j < k_end; ++j)
          newcenter -= alpha[j] * mut[k][j];
      }
      else
      {
        for (int j = k + 1; j < k_end; ++j)
          newcenter -= x[j] * mut[k][j];
      }
      roundto(x[k], newcenter);  // newX = rint(newCenter) / lrint(newCenter)
      center[k]   = newcenter;
      partdist[k] = newdist;
      dx[k] = ddx[k] = (((int)(newcenter >= x[k]) & 1) << 1) - 1;
    }
    if (!subtree_reset || k < k_end)
    {
      alpha[k] = x[k] - newcenter;
      newdist += alpha[k] * alpha[k] * rdiag[k];
    }
  }
  if (!is_svp)
  {
    k_max = k_end;  // The last non-zero coordinate of x will not stay positive
  }
  else
  {
    k_max = 0;
    x[0]  = 1;  // Excludes (0,...,0) from the enumeration
  }
  ++k;
}
Example #3
0
inline void EnumerationBase::enumerate_recursive(
    EnumerationBase::opts<kk, kk_start, dualenum, findsubsols, enable_reset>)
{
  enumf alphak  = x[kk] - center[kk];
  enumf newdist = partdist[kk] + alphak * alphak * rdiag[kk];

  if (!(newdist <= partdistbounds[kk]))
    return;
  ++nodes;

  alpha[kk] = alphak;
  if (findsubsols && newdist < subsoldists[kk])
  {
    subsoldists[kk] = newdist;
    process_subsolution(kk, newdist);
  }

  if (kk == 0)
  {
    if (newdist > 0.0 || !is_svp)
      process_solution(newdist);
  }
  else if (enable_reset &&
           kk < reset_depth)  // in CVP, below the max GS vector, we reset the partial distance
  {
    reset(newdist, kk);
    return;
  }
  else
  {
    partdist[kk - 1] = newdist;
    if (dualenum)
    {
      for (int j                   = center_partsum_begin[kk]; j > kk - 1; --j)
        center_partsums[kk - 1][j] = center_partsums[kk - 1][j + 1] - alpha[j] * mut[kk - 1][j];
    }
    else
    {
      for (int j                   = center_partsum_begin[kk]; j > kk - 1; --j)
        center_partsums[kk - 1][j] = center_partsums[kk - 1][j + 1] - x[j] * mut[kk - 1][j];
    }
    if (center_partsum_begin[kk] > center_partsum_begin[kk - 1])
      center_partsum_begin[kk - 1] = center_partsum_begin[kk];
    center_partsum_begin[kk]       = kk;
    center[kk - 1]                 = center_partsums[kk - 1][kk];
    roundto(x[kk - 1], center[kk - 1]);
    dx[kk - 1] = ddx[kk - 1] = (((int)(center[kk - 1] >= x[kk - 1]) & 1) << 1) - 1;
  }

  while (true)
  {
    FPLLL_TRACE("Level k=" << kk << " dist_k=" << partdist[kk] << " x_k=" << x[kk]
                           << " newdist=" << newdist << " partdistbounds_k=" << partdistbounds[kk]);
    enumerate_recursive(opts<kk - 1, kk_start, dualenum, findsubsols, enable_reset>());

    if (partdist[kk] != 0.0)
    {
      x[kk] += dx[kk];
      ddx[kk] = -ddx[kk];
      dx[kk]  = ddx[kk] - dx[kk];

      enumf alphak2  = x[kk] - center[kk];
      enumf newdist2 = partdist[kk] + alphak2 * alphak2 * rdiag[kk];
      if (!(newdist2 <= partdistbounds[kk]))
        return;
      ++nodes;
      alpha[kk] = alphak2;
      if (kk == 0)
      {
        if (newdist2 > 0.0 || !is_svp)
          process_solution(newdist2);
      }
      else
      {
        partdist[kk - 1] = newdist2;
        if (dualenum)
          center_partsums[kk - 1][kk - 1 + 1] =
              center_partsums[kk - 1][kk - 1 + 1 + 1] - alpha[kk - 1 + 1] * mut[kk - 1][kk - 1 + 1];
        else
          center_partsums[kk - 1][kk - 1 + 1] =
              center_partsums[kk - 1][kk - 1 + 1 + 1] - x[kk - 1 + 1] * mut[kk - 1][kk - 1 + 1];
        if (kk > center_partsum_begin[kk - 1])
          center_partsum_begin[kk - 1] = kk;
        center[kk - 1]                 = center_partsums[kk - 1][kk - 1 + 1];
        roundto(x[kk - 1], center[kk - 1]);
        dx[kk - 1] = ddx[kk - 1] = (((int)(center[kk - 1] >= x[kk - 1]) & 1) << 1) - 1;
      }
    }
    else
    {
      ++x[kk];

      enumf alphak2  = x[kk] - center[kk];
      enumf newdist2 = partdist[kk] + alphak2 * alphak2 * rdiag[kk];
      if (!(newdist2 <= partdistbounds[kk]))
        return;
      ++nodes;
      alpha[kk] = alphak2;
      if (kk == 0)
      {
        if (newdist2 > 0.0 || !is_svp)
          process_solution(newdist2);
      }
      else
      {
        partdist[kk - 1] = newdist2;
        if (dualenum)
          center_partsums[kk - 1][kk - 1 + 1] =
              center_partsums[kk - 1][kk - 1 + 1 + 1] - alpha[kk - 1 + 1] * mut[kk - 1][kk - 1 + 1];
        else
          center_partsums[kk - 1][kk - 1 + 1] =
              center_partsums[kk - 1][kk - 1 + 1 + 1] - x[kk - 1 + 1] * mut[kk - 1][kk - 1 + 1];
        if (kk > center_partsum_begin[kk - 1])
          center_partsum_begin[kk - 1] = kk;
        center[kk - 1]                 = center_partsums[kk - 1][kk - 1 + 1];
        roundto(x[kk - 1], center[kk - 1]);
        dx[kk - 1] = ddx[kk - 1] = (((int)(center[kk - 1] >= x[kk - 1]) & 1) << 1) - 1;
      }
    }
  }
}
Example #4
0
template <bool dualenum, bool findsubsols, bool enable_reset> void EnumerationBase::enumerate_loop()
{
  if (k >= k_end)
    return;

  for (int i = 0; i < k_end; ++i)
  {
    center_partsum_begin[i + 1] = k_end - 1;
    center_partsums[i][k_end]   = center_partsum[i];
  }

  partdist[k_end] = 0.0;  // needed to make next_pos_up() work properly

  nodes -= k_end - k;
  k = k_end - 1;

#ifdef FPLLL_WITH_RECURSIVE_ENUM
  enumerate_recursive_dispatch<dualenum, findsubsols, enable_reset>(k);
  return;
#endif

  finished = false;
  while (!finished)
  {
    enumf alphak  = x[k] - center[k];
    enumf newdist = partdist[k] + alphak * alphak * rdiag[k];
    FPLLL_TRACE("Level k=" << k << " dist_k=" << partdist[k] << " x_k=" << x[k]
                           << " newdist=" << newdist << " partdistbounds_k=" << partdistbounds[k]);
    if (newdist <= partdistbounds[k])
    {
      ++nodes;
      alpha[k] = alphak;
      if (findsubsols && newdist < subsoldists[k])
      {
        subsoldists[k] = newdist;
        process_subsolution(k, newdist);
      }
      --k;
      if (k < 0)
      {
        if (newdist > 0.0 || !is_svp)
          process_solution(newdist);
        finished = !next_pos_up();
        continue;
      }
      if (enable_reset &&
          k < reset_depth)  // in CVP, below the max GS vector, we reset the partial distance
      {
        reset(newdist, k);
        finished = !next_pos_up();
        continue;
      }
      if (dualenum)
      {
        for (int j              = center_partsum_begin[k + 1]; j > k; --j)
          center_partsums[k][j] = center_partsums[k][j + 1] - alpha[j] * mut[k][j];
      }
      else
      {
        for (int j              = center_partsum_begin[k + 1]; j > k; --j)
          center_partsums[k][j] = center_partsums[k][j + 1] - x[j] * mut[k][j];
      }
      center_partsum_begin[k]     = max(center_partsum_begin[k], center_partsum_begin[k + 1]);
      center_partsum_begin[k + 1] = k + 1;

      enumf newcenter = center_partsums[k][k + 1];
      center[k]       = newcenter;
      partdist[k]     = newdist;
      roundto(x[k], newcenter);
      dx[k] = ddx[k] = (((int)(newcenter >= x[k]) & 1) << 1) - 1;
    }
    else
    {
      finished = !next_pos_up();
    }
  }
}