time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

dist.js (6354B)


      1 import { argumentError, otherError } from "../dist/DistError.js";
      2 import * as SymbolicDist from "../dist/SymbolicDist.js";
      3 import { REDistributionError } from "../errors/messages.js";
      4 import { makeDefinition } from "../library/registry/fnDefinition.js";
      5 import { frDist, frNumber, frDict } from "../library/registry/frTypes.js";
      6 import { FnFactory, makeOneArgDist, makeSampleSet, makeTwoArgsDist, twoVarSample, } from "../library/registry/helpers.js";
      7 import { vDist } from "../value/index.js";
      8 import { CI_CONFIG, symDistResultToValue } from "./distUtil.js";
      9 import { mixtureDefinitions } from "./mixture.js";
     10 const maker = new FnFactory({
     11     nameSpace: "Dist",
     12     requiresNamespace: false,
     13 });
     14 function makeCIDist(lowKey, highKey, fn) {
     15     return makeDefinition([frDict([lowKey, frNumber], [highKey, frNumber])], ([dict], { environment }) => twoVarSample(dict[lowKey], dict[highKey], environment, fn));
     16 }
     17 function makeMeanStdevDist(fn) {
     18     return makeDefinition([frDict(["mean", frNumber], ["stdev", frNumber])], ([{ mean, stdev }], { environment }) => twoVarSample(mean, stdev, environment, fn));
     19 }
     20 export const library = [
     21     maker.make({
     22         name: "make",
     23         requiresNamespace: true,
     24         examples: ["Dist.make(5)", "Dist.make(normal({p5: 4, p95: 10}))"],
     25         definitions: [
     26             makeDefinition([frDist], ([dist]) => vDist(dist)),
     27             makeDefinition([frNumber], ([v]) => symDistResultToValue(SymbolicDist.PointMass.make(v))),
     28         ],
     29     }),
     30     maker.make({
     31         name: "mx",
     32         examples: ["mx(1,normal(5,2))"],
     33         definitions: mixtureDefinitions,
     34     }),
     35     maker.make({
     36         name: "mixture",
     37         examples: ["mixture(1,normal(5,2))"],
     38         definitions: mixtureDefinitions,
     39     }),
     40     maker.make({
     41         name: "normal",
     42         examples: [
     43             "normal(5,1)",
     44             "normal({p5: 4, p95: 10})",
     45             "normal({p10: 4, p90: 10})",
     46             "normal({p25: 4, p75: 10})",
     47             "normal({mean: 5, stdev: 2})",
     48         ],
     49         definitions: [
     50             makeTwoArgsDist((mean, stdev) => SymbolicDist.Normal.make({ mean, stdev })),
     51             ...CI_CONFIG.map((entry) => makeCIDist(entry.lowKey, entry.highKey, (low, high) => SymbolicDist.Normal.fromCredibleInterval({
     52                 low,
     53                 high,
     54                 probability: entry.probability,
     55             }))),
     56             makeMeanStdevDist((mean, stdev) => SymbolicDist.Normal.make({ mean, stdev })),
     57         ],
     58     }),
     59     maker.make({
     60         name: "lognormal",
     61         examples: [
     62             "lognormal(0.5, 0.8)",
     63             "lognormal({p5: 4, p95: 10})",
     64             "lognormal({p10: 4, p90: 10})",
     65             "lognormal({p25: 4, p75: 10})",
     66             "lognormal({mean: 5, stdev: 2})",
     67         ],
     68         definitions: [
     69             makeTwoArgsDist((mu, sigma) => SymbolicDist.Lognormal.make({ mu, sigma })),
     70             ...CI_CONFIG.map((entry) => makeCIDist(entry.lowKey, entry.highKey, (low, high) => SymbolicDist.Lognormal.fromCredibleInterval({
     71                 low,
     72                 high,
     73                 probability: entry.probability,
     74             }))),
     75             makeMeanStdevDist((mean, stdev) => SymbolicDist.Lognormal.fromMeanAndStdev({ mean, stdev })),
     76         ],
     77     }),
     78     maker.make({
     79         name: "uniform",
     80         examples: ["uniform(10, 12)"],
     81         definitions: [
     82             makeTwoArgsDist((low, high) => SymbolicDist.Uniform.make({ low, high })),
     83         ],
     84     }),
     85     maker.make({
     86         name: "beta",
     87         examples: ["beta(20, 25)", "beta({mean: 0.39, stdev: 0.1})"],
     88         definitions: [
     89             makeTwoArgsDist((alpha, beta) => SymbolicDist.Beta.make({ alpha, beta })),
     90             makeMeanStdevDist((mean, stdev) => SymbolicDist.Beta.fromMeanAndStdev({ mean, stdev })),
     91         ],
     92     }),
     93     maker.make({
     94         name: "cauchy",
     95         examples: ["cauchy(5, 1)"],
     96         definitions: [
     97             makeTwoArgsDist((local, scale) => SymbolicDist.Cauchy.make({ local, scale })),
     98         ],
     99     }),
    100     maker.make({
    101         name: "gamma",
    102         examples: ["gamma(5, 1)"],
    103         definitions: [
    104             makeTwoArgsDist((shape, scale) => SymbolicDist.Gamma.make({ shape, scale })),
    105         ],
    106     }),
    107     maker.make({
    108         name: "logistic",
    109         examples: ["logistic(5, 1)"],
    110         definitions: [
    111             makeTwoArgsDist((location, scale) => SymbolicDist.Logistic.make({ location, scale })),
    112         ],
    113     }),
    114     maker.make({
    115         name: "to",
    116         examples: ["5 to 10", "to(5,10)"],
    117         definitions: [
    118             makeTwoArgsDist((low, high) => {
    119                 if (low >= high) {
    120                     throw new REDistributionError(argumentError("Low value must be less than high value"));
    121                 }
    122                 else if (low <= 0 || high <= 0) {
    123                     throw new REDistributionError(argumentError(`The "to" function only accepts paramaters above 0. It's a shorthand for lognormal({p5:min, p95:max}), which is only valid with positive entries for then minimum and maximum. If you would like to use a normal distribution, which accepts values under 0, you can use it like this: normal({p5:${low}, p95:${high}}).`));
    124                 }
    125                 return SymbolicDist.Lognormal.fromCredibleInterval({
    126                     low,
    127                     high,
    128                     probability: 0.9,
    129                 });
    130             }),
    131         ],
    132     }),
    133     maker.make({
    134         name: "exponential",
    135         examples: ["exponential(2)"],
    136         definitions: [
    137             makeOneArgDist((rate) => SymbolicDist.Exponential.make(rate)),
    138         ],
    139     }),
    140     maker.make({
    141         name: "bernoulli",
    142         examples: ["bernoulli(0.5)"],
    143         definitions: [makeOneArgDist((p) => SymbolicDist.Bernoulli.make(p))],
    144     }),
    145     maker.make({
    146         name: "triangular",
    147         examples: ["triangular(3, 5, 10)"],
    148         definitions: [
    149             makeDefinition([frNumber, frNumber, frNumber], ([low, medium, high], { environment }) => {
    150                 const result = SymbolicDist.Triangular.make({ low, medium, high });
    151                 if (!result.ok) {
    152                     throw new REDistributionError(otherError(result.value));
    153                 }
    154                 return vDist(makeSampleSet(result.value, environment));
    155             }),
    156         ],
    157     }),
    158 ];
    159 //# sourceMappingURL=dist.js.map