Merge pull request #864 from quantified-uncertainty/add-reducer-to-function-registry
Add reducer to function registry
This commit is contained in:
commit
7f87398c1f
|
@ -17,14 +17,6 @@ describe("builtin", () => {
|
||||||
testEval("1-1", "Ok(0)")
|
testEval("1-1", "Ok(0)")
|
||||||
testEval("2>1", "Ok(true)")
|
testEval("2>1", "Ok(true)")
|
||||||
testEval("concat('a','b')", "Ok('ab')")
|
testEval("concat('a','b')", "Ok('ab')")
|
||||||
testEval(
|
|
||||||
"addOne(t)=t+1; toList(mapSamples(fromSamples([1,2,3,4,5,6]), addOne))",
|
|
||||||
"Ok([2,3,4,5,6,7])",
|
|
||||||
)
|
|
||||||
testEval(
|
|
||||||
"toList(mapSamplesN([fromSamples([1,2,3,4,5,6]), fromSamples([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))",
|
|
||||||
"Ok([6,5,4,4,5,6])",
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("builtin exception", () => {
|
describe("builtin exception", () => {
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
open Jest
|
open Jest
|
||||||
open Reducer_TestHelpers
|
open Reducer_TestHelpers
|
||||||
|
|
||||||
describe("map reduce", () => {
|
|
||||||
testEvalToBe("double(x)=2*x; arr=[1,2,3]; map(arr, double)", "Ok([2,4,6])")
|
|
||||||
testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; reduce(arr, 0, myadd)", "Ok(6)")
|
|
||||||
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduce(arr, 0, change)", "Ok(15)")
|
|
||||||
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduceReverse(arr, 0, change)", "Ok(9)")
|
|
||||||
testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])")
|
|
||||||
testEvalToBe("check(x)=(x==2);arr=[1,2,3]; filter(arr,check)", "Ok([2])")
|
|
||||||
})
|
|
||||||
|
|
||||||
Skip.describe("map reduce (sam)", () => {
|
Skip.describe("map reduce (sam)", () => {
|
||||||
testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???")
|
testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???")
|
||||||
testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???")
|
testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???")
|
||||||
|
|
|
@ -41,12 +41,6 @@ describe("eval on distribution functions", () => {
|
||||||
describe("normalize", () => {
|
describe("normalize", () => {
|
||||||
testEval("normalize(normal(5,2))", "Ok(Normal(5,2))")
|
testEval("normalize(normal(5,2))", "Ok(Normal(5,2))")
|
||||||
})
|
})
|
||||||
describe("toPointSet", () => {
|
|
||||||
testEval("toPointSet(normal(5,2))", "Ok(Point Set Distribution)")
|
|
||||||
})
|
|
||||||
describe("toSampleSet", () => {
|
|
||||||
testEval("toSampleSet(normal(5,2), 100)", "Ok(Sample Set Distribution)")
|
|
||||||
})
|
|
||||||
describe("add", () => {
|
describe("add", () => {
|
||||||
testEval("add(normal(5,2), normal(10,2))", "Ok(Normal(15,2.8284271247461903))")
|
testEval("add(normal(5,2), normal(10,2))", "Ok(Normal(15,2.8284271247461903))")
|
||||||
testEval("add(normal(5,2), lognormal(10,2))", "Ok(Sample Set Distribution)")
|
testEval("add(normal(5,2), lognormal(10,2))", "Ok(Sample Set Distribution)")
|
||||||
|
|
|
@ -16,6 +16,13 @@ describe("FunctionRegistry Library", () => {
|
||||||
testEvalToBe("List.first([3,5,8])", "Ok(3)")
|
testEvalToBe("List.first([3,5,8])", "Ok(3)")
|
||||||
testEvalToBe("List.last([3,5,8])", "Ok(8)")
|
testEvalToBe("List.last([3,5,8])", "Ok(8)")
|
||||||
testEvalToBe("List.reverse([3,5,8])", "Ok([8,5,3])")
|
testEvalToBe("List.reverse([3,5,8])", "Ok([8,5,3])")
|
||||||
|
testEvalToBe("double(x)=2*x; arr=[1,2,3]; List.map(arr, double)", "Ok([2,4,6])")
|
||||||
|
testEvalToBe("double(x)=2*x; arr=[1,2,3]; map(arr, double)", "Ok([2,4,6])")
|
||||||
|
testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; List.reduce(arr, 0, myadd)", "Ok(6)")
|
||||||
|
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduce(arr, 0, change)", "Ok(15)")
|
||||||
|
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduceReverse(arr, 0, change)", "Ok(9)")
|
||||||
|
testEvalToBe("check(x)=(x==2);arr=[1,2,3]; List.filter(arr,check)", "Ok([2])")
|
||||||
|
testEvalToBe("arr=[1,2,3]; List.reverse(arr)", "Ok([3,2,1])")
|
||||||
testEvalToBe("Dist.normal(5,2)", "Ok(Normal(5,2))")
|
testEvalToBe("Dist.normal(5,2)", "Ok(Normal(5,2))")
|
||||||
testEvalToBe("normal(5,2)", "Ok(Normal(5,2))")
|
testEvalToBe("normal(5,2)", "Ok(Normal(5,2))")
|
||||||
testEvalToBe("normal({mean:5,stdev:2})", "Ok(Normal(5,2))")
|
testEvalToBe("normal({mean:5,stdev:2})", "Ok(Normal(5,2))")
|
||||||
|
@ -53,6 +60,17 @@ describe("FunctionRegistry Library", () => {
|
||||||
)
|
)
|
||||||
testEvalToBe("Dist.logScore({estimate: normal(5,2), answer: 4.5})", "Ok(1.6433360626394853)")
|
testEvalToBe("Dist.logScore({estimate: normal(5,2), answer: 4.5})", "Ok(1.6433360626394853)")
|
||||||
testEvalToBe("Dist.klDivergence(normal(5,2), normal(5,1.5))", "Ok(0.06874342818671068)")
|
testEvalToBe("Dist.klDivergence(normal(5,2), normal(5,1.5))", "Ok(0.06874342818671068)")
|
||||||
|
testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)")
|
||||||
|
testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)")
|
||||||
|
testEvalToBe("SampleSet.fromFn({|| sample(normal(5,2))})", "Ok(Sample Set Distribution)")
|
||||||
|
testEvalToBe(
|
||||||
|
"addOne(t)=t+1; SampleSet.toList(SampleSet.map(SampleSet.fromList([1,2,3,4,5,6]), addOne))",
|
||||||
|
"Ok([2,3,4,5,6,7])",
|
||||||
|
)
|
||||||
|
testEvalToBe(
|
||||||
|
"SampleSet.toList(SampleSet.mapN([SampleSet.fromList([1,2,3,4,5,6]), SampleSet.fromList([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))",
|
||||||
|
"Ok([6,5,4,4,5,6])",
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("Fn auto-testing", () => {
|
describe("Fn auto-testing", () => {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
"test:ts": "jest __tests__/TS/",
|
"test:ts": "jest __tests__/TS/",
|
||||||
"test:rescript": "jest --modulePathIgnorePatterns=__tests__/TS/*",
|
"test:rescript": "jest --modulePathIgnorePatterns=__tests__/TS/*",
|
||||||
"test:watch": "jest --watchAll",
|
"test:watch": "jest --watchAll",
|
||||||
|
"test:fnRegistry": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js",
|
||||||
"coverage:rescript": "rm -f *.coverage && yarn clean && BISECT_ENABLE=yes yarn build && yarn test:rescript && bisect-ppx-report html",
|
"coverage:rescript": "rm -f *.coverage && yarn clean && BISECT_ENABLE=yes yarn build && yarn test:rescript && bisect-ppx-report html",
|
||||||
"coverage:ts": "yarn clean && yarn build && nyc --reporter=lcov yarn test:ts",
|
"coverage:ts": "yarn clean && yarn build && nyc --reporter=lcov yarn test:ts",
|
||||||
"coverage:rescript:ci": "yarn clean && BISECT_ENABLE=yes yarn build:rescript && yarn test:rescript && bisect-ppx-report send-to Codecov",
|
"coverage:rescript:ci": "yarn clean && BISECT_ENABLE=yes yarn build:rescript && yarn test:rescript && bisect-ppx-report send-to Codecov",
|
||||||
|
|
|
@ -47,6 +47,7 @@ type fnDefinition = {
|
||||||
array<internalExpressionValue>,
|
array<internalExpressionValue>,
|
||||||
array<frValue>,
|
array<frValue>,
|
||||||
GenericDist.env,
|
GenericDist.env,
|
||||||
|
Reducer_Expression_T.reducerFn,
|
||||||
) => result<internalExpressionValue, string>,
|
) => result<internalExpressionValue, string>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +185,9 @@ module FRType = {
|
||||||
This module, Matcher, is fairly lengthy. However, only two functions from it
|
This module, Matcher, is fairly lengthy. However, only two functions from it
|
||||||
are meant to be used outside of it. These are findMatches and matchToDef in Matches.Registry.
|
are meant to be used outside of it. These are findMatches and matchToDef in Matches.Registry.
|
||||||
The rest of it is just called from those two functions.
|
The rest of it is just called from those two functions.
|
||||||
|
|
||||||
|
Update: This really should be completely re-done sometime, and tested. It works, but it's pretty messy. I'm sure
|
||||||
|
there are internal bugs, but the end functionality works, so I'm not too worried.
|
||||||
*/
|
*/
|
||||||
module Matcher = {
|
module Matcher = {
|
||||||
module MatchSimple = {
|
module MatchSimple = {
|
||||||
|
@ -239,53 +243,82 @@ module Matcher = {
|
||||||
type definitionId = int
|
type definitionId = int
|
||||||
type match = Match.t<array<definitionId>, definitionId>
|
type match = Match.t<array<definitionId>, definitionId>
|
||||||
|
|
||||||
let match = (f: function, fnName: string, args: array<internalExpressionValue>): match => {
|
let match = (
|
||||||
let matchedDefinition = () =>
|
f: function,
|
||||||
E.A.getIndexBy(f.definitions, r =>
|
nameSpace: option<string>,
|
||||||
MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args))
|
fnName: string,
|
||||||
) |> E.O.fmap(r => Match.FullMatch(r))
|
args: array<internalExpressionValue>,
|
||||||
let getMatchedNameOnlyDefinition = () => {
|
): match => {
|
||||||
let nameMatchIndexes =
|
switch nameSpace {
|
||||||
f.definitions
|
| Some(ns) if ns !== f.nameSpace => Match.DifferentName
|
||||||
->E.A2.fmapi((index, r) =>
|
| _ => {
|
||||||
MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args)) ? Some(index) : None
|
let matchedDefinition = () =>
|
||||||
|
E.A.getIndexBy(f.definitions, r =>
|
||||||
|
MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args))
|
||||||
|
) |> E.O.fmap(r => Match.FullMatch(r))
|
||||||
|
let getMatchedNameOnlyDefinition = () => {
|
||||||
|
let nameMatchIndexes =
|
||||||
|
f.definitions
|
||||||
|
->E.A2.fmapi((index, r) =>
|
||||||
|
MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args))
|
||||||
|
? Some(index)
|
||||||
|
: None
|
||||||
|
)
|
||||||
|
->E.A.O.concatSomes
|
||||||
|
switch nameMatchIndexes {
|
||||||
|
| [] => None
|
||||||
|
| elements => Some(Match.SameNameDifferentArguments(elements))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
E.A.O.firstSomeFnWithDefault(
|
||||||
|
[matchedDefinition, getMatchedNameOnlyDefinition],
|
||||||
|
Match.DifferentName,
|
||||||
)
|
)
|
||||||
->E.A.O.concatSomes
|
|
||||||
switch nameMatchIndexes {
|
|
||||||
| [] => None
|
|
||||||
| elements => Some(Match.SameNameDifferentArguments(elements))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
E.A.O.firstSomeFnWithDefault(
|
|
||||||
[matchedDefinition, getMatchedNameOnlyDefinition],
|
|
||||||
Match.DifferentName,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module RegistryMatch = {
|
module RegistryMatch = {
|
||||||
type match = {
|
type match = {
|
||||||
|
nameSpace: string,
|
||||||
fnName: string,
|
fnName: string,
|
||||||
inputIndex: int,
|
inputIndex: int,
|
||||||
}
|
}
|
||||||
let makeMatch = (fnName: string, inputIndex: int) => {fnName: fnName, inputIndex: inputIndex}
|
let makeMatch = (nameSpace: string, fnName: string, inputIndex: int) => {
|
||||||
|
nameSpace: nameSpace,
|
||||||
|
fnName: fnName,
|
||||||
|
inputIndex: inputIndex,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module Registry = {
|
module Registry = {
|
||||||
let _findExactMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
|
let _findExactMatches = (
|
||||||
let functionMatchPairs = r.functions->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
|
r: registry,
|
||||||
|
nameSpace: option<string>,
|
||||||
|
fnName: string,
|
||||||
|
args: array<internalExpressionValue>,
|
||||||
|
) => {
|
||||||
|
let functionMatchPairs =
|
||||||
|
r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args)))
|
||||||
let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match))
|
let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match))
|
||||||
fullMatch->E.O.bind(((fn, match)) =>
|
fullMatch->E.O.bind(((fn, match)) =>
|
||||||
switch match {
|
switch match {
|
||||||
| FullMatch(index) => Some(RegistryMatch.makeMatch(fn.name, index))
|
| FullMatch(index) => Some(RegistryMatch.makeMatch(fn.nameSpace, fn.name, index))
|
||||||
| _ => None
|
| _ => None
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let _findNameMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
|
let _findNameMatches = (
|
||||||
let functionMatchPairs = r.functions->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
|
r: registry,
|
||||||
|
nameSpace: option<string>,
|
||||||
|
fnName: string,
|
||||||
|
args: array<internalExpressionValue>,
|
||||||
|
) => {
|
||||||
|
let functionMatchPairs =
|
||||||
|
r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args)))
|
||||||
let getNameMatches =
|
let getNameMatches =
|
||||||
functionMatchPairs
|
functionMatchPairs
|
||||||
->E.A2.fmap(((fn, match)) => Match.isNameMatchOnly(match) ? Some((fn, match)) : None)
|
->E.A2.fmap(((fn, match)) => Match.isNameMatchOnly(match) ? Some((fn, match)) : None)
|
||||||
|
@ -295,7 +328,7 @@ module Matcher = {
|
||||||
->E.A2.fmap(((fn, match)) =>
|
->E.A2.fmap(((fn, match)) =>
|
||||||
switch match {
|
switch match {
|
||||||
| SameNameDifferentArguments(indexes) =>
|
| SameNameDifferentArguments(indexes) =>
|
||||||
indexes->E.A2.fmap(index => RegistryMatch.makeMatch(fn.name, index))
|
indexes->E.A2.fmap(index => RegistryMatch.makeMatch(fn.nameSpace, fn.name, index))
|
||||||
| _ => []
|
| _ => []
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -306,22 +339,26 @@ module Matcher = {
|
||||||
let findMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
|
let findMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
|
||||||
let fnNameInParts = Js.String.split(".", fnName)
|
let fnNameInParts = Js.String.split(".", fnName)
|
||||||
let fnToSearch = E.A.get(fnNameInParts, 1) |> E.O.default(fnNameInParts[0])
|
let fnToSearch = E.A.get(fnNameInParts, 1) |> E.O.default(fnNameInParts[0])
|
||||||
|
let nameSpace = E.A.length(fnNameInParts) > 1 ? Some(fnNameInParts[0]) : None
|
||||||
|
|
||||||
switch _findExactMatches(r, fnToSearch, args) {
|
switch _findExactMatches(r, nameSpace, fnToSearch, args) {
|
||||||
| Some(r) => Match.FullMatch(r)
|
| Some(r) => Match.FullMatch(r)
|
||||||
| None =>
|
| None =>
|
||||||
switch _findNameMatches(r, fnToSearch, args) {
|
switch _findNameMatches(r, nameSpace, fnToSearch, args) {
|
||||||
| Some(r) => Match.SameNameDifferentArguments(r)
|
| Some(r) => Match.SameNameDifferentArguments(r)
|
||||||
| None => Match.DifferentName
|
| None => Match.DifferentName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let matchToDef = (registry: registry, {fnName, inputIndex}: RegistryMatch.match): option<
|
let matchToDef = (
|
||||||
fnDefinition,
|
registry: registry,
|
||||||
> =>
|
{nameSpace, fnName, inputIndex}: RegistryMatch.match,
|
||||||
|
): option<fnDefinition> =>
|
||||||
registry.functions
|
registry.functions
|
||||||
->E.A.getBy(fn => fn.name === fnName)
|
->E.A.getBy(fn => {
|
||||||
|
nameSpace === fn.nameSpace && fnName === fn.name
|
||||||
|
})
|
||||||
->E.O.bind(fn => E.A.get(fn.definitions, inputIndex))
|
->E.O.bind(fn => E.A.get(fn.definitions, inputIndex))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,10 +379,15 @@ module FnDefinition = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let run = (t: t, args: array<internalExpressionValue>, env: GenericDist.env) => {
|
let run = (
|
||||||
|
t: t,
|
||||||
|
args: array<internalExpressionValue>,
|
||||||
|
env: GenericDist.env,
|
||||||
|
reducer: Reducer_Expression_T.reducerFn,
|
||||||
|
) => {
|
||||||
let argValues = FRType.matchWithExpressionValueArray(t.inputs, args)
|
let argValues = FRType.matchWithExpressionValueArray(t.inputs, args)
|
||||||
switch argValues {
|
switch argValues {
|
||||||
| Some(values) => t.run(args, values, env)
|
| Some(values) => t.run(args, values, env, reducer)
|
||||||
| None => Error("Incorrect Types")
|
| None => Error("Incorrect Types")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,6 +494,7 @@ module Registry = {
|
||||||
~fnName: string,
|
~fnName: string,
|
||||||
~args: array<internalExpressionValue>,
|
~args: array<internalExpressionValue>,
|
||||||
~env: GenericDist.env,
|
~env: GenericDist.env,
|
||||||
|
~reducer: Reducer_Expression_T.reducerFn,
|
||||||
) => {
|
) => {
|
||||||
let relevantFunctions = Js.Dict.get(registry.fnNameDict, fnName) |> E.O.default([])
|
let relevantFunctions = Js.Dict.get(registry.fnNameDict, fnName) |> E.O.default([])
|
||||||
let modified = {functions: relevantFunctions, fnNameDict: registry.fnNameDict}
|
let modified = {functions: relevantFunctions, fnNameDict: registry.fnNameDict}
|
||||||
|
@ -468,7 +511,8 @@ module Registry = {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch Matcher.Registry.findMatches(modified, fnName, args) {
|
switch Matcher.Registry.findMatches(modified, fnName, args) {
|
||||||
| Matcher.Match.FullMatch(match) => match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env))
|
| Matcher.Match.FullMatch(match) =>
|
||||||
|
match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer))
|
||||||
| SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m)))
|
| SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m)))
|
||||||
| _ => None
|
| _ => None
|
||||||
}
|
}
|
||||||
|
@ -478,8 +522,9 @@ module Registry = {
|
||||||
registry,
|
registry,
|
||||||
(fnName, args): ReducerInterface_InternalExpressionValue.functionCall,
|
(fnName, args): ReducerInterface_InternalExpressionValue.functionCall,
|
||||||
env,
|
env,
|
||||||
|
reducer: Reducer_Expression_T.reducerFn,
|
||||||
) => {
|
) => {
|
||||||
_matchAndRun(~registry, ~fnName, ~args, ~env)->E.O2.fmap(
|
_matchAndRun(~registry, ~fnName, ~args, ~env, ~reducer)->E.O2.fmap(
|
||||||
E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)),
|
E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ let impossibleError = "Wrong inputs / Logically impossible"
|
||||||
|
|
||||||
module Wrappers = {
|
module Wrappers = {
|
||||||
let symbolic = r => DistributionTypes.Symbolic(r)
|
let symbolic = r => DistributionTypes.Symbolic(r)
|
||||||
|
let pointSet = r => DistributionTypes.PointSet(r)
|
||||||
|
let sampleSet = r => DistributionTypes.SampleSet(r)
|
||||||
let evDistribution = r => ReducerInterface_InternalExpressionValue.IEvDistribution(r)
|
let evDistribution = r => ReducerInterface_InternalExpressionValue.IEvDistribution(r)
|
||||||
let evNumber = r => ReducerInterface_InternalExpressionValue.IEvNumber(r)
|
let evNumber = r => ReducerInterface_InternalExpressionValue.IEvNumber(r)
|
||||||
let evArray = r => ReducerInterface_InternalExpressionValue.IEvArray(r)
|
let evArray = r => ReducerInterface_InternalExpressionValue.IEvArray(r)
|
||||||
|
|
|
@ -2,6 +2,7 @@ let fnList = Belt.Array.concatMany([
|
||||||
FR_Dict.library,
|
FR_Dict.library,
|
||||||
FR_Dist.library,
|
FR_Dist.library,
|
||||||
FR_Fn.library,
|
FR_Fn.library,
|
||||||
|
FR_Sampleset.library,
|
||||||
FR_List.library,
|
FR_List.library,
|
||||||
FR_Number.library,
|
FR_Number.library,
|
||||||
FR_Pointset.library,
|
FR_Pointset.library,
|
||||||
|
|
|
@ -52,7 +52,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="merge",
|
~name="merge",
|
||||||
~inputs=[FRTypeDict(FRTypeAny), FRTypeDict(FRTypeAny)],
|
~inputs=[FRTypeDict(FRTypeAny), FRTypeDict(FRTypeAny)],
|
||||||
~run=(inputs, _, _) => {
|
~run=(inputs, _, _, _) => {
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvRecord(d1), IEvRecord(d2)] => Internals.merge(d1, d2)->Ok
|
| [IEvRecord(d1), IEvRecord(d2)] => Internals.merge(d1, d2)->Ok
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -74,7 +74,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="mergeMany",
|
~name="mergeMany",
|
||||||
~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))],
|
~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))],
|
||||||
~run=(_, inputs, _) =>
|
~run=(_, inputs, _, _) =>
|
||||||
inputs
|
inputs
|
||||||
->Prepare.ToTypedArray.dicts
|
->Prepare.ToTypedArray.dicts
|
||||||
->E.R2.fmap(E.Dict.concatMany)
|
->E.R2.fmap(E.Dict.concatMany)
|
||||||
|
@ -96,7 +96,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="keys",
|
~name="keys",
|
||||||
~inputs=[FRTypeDict(FRTypeAny)],
|
~inputs=[FRTypeDict(FRTypeAny)],
|
||||||
~run=(inputs, _, _) =>
|
~run=(inputs, _, _, _) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvRecord(d1)] => Internals.keys(d1)->Ok
|
| [IEvRecord(d1)] => Internals.keys(d1)->Ok
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -116,7 +116,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="values",
|
~name="values",
|
||||||
~inputs=[FRTypeDict(FRTypeAny)],
|
~inputs=[FRTypeDict(FRTypeAny)],
|
||||||
~run=(inputs, _, _) =>
|
~run=(inputs, _, _, _) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvRecord(d1)] => Internals.values(d1)->Ok
|
| [IEvRecord(d1)] => Internals.values(d1)->Ok
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -136,7 +136,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="toList",
|
~name="toList",
|
||||||
~inputs=[FRTypeDict(FRTypeAny)],
|
~inputs=[FRTypeDict(FRTypeAny)],
|
||||||
~run=(inputs, _, _) =>
|
~run=(inputs, _, _, _) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvRecord(dict)] => dict->Internals.toList->Ok
|
| [IEvRecord(dict)] => dict->Internals.toList->Ok
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -156,11 +156,12 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="fromList",
|
~name="fromList",
|
||||||
~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))],
|
~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))],
|
||||||
~run=(inputs, _, _) =>
|
~run=(inputs, _, _, _) => {
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvArray(items)] => Internals.fromList(items)
|
| [IEvArray(items)] => Internals.fromList(items)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
},
|
}
|
||||||
|
},
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -21,7 +21,8 @@ module DistributionCreation = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber],
|
~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber],
|
||||||
~run=(_, inputs, env) => inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env),
|
~run=(_, inputs, env, _) =>
|
||||||
|
inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +31,7 @@ module DistributionCreation = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])],
|
~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])],
|
||||||
~run=(_, inputs, env) =>
|
~run=(_, inputs, env, _) =>
|
||||||
inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env),
|
inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
|
@ -40,7 +41,7 @@ module DistributionCreation = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])],
|
~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])],
|
||||||
~run=(_, inputs, env) =>
|
~run=(_, inputs, env, _) =>
|
||||||
inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env),
|
inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
|
@ -57,7 +58,8 @@ module DistributionCreation = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeDistOrNumber],
|
~inputs=[FRTypeDistOrNumber],
|
||||||
~run=(_, inputs, env) => inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env),
|
~run=(_, inputs, env, _) =>
|
||||||
|
inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="declare",
|
~name="declare",
|
||||||
~inputs=[Declaration.frType],
|
~inputs=[Declaration.frType],
|
||||||
~run=(_, inputs, _) => {
|
~run=(_, inputs, _, _) => {
|
||||||
inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue)
|
inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue)
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
|
|
|
@ -23,13 +23,67 @@ module Internals = {
|
||||||
let reverse = (array: array<internalExpressionValue>): internalExpressionValue => IEvArray(
|
let reverse = (array: array<internalExpressionValue>): internalExpressionValue => IEvArray(
|
||||||
Belt.Array.reverse(array),
|
Belt.Array.reverse(array),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let map = (array: array<internalExpressionValue>, environment, eLambdaValue, reducer): result<
|
||||||
|
ReducerInterface_InternalExpressionValue.t,
|
||||||
|
Reducer_ErrorValue.errorValue,
|
||||||
|
> => {
|
||||||
|
let rMappedList = array->E.A.reduceReverse(Ok(list{}), (rAcc, elem) =>
|
||||||
|
rAcc->E.R.bind(_, acc => {
|
||||||
|
let rNewElem = Reducer_Expression_Lambda.doLambdaCall(
|
||||||
|
eLambdaValue,
|
||||||
|
list{elem},
|
||||||
|
environment,
|
||||||
|
reducer,
|
||||||
|
)
|
||||||
|
rNewElem->E.R2.fmap(newElem => list{newElem, ...acc})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
let reduce = (aValueArray, initialValue, aLambdaValue, environment, reducer) => {
|
||||||
|
aValueArray->E.A.reduce(Ok(initialValue), (rAcc, elem) =>
|
||||||
|
rAcc->E.R.bind(_, acc =>
|
||||||
|
Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let reduceReverse = (aValueArray, initialValue, aLambdaValue, environment, reducer) => {
|
||||||
|
aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) =>
|
||||||
|
rAcc->Belt.Result.flatMap(acc =>
|
||||||
|
Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let filter = (aValueArray, aLambdaValue, environment, reducer) => {
|
||||||
|
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
|
||||||
|
rAcc->E.R.bind(_, acc => {
|
||||||
|
let rNewElem = Reducer_Expression_Lambda.doLambdaCall(
|
||||||
|
aLambdaValue,
|
||||||
|
list{elem},
|
||||||
|
environment,
|
||||||
|
reducer,
|
||||||
|
)
|
||||||
|
rNewElem->E.R2.fmap(newElem => {
|
||||||
|
switch newElem {
|
||||||
|
| IEvBool(true) => list{elem, ...acc}
|
||||||
|
| _ => acc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let library = [
|
let library = [
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="make",
|
~name="make",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
~requiresNamespace,
|
~requiresNamespace=true,
|
||||||
~output=EvtArray,
|
~output=EvtArray,
|
||||||
~examples=[`List.make(2, "testValue")`],
|
~examples=[`List.make(2, "testValue")`],
|
||||||
~definitions=[
|
~definitions=[
|
||||||
|
@ -37,7 +91,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="make",
|
~name="make",
|
||||||
~inputs=[FRTypeNumber, FRTypeAny],
|
~inputs=[FRTypeNumber, FRTypeAny],
|
||||||
~run=(inputs, _, _) => {
|
~run=(inputs, _, _, _) => {
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvNumber(number), value] => Internals.makeFromNumber(number, value)->Ok
|
| [IEvNumber(number), value] => Internals.makeFromNumber(number, value)->Ok
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -51,14 +105,14 @@ let library = [
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="upTo",
|
~name="upTo",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
~requiresNamespace,
|
~requiresNamespace=true,
|
||||||
~output=EvtArray,
|
~output=EvtArray,
|
||||||
~examples=[`List.upTo(1,4)`],
|
~examples=[`List.upTo(1,4)`],
|
||||||
~definitions=[
|
~definitions=[
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="upTo",
|
~name="upTo",
|
||||||
~inputs=[FRTypeNumber, FRTypeNumber],
|
~inputs=[FRTypeNumber, FRTypeNumber],
|
||||||
~run=(_, inputs, _) =>
|
~run=(_, inputs, _, _) =>
|
||||||
inputs
|
inputs
|
||||||
->Prepare.ToValueTuple.twoNumbers
|
->Prepare.ToValueTuple.twoNumbers
|
||||||
->E.R2.fmap(((low, high)) => Internals.upTo(low, high)),
|
->E.R2.fmap(((low, high)) => Internals.upTo(low, high)),
|
||||||
|
@ -70,13 +124,13 @@ let library = [
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="first",
|
~name="first",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
~requiresNamespace,
|
~requiresNamespace=true,
|
||||||
~examples=[`List.first([1,4,5])`],
|
~examples=[`List.first([1,4,5])`],
|
||||||
~definitions=[
|
~definitions=[
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="first",
|
~name="first",
|
||||||
~inputs=[FRTypeArray(FRTypeAny)],
|
~inputs=[FRTypeArray(FRTypeAny)],
|
||||||
~run=(inputs, _, _) =>
|
~run=(inputs, _, _, _) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvArray(array)] => Internals.first(array)
|
| [IEvArray(array)] => Internals.first(array)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -89,13 +143,13 @@ let library = [
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="last",
|
~name="last",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
~requiresNamespace,
|
~requiresNamespace=true,
|
||||||
~examples=[`List.last([1,4,5])`],
|
~examples=[`List.last([1,4,5])`],
|
||||||
~definitions=[
|
~definitions=[
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="last",
|
~name="last",
|
||||||
~inputs=[FRTypeArray(FRTypeAny)],
|
~inputs=[FRTypeArray(FRTypeAny)],
|
||||||
~run=(inputs, _, _) =>
|
~run=(inputs, _, _, _) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvArray(array)] => Internals.last(array)
|
| [IEvArray(array)] => Internals.last(array)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -115,7 +169,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="reverse",
|
~name="reverse",
|
||||||
~inputs=[FRTypeArray(FRTypeAny)],
|
~inputs=[FRTypeArray(FRTypeAny)],
|
||||||
~run=(inputs, _, _) =>
|
~run=(inputs, _, _, _) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvArray(array)] => Internals.reverse(array)->Ok
|
| [IEvArray(array)] => Internals.reverse(array)->Ok
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
|
@ -125,4 +179,87 @@ let library = [
|
||||||
],
|
],
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="map",
|
||||||
|
~nameSpace,
|
||||||
|
~output=EvtArray,
|
||||||
|
~requiresNamespace=false,
|
||||||
|
~examples=[`List.map([1,4,5], {|x| x+1})`],
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="map",
|
||||||
|
~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvArray(array), IEvLambda(lambda)] =>
|
||||||
|
Internals.map(array, env, lambda, reducer)->E.R2.errMap(_ => "Error!")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="reduce",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=false,
|
||||||
|
~examples=[`List.reduce([1,4,5], 2, {|acc, el| acc+el})`],
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="reduce",
|
||||||
|
~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvArray(array), initialValue, IEvLambda(lambda)] =>
|
||||||
|
Internals.reduce(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ => "Error!")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="reduceReverse",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=false,
|
||||||
|
~examples=[`List.reduceReverse([1,4,5], 2, {|acc, el| acc-el})`],
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="reduceReverse",
|
||||||
|
~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvArray(array), initialValue, IEvLambda(lambda)] =>
|
||||||
|
Internals.reduceReverse(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ =>
|
||||||
|
"Error!"
|
||||||
|
)
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="filter",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=false,
|
||||||
|
~examples=[`List.filter([1,4,5], {|x| x>3})`],
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="filter",
|
||||||
|
~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvArray(array), IEvLambda(lambda)] =>
|
||||||
|
Internals.filter(array, lambda, env, reducer)->E.R2.errMap(_ => "Error!")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,7 +9,7 @@ module NumberToNumber = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeNumber],
|
~inputs=[FRTypeNumber],
|
||||||
~run=(_, inputs, _) => {
|
~run=(_, inputs, _, _) => {
|
||||||
inputs
|
inputs
|
||||||
->getOrError(0)
|
->getOrError(0)
|
||||||
->E.R.bind(Prepare.oneNumber)
|
->E.R.bind(Prepare.oneNumber)
|
||||||
|
@ -25,7 +25,7 @@ module ArrayNumberDist = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeArray(FRTypeNumber)],
|
~inputs=[FRTypeArray(FRTypeNumber)],
|
||||||
~run=(_, inputs, _) =>
|
~run=(_, inputs, _, _) =>
|
||||||
Prepare.ToTypedArray.numbers(inputs)
|
Prepare.ToTypedArray.numbers(inputs)
|
||||||
->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r))
|
->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r))
|
||||||
->E.R.bind(fn),
|
->E.R.bind(fn),
|
||||||
|
@ -36,7 +36,7 @@ module ArrayNumberDist = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeArray(FRTypeAny)],
|
~inputs=[FRTypeArray(FRTypeAny)],
|
||||||
~run=(_, inputs, _) =>
|
~run=(_, inputs, _, _) =>
|
||||||
Prepare.ToTypedArray.numbers(inputs)
|
Prepare.ToTypedArray.numbers(inputs)
|
||||||
->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r))
|
->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r))
|
||||||
->E.R.bind(fn),
|
->E.R.bind(fn),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
open FunctionRegistry_Core
|
open FunctionRegistry_Core
|
||||||
open FunctionRegistry_Helpers
|
open FunctionRegistry_Helpers
|
||||||
|
|
||||||
let nameSpace = "Pointset"
|
let nameSpace = "PointSet"
|
||||||
let requiresNamespace = true
|
let requiresNamespace = true
|
||||||
|
|
||||||
let inputsTodist = (inputs: array<FunctionRegistry_Core.frValue>, makeDist) => {
|
let inputsTodist = (inputs: array<FunctionRegistry_Core.frValue>, makeDist) => {
|
||||||
|
@ -24,12 +24,41 @@ let inputsTodist = (inputs: array<FunctionRegistry_Core.frValue>, makeDist) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
let library = [
|
let library = [
|
||||||
|
Function.make(
|
||||||
|
~name="fromDist",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=true,
|
||||||
|
~examples=[`PointSet.fromDist(normal(5,2))`],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="fromDist",
|
||||||
|
~inputs=[FRTypeDist],
|
||||||
|
~run=(_, inputs, env, _) =>
|
||||||
|
switch inputs {
|
||||||
|
| [FRValueDist(dist)] =>
|
||||||
|
GenericDist.toPointSet(
|
||||||
|
dist,
|
||||||
|
~xyPointLength=env.xyPointLength,
|
||||||
|
~sampleCount=env.sampleCount,
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
->E.R2.fmap(Wrappers.pointSet)
|
||||||
|
->E.R2.fmap(Wrappers.evDistribution)
|
||||||
|
->E.R2.errMap(_ => "")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="makeContinuous",
|
~name="makeContinuous",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
~requiresNamespace,
|
~requiresNamespace,
|
||||||
~examples=[
|
~examples=[
|
||||||
`Pointset.makeContinuous([
|
`PointSet.makeContinuous([
|
||||||
{x: 0, y: 0.2},
|
{x: 0, y: 0.2},
|
||||||
{x: 1, y: 0.7},
|
{x: 1, y: 0.7},
|
||||||
{x: 2, y: 0.8},
|
{x: 2, y: 0.8},
|
||||||
|
@ -41,7 +70,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="makeContinuous",
|
~name="makeContinuous",
|
||||||
~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))],
|
~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))],
|
||||||
~run=(_, inputs, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))),
|
~run=(_, inputs, _, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))),
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -52,7 +81,7 @@ let library = [
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
~requiresNamespace,
|
~requiresNamespace,
|
||||||
~examples=[
|
~examples=[
|
||||||
`Pointset.makeDiscrete([
|
`PointSet.makeDiscrete([
|
||||||
{x: 0, y: 0.2},
|
{x: 0, y: 0.2},
|
||||||
{x: 1, y: 0.7},
|
{x: 1, y: 0.7},
|
||||||
{x: 2, y: 0.8},
|
{x: 2, y: 0.8},
|
||||||
|
@ -64,7 +93,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="makeDiscrete",
|
~name="makeDiscrete",
|
||||||
~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))],
|
~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))],
|
||||||
~run=(_, inputs, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))),
|
~run=(_, inputs, _, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))),
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,272 @@
|
||||||
|
open FunctionRegistry_Core
|
||||||
|
open FunctionRegistry_Helpers
|
||||||
|
|
||||||
|
let nameSpace = "SampleSet"
|
||||||
|
let requiresNamespace = true
|
||||||
|
|
||||||
|
module Internal = {
|
||||||
|
type t = SampleSetDist.t
|
||||||
|
let doLambdaCall = (aLambdaValue, list, environment, reducer) =>
|
||||||
|
switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) {
|
||||||
|
| Ok(IEvNumber(f)) => Ok(f)
|
||||||
|
| _ => Error(Operation.SampleMapNeedsNtoNFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
let toType = (r): result<
|
||||||
|
ReducerInterface_InternalExpressionValue.t,
|
||||||
|
Reducer_ErrorValue.errorValue,
|
||||||
|
> =>
|
||||||
|
switch r {
|
||||||
|
| Ok(r) => Ok(Wrappers.evDistribution(SampleSet(r)))
|
||||||
|
| Error(r) => Error(REDistributionError(SampleSetError(r)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: I don't know why this seems to need at least one input
|
||||||
|
let fromFn = (
|
||||||
|
aLambdaValue,
|
||||||
|
env: ReducerInterface_InternalExpressionValue.environment,
|
||||||
|
reducer,
|
||||||
|
) => {
|
||||||
|
let sampleCount = env.sampleCount
|
||||||
|
let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer)
|
||||||
|
Belt_Array.makeBy(sampleCount, r => fn(r->Js.Int.toFloat))->E.A.R.firstErrorOrOpen
|
||||||
|
}
|
||||||
|
|
||||||
|
let map1 = (sampleSetDist: t, aLambdaValue, env, reducer) => {
|
||||||
|
let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer)
|
||||||
|
SampleSetDist.samplesMap(~fn, sampleSetDist)->toType
|
||||||
|
}
|
||||||
|
|
||||||
|
let map2 = (t1: t, t2: t, aLambdaValue, env, reducer) => {
|
||||||
|
let fn = (a, b) => doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)}, env, reducer)
|
||||||
|
SampleSetDist.map2(~fn, ~t1, ~t2)->toType
|
||||||
|
}
|
||||||
|
|
||||||
|
let map3 = (t1: t, t2: t, t3: t, aLambdaValue, env, reducer) => {
|
||||||
|
let fn = (a, b, c) =>
|
||||||
|
doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)}, env, reducer)
|
||||||
|
SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType
|
||||||
|
}
|
||||||
|
|
||||||
|
let parseSampleSetArray = (arr: array<internalExpressionValue>): option<
|
||||||
|
array<SampleSetDist.t>,
|
||||||
|
> => {
|
||||||
|
let parseSampleSet = (value: internalExpressionValue): option<SampleSetDist.t> =>
|
||||||
|
switch value {
|
||||||
|
| IEvDistribution(SampleSet(dist)) => Some(dist)
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
E.A.O.openIfAllSome(E.A.fmap(parseSampleSet, arr))
|
||||||
|
}
|
||||||
|
|
||||||
|
let mapN = (aValueArray: array<internalExpressionValue>, aLambdaValue, env, reducer) => {
|
||||||
|
switch parseSampleSetArray(aValueArray) {
|
||||||
|
| Some(t1) =>
|
||||||
|
let fn = a =>
|
||||||
|
doLambdaCall(
|
||||||
|
aLambdaValue,
|
||||||
|
list{IEvArray(E.A.fmap(x => Wrappers.evNumber(x), a))},
|
||||||
|
env,
|
||||||
|
reducer,
|
||||||
|
)
|
||||||
|
SampleSetDist.mapN(~fn, ~t1)->toType
|
||||||
|
| None => Error(REFunctionNotFound(""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let library = [
|
||||||
|
Function.make(
|
||||||
|
~name="fromDist",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=true,
|
||||||
|
~examples=[`SampleSet.fromDist(normal(5,2))`],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="fromDist",
|
||||||
|
~inputs=[FRTypeDist],
|
||||||
|
~run=(_, inputs, env, _) =>
|
||||||
|
switch inputs {
|
||||||
|
| [FRValueDist(dist)] =>
|
||||||
|
GenericDist.toSampleSetDist(dist, env.sampleCount)
|
||||||
|
->E.R2.fmap(Wrappers.sampleSet)
|
||||||
|
->E.R2.fmap(Wrappers.evDistribution)
|
||||||
|
->E.R2.errMap(_ => "")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="fromList",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=true,
|
||||||
|
~examples=[`SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="fromList",
|
||||||
|
~inputs=[FRTypeArray(FRTypeNumber)],
|
||||||
|
~run=(_, inputs, _, _) => {
|
||||||
|
let sampleSet =
|
||||||
|
Prepare.ToTypedArray.numbers(inputs) |> E.R2.bind(r =>
|
||||||
|
SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??")
|
||||||
|
)
|
||||||
|
sampleSet->E.R2.fmap(Wrappers.sampleSet)->E.R2.fmap(Wrappers.evDistribution)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="toList",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=true,
|
||||||
|
~examples=[`SampleSet.toList(SampleSet.fromDist(normal(5,2)))`],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtArray,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="toList",
|
||||||
|
~inputs=[FRTypeDist],
|
||||||
|
~run=(inputs, _, _, _) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvDistribution(SampleSet(dist))] =>
|
||||||
|
dist->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="fromFn",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=true,
|
||||||
|
~examples=[`SampleSet.fromFn({|| sample(normal(5,2))})`],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="fromFn",
|
||||||
|
~inputs=[FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvLambda(lambda)] =>
|
||||||
|
switch Internal.fromFn(lambda, env, reducer) {
|
||||||
|
| Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution)
|
||||||
|
| Error(_) => Error("issue")
|
||||||
|
}
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="map",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace,
|
||||||
|
~examples=[`SampleSet.map(SampleSet.fromDist(normal(5,2)), {|x| x + 1})`],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="map",
|
||||||
|
~inputs=[FRTypeDist, FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] =>
|
||||||
|
Internal.map1(dist, lambda, env, reducer)->E.R2.errMap(_ => "")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="map2",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace,
|
||||||
|
~examples=[
|
||||||
|
`SampleSet.map2(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y| x + y})`,
|
||||||
|
],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="map2",
|
||||||
|
~inputs=[FRTypeDist, FRTypeDist, FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) => {
|
||||||
|
switch inputs {
|
||||||
|
| [
|
||||||
|
IEvDistribution(SampleSet(dist1)),
|
||||||
|
IEvDistribution(SampleSet(dist2)),
|
||||||
|
IEvLambda(lambda),
|
||||||
|
] =>
|
||||||
|
Internal.map2(dist1, dist2, lambda, env, reducer)->E.R2.errMap(_ => "")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="map3",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace,
|
||||||
|
~examples=[
|
||||||
|
`SampleSet.map3(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y, z| max([x,y,z])})`,
|
||||||
|
],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="map3",
|
||||||
|
~inputs=[FRTypeDist, FRTypeDist, FRTypeDist, FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [
|
||||||
|
IEvDistribution(SampleSet(dist1)),
|
||||||
|
IEvDistribution(SampleSet(dist2)),
|
||||||
|
IEvDistribution(SampleSet(dist3)),
|
||||||
|
IEvLambda(lambda),
|
||||||
|
] =>
|
||||||
|
Internal.map3(dist1, dist2, dist3, lambda, env, reducer)->E.R2.errMap(_ => "")
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="mapN",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace,
|
||||||
|
~examples=[
|
||||||
|
`SampleSet.mapN([SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2))], {|x| max(x)})`,
|
||||||
|
],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="mapN",
|
||||||
|
~inputs=[FRTypeArray(FRTypeDist), FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvArray(dists), IEvLambda(lambda)] =>
|
||||||
|
Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(e => {
|
||||||
|
"AHHH doesn't work"
|
||||||
|
})
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
]
|
|
@ -30,7 +30,7 @@ let library = [
|
||||||
("prior", FRTypeDist),
|
("prior", FRTypeDist),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
~run=(_, inputs, env) => {
|
~run=(_, inputs, env, _) => {
|
||||||
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs) {
|
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs) {
|
||||||
| Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d)), FRValueDist(prior)]) =>
|
| Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d)), FRValueDist(prior)]) =>
|
||||||
runScoring(estimate, Score_Dist(d), Some(prior), env)
|
runScoring(estimate, Score_Dist(d), Some(prior), env)
|
||||||
|
@ -49,7 +49,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="logScore",
|
~name="logScore",
|
||||||
~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])],
|
~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])],
|
||||||
~run=(_, inputs, env) => {
|
~run=(_, inputs, env, _) => {
|
||||||
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs) {
|
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs) {
|
||||||
| Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d))]) =>
|
| Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d))]) =>
|
||||||
runScoring(estimate, Score_Dist(d), None, env)
|
runScoring(estimate, Score_Dist(d), None, env)
|
||||||
|
@ -74,7 +74,7 @@ let library = [
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name="klDivergence",
|
~name="klDivergence",
|
||||||
~inputs=[FRTypeDist, FRTypeDist],
|
~inputs=[FRTypeDist, FRTypeDist],
|
||||||
~run=(_, inputs, env) => {
|
~run=(_, inputs, env, _) => {
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [FRValueDist(estimate), FRValueDist(d)] =>
|
| [FRValueDist(estimate), FRValueDist(d)] =>
|
||||||
runScoring(estimate, Score_Dist(d), None, env)
|
runScoring(estimate, Score_Dist(d), None, env)
|
||||||
|
|
|
@ -95,33 +95,7 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
|
||||||
|
|
||||||
let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok
|
let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok
|
||||||
|
|
||||||
let doKeepArray = (aValueArray, aLambdaValue) => {
|
|
||||||
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
|
|
||||||
rAcc->Result.flatMap(acc => {
|
|
||||||
let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer)
|
|
||||||
rNewElem->Result.map(newElem =>
|
|
||||||
switch newElem {
|
|
||||||
| IEvBool(true) => list{elem, ...acc}
|
|
||||||
| _ => acc
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray)
|
|
||||||
}
|
|
||||||
|
|
||||||
let doMapArray = (aValueArray, aLambdaValue) => {
|
|
||||||
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
|
|
||||||
rAcc->Result.flatMap(acc => {
|
|
||||||
let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer)
|
|
||||||
rNewElem->Result.map(newElem => list{newElem, ...acc})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray)
|
|
||||||
}
|
|
||||||
|
|
||||||
module SampleMap = {
|
module SampleMap = {
|
||||||
type t = SampleSetDist.t
|
|
||||||
let doLambdaCall = (aLambdaValue, list) =>
|
let doLambdaCall = (aLambdaValue, list) =>
|
||||||
switch Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) {
|
switch Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) {
|
||||||
| Ok(IEvNumber(f)) => Ok(f)
|
| Ok(IEvNumber(f)) => Ok(f)
|
||||||
|
@ -134,22 +108,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
|
||||||
| Error(r) => Error(REDistributionError(SampleSetError(r)))
|
| Error(r) => Error(REDistributionError(SampleSetError(r)))
|
||||||
}
|
}
|
||||||
|
|
||||||
let map1 = (sampleSetDist: t, aLambdaValue) => {
|
|
||||||
let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)})
|
|
||||||
toType(SampleSetDist.samplesMap(~fn, sampleSetDist))
|
|
||||||
}
|
|
||||||
|
|
||||||
let map2 = (t1: t, t2: t, aLambdaValue) => {
|
|
||||||
let fn = (a, b) => doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)})
|
|
||||||
SampleSetDist.map2(~fn, ~t1, ~t2)->toType
|
|
||||||
}
|
|
||||||
|
|
||||||
let map3 = (t1: t, t2: t, t3: t, aLambdaValue) => {
|
|
||||||
let fn = (a, b, c) =>
|
|
||||||
doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)})
|
|
||||||
SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType
|
|
||||||
}
|
|
||||||
|
|
||||||
let parseSampleSetArray = (arr: array<internalExpressionValue>): option<
|
let parseSampleSetArray = (arr: array<internalExpressionValue>): option<
|
||||||
array<SampleSetDist.t>,
|
array<SampleSetDist.t>,
|
||||||
> => {
|
> => {
|
||||||
|
@ -172,22 +130,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let doReduceArray = (aValueArray, initialValue, aLambdaValue) => {
|
|
||||||
aValueArray->Belt.Array.reduce(Ok(initialValue), (rAcc, elem) =>
|
|
||||||
rAcc->Result.flatMap(acc =>
|
|
||||||
Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let doReduceReverseArray = (aValueArray, initialValue, aLambdaValue) => {
|
|
||||||
aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) =>
|
|
||||||
rAcc->Result.flatMap(acc =>
|
|
||||||
Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch call {
|
switch call {
|
||||||
| ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
|
| ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
|
||||||
| ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex)
|
| ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex)
|
||||||
|
@ -226,38 +168,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
|
||||||
doAddString(aValueString, bValueString)
|
doAddString(aValueString, bValueString)
|
||||||
| ("inspect", [value, IEvString(label)]) => inspectLabel(value, label)
|
| ("inspect", [value, IEvString(label)]) => inspectLabel(value, label)
|
||||||
| ("inspect", [value]) => inspect(value)
|
| ("inspect", [value]) => inspect(value)
|
||||||
| ("filter", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
|
|
||||||
doKeepArray(aValueArray, aLambdaValue)
|
|
||||||
| ("map", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
|
|
||||||
doMapArray(aValueArray, aLambdaValue)
|
|
||||||
| ("mapSamples", [IEvDistribution(SampleSet(dist)), IEvLambda(aLambdaValue)]) =>
|
|
||||||
SampleMap.map1(dist, aLambdaValue)
|
|
||||||
| (
|
|
||||||
"mapSamples2",
|
|
||||||
[
|
|
||||||
IEvDistribution(SampleSet(dist1)),
|
|
||||||
IEvDistribution(SampleSet(dist2)),
|
|
||||||
IEvLambda(aLambdaValue),
|
|
||||||
],
|
|
||||||
) =>
|
|
||||||
SampleMap.map2(dist1, dist2, aLambdaValue)
|
|
||||||
| (
|
|
||||||
"mapSamples3",
|
|
||||||
[
|
|
||||||
IEvDistribution(SampleSet(dist1)),
|
|
||||||
IEvDistribution(SampleSet(dist2)),
|
|
||||||
IEvDistribution(SampleSet(dist3)),
|
|
||||||
IEvLambda(aLambdaValue),
|
|
||||||
],
|
|
||||||
) =>
|
|
||||||
SampleMap.map3(dist1, dist2, dist3, aLambdaValue)
|
|
||||||
| ("mapSamplesN", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
|
|
||||||
SampleMap.mapN(aValueArray, aLambdaValue)
|
|
||||||
| ("reduce", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) =>
|
|
||||||
doReduceArray(aValueArray, initialValue, aLambdaValue)
|
|
||||||
| ("reduceReverse", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) =>
|
|
||||||
doReduceReverseArray(aValueArray, initialValue, aLambdaValue)
|
|
||||||
| ("reverse", [IEvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->IEvArray->Ok
|
|
||||||
| (_, [IEvBool(_)])
|
| (_, [IEvBool(_)])
|
||||||
| (_, [IEvNumber(_)])
|
| (_, [IEvNumber(_)])
|
||||||
| (_, [IEvString(_)])
|
| (_, [IEvString(_)])
|
||||||
|
|
|
@ -4,16 +4,18 @@ type internalExpressionValue = InternalExpressionValue.t
|
||||||
/*
|
/*
|
||||||
Map external calls of Reducer
|
Map external calls of Reducer
|
||||||
*/
|
*/
|
||||||
let dispatch = (call: InternalExpressionValue.functionCall, environment, reducer, chain): result<
|
let dispatch = (
|
||||||
internalExpressionValue,
|
call: InternalExpressionValue.functionCall,
|
||||||
'e,
|
environment,
|
||||||
> => {
|
reducer: Reducer_Expression_T.reducerFn,
|
||||||
|
chain,
|
||||||
|
): result<internalExpressionValue, 'e> => {
|
||||||
E.A.O.firstSomeFn([
|
E.A.O.firstSomeFn([
|
||||||
() => ReducerInterface_GenericDistribution.dispatch(call, environment),
|
() => ReducerInterface_GenericDistribution.dispatch(call, environment),
|
||||||
() => ReducerInterface_Date.dispatch(call, environment),
|
() => ReducerInterface_Date.dispatch(call, environment),
|
||||||
() => ReducerInterface_Duration.dispatch(call, environment),
|
() => ReducerInterface_Duration.dispatch(call, environment),
|
||||||
() => ReducerInterface_Number.dispatch(call, environment),
|
() => ReducerInterface_Number.dispatch(call, environment),
|
||||||
() => FunctionRegistry_Library.dispatch(call, environment),
|
() => FunctionRegistry_Library.dispatch(call, environment, reducer),
|
||||||
])->E.O2.default(chain(call, environment, reducer))
|
])->E.O2.default(chain(call, environment, reducer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -233,19 +233,6 @@ let dispatchToGenericOutput = (call: IEV.functionCall, env: GenericDist.env): op
|
||||||
| ("inv", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env)
|
| ("inv", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env)
|
||||||
| ("quantile", [IEvDistribution(dist), IEvNumber(float)]) =>
|
| ("quantile", [IEvDistribution(dist), IEvNumber(float)]) =>
|
||||||
Helpers.toFloatFn(#Inv(float), dist, ~env)
|
Helpers.toFloatFn(#Inv(float), dist, ~env)
|
||||||
| ("toSampleSet", [IEvDistribution(dist), IEvNumber(float)]) =>
|
|
||||||
Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist, ~env)
|
|
||||||
| ("toSampleSet", [IEvDistribution(dist)]) =>
|
|
||||||
Helpers.toDistFn(ToSampleSet(env.sampleCount), dist, ~env)
|
|
||||||
| ("toList", [IEvDistribution(SampleSet(dist))]) => Some(FloatArray(SampleSetDist.T.get(dist)))
|
|
||||||
| ("fromSamples", [IEvArray(inputArray)]) => {
|
|
||||||
let _wrapInputErrors = x => SampleSetDist.NonNumericInput(x)
|
|
||||||
let parsedArray = Helpers.parseNumberArray(inputArray)->E.R2.errMap(_wrapInputErrors)
|
|
||||||
switch parsedArray {
|
|
||||||
| Ok(array) => DistributionOperation.run(FromSamples(array), ~env)
|
|
||||||
| Error(e) => GenDistError(SampleSetError(e))
|
|
||||||
}->Some
|
|
||||||
}
|
|
||||||
| ("inspect", [IEvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist, ~env)
|
| ("inspect", [IEvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist, ~env)
|
||||||
| ("truncateLeft", [IEvDistribution(dist), IEvNumber(float)]) =>
|
| ("truncateLeft", [IEvDistribution(dist), IEvNumber(float)]) =>
|
||||||
Helpers.toDistFn(Truncate(Some(float), None), dist, ~env)
|
Helpers.toDistFn(Truncate(Some(float), None), dist, ~env)
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Bindings = Reducer_Bindings
|
||||||
|
|
||||||
let bindings: Bindings.t =
|
let bindings: Bindings.t =
|
||||||
[
|
[
|
||||||
("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.2.11")),
|
("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.2.12")),
|
||||||
]->Bindings.fromArray
|
]->Bindings.fromArray
|
||||||
|
|
||||||
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
||||||
|
|
|
@ -546,6 +546,7 @@ module A = {
|
||||||
let slice = Belt.Array.slice
|
let slice = Belt.Array.slice
|
||||||
let init = Array.init
|
let init = Array.init
|
||||||
let reduce = Belt.Array.reduce
|
let reduce = Belt.Array.reduce
|
||||||
|
let reduceReverse = Belt.Array.reduceReverse
|
||||||
let reducei = Belt.Array.reduceWithIndex
|
let reducei = Belt.Array.reduceWithIndex
|
||||||
let some = Belt.Array.some
|
let some = Belt.Array.some
|
||||||
let isEmpty = r => length(r) < 1
|
let isEmpty = r => length(r) < 1
|
||||||
|
|
|
@ -5,16 +5,14 @@ title: Date
|
||||||
|
|
||||||
Squiggle date types are a very simple implementation on [Javascript's Date type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). It's mainly here for early experimentation. There are more relevant functions for the [Duration](/docs/Api/Duration) type.
|
Squiggle date types are a very simple implementation on [Javascript's Date type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). It's mainly here for early experimentation. There are more relevant functions for the [Duration](/docs/Api/Duration) type.
|
||||||
|
|
||||||
### makeFromYear
|
### fromYear
|
||||||
|
|
||||||
(Now `makeDateFromYear`)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Date.makeFromYear: (number) => date
|
Date.fromYear: (number) => date
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
makeFromYear(2022.32);
|
Date.fromYear(2022.32);
|
||||||
```
|
```
|
||||||
|
|
||||||
### toString
|
### toString
|
||||||
|
@ -30,7 +28,7 @@ add: (date, duration) => date
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
makeFromYear(2022.32) + years(5);
|
Date.fromYear(2022.32) + years(5);
|
||||||
```
|
```
|
||||||
|
|
||||||
### subtract
|
### subtract
|
||||||
|
@ -41,6 +39,6 @@ subtract: (date, duration) => date
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
makeFromYear(2040) - makeFromYear(2020); // 20 years
|
Date.fromYear(2040) - Date.fromYear(2020); // 20 years
|
||||||
makeFromYear(2040) - years(20); // 2020
|
Date.fromYear(2040) - years(20); // 2020
|
||||||
```
|
```
|
||||||
|
|
|
@ -364,6 +364,26 @@ klDivergence: (distribution, distribution) => number
|
||||||
klDivergence(normal(5, 2), normal(5, 4)); // returns 0.57
|
klDivergence(normal(5, 2), normal(5, 4)); // returns 0.57
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### logScore
|
||||||
|
|
||||||
|
A log loss score. Often that often acts as a [scoring rule](https://en.wikipedia.org/wiki/Scoring_rule). Useful when evaluating the accuracy of a forecast.
|
||||||
|
|
||||||
|
Note that it is fairly slow.
|
||||||
|
|
||||||
|
```
|
||||||
|
logScore: ({estimate: distribution, ?prior: distribution, answer: distribution|number}) => number
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
Dist.logScore({
|
||||||
|
estimate: normal(5, 2),
|
||||||
|
answer: normal(4.5, 1.2),
|
||||||
|
prior: normal(6, 4),
|
||||||
|
}); // returns -0.597.57
|
||||||
|
```
|
||||||
|
|
||||||
## Display
|
## Display
|
||||||
|
|
||||||
### toString
|
### toString
|
||||||
|
@ -414,7 +434,7 @@ The only functions that do not return normalized distributions are the pointwise
|
||||||
|
|
||||||
### normalize
|
### normalize
|
||||||
|
|
||||||
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1.
|
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. This only impacts Pointset distributions, because those are the only ones that can be non-normlized.
|
||||||
|
|
||||||
```
|
```
|
||||||
normalize: (distribution) => distribution
|
normalize: (distribution) => distribution
|
||||||
|
@ -606,75 +626,3 @@ dotPow: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
dotExp: (distributionLike, distributionLike) => distribution
|
dotExp: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
## Scale Arithmetic Operations
|
|
||||||
|
|
||||||
<Admonition type="caution" title="Likely to change">
|
|
||||||
<p>
|
|
||||||
We're planning on removing scale operations in favor of more general
|
|
||||||
functions soon.
|
|
||||||
</p>
|
|
||||||
</Admonition>
|
|
||||||
|
|
||||||
Scale operations are similar to pointwise operations, but operate on a constant y-value instead of y-values coming from a distribution. You can think about this as scaling a distribution vertically by a constant.
|
|
||||||
|
|
||||||
The following items would be equivalent.
|
|
||||||
|
|
||||||
```js
|
|
||||||
scalePow(normal(5,2), 2)
|
|
||||||
mapY(normal(5,2), {|y| y ^ 2}) // Not yet available
|
|
||||||
```
|
|
||||||
|
|
||||||
### scaleMultiply
|
|
||||||
|
|
||||||
```
|
|
||||||
scaleMultiply: (distributionLike, number) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
### scalePow
|
|
||||||
|
|
||||||
```
|
|
||||||
scalePow: (distributionLike, number) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
### scaleExp
|
|
||||||
|
|
||||||
```
|
|
||||||
scaleExp: (distributionLike, number) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
### scaleLog
|
|
||||||
|
|
||||||
```
|
|
||||||
scaleLog: (distributionLike, number) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
### scaleLog10
|
|
||||||
|
|
||||||
```
|
|
||||||
scaleLog10: (distributionLike, number) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
## Special
|
|
||||||
|
|
||||||
### Declaration (Continuous Functions)
|
|
||||||
|
|
||||||
Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making formal predictions. It allows you to limit the domain that your prediction will be used and scored within.
|
|
||||||
|
|
||||||
Declarations are currently experimental and will likely be removed or changed in the future.
|
|
||||||
|
|
||||||
```
|
|
||||||
declareFn: (dict<{fn: lambda, inputs: array<dict<{min: number, max: number}>>}>) => declaration
|
|
||||||
```
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
declareFn({
|
|
||||||
fn: {|a,b| a },
|
|
||||||
inputs: [
|
|
||||||
{min: 0, max: 100},
|
|
||||||
{min: 30, max: 50}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
|
@ -3,26 +3,20 @@ sidebar_position: 4
|
||||||
title: Point Set Distribution
|
title: Point Set Distribution
|
||||||
---
|
---
|
||||||
|
|
||||||
:::danger
|
|
||||||
These functions aren't yet implemented with these specific names. This should be changed soon
|
|
||||||
:::
|
|
||||||
|
|
||||||
Point set distributions are one of the three distribution formats. They are stored as a list of x-y coordinates representing both discrete and continuous distributions.
|
Point set distributions are one of the three distribution formats. They are stored as a list of x-y coordinates representing both discrete and continuous distributions.
|
||||||
|
|
||||||
One complication is that it's possible to represent invalid probability distributions in the point set format. For example, you can represent shapes with negative values, or shapes that are not normalized.
|
One complication is that it's possible to represent invalid probability distributions in the point set format. For example, you can represent shapes with negative values, or shapes that are not normalized.
|
||||||
|
|
||||||
### make
|
### fromDist
|
||||||
|
|
||||||
Converts the distribution in question into a point set distribution. If the distribution is symbolic, then it does this by taking the quantiles. If the distribution is a sample set, then it uses a version of kernel density estimation to approximate the point set format. One complication of this latter process is that if there is a high proportion of overlapping samples (samples that are exactly the same as each other), it will convert these samples into discrete point masses. Eventually we'd like to add further methods to help adjust this process.
|
Converts the distribution in question into a point set distribution. If the distribution is symbolic, then it does this by taking the quantiles. If the distribution is a sample set, then it uses a version of kernel density estimation to approximate the point set format. One complication of this latter process is that if there is a high proportion of overlapping samples (samples that are exactly the same as each other), it will convert these samples into discrete point masses. Eventually we'd like to add further methods to help adjust this process.
|
||||||
|
|
||||||
```
|
```
|
||||||
PointSet.make: (distribution) => pointSetDist
|
PointSet.fromDist: (distribution) => pointSetDist
|
||||||
```
|
```
|
||||||
|
|
||||||
### makeContinuous
|
### makeContinuous
|
||||||
|
|
||||||
**TODO: Now called "toContinuousPointSet"**
|
|
||||||
|
|
||||||
Converts a set of x-y coordinates directly into a continuous distribution.
|
Converts a set of x-y coordinates directly into a continuous distribution.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -40,10 +34,6 @@ PointSet.makeContinuous([
|
||||||
|
|
||||||
### makeDiscrete
|
### makeDiscrete
|
||||||
|
|
||||||
**TODO: Now called "toDiscretePointSet"**
|
|
||||||
|
|
||||||
Converts a set of x-y coordinates directly into a discrete distribution.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
PointSet.makeDiscrete: (list<{x: number, y: number}>) => pointSetDist
|
PointSet.makeDiscrete: (list<{x: number, y: number}>) => pointSetDist
|
||||||
```
|
```
|
||||||
|
|
|
@ -3,22 +3,42 @@ sidebar_position: 5
|
||||||
title: Sample Set Distribution
|
title: Sample Set Distribution
|
||||||
---
|
---
|
||||||
|
|
||||||
:::danger
|
|
||||||
These functions aren't yet implemented with these specific names. This should be added soon.
|
|
||||||
:::
|
|
||||||
|
|
||||||
Sample set distributions are one of the three distribution formats. Internally, they are stored as a list of numbers. It's useful to distinguish point set distributions from arbitrary lists of numbers to make it clear which functions are applicable.
|
Sample set distributions are one of the three distribution formats. Internally, they are stored as a list of numbers. It's useful to distinguish point set distributions from arbitrary lists of numbers to make it clear which functions are applicable.
|
||||||
|
|
||||||
Monte Carlo calculations typically result in sample set distributions.
|
Monte Carlo calculations typically result in sample set distributions.
|
||||||
|
|
||||||
All regular distribution function work on sample set distributions. In addition, there are several functions that only work on sample set distributions.
|
All regular distribution function work on sample set distributions. In addition, there are several functions that only work on sample set distributions.
|
||||||
|
|
||||||
### make
|
### fromDist
|
||||||
|
|
||||||
```
|
```
|
||||||
SampleSet.make: (distribution) => sampleSet
|
SampleSet.fromDist: (list<number>) => sampleSet
|
||||||
SampleSet.make: (list<number>) => sampleSet
|
```
|
||||||
SampleSet.make: (() => number) => sampleSet // not yet implemented
|
|
||||||
|
### fromList
|
||||||
|
|
||||||
|
```
|
||||||
|
SampleSet.fromList: (list<number>) => sampleSet
|
||||||
|
```
|
||||||
|
|
||||||
|
### fromFn
|
||||||
|
|
||||||
|
```
|
||||||
|
SampleSet.fromFn: ((float) => number) => sampleSet
|
||||||
|
```
|
||||||
|
|
||||||
|
### toList
|
||||||
|
|
||||||
|
```
|
||||||
|
SampleSet.toList: (sampleSet) => list<number>
|
||||||
|
```
|
||||||
|
|
||||||
|
Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length.
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```
|
||||||
|
toList(toSampleSet(normal(5,2)))
|
||||||
```
|
```
|
||||||
|
|
||||||
### map
|
### map
|
||||||
|
@ -39,16 +59,8 @@ SampleSet.map2: (sampleSet, sampleSet, ((number, number) => number)) => sampleSe
|
||||||
SampleSet.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet
|
SampleSet.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet
|
||||||
```
|
```
|
||||||
|
|
||||||
### toList
|
### mapN
|
||||||
|
|
||||||
```
|
```
|
||||||
SampleSet.toList: (sampleSet) => list<number>
|
Sampleset.mapN: (list<sampleSet>, (list<sampleSet> => number)) => sampleSet
|
||||||
```
|
|
||||||
|
|
||||||
Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length.
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```
|
|
||||||
toList(toSampleSet(normal(5,2)))
|
|
||||||
```
|
```
|
||||||
|
|
27
packages/website/docs/Api/Function.md
Normal file
27
packages/website/docs/Api/Function.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
sidebar_position: 6
|
||||||
|
title: Function
|
||||||
|
---
|
||||||
|
|
||||||
|
## declare (experimental)
|
||||||
|
|
||||||
|
Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making formal predictions. It allows you to limit the domain that your prediction will be used and scored within.
|
||||||
|
|
||||||
|
The one function that declarations currently have is that they impact plotting. If you `declare` a single-variable function within a specific range, this specific range will be plotted.
|
||||||
|
|
||||||
|
Declarations are currently experimental and will likely be removed or changed in the future.
|
||||||
|
|
||||||
|
```
|
||||||
|
Function.declare: (dict<{fn: lambda, inputs: array<dict<{min: number, max: number}>>}>) => declaration
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
Function.declare({
|
||||||
|
fn: {|a| a+10 },
|
||||||
|
inputs: [
|
||||||
|
{min: 30, max: 100}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
|
@ -11,8 +11,6 @@ myList = [3, normal(5, 2), "random"];
|
||||||
|
|
||||||
### make
|
### make
|
||||||
|
|
||||||
**Note: currently just called `makeList`, without the preix**
|
|
||||||
|
|
||||||
```
|
```
|
||||||
List.make: (number, 'a) => list<'a>
|
List.make: (number, 'a) => list<'a>
|
||||||
```
|
```
|
||||||
|
@ -37,9 +35,7 @@ toString: (list<'a>) => string
|
||||||
length: (list<'a>) => number
|
length: (list<'a>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### up to
|
### upTo
|
||||||
|
|
||||||
**Note: currently just called `upTo`, without the preix**
|
|
||||||
|
|
||||||
```
|
```
|
||||||
List.upTo: (low:number, high:number) => list<number>
|
List.upTo: (low:number, high:number) => list<number>
|
||||||
|
|
|
@ -55,6 +55,12 @@ min: (list<number>) => number
|
||||||
mean: (list<number>) => number
|
mean: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### geometric mean
|
||||||
|
|
||||||
|
```
|
||||||
|
geomean: (list<number>) => number
|
||||||
|
```
|
||||||
|
|
||||||
### stdev
|
### stdev
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -117,6 +123,12 @@ product: (list<number>) => number
|
||||||
cumprod: (list<number>) => list<number>
|
cumprod: (list<number>) => list<number>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### diff
|
||||||
|
|
||||||
|
```
|
||||||
|
diff: (list<number>) => list<number>
|
||||||
|
```
|
||||||
|
|
||||||
### subtract
|
### subtract
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue
Block a user