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