Light cleanup of ReducerInterface_GenericDistribution
This commit is contained in:
parent
18d742b63c
commit
e7c2a7db01
|
@ -6,6 +6,9 @@ let makeTest = (str, result) => test(str, () => expectEvalToBe(str, result))
|
||||||
describe("eval", () => {
|
describe("eval", () => {
|
||||||
Only.describe("expressions", () => {
|
Only.describe("expressions", () => {
|
||||||
makeTest("normal(5,2)", "Ok(Normal(5,2))")
|
makeTest("normal(5,2)", "Ok(Normal(5,2))")
|
||||||
|
makeTest("5 to 2", "Error(TODO: Low value must be less than high value.)")
|
||||||
|
makeTest("to(2,5)", "Ok(Lognormal(1.1512925464970227,0.278507821238345))")
|
||||||
|
makeTest("to(-2,2)", "Ok(Normal(0,1.215913388057542))")
|
||||||
makeTest("lognormal(5,2)", "Ok(Lognormal(5,2))")
|
makeTest("lognormal(5,2)", "Ok(Lognormal(5,2))")
|
||||||
makeTest("mean(normal(5,2))", "Ok(5)")
|
makeTest("mean(normal(5,2))", "Ok(5)")
|
||||||
makeTest("mean(lognormal(1,2))", "Ok(20.085536923187668)")
|
makeTest("mean(lognormal(1,2))", "Ok(20.085536923187668)")
|
||||||
|
@ -21,6 +24,5 @@ describe("eval", () => {
|
||||||
makeTest("3+normal(5,2)", "Ok(Point Set Distribution)")
|
makeTest("3+normal(5,2)", "Ok(Point Set Distribution)")
|
||||||
makeTest("add(3, 3)", "Ok(6)")
|
makeTest("add(3, 3)", "Ok(6)")
|
||||||
makeTest("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
makeTest("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
||||||
makeTest("mean(add(3, normal(5,2)))", "Ok(8.004619792609384)")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -228,7 +228,7 @@ let pointwiseCombinationFloat = (
|
||||||
): result<t, error> => {
|
): result<t, error> => {
|
||||||
let m = switch arithmeticOperation {
|
let m = switch arithmeticOperation {
|
||||||
| #Add | #Subtract => Error(GenericDist_Types.DistributionVerticalShiftIsInvalid)
|
| #Add | #Subtract => Error(GenericDist_Types.DistributionVerticalShiftIsInvalid)
|
||||||
| (#Multiply | #Divide | #Exponentiate | #Log) as arithmeticOperation =>
|
| (#Multiply | #Divide | #Exponentiate | #Logarithm) as arithmeticOperation =>
|
||||||
toPointSetFn(t)->E.R2.fmap(t => {
|
toPointSetFn(t)->E.R2.fmap(t => {
|
||||||
//TODO: Move to PointSet codebase
|
//TODO: Move to PointSet codebase
|
||||||
let fn = (secondary, main) => Operation.Scale.toFn(arithmeticOperation, main, secondary)
|
let fn = (secondary, main) => Operation.Scale.toFn(arithmeticOperation, main, secondary)
|
||||||
|
|
|
@ -20,7 +20,7 @@ module Operation = {
|
||||||
| #Subtract
|
| #Subtract
|
||||||
| #Divide
|
| #Divide
|
||||||
| #Exponentiate
|
| #Exponentiate
|
||||||
| #Log
|
| #Logarithm
|
||||||
]
|
]
|
||||||
|
|
||||||
let arithmeticToFn = (arithmetic: arithmeticOperation) =>
|
let arithmeticToFn = (arithmetic: arithmeticOperation) =>
|
||||||
|
@ -30,7 +30,7 @@ module Operation = {
|
||||||
| #Subtract => \"-."
|
| #Subtract => \"-."
|
||||||
| #Exponentiate => \"**"
|
| #Exponentiate => \"**"
|
||||||
| #Divide => \"/."
|
| #Divide => \"/."
|
||||||
| #Log => (a, b) => log(a) /. log(b)
|
| #Logarithm => (a, b) => log(a) /. log(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
type toFloat = [
|
type toFloat = [
|
||||||
|
|
|
@ -1,80 +1,67 @@
|
||||||
module ExpressionValue = ReducerInterface_ExpressionValue
|
module ExpressionValue = ReducerInterface_ExpressionValue
|
||||||
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
|
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
|
||||||
|
|
||||||
let env: GenericDist_GenericOperation.env = {
|
let runGenericOperation = GenericDist_GenericOperation.run(
|
||||||
sampleCount: 1000,
|
~env={
|
||||||
xyPointLength: 1000,
|
sampleCount: 1000,
|
||||||
}
|
xyPointLength: 1000,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
let runGenericOperation = GenericDist_GenericOperation.run(~env)
|
module Helpers = {
|
||||||
|
let arithmeticMap = r =>
|
||||||
|
switch r {
|
||||||
|
| "add" => #Add
|
||||||
|
| "dotAdd" => #Add
|
||||||
|
| "subtract" => #Subtract
|
||||||
|
| "dotSubtract" => #Subtract
|
||||||
|
| "divide" => #Divide
|
||||||
|
| "logarithm" => #Logarithm
|
||||||
|
| "dotDivide" => #Divide
|
||||||
|
| "exponentiate" => #Exponentiate
|
||||||
|
| "dotExponentiate" => #Exponentiate
|
||||||
|
| "multiply" => #Multiply
|
||||||
|
| "dotMultiply" => #Multiply
|
||||||
|
| "dotLogarithm" => #Logarithm
|
||||||
|
| _ => #Multiply
|
||||||
|
}
|
||||||
|
|
||||||
let arithmeticMap = r =>
|
let catchAndConvertTwoArgsToDists = (args: array<expressionValue>): option<(
|
||||||
switch r {
|
GenericDist_Types.genericDist,
|
||||||
| "add" => #Add
|
GenericDist_Types.genericDist,
|
||||||
| "dotAdd" => #Add
|
)> => {
|
||||||
| "subtract" => #Subtract
|
switch args {
|
||||||
| "dotSubtract" => #Subtract
|
| [EvDistribution(a), EvDistribution(b)] => Some((a, b))
|
||||||
| "divide" => #Divide
|
| [EvNumber(a), EvDistribution(b)] => Some((GenericDist.fromFloat(a), b))
|
||||||
| "logarithm" => #Divide
|
| [EvDistribution(a), EvNumber(b)] => Some((a, GenericDist.fromFloat(b)))
|
||||||
| "dotDivide" => #Divide
|
| _ => None
|
||||||
| "exponentiate" => #Exponentiate
|
}
|
||||||
| "dotExponentiate" => #Exponentiate
|
|
||||||
| "multiply" => #Multiply
|
|
||||||
| "dotMultiply" => #Multiply
|
|
||||||
| "dotLogarithm" => #Divide
|
|
||||||
| _ => #Multiply
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let catchAndConvertTwoArgsToDists = (args: array<expressionValue>): option<(
|
let toFloatFn = (
|
||||||
GenericDist_Types.genericDist,
|
fnCall: GenericDist_Types.Operation.toFloat,
|
||||||
GenericDist_Types.genericDist,
|
dist: GenericDist_Types.genericDist,
|
||||||
)> => {
|
) => {
|
||||||
switch args {
|
FromDist(GenericDist_Types.Operation.ToFloat(fnCall), dist)->runGenericOperation->Some
|
||||||
| [EvDistribution(a), EvDistribution(b)] => Some((a, b))
|
}
|
||||||
| [EvNumber(a), EvDistribution(b)] => Some((GenericDist.fromFloat(a), b))
|
|
||||||
| [EvDistribution(a), EvNumber(b)] => Some((a, GenericDist.fromFloat(b)))
|
let toDistFn = (fnCall: GenericDist_Types.Operation.toDist, dist) => {
|
||||||
| _ => None
|
FromDist(GenericDist_Types.Operation.ToDist(fnCall), dist)->runGenericOperation->Some
|
||||||
|
}
|
||||||
|
|
||||||
|
let twoDiststoDistFn = (direction, arithmetic, dist1, dist2) => {
|
||||||
|
FromDist(
|
||||||
|
GenericDist_Types.Operation.ToDistCombination(
|
||||||
|
direction,
|
||||||
|
arithmeticMap(arithmetic),
|
||||||
|
#Dist(dist2),
|
||||||
|
),
|
||||||
|
dist1,
|
||||||
|
)->runGenericOperation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let toFloatFn = (
|
module SymbolicConstructors = {
|
||||||
fnCall: GenericDist_Types.Operation.toFloat,
|
|
||||||
dist: GenericDist_Types.genericDist,
|
|
||||||
) => {
|
|
||||||
FromDist(GenericDist_Types.Operation.ToFloat(fnCall), dist)->runGenericOperation->Some
|
|
||||||
}
|
|
||||||
|
|
||||||
let toDistFn = (fnCall: GenericDist_Types.Operation.toDist, dist) => {
|
|
||||||
FromDist(GenericDist_Types.Operation.ToDist(fnCall), dist)->runGenericOperation->Some
|
|
||||||
}
|
|
||||||
|
|
||||||
let twoDiststoDistFn = (direction, arithmetic, dist1, dist2) => {
|
|
||||||
FromDist(
|
|
||||||
GenericDist_Types.Operation.ToDistCombination(
|
|
||||||
direction,
|
|
||||||
arithmeticMap(arithmetic),
|
|
||||||
#Dist(dist2),
|
|
||||||
),
|
|
||||||
dist1,
|
|
||||||
)->runGenericOperation
|
|
||||||
}
|
|
||||||
|
|
||||||
let genericOutputToReducerValue = (o: GenericDist_GenericOperation.outputType): result<
|
|
||||||
expressionValue,
|
|
||||||
Reducer_ErrorValue.errorValue,
|
|
||||||
> =>
|
|
||||||
switch o {
|
|
||||||
| Dist(d) => Ok(ReducerInterface_ExpressionValue.EvDistribution(d))
|
|
||||||
| Float(d) => Ok(EvNumber(d))
|
|
||||||
| String(d) => Ok(EvString(d))
|
|
||||||
| GenDistError(NotYetImplemented) => Error(RETodo("Function not yet implemented"))
|
|
||||||
| GenDistError(Unreachable) => Error(RETodo("Unreachable"))
|
|
||||||
| GenDistError(DistributionVerticalShiftIsInvalid) =>
|
|
||||||
Error(RETodo("Distribution Vertical Shift is Invalid"))
|
|
||||||
| GenDistError(Other(s)) => Error(RETodo(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
module SymbolicConstructor = {
|
|
||||||
let oneFloat = name =>
|
let oneFloat = name =>
|
||||||
switch name {
|
switch name {
|
||||||
| "exponential" => Ok(SymbolicDist.Exponential.make)
|
| "exponential" => Ok(SymbolicDist.Exponential.make)
|
||||||
|
@ -87,6 +74,7 @@ module SymbolicConstructor = {
|
||||||
| "uniform" => Ok(SymbolicDist.Uniform.make)
|
| "uniform" => Ok(SymbolicDist.Uniform.make)
|
||||||
| "beta" => Ok(SymbolicDist.Beta.make)
|
| "beta" => Ok(SymbolicDist.Beta.make)
|
||||||
| "lognormal" => Ok(SymbolicDist.Lognormal.make)
|
| "lognormal" => Ok(SymbolicDist.Lognormal.make)
|
||||||
|
| "to" => Ok(SymbolicDist.From90thPercentile.make)
|
||||||
| _ => Error("impossible path")
|
| _ => Error("impossible path")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,47 +99,65 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option<
|
||||||
let (fnName, args) = call
|
let (fnName, args) = call
|
||||||
switch (fnName, args) {
|
switch (fnName, args) {
|
||||||
| ("exponential" as fnName, [EvNumber(f1)]) =>
|
| ("exponential" as fnName, [EvNumber(f1)]) =>
|
||||||
SymbolicConstructor.oneFloat(fnName)
|
SymbolicConstructors.oneFloat(fnName)
|
||||||
->E.R.bind(r => r(f1))
|
->E.R.bind(r => r(f1))
|
||||||
->SymbolicConstructor.symbolicResultToOutput
|
->SymbolicConstructors.symbolicResultToOutput
|
||||||
| (("normal" | "uniform" | "beta" | "lognormal") as fnName, [EvNumber(f1), EvNumber(f2)]) =>
|
| (
|
||||||
SymbolicConstructor.twoFloat(fnName)
|
("normal" | "uniform" | "beta" | "lognormal" | "to") as fnName,
|
||||||
|
[EvNumber(f1), EvNumber(f2)],
|
||||||
|
) =>
|
||||||
|
SymbolicConstructors.twoFloat(fnName)
|
||||||
->E.R.bind(r => r(f1, f2))
|
->E.R.bind(r => r(f1, f2))
|
||||||
->SymbolicConstructor.symbolicResultToOutput
|
->SymbolicConstructors.symbolicResultToOutput
|
||||||
| ("triangular" as fnName, [EvNumber(f1), EvNumber(f2), EvNumber(f3)]) =>
|
| ("triangular" as fnName, [EvNumber(f1), EvNumber(f2), EvNumber(f3)]) =>
|
||||||
SymbolicConstructor.threeFloat(fnName)
|
SymbolicConstructors.threeFloat(fnName)
|
||||||
->E.R.bind(r => r(f1, f2, f3))
|
->E.R.bind(r => r(f1, f2, f3))
|
||||||
->SymbolicConstructor.symbolicResultToOutput
|
->SymbolicConstructors.symbolicResultToOutput
|
||||||
| ("sample", [EvDistribution(dist)]) => toFloatFn(#Sample, dist)
|
| ("sample", [EvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist)
|
||||||
| ("mean", [EvDistribution(dist)]) => toFloatFn(#Mean, dist)
|
| ("mean", [EvDistribution(dist)]) => Helpers.toFloatFn(#Mean, dist)
|
||||||
| ("normalize", [EvDistribution(dist)]) => toDistFn(Normalize, dist)
|
| ("normalize", [EvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist)
|
||||||
| ("toPointSet", [EvDistribution(dist)]) => toDistFn(ToPointSet, dist)
|
| ("toPointSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist)
|
||||||
| ("cdf", [EvDistribution(dist), EvNumber(float)]) => toFloatFn(#Cdf(float), dist)
|
| ("cdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist)
|
||||||
| ("pdf", [EvDistribution(dist), EvNumber(float)]) => toFloatFn(#Pdf(float), dist)
|
| ("pdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist)
|
||||||
| ("inv", [EvDistribution(dist), EvNumber(float)]) => toFloatFn(#Inv(float), dist)
|
| ("inv", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist)
|
||||||
| ("toSampleSet", [EvDistribution(dist), EvNumber(float)]) =>
|
| ("toSampleSet", [EvDistribution(dist), EvNumber(float)]) =>
|
||||||
toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist)
|
Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist)
|
||||||
| ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) =>
|
| ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) =>
|
||||||
toDistFn(Truncate(Some(float), None), dist)
|
Helpers.toDistFn(Truncate(Some(float), None), dist)
|
||||||
| ("truncateRight", [EvDistribution(dist), EvNumber(float)]) =>
|
| ("truncateRight", [EvDistribution(dist), EvNumber(float)]) =>
|
||||||
toDistFn(Truncate(None, Some(float)), dist)
|
Helpers.toDistFn(Truncate(None, Some(float)), dist)
|
||||||
| ("truncate", [EvDistribution(dist), EvNumber(float1), EvNumber(float2)]) =>
|
| ("truncate", [EvDistribution(dist), EvNumber(float1), EvNumber(float2)]) =>
|
||||||
toDistFn(Truncate(Some(float1), Some(float2)), dist)
|
Helpers.toDistFn(Truncate(Some(float1), Some(float2)), dist)
|
||||||
| (("add" | "multiply" | "subtract" | "divide" | "exponentiate") as arithmetic, [a, b] as args) =>
|
| (("add" | "multiply" | "subtract" | "divide" | "exponentiate" | "log") as arithmetic, [a, b] as args) =>
|
||||||
catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) =>
|
Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) =>
|
||||||
twoDiststoDistFn(Algebraic, arithmetic, fst, snd)
|
Helpers.twoDiststoDistFn(Algebraic, arithmetic, fst, snd)
|
||||||
)
|
)
|
||||||
| (
|
| (
|
||||||
("dotAdd" | "dotMultiply" | "dotSubtract" | "dotDivide" | "dotExponentiate") as arithmetic,
|
("dotAdd" | "dotMultiply" | "dotSubtract" | "dotDivide" | "dotExponentiate" | "dotLogarithm") as arithmetic,
|
||||||
[a, b] as args,
|
[a, b] as args,
|
||||||
) =>
|
) =>
|
||||||
catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) =>
|
Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) =>
|
||||||
twoDiststoDistFn(Pointwise, arithmetic, fst, snd)
|
Helpers.twoDiststoDistFn(Pointwise, arithmetic, fst, snd)
|
||||||
)
|
)
|
||||||
| _ => None
|
| _ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let genericOutputToReducerValue = (o: GenericDist_GenericOperation.outputType): result<
|
||||||
|
expressionValue,
|
||||||
|
Reducer_ErrorValue.errorValue,
|
||||||
|
> =>
|
||||||
|
switch o {
|
||||||
|
| Dist(d) => Ok(ReducerInterface_ExpressionValue.EvDistribution(d))
|
||||||
|
| Float(d) => Ok(EvNumber(d))
|
||||||
|
| String(d) => Ok(EvString(d))
|
||||||
|
| GenDistError(NotYetImplemented) => Error(RETodo("Function not yet implemented"))
|
||||||
|
| GenDistError(Unreachable) => Error(RETodo("Unreachable"))
|
||||||
|
| GenDistError(DistributionVerticalShiftIsInvalid) =>
|
||||||
|
Error(RETodo("Distribution Vertical Shift is Invalid"))
|
||||||
|
| GenDistError(Other(s)) => Error(RETodo(s))
|
||||||
|
}
|
||||||
|
|
||||||
let dispatch = call => {
|
let dispatch = call => {
|
||||||
dispatchToGenericOutput(call)->E.O2.fmap(genericOutputToReducerValue)
|
dispatchToGenericOutput(call)->E.O2.fmap(genericOutputToReducerValue)
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,6 @@ let all = [
|
||||||
),
|
),
|
||||||
makeRenderedDistFloat("scaleExp", (dist, float) => verticalScaling(#Exponentiate, dist, float)),
|
makeRenderedDistFloat("scaleExp", (dist, float) => verticalScaling(#Exponentiate, dist, float)),
|
||||||
makeRenderedDistFloat("scaleMultiply", (dist, float) => verticalScaling(#Multiply, dist, float)),
|
makeRenderedDistFloat("scaleMultiply", (dist, float) => verticalScaling(#Multiply, dist, float)),
|
||||||
makeRenderedDistFloat("scaleLog", (dist, float) => verticalScaling(#Log, dist, float)),
|
makeRenderedDistFloat("scaleLog", (dist, float) => verticalScaling(#Logarithm, dist, float)),
|
||||||
Multimodal._function,
|
Multimodal._function,
|
||||||
]
|
]
|
||||||
|
|
|
@ -115,7 +115,7 @@ let combineShapesContinuousContinuous = (
|
||||||
| #Multiply => (m1, m2) => m1 *. m2
|
| #Multiply => (m1, m2) => m1 *. m2
|
||||||
| #Divide => (m1, mInv2) => m1 *. mInv2
|
| #Divide => (m1, mInv2) => m1 *. mInv2
|
||||||
| #Exponentiate => (m1, mInv2) => m1 ** mInv2
|
| #Exponentiate => (m1, mInv2) => m1 ** mInv2
|
||||||
| #Log => (m1, m2) => log(m1) /. log(m2)
|
| #Logarithm => (m1, m2) => log(m1) /. log(m2)
|
||||||
} // note: here, mInv2 = mean(1 / t2) ~= 1 / mean(t2)
|
} // note: here, mInv2 = mean(1 / t2) ~= 1 / mean(t2)
|
||||||
|
|
||||||
// TODO: I don't know what the variances are for exponentatiation
|
// TODO: I don't know what the variances are for exponentatiation
|
||||||
|
@ -233,7 +233,7 @@ let combineShapesContinuousDiscrete = (
|
||||||
}
|
}
|
||||||
| #Multiply
|
| #Multiply
|
||||||
| #Exponentiate
|
| #Exponentiate
|
||||||
| #Log
|
| #Logarithm
|
||||||
| #Divide =>
|
| #Divide =>
|
||||||
for j in 0 to t2n - 1 {
|
for j in 0 to t2n - 1 {
|
||||||
// creates a new continuous shape for each one of the discrete points, and collects them in outXYShapes.
|
// creates a new continuous shape for each one of the discrete points, and collects them in outXYShapes.
|
||||||
|
|
|
@ -2,7 +2,7 @@ open SymbolicDistTypes
|
||||||
|
|
||||||
module Normal = {
|
module Normal = {
|
||||||
type t = normal
|
type t = normal
|
||||||
let make = (mean: float, stdev: float): result<symbolicDist,string> =>
|
let make = (mean: float, stdev: float): result<symbolicDist, string> =>
|
||||||
stdev > 0.0
|
stdev > 0.0
|
||||||
? Ok(#Normal({mean: mean, stdev: stdev}))
|
? Ok(#Normal({mean: mean, stdev: stdev}))
|
||||||
: Error("Standard deviation of normal distribution must be larger than 0")
|
: Error("Standard deviation of normal distribution must be larger than 0")
|
||||||
|
@ -48,11 +48,13 @@ module Normal = {
|
||||||
|
|
||||||
module Exponential = {
|
module Exponential = {
|
||||||
type t = exponential
|
type t = exponential
|
||||||
let make = (rate: float): result<symbolicDist,string> =>
|
let make = (rate: float): result<symbolicDist, string> =>
|
||||||
rate > 0.0
|
rate > 0.0
|
||||||
? Ok(#Exponential({
|
? Ok(
|
||||||
rate: rate,
|
#Exponential({
|
||||||
}))
|
rate: rate,
|
||||||
|
}),
|
||||||
|
)
|
||||||
: Error("Exponential distributions mean must be larger than 0")
|
: Error("Exponential distributions mean must be larger than 0")
|
||||||
let pdf = (x, t: t) => Jstat.Exponential.pdf(x, t.rate)
|
let pdf = (x, t: t) => Jstat.Exponential.pdf(x, t.rate)
|
||||||
let cdf = (x, t: t) => Jstat.Exponential.cdf(x, t.rate)
|
let cdf = (x, t: t) => Jstat.Exponential.cdf(x, t.rate)
|
||||||
|
@ -89,7 +91,7 @@ module Triangular = {
|
||||||
|
|
||||||
module Beta = {
|
module Beta = {
|
||||||
type t = beta
|
type t = beta
|
||||||
let make = (alpha, beta) =>
|
let make = (alpha, beta) =>
|
||||||
alpha > 0.0 && beta > 0.0
|
alpha > 0.0 && beta > 0.0
|
||||||
? Ok(#Beta({alpha: alpha, beta: beta}))
|
? Ok(#Beta({alpha: alpha, beta: beta}))
|
||||||
: Error("Beta distribution parameters must be positive")
|
: Error("Beta distribution parameters must be positive")
|
||||||
|
@ -103,10 +105,10 @@ module Beta = {
|
||||||
|
|
||||||
module Lognormal = {
|
module Lognormal = {
|
||||||
type t = lognormal
|
type t = lognormal
|
||||||
let make = (mu, sigma) =>
|
let make = (mu, sigma) =>
|
||||||
sigma > 0.0
|
sigma > 0.0
|
||||||
? Ok(#Lognormal({mu: mu, sigma: sigma}))
|
? Ok(#Lognormal({mu: mu, sigma: sigma}))
|
||||||
: Error("Lognormal standard deviation must be larger than 0")
|
: Error("Lognormal standard deviation must be larger than 0")
|
||||||
let pdf = (x, t: t) => Jstat.Lognormal.pdf(x, t.mu, t.sigma)
|
let pdf = (x, t: t) => Jstat.Lognormal.pdf(x, t.mu, t.sigma)
|
||||||
let cdf = (x, t: t) => Jstat.Lognormal.cdf(x, t.mu, t.sigma)
|
let cdf = (x, t: t) => Jstat.Lognormal.cdf(x, t.mu, t.sigma)
|
||||||
let inv = (p, t: t) => Jstat.Lognormal.inv(p, t.mu, t.sigma)
|
let inv = (p, t: t) => Jstat.Lognormal.inv(p, t.mu, t.sigma)
|
||||||
|
@ -127,8 +129,7 @@ module Lognormal = {
|
||||||
let mu = Js.Math.log(mean) -. 0.5 *. Js.Math.log(variance /. meanSquared +. 1.0)
|
let mu = Js.Math.log(mean) -. 0.5 *. Js.Math.log(variance /. meanSquared +. 1.0)
|
||||||
let sigma = Js.Math.pow_float(~base=Js.Math.log(variance /. meanSquared +. 1.0), ~exp=0.5)
|
let sigma = Js.Math.pow_float(~base=Js.Math.log(variance /. meanSquared +. 1.0), ~exp=0.5)
|
||||||
Ok(#Lognormal({mu: mu, sigma: sigma}))
|
Ok(#Lognormal({mu: mu, sigma: sigma}))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Error("Lognormal standard deviation must be larger than 0")
|
Error("Lognormal standard deviation must be larger than 0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,9 +155,7 @@ module Lognormal = {
|
||||||
module Uniform = {
|
module Uniform = {
|
||||||
type t = uniform
|
type t = uniform
|
||||||
let make = (low, high) =>
|
let make = (low, high) =>
|
||||||
high > low
|
high > low ? Ok(#Uniform({low: low, high: high})) : Error("High must be larger than low")
|
||||||
? Ok(#Uniform({low: low, high: high}))
|
|
||||||
: Error("High must be larger than low")
|
|
||||||
|
|
||||||
let pdf = (x, t: t) => Jstat.Uniform.pdf(x, t.low, t.high)
|
let pdf = (x, t: t) => Jstat.Uniform.pdf(x, t.low, t.high)
|
||||||
let cdf = (x, t: t) => Jstat.Uniform.cdf(x, t.low, t.high)
|
let cdf = (x, t: t) => Jstat.Uniform.cdf(x, t.low, t.high)
|
||||||
|
@ -165,7 +164,7 @@ module Uniform = {
|
||||||
let mean = (t: t) => Ok(Jstat.Uniform.mean(t.low, t.high))
|
let mean = (t: t) => Ok(Jstat.Uniform.mean(t.low, t.high))
|
||||||
let toString = ({low, high}: t) => j`Uniform($low,$high)`
|
let toString = ({low, high}: t) => j`Uniform($low,$high)`
|
||||||
let truncate = (low, high, t: t): t => {
|
let truncate = (low, high, t: t): t => {
|
||||||
//todo: add check
|
//todo: add check
|
||||||
let newLow = max(E.O.default(neg_infinity, low), t.low)
|
let newLow = max(E.O.default(neg_infinity, low), t.low)
|
||||||
let newHigh = min(E.O.default(infinity, high), t.high)
|
let newHigh = min(E.O.default(infinity, high), t.high)
|
||||||
{low: newLow, high: newHigh}
|
{low: newLow, high: newHigh}
|
||||||
|
@ -183,6 +182,15 @@ module Float = {
|
||||||
let toString = Js.Float.toString
|
let toString = Js.Float.toString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module From90thPercentile = {
|
||||||
|
let make = (low, high) =>
|
||||||
|
switch (low, high) {
|
||||||
|
| (low, high) if low <= 0.0 && low < high => Ok(Normal.from90PercentCI(low, high))
|
||||||
|
| (low, high) if low < high => Ok(Lognormal.from90PercentCI(low, high))
|
||||||
|
| (_, _) => Error("Low value must be less than high value.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module T = {
|
module T = {
|
||||||
let minCdfValue = 0.0001
|
let minCdfValue = 0.0001
|
||||||
let maxCdfValue = 0.9999
|
let maxCdfValue = 0.9999
|
||||||
|
|
|
@ -7,11 +7,11 @@ type algebraicOperation = [
|
||||||
| #Subtract
|
| #Subtract
|
||||||
| #Divide
|
| #Divide
|
||||||
| #Exponentiate
|
| #Exponentiate
|
||||||
| #Log
|
| #Logarithm
|
||||||
]
|
]
|
||||||
@genType
|
@genType
|
||||||
type pointwiseOperation = [#Add | #Multiply | #Exponentiate]
|
type pointwiseOperation = [#Add | #Multiply | #Exponentiate]
|
||||||
type scaleOperation = [#Multiply | #Exponentiate | #Log | #Divide]
|
type scaleOperation = [#Multiply | #Exponentiate | #Logarithm | #Divide]
|
||||||
type distToFloatOperation = [
|
type distToFloatOperation = [
|
||||||
| #Pdf(float)
|
| #Pdf(float)
|
||||||
| #Cdf(float)
|
| #Cdf(float)
|
||||||
|
@ -29,7 +29,7 @@ module Algebraic = {
|
||||||
| #Multiply => \"*."
|
| #Multiply => \"*."
|
||||||
| #Exponentiate => \"**"
|
| #Exponentiate => \"**"
|
||||||
| #Divide => \"/."
|
| #Divide => \"/."
|
||||||
| #Log => (a, b) => log(a) /. log(b)
|
| #Logarithm => (a, b) => log(a) /. log(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
let applyFn = (t, f1, f2) =>
|
let applyFn = (t, f1, f2) =>
|
||||||
|
@ -45,7 +45,7 @@ module Algebraic = {
|
||||||
| #Multiply => "*"
|
| #Multiply => "*"
|
||||||
| #Exponentiate => "**"
|
| #Exponentiate => "**"
|
||||||
| #Divide => "/"
|
| #Divide => "/"
|
||||||
| #Log => "log"
|
| #Logarithm => "log"
|
||||||
}
|
}
|
||||||
|
|
||||||
let format = (a, b, c) => b ++ (" " ++ (toString(a) ++ (" " ++ c)))
|
let format = (a, b, c) => b ++ (" " ++ (toString(a) ++ (" " ++ c)))
|
||||||
|
@ -84,7 +84,7 @@ module Scale = {
|
||||||
| #Multiply => \"*."
|
| #Multiply => \"*."
|
||||||
| #Divide => \"/."
|
| #Divide => \"/."
|
||||||
| #Exponentiate => \"**"
|
| #Exponentiate => \"**"
|
||||||
| #Log => (a, b) => log(a) /. log(b)
|
| #Logarithm => (a, b) => log(a) /. log(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
let format = (operation: t, value, scaleBy) =>
|
let format = (operation: t, value, scaleBy) =>
|
||||||
|
@ -92,7 +92,7 @@ module Scale = {
|
||||||
| #Multiply => j`verticalMultiply($value, $scaleBy) `
|
| #Multiply => j`verticalMultiply($value, $scaleBy) `
|
||||||
| #Divide => j`verticalDivide($value, $scaleBy) `
|
| #Divide => j`verticalDivide($value, $scaleBy) `
|
||||||
| #Exponentiate => j`verticalExponentiate($value, $scaleBy) `
|
| #Exponentiate => j`verticalExponentiate($value, $scaleBy) `
|
||||||
| #Log => j`verticalLog($value, $scaleBy) `
|
| #Logarithm => j`verticalLog($value, $scaleBy) `
|
||||||
}
|
}
|
||||||
|
|
||||||
let toIntegralSumCacheFn = x =>
|
let toIntegralSumCacheFn = x =>
|
||||||
|
@ -100,7 +100,7 @@ module Scale = {
|
||||||
| #Multiply => (a, b) => Some(a *. b)
|
| #Multiply => (a, b) => Some(a *. b)
|
||||||
| #Divide => (a, b) => Some(a /. b)
|
| #Divide => (a, b) => Some(a /. b)
|
||||||
| #Exponentiate => (_, _) => None
|
| #Exponentiate => (_, _) => None
|
||||||
| #Log => (_, _) => None
|
| #Logarithm => (_, _) => None
|
||||||
}
|
}
|
||||||
|
|
||||||
let toIntegralCacheFn = x =>
|
let toIntegralCacheFn = x =>
|
||||||
|
@ -108,7 +108,7 @@ module Scale = {
|
||||||
| #Multiply => (_, _) => None // TODO: this could probably just be multiplied out (using Continuous.scaleBy)
|
| #Multiply => (_, _) => None // TODO: this could probably just be multiplied out (using Continuous.scaleBy)
|
||||||
| #Divide => (_, _) => None
|
| #Divide => (_, _) => None
|
||||||
| #Exponentiate => (_, _) => None
|
| #Exponentiate => (_, _) => None
|
||||||
| #Log => (_, _) => None
|
| #Logarithm => (_, _) => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user