public static SharedStateDiscreteSampler of()

in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/GuideTableDiscreteSampler.java [146:194]


    public static SharedStateDiscreteSampler of(UniformRandomProvider rng,
                                                double[] probabilities,
                                                double alpha) {
        validateParameters(probabilities, alpha);

        final int size = probabilities.length;
        final double[] cumulativeProbabilities = new double[size];

        double sumProb = 0;
        int count = 0;
        for (final double prob : probabilities) {
            // Compute and store cumulative probability.
            sumProb += InternalUtils.requirePositiveFinite(prob, "probability");
            cumulativeProbabilities[count++] = sumProb;
        }

        InternalUtils.requireStrictlyPositiveFinite(sumProb, "sum of probabilities");

        // Note: The guide table is at least length 1. Compute the size avoiding overflow
        // in case (alpha * size) is too large.
        final int guideTableSize = (int) Math.ceil(alpha * size);
        final int[] guideTable = new int[Math.max(guideTableSize, guideTableSize + 1)];

        // Compute and store cumulative probability.
        for (int x = 0; x < size; x++) {
            final double norm = cumulativeProbabilities[x] / sumProb;
            cumulativeProbabilities[x] = (norm < 1) ? norm : 1.0;

            // Set the guide table value as an exclusive upper bound (x + 1)
            final int index = getGuideTableIndex(cumulativeProbabilities[x], guideTable.length);
            guideTable[index] = x + 1;
        }

        // Edge case for round-off
        cumulativeProbabilities[size - 1] = 1.0;
        // The final guide table entry is (maximum value of x + 1)
        guideTable[guideTable.length - 1] = size;

        // The first non-zero value in the guide table is from f(x=0).
        // Any probabilities mapped below this must be sample x=0 so the
        // table may initially be filled with zeros.

        // Fill missing values in the guide table.
        for (int i = 1; i < guideTable.length; i++) {
            guideTable[i] = Math.max(guideTable[i - 1], guideTable[i]);
        }

        return new GuideTableDiscreteSampler(rng, cumulativeProbabilities, guideTable);
    }