How to resolve the algorithm Probabilistic choice step by step in the E programming language

Published on 12 May 2024 09:40 PM
#E

How to resolve the algorithm Probabilistic choice step by step in the E programming language

Table of Contents

Problem Statement

Given a mapping between items and their required probability of occurrence, generate a million items randomly subject to the given probabilities and compare the target probability of occurrence versus the generated values. The total of all the probabilities should equal one. (Because floating point arithmetic is involved, this is subject to rounding errors).

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Probabilistic choice step by step in the E programming language

Source code in the e programming language

pragma.syntax("0.9")

/** Makes leaves of the binary tree */
def leaf(value) { 
    return def leaf { 
        to run(_) { return value }
        to __printOn(out) { out.print("=> ", value) }
    }
}
/** Makes branches of the binary tree */
def split(leastRight, left, right) {
    return def tree {
        to run(specimen) {
            return if (specimen < leastRight) {
                left(specimen)
            } else {
                right(specimen)
            }
        }
        to __printOn(out) {
            out.print("    ")
            out.indent().print(left)
            out.lnPrint("< ")
            out.print(leastRight)
            out.indent().lnPrint(right)
        }
    }
}
def makeIntervalTree(assocs :List[Tuple[any, float64]]) {
    def size :int := assocs.size()
    if (size > 1) {
        def midpoint := size // 2
        return split(assocs[midpoint][1], makeIntervalTree(assocs.run(0, midpoint)),
                                          makeIntervalTree(assocs.run(midpoint)))
    } else {
        def [[value, _]] := assocs
        return leaf(value)
    }
}
def setupProbabilisticChoice(entropy, table :Map[any, float64]) {
    var cumulative := 0.0
    var intervalTable := []
    for value => probability in table {
        intervalTable with= [value, cumulative]
        cumulative += probability
    }
    def total := cumulative
    def selector := makeIntervalTree(intervalTable)
    return def probChoice {
        # Multiplying by the total helps correct for any error in the sum of the inputs
        to run() { return selector(entropy.nextDouble() * total) }
        to __printOn(out) {
            out.print("Probabilistic choice using tree:")
            out.indent().lnPrint(selector)
        }
    }
}

def rosetta := setupProbabilisticChoice(entropy, def probTable := [
    "aleph"  => 1/5,
    "beth"   => 1/6.0,
    "gimel"  => 1/7.0,
    "daleth" => 1/8.0,
    "he"     => 1/9.0,
    "waw"    => 1/10.0,
    "zayin"  => 1/11.0,
    "heth"   => 0.063455988455988432,
])

var trials := 1000000
var timesFound := [].asMap()
for i in 1..trials {
    if (i % 1000 == 0) { print(`${i//1000} `) }
    def value := rosetta()
    timesFound with= (value, timesFound.fetch(value, fn { 0 }) + 1)
}
stdout.println()
for item in probTable.domain() {
    stdout.print(item, "\t", timesFound[item] / trials, "\t", probTable[item], "\n")
}

  

You may also check:How to resolve the algorithm Polynomial long division step by step in the E programming language
You may also check:How to resolve the algorithm Non-decimal radices/Convert step by step in the E programming language
You may also check:How to resolve the algorithm Apply a callback to an array step by step in the E programming language
You may also check:How to resolve the algorithm Range extraction step by step in the E programming language
You may also check:How to resolve the algorithm Exceptions step by step in the E programming language