/** * The inverse function of H(x). * * @param x free parameter * @return y for which {@code H(y) = x} */ private double hIntegralInverse(final double x) { double t = x*(1d-exponent); if (t < -1d) { // Limit value to the range [-1, +inf). // t could be smaller than -1 in some rare cases due to numerical errors. t = -1; } return Math.exp(helper1(t)*x); }
/** * {@code H(x) :=} * <ul> * <li>{@code (x^(1-exponent) - 1)/(1 - exponent)}, if {@code exponent != 1}</li> * <li>{@code log(x)}, if {@code exponent == 1}</li> * </ul> * H(x) is an integral function of h(x), * the derivative of H(x) is h(x). * * @param x free parameter * @return {@code H(x)} */ private double hIntegral(final double x) { final double logX = Math.log(x); return helper2((1d-exponent)*logX)*logX; }
double x = hIntegralInverse(u); if (k - x <= s || u >= hIntegral(k + 0.5) - h(k)) {
double x = hIntegralInverse(u); if (k - x <= s || u >= hIntegral(k + 0.5) - h(k)) {
/** * {@code H(x) :=} * <ul> * <li>{@code (x^(1-exponent) - 1)/(1 - exponent)}, if {@code exponent != 1}</li> * <li>{@code log(x)}, if {@code exponent == 1}</li> * </ul> * H(x) is an integral function of h(x), * the derivative of H(x) is h(x). * * @param x free parameter * @return {@code H(x)} */ private double hIntegral(final double x) { final double logX = FastMath.log(x); return helper2((1d-exponent)*logX)*logX; }
/** * The inverse function of H(x). * * @param x free parameter * @return y for which {@code H(y) = x} */ private double hIntegralInverse(final double x) { double t = x*(1d-exponent); if (t < -1d) { // Limit value to the range [-1, +inf). // t could be smaller than -1 in some rare cases due to numerical errors. t = -1; } return FastMath.exp(helper1(t)*x); }
/** * {@inheritDoc} */ @Override public int sample() { if (sampler == null) { sampler = new ZipfRejectionInversionSampler(numberOfElements, exponent); } return sampler.sample(random); }
/** * {@inheritDoc} */ @Override public int sample() { if (sampler == null) { sampler = new ZipfRejectionInversionSampler(numberOfElements, exponent); } return sampler.sample(random); }
/** Simple constructor. * @param numberOfElements number of elements * @param exponent exponent parameter of the distribution */ ZipfRejectionInversionSampler(final int numberOfElements, final double exponent) { this.exponent = exponent; this.numberOfElements = numberOfElements; this.hIntegralX1 = hIntegral(1.5) - 1d; this.hIntegralNumberOfElements = hIntegral(numberOfElements + 0.5); this.s = 2d - hIntegralInverse(hIntegral(2.5) - h(2)); }
/** Simple constructor. * @param numberOfElements number of elements * @param exponent exponent parameter of the distribution */ ZipfRejectionInversionSampler(final int numberOfElements, final double exponent) { this.exponent = exponent; this.numberOfElements = numberOfElements; this.hIntegralX1 = hIntegral(1.5) - 1d; this.hIntegralNumberOfElements = hIntegral(numberOfElements + 0.5); this.s = 2d - hIntegralInverse(hIntegral(2.5) - h(2)); }
double x = hIntegralInverse(u); if (k - x <= s || u >= hIntegral(k + 0.5) - h(k)) {
/** * {@code H(x) :=} * <ul> * <li>{@code (x^(1-exponent) - 1)/(1 - exponent)}, if {@code exponent != 1}</li> * <li>{@code log(x)}, if {@code exponent == 1}</li> * </ul> * H(x) is an integral function of h(x), * the derivative of H(x) is h(x). * * @param x free parameter * @return {@code H(x)} */ private double hIntegral(final double x) { final double logX = FastMath.log(x); return helper2((1d-exponent)*logX)*logX; }
/** * The inverse function of H(x). * * @param x free parameter * @return y for which {@code H(y) = x} */ private double hIntegralInverse(final double x) { double t = x*(1d-exponent); if (t < -1d) { // Limit value to the range [-1, +inf). // t could be smaller than -1 in some rare cases due to numerical errors. t = -1; } return FastMath.exp(helper1(t)*x); }
/** Simple constructor. * @param numberOfElements number of elements * @param exponent exponent parameter of the distribution */ ZipfRejectionInversionSampler(final int numberOfElements, final double exponent) { this.exponent = exponent; this.numberOfElements = numberOfElements; this.hIntegralX1 = hIntegral(1.5) - 1d; this.hIntegralNumberOfElements = hIntegral(numberOfElements + 0.5); this.s = 2d - hIntegralInverse(hIntegral(2.5) - h(2)); }
/** * {@inheritDoc} */ @Override public int sample() { if (sampler == null) { sampler = new ZipfRejectionInversionSampler(numberOfElements, exponent); } return sampler.sample(random); }