Esempio n. 1
0
int test_defaults_dp() {
  dgs_disc_gauss_dp_t *self;
  self = dgs_disc_gauss_dp_init(3.0, 0, 6, DGS_DISC_GAUSS_DEFAULT);
  if (self->algorithm != DGS_DISC_GAUSS_UNIFORM_TABLE)
    dgs_die("automatic choice of uniform table algorithm failed (%d)", self->algorithm);
  dgs_disc_gauss_dp_clear(self);

  self = dgs_disc_gauss_dp_init(3.0, 0, 1<<10, DGS_DISC_GAUSS_DEFAULT);
  if (self->algorithm != DGS_DISC_GAUSS_UNIFORM_TABLE)
    dgs_die("automatic choice of uniform table algorithm failed (%d)", self->algorithm);
  dgs_disc_gauss_dp_clear(self);

  self = dgs_disc_gauss_dp_init(3.0, 0, 1<<14, DGS_DISC_GAUSS_DEFAULT);
  if (self->algorithm != DGS_DISC_GAUSS_UNIFORM_LOGTABLE)
    dgs_die("automatic choice of uniform table algorithm failed (%d)", self->algorithm);
  dgs_disc_gauss_dp_clear(self);


  double sigma2 = sqrt(1.0/(2*log(2.0)));
  self = dgs_disc_gauss_dp_init(1024*sigma2, 0, 6, DGS_DISC_GAUSS_DEFAULT);
  if (self->algorithm != DGS_DISC_GAUSS_SIGMA2_LOGTABLE)
    dgs_die("automatic choice of uniform table algorithm failed (%d)", self->algorithm);
  dgs_disc_gauss_dp_clear(self);


  printf("passed\n");
  return 0;
}
Esempio n. 2
0
double run_dp(double sigma, double c, int tau, dgs_disc_gauss_alg_t alg, size_t ntrials, unsigned long long *t) {
  double variance = 0.0;
  gmp_randstate_t state;
  gmp_randinit_default(state);

  dgs_disc_gauss_dp_t *gen = dgs_disc_gauss_dp_init(sigma, c, tau, alg);

  *t =  walltime(0);
  for(size_t i=0; i<ntrials; i++) {
    long r = gen->call(gen);
    variance += ((double)r)*((double)r);
  }
  *t = walltime(*t);

  dgs_disc_gauss_dp_clear(gen);
  gmp_randclear(state);

  variance /= ntrials;
  return sqrt(variance);
}
Esempio n. 3
0
dgs_disc_gauss_dp_t *dgs_disc_gauss_dp_init(double sigma, double c, size_t tau, dgs_disc_gauss_alg_t algorithm) {
    if (sigma <= 0.0)
        dgs_die("sigma must be > 0");
    if (tau == 0)
        dgs_die("tau must be > 0");

    size_t upper_bound;

    dgs_disc_gauss_dp_t *self = (dgs_disc_gauss_dp_t*)calloc(sizeof(dgs_disc_gauss_dp_t),1);
    if (!self) dgs_die("out of memory");

    self->sigma = sigma;
    self->c   = c;
    self->c_z = (long)c;
    self->c_r = self->c - ((double)self->c_z);
    self->tau = tau;

    switch(algorithm) {

    case DGS_DISC_GAUSS_UNIFORM_ONLINE:
        self->call = dgs_disc_gauss_dp_call_uniform_online;

        upper_bound = ceil(self->sigma*tau) + 1;
        self->upper_bound = upper_bound;
        self->upper_bound_minus_one = upper_bound - 1;
        self->two_upper_bound_minus_one = 2*upper_bound - 1;
        self->f = -1.0/(2.0*(self->sigma*self->sigma));
        break;

    case DGS_DISC_GAUSS_UNIFORM_TABLE:
        self->call = dgs_disc_gauss_dp_call_uniform_table;

        upper_bound = ceil(self->sigma*tau) + 1;
        self->upper_bound = upper_bound;
        self->upper_bound_minus_one = upper_bound - 1;
        self->two_upper_bound_minus_one = 2*upper_bound - 1;
        self->B = dgs_bern_uniform_init(0);
        self->f = -1.0/(2.0*(sigma*sigma));

        if(self->c_r == 0) {
            self->call = dgs_disc_gauss_dp_call_uniform_table;
            self->rho = (double*)malloc(sizeof(double)*self->upper_bound);
            if (!self->rho) {
                dgs_disc_gauss_dp_clear(self);
                dgs_die("out of memory");
            }
            for(unsigned long x=0; x<self->upper_bound; x++) {
                self->rho[x] = exp( (((double)x) - self->c_r) * (((double)x) - self->c_r) * self->f);
            }
            self->rho[0]/= 2.0;
        } else {
            self->call = dgs_disc_gauss_dp_call_uniform_table_offset;
            self->rho = (double*)malloc(sizeof(double)*self->two_upper_bound_minus_one);
            if (!self->rho) {
                dgs_disc_gauss_dp_clear(self);
                dgs_die("out of memory");
            }
            long absmax = self->upper_bound_minus_one;
            for(long x=-absmax; x<=absmax; x++) {
                self->rho[x+self->upper_bound_minus_one] = exp( (((double)x) - self->c_r) * (((double)x) - self->c_r) * self->f);
            }
        }
        break;

    case DGS_DISC_GAUSS_UNIFORM_LOGTABLE:
        self->call = dgs_disc_gauss_dp_call_uniform_logtable;

        if (fabs(self->c_r) > DGS_DISC_GAUSS_INTEGER_CUTOFF) {
            dgs_disc_gauss_dp_clear(self);
            dgs_die("algorithm DGS_DISC_GAUSS_UNIFORM_LOGTABLE requires c%1 == 0");
        }
        upper_bound = ceil(self->sigma*tau) + 1;
        self->upper_bound = upper_bound;
        self->upper_bound_minus_one = upper_bound - 1;
        self->two_upper_bound_minus_one = 2*upper_bound - 1;

        _dgs_disc_gauss_dp_init_bexp(self, self->sigma, self->upper_bound);
        break;

    case DGS_DISC_GAUSS_SIGMA2_LOGTABLE: {
        self->call = dgs_disc_gauss_dp_call_sigma2_logtable;

        if (fabs(self->c_r) > DGS_DISC_GAUSS_INTEGER_CUTOFF) {
            dgs_disc_gauss_dp_clear(self);
            dgs_die("algorithm DGS_DISC_GAUSS_SIGMA2_LOGTABLE requires c%1 == 0");
        }

        double sigma2 = sqrt(1.0/(2*log(2.0)));
        double k = sigma/sigma2;
        self->k = round(k);
        self->sigma = self->k * sigma2;

        upper_bound = ceil(self->sigma*tau) + 1;
        self->upper_bound = upper_bound;
        self->upper_bound_minus_one = upper_bound - 1;
        self->two_upper_bound_minus_one = 2*upper_bound - 1;

        _dgs_disc_gauss_dp_init_bexp(self, self->sigma, self->upper_bound);
        self->B = dgs_bern_uniform_init(0);
        self->D2 = dgs_disc_gauss_sigma2p_init();
        break;
    }

    default:
        dgs_disc_gauss_dp_clear(self);
        dgs_die("unknown algorithm %d", algorithm);
    }
    return self;
}