2022-05-19 22:24:56 +00:00
open FunctionRegistry_Core
open FunctionRegistry_Helpers
2022-05-21 15:41:12 +00:00
let twoArgs = E.Tuple2.toFnCall
2022-05-19 22:24:56 +00:00
2022-05-24 21:02:27 +00:00
module Declaration = {
2022-05-24 11:52:27 +00:00
let frType = FRTypeRecord([
("fn", FRTypeLambda),
("inputs", FRTypeArray(FRTypeRecord([("min", FRTypeNumber), ("max", FRTypeNumber)]))),
])
2022-05-24 21:02:27 +00:00
let fromExpressionValue = (e: frValue): result<expressionValue, string> => {
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs([e]) {
| Ok([FRValueLambda(lambda), FRValueArray(inputs)]) => {
2022-05-24 11:52:27 +00:00
open FunctionRegistry_Helpers.Prepare
2022-05-24 21:02:27 +00:00
let getMinMax = arg =>
2022-05-24 11:52:27 +00:00
ToValueArray.Record.toArgs([arg])
->E.R.bind(ToValueTuple.twoNumbers)
2022-05-24 21:02:27 +00:00
->E.R2.fmap(((min, max)) => Declaration.ContinuousFloatArg.make(min, max))
2022-05-24 11:52:27 +00:00
inputs
->E.A2.fmap(getMinMax)
->E.A.R.firstErrorOrOpen
2022-05-24 21:02:27 +00:00
->E.R2.fmap(args => ReducerInterface_ExpressionValue.EvDeclaration(
2022-05-25 23:27:15 +00:00
Declaration.make(lambda, args),
2022-05-24 21:02:27 +00:00
))
2022-05-24 11:52:27 +00:00
}
2022-05-27 11:29:39 +00:00
| Error(r) => Error(r)
| Ok(_) => Error(FunctionRegistry_Helpers.impossibleError)
2022-05-24 11:52:27 +00:00
}
}
}
2022-05-27 18:03:41 +00:00
let inputsTodist = (inputs: array<FunctionRegistry_Core.frValue>, makeDist) => {
let array = inputs->E.A.unsafe_get(0)->Prepare.ToValueArray.Array.openA
let xyCoords =
array->E.R.bind(xyCoords =>
xyCoords
->E.A2.fmap(xyCoord =>
[xyCoord]->Prepare.ToValueArray.Record.twoArgs->E.R.bind(Prepare.ToValueTuple.twoNumbers)
)
->E.A.R.firstErrorOrOpen
)
let expressionValue =
xyCoords
->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString))
2022-05-27 18:09:17 +00:00
->E.R2.fmap(r => ReducerInterface_ExpressionValue.EvDistribution(PointSet(makeDist(r))))
2022-05-27 18:03:41 +00:00
expressionValue
}
2022-05-22 14:38:17 +00:00
let registry = [
2022-05-24 00:49:10 +00:00
Function.make(
2022-06-04 00:59:02 +00:00
~name="Normal Distribution",
~examples=`normal(5,1)
normal({p5: 4, p95: 10})
normal({mean: 5, stdev: 2})`,
2022-05-19 22:24:56 +00:00
~definitions=[
2022-05-22 14:38:17 +00:00
TwoArgDist.make("normal", twoArgs(SymbolicDist.Normal.make)),
2022-05-23 18:28:32 +00:00
TwoArgDist.makeRecordP5P95("normal", r =>
twoArgs(SymbolicDist.Normal.from90PercentCI, r)->Ok
),
2022-05-22 14:38:17 +00:00
TwoArgDist.makeRecordMeanStdev("normal", twoArgs(SymbolicDist.Normal.make)),
2022-05-19 22:24:56 +00:00
],
2022-06-04 00:59:02 +00:00
(),
2022-05-22 14:38:17 +00:00
),
Function.make(
2022-06-04 00:59:02 +00:00
~name="Lognormal Distribution",
~examples=`lognormal(0.5, 0.8)
lognormal({p5: 4, p95: 10})
lognormal({mean: 5, stdev: 2})`,
2022-05-19 22:24:56 +00:00
~definitions=[
2022-05-22 14:38:17 +00:00
TwoArgDist.make("lognormal", twoArgs(SymbolicDist.Lognormal.make)),
TwoArgDist.makeRecordP5P95("lognormal", r =>
twoArgs(SymbolicDist.Lognormal.from90PercentCI, r)->Ok
),
TwoArgDist.makeRecordMeanStdev("lognormal", twoArgs(SymbolicDist.Lognormal.fromMeanAndStdev)),
2022-05-19 22:24:56 +00:00
],
2022-06-04 00:59:02 +00:00
(),
2022-05-22 14:38:17 +00:00
),
2022-05-20 21:36:40 +00:00
Function.make(
2022-06-04 00:59:02 +00:00
~name="Uniform Distribution",
~examples=`uniform(10, 12)`,
2022-05-22 14:38:17 +00:00
~definitions=[TwoArgDist.make("uniform", twoArgs(SymbolicDist.Uniform.make))],
2022-06-04 00:59:02 +00:00
(),
2022-05-20 21:36:40 +00:00
),
Function.make(
2022-06-04 00:59:02 +00:00
~name="Beta Distribution",
~examples=`beta(20, 25)`,
2022-05-22 14:38:17 +00:00
~definitions=[TwoArgDist.make("beta", twoArgs(SymbolicDist.Beta.make))],
2022-06-04 00:59:02 +00:00
(),
2022-05-20 21:36:40 +00:00
),
Function.make(
2022-06-04 00:59:02 +00:00
~name="Cauchy Distribution",
~examples=`cauchy(5, 1)`,
2022-05-22 14:38:17 +00:00
~definitions=[TwoArgDist.make("cauchy", twoArgs(SymbolicDist.Cauchy.make))],
2022-06-04 00:59:02 +00:00
(),
2022-05-20 21:36:40 +00:00
),
Function.make(
2022-06-04 00:59:02 +00:00
~name="Gamma Distribution",
~examples=`gamma(5, 1)`,
2022-05-22 14:38:17 +00:00
~definitions=[TwoArgDist.make("gamma", twoArgs(SymbolicDist.Gamma.make))],
2022-06-04 00:59:02 +00:00
(),
2022-05-20 21:36:40 +00:00
),
Function.make(
2022-06-04 00:59:02 +00:00
~name="Logistic Distribution",
~examples=`gamma(5, 1)`,
2022-05-22 14:38:17 +00:00
~definitions=[TwoArgDist.make("logistic", twoArgs(SymbolicDist.Logistic.make))],
2022-06-04 00:59:02 +00:00
(),
2022-05-20 21:36:40 +00:00
),
Function.make(
2022-06-04 00:59:02 +00:00
~name="To (Distribution)",
~examples=`5 to 10
to(5,10)
-5 to 5`,
2022-05-23 18:28:32 +00:00
~definitions=[
TwoArgDist.make("to", twoArgs(SymbolicDist.From90thPercentile.make)),
TwoArgDist.make(
"credibleIntervalToDistribution",
twoArgs(SymbolicDist.From90thPercentile.make),
),
2022-05-23 17:49:39 +00:00
],
2022-06-04 00:59:02 +00:00
(),
2022-05-23 18:28:32 +00:00
),
Function.make(
~name="Exponential",
2022-06-04 00:59:02 +00:00
~examples=`exponential(2)`,
2022-05-23 18:28:32 +00:00
~definitions=[OneArgDist.make("exponential", SymbolicDist.Exponential.make)],
2022-06-04 00:59:02 +00:00
(),
2022-05-23 18:28:32 +00:00
),
Function.make(
~name="Bernoulli",
2022-06-04 00:59:02 +00:00
~examples=`bernoulli(0.5)`,
2022-05-23 18:28:32 +00:00
~definitions=[OneArgDist.make("bernoulli", SymbolicDist.Bernoulli.make)],
2022-06-04 00:59:02 +00:00
(),
),
2022-06-04 16:26:52 +00:00
Function.make(
~name="PointMass",
~examples=`pointMass(0.5)`,
~definitions=[OneArgDist.make("pointMass", SymbolicDist.Float.makeSafe)],
(),
),
2022-06-04 00:59:02 +00:00
Function.make(
~name="toContinuousPointSet",
~description="Converts a set of points to a continuous distribution",
~examples=`toContinuousPointSet([
{x: 0, y: 0.1},
{x: 1, y: 0.2},
{x: 2, y: 0.15},
{x: 3, y: 0.1}
])`,
~definitions=[
FnDefinition.make(
~name="toContinuousPointSet",
~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))],
~run=(inputs, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))),
),
],
(),
),
Function.make(
~name="toDiscretePointSet",
~description="Converts a set of points to a discrete distribution",
~examples=`toDiscretePointSet([
{x: 0, y: 0.1},
{x: 1, y: 0.2},
{x: 2, y: 0.15},
{x: 3, y: 0.1}
])`,
~definitions=[
FnDefinition.make(
~name="toDiscretePointSet",
~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))],
~run=(inputs, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))),
),
],
(),
),
Function.make(
~name="Declaration (Continuous Function)",
~description="Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making predictions. It allows you to limit the domain that your prediction will be used and scored within.",
~examples=`declareFn({
fn: {|a,b| a },
inputs: [
{min: 0, max: 100},
{min: 30, max: 50}
]
})`,
~definitions=[
FnDefinition.make(~name="declareFn", ~inputs=[Declaration.frType], ~run=(inputs, _) => {
inputs->E.A.unsafe_get(0)->Declaration.fromExpressionValue
}),
],
~isExperimental=true,
(),
2022-05-21 02:54:15 +00:00
),
2022-05-20 21:36:40 +00:00
]