#include #include #include #include "oracles.h" #include "utils.h" double bernoulli_extent_generator (const gsl_rng* r, double p, double r0, double r1) { return gsl_ran_bernoulli(r, p) ? r1 : r0; } double bernoulli_true_volume (double p, double r0, double r1, unsigned int dimension) { return volume_of_ball(dimension) * (p * gsl_pow_uint(r1, dimension) + (1 - p) * gsl_pow_uint(r0, dimension)); } double uniform_extent_generator (const gsl_rng* r, double a, double b) { return gsl_ran_flat(r, a, b); } // TODO: Verify the accuracy of this function for non-trivial a, b double uniform_true_volume (double a, double b, unsigned int dimension) { return exp(ln_volume_of_ball(dimension) + dimension*log(b) - log(dimension + 1)) - exp(ln_volume_of_ball(dimension) + dimension*log(a) - log(dimension + 1)); } double beta_extent_generator (const gsl_rng* r, double alpha, double beta) { return gsl_ran_beta(r, alpha, beta); } double beta_true_volume (double alpha, double beta, unsigned int dimension) { double vol = volume_of_ball(dimension); for (unsigned int r=0; r 0) && (angle < max_angle) ? base / cos(angle) : 0; } double right_triangle_true_volume (double base, double height) { return 0.5 * base * height; } double sphere_extent_oracle (const gsl_vector* x, double radius) { return radius; } double sphere_maximum_extent (double radius) { return radius; } double plane_extent_oracle (const gsl_vector* x, double displacement) { return displacement / fabs(gsl_vector_get(x, 0)); } double infinity_norm (const gsl_vector* x) { double max = fabs(gsl_vector_get(x, 0)); for (int i=1; isize; i++) max = GSL_MAX(max, fabs(gsl_vector_get(x, i))); return max; } double cube_extent_oracle (const gsl_vector* x, double edge) { return edge / 2 / infinity_norm(x); } double cube_extent_oracle_with_center (const gsl_vector* x, const gsl_vector* center, double edge) { double min = (0.5*edge - GSL_SIGN(gsl_vector_get(x, 0))*gsl_vector_get(center, 0)) / fabs(gsl_vector_get(x, 0)); for (int i=1; isize; i++) min = GSL_MIN(min, (0.5*edge - GSL_SIGN(gsl_vector_get(x, i))*gsl_vector_get(center, i)) / fabs(gsl_vector_get(x, i))); return min; } double cube_true_volume (double edge, unsigned int dimension) { return gsl_pow_uint(edge, dimension); } double cube_maximum_extent (double edge, unsigned int dimension) { return edge * sqrt(dimension) / 2; } double ellipsoid_extent_oracle (const gsl_vector* x, const gsl_vector* axes) { double k = 0; for (int i=0; isize; i++) k += gsl_pow_2(gsl_vector_get(x, i) / gsl_vector_get(axes, i)); return 1/sqrt(k); } double ellipsoid_true_volume (const gsl_vector* axes) { unsigned int dimension = axes->size; double vol = volume_of_ball(dimension); for (int i=0; isize; gsl_vector_const_view xsub = gsl_vector_const_subvector(x, 1, dimension - 1); return 1/sqrt(gsl_pow_2(gsl_blas_dnrm2(&xsub.vector)) + gsl_pow_2(gsl_vector_get(x, 0) / eccentricity)); } double spheroid_true_volume (double eccentricity, unsigned int dimension) { return volume_of_ball(dimension) * eccentricity; }