// Path: fast-rng/src/main/java/biz/k11i/util/MathFunctions.java
// public static final double exp(double value) {
//     return JafamaMath.exp(value);
// }
// 
// Path: fast-rng/src/main/java/biz/k11i/util/MathFunctions.java
// public static final double log(double value) {
//     return JafamaMath.log(value);
// }
// 
// Path: fast-rng/src/main/java/biz/k11i/util/MathFunctions.java
// public static final double log1p(double value) {
//     return JafamaMath.log1p(value);
// }


import java.util.Random;
import static biz.k11i.util.MathFunctions.exp;
import static biz.k11i.util.MathFunctions.log;
import static biz.k11i.util.MathFunctions.log1p;
package biz.k11i.rng;



/**
 * Exponential random number generator.
 */
public interface ExponentialRNG {
    ExponentialRNG FAST_RNG = ZigguratFast.Z_256;
    ExponentialRNG GENERAL_RNG = ZigguratGeneral.Z_256;

    /**
     * Generates a random value sampled from exponential distribution.
     *
     * @param random random number generator
     * @param theta  mean of the distribution
     * @return a random value
     */
    double generate(Random random, double theta);

    abstract class ZigguratBase implements ExponentialRNG {
        final int N;
        final double R;
        final double V;
        final int INDEX_BIT_MASK;
        final int TAIL_INDEX;

        ZigguratBase(int nBits, double r, double v) {
            N = 1 << nBits;
            R = r;
            V = v;

            INDEX_BIT_MASK = (1 << nBits) - 1;
            TAIL_INDEX = (1 << nBits) - 1;
        }

        static double finv(double x, double v) {
// Path: fast-rng/src/main/java/biz/k11i/util/MathFunctions.java
// public static final double exp(double value) {
//     return JafamaMath.exp(value);
// }
// 
// Path: fast-rng/src/main/java/biz/k11i/util/MathFunctions.java
// public static final double log(double value) {
//     return JafamaMath.log(value);
// }
// 
// Path: fast-rng/src/main/java/biz/k11i/util/MathFunctions.java
// public static final double log1p(double value) {
//     return JafamaMath.log1p(value);
// }


// Path: fast-rng/src/main/java/biz/k11i/rng/ExponentialRNG.java
import java.util.Random;
import static biz.k11i.util.MathFunctions.exp;
import static biz.k11i.util.MathFunctions.log;
import static biz.k11i.util.MathFunctions.log1p;

package biz.k11i.rng;



/**
 * Exponential random number generator.
 */
public interface ExponentialRNG {
    ExponentialRNG FAST_RNG = ZigguratFast.Z_256;
    ExponentialRNG GENERAL_RNG = ZigguratGeneral.Z_256;

    /**
     * Generates a random value sampled from exponential distribution.
     *
     * @param random random number generator
     * @param theta  mean of the distribution
     * @return a random value
     */
    double generate(Random random, double theta);

    abstract class ZigguratBase implements ExponentialRNG {
        final int N;
        final double R;
        final double V;
        final int INDEX_BIT_MASK;
        final int TAIL_INDEX;

        ZigguratBase(int nBits, double r, double v) {
            N = 1 << nBits;
            R = r;
            V = v;

            INDEX_BIT_MASK = (1 << nBits) - 1;
            TAIL_INDEX = (1 << nBits) - 1;
        }

        static double finv(double x, double v) {
            return -log(exp(-x) + v / x);