This commit is contained in:
NunoSempere 2022-09-06 13:59:21 +02:00
parent edce22050a
commit 4903319073

View File

@ -8,8 +8,7 @@ let requiresNamespace = true
module Combinatorics = { module Combinatorics = {
module Helpers = { module Helpers = {
let laplace = ((successes, trials)) => let laplace = ((successes, trials)) => (successes +. 1.0) /. (trials +. 2.0)
(successes +. 1.0) /. (trials +. 2.0)
let factorial = Stdlib.Math.factorial let factorial = Stdlib.Math.factorial
let choose = ((n, k)) => factorial(n) /. (factorial(n -. k) *. factorial(k)) let choose = ((n, k)) => factorial(n) /. (factorial(n -. k) *. factorial(k))
let pow = (base, exp) => Js.Math.pow_float(~base, ~exp) let pow = (base, exp) => Js.Math.pow_float(~base, ~exp)
@ -22,12 +21,10 @@ module Combinatorics = {
~requiresNamespace, ~requiresNamespace,
~output=EvtNumber, ~output=EvtNumber,
~examples=[`Danger.laplace(1, 20)`], ~examples=[`Danger.laplace(1, 20)`],
~definitions=[ ~definitions=[DefineFn.Numbers.twoToOne("laplace", laplace)],
DefineFn.Numbers.twoToOne("laplace", laplace),
],
(), (),
) )
let factorial = Function.make( let factorial = Function.make(
~name="factorial", ~name="factorial",
~nameSpace, ~nameSpace,
~requiresNamespace, ~requiresNamespace,
@ -154,87 +151,92 @@ module Integration = {
} }
} }
module Lib = { module Lib = {
// Integral in terms of function, min, max, num points // Integral in terms of function, min, max, num points
// Note that execution time will be more predictable, because it // Note that execution time will be more predictable, because it
// will only depend on num points and the complexity of the function // will only depend on num points and the complexity of the function
let integrateFunctionBetweenWithNumIntegrationPoints = Function.make( let integrateFunctionBetweenWithNumIntegrationPoints = Function.make(
~name="integrateFunctionBetweenWithNumIntegrationPoints", ~name="integrateFunctionBetweenWithNumIntegrationPoints",
~nameSpace, ~nameSpace,
~output=EvtNumber, ~output=EvtNumber,
~requiresNamespace=false, ~requiresNamespace=false,
~examples=[`Danger.integrateFunctionBetweenWithNumIntegrationPoints({|x| x+1}, 1, 10, 10)`], ~examples=[`Danger.integrateFunctionBetweenWithNumIntegrationPoints({|x| x+1}, 1, 10, 10)`],
// should be [x^2/2 + x]1_10 = (100/2 + 10) - (1/2 + 1) = 60 - 1.5 = 58.5 // should be [x^2/2 + x]1_10 = (100/2 + 10) - (1/2 + 1) = 60 - 1.5 = 58.5
// https://www.wolframalpha.com/input?i=integrate+x%2B1+from+1+to+10 // https://www.wolframalpha.com/input?i=integrate+x%2B1+from+1+to+10
~definitions=[ ~definitions=[
FnDefinition.make( FnDefinition.make(
~name="integrateFunctionBetweenWithNumIntegrationPoints", ~name="integrateFunctionBetweenWithNumIntegrationPoints",
~inputs=[FRTypeLambda, FRTypeNumber, FRTypeNumber, FRTypeNumber], ~inputs=[FRTypeLambda, FRTypeNumber, FRTypeNumber, FRTypeNumber],
~run=(inputs, _, env, reducer) => { ~run=(inputs, _, env, reducer) => {
let result = switch inputs { let result = switch inputs {
| [_, _, _, IEvNumber(0.0)] => | [_, _, _, IEvNumber(0.0)] =>
Error("Integration error 4 in Danger.integrate: Increment can't be 0.") Error("Integration error 4 in Danger.integrate: Increment can't be 0.")
| [IEvLambda(aLambda), IEvNumber(min), IEvNumber(max), IEvNumber(numIntegrationPoints)] => | [
Helpers.integrateFunctionBetweenWithNumIntegrationPoints( IEvLambda(aLambda),
aLambda, IEvNumber(min),
min, IEvNumber(max),
max, IEvNumber(numIntegrationPoints),
numIntegrationPoints, ] =>
env, Helpers.integrateFunctionBetweenWithNumIntegrationPoints(
reducer, aLambda,
) min,
| _ => max,
Error( numIntegrationPoints,
"Integration error 5 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))", env,
) reducer,
} )
result | _ =>
}, Error(
(), "Integration error 5 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))",
), )
], }
(), result
) },
// Integral in terms of function, min, max, epsilon (distance between points) (),
// Execution time will be less predictable, because it ),
// will depend on min, max and epsilon together, ],
// as well and the complexity of the function (),
let integrateFunctionBetweenWithEpsilon = Function.make( )
~name="integrateFunctionBetweenWithEpsilon", // Integral in terms of function, min, max, epsilon (distance between points)
~nameSpace, // Execution time will be less predictable, because it
~output=EvtNumber, // will depend on min, max and epsilon together,
~requiresNamespace=false, // as well and the complexity of the function
~examples=[`Danger.integrateFunctionBetweenWithEpsilon({|x| x+1}, 1, 10, 0.1)`], let integrateFunctionBetweenWithEpsilon = Function.make(
~definitions=[ ~name="integrateFunctionBetweenWithEpsilon",
FnDefinition.make( ~nameSpace,
~name="integrateFunctionBetweenWithEpsilon", ~output=EvtNumber,
~inputs=[FRTypeLambda, FRTypeNumber, FRTypeNumber, FRTypeNumber], ~requiresNamespace=false,
~run=(inputs, _, env, reducer) => { ~examples=[`Danger.integrateFunctionBetweenWithEpsilon({|x| x+1}, 1, 10, 0.1)`],
let result = switch inputs { ~definitions=[
| [_, _, _, IEvNumber(0.0)] => FnDefinition.make(
Error("Integration error in Danger.integrate: Increment can't be 0.") ~name="integrateFunctionBetweenWithEpsilon",
| [IEvLambda(aLambda), IEvNumber(min), IEvNumber(max), IEvNumber(epsilon)] => ~inputs=[FRTypeLambda, FRTypeNumber, FRTypeNumber, FRTypeNumber],
Helpers.integrateFunctionBetweenWithNumIntegrationPoints( ~run=(inputs, _, env, reducer) => {
aLambda, let result = switch inputs {
min, | [_, _, _, IEvNumber(0.0)] =>
max, Error("Integration error in Danger.integrate: Increment can't be 0.")
(max -. min) /. epsilon, | [IEvLambda(aLambda), IEvNumber(min), IEvNumber(max), IEvNumber(epsilon)] =>
env, Helpers.integrateFunctionBetweenWithNumIntegrationPoints(
reducer, aLambda,
)->E.R2.errMap(_ => min,
"Integration error 7 in Danger.integrate. Something went wrong along the way" max,
) (max -. min) /. epsilon,
| _ => env,
Error( reducer,
"Integration error 8 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))", )->E.R2.errMap(_ =>
) "Integration error 7 in Danger.integrate. Something went wrong along the way"
} )
result | _ =>
}, Error(
(), "Integration error 8 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))",
), )
], }
(), result
) },
(),
),
],
(),
)
} }
} }
@ -246,7 +248,6 @@ module Internals = {
->Belt.Array.map(FunctionRegistry_Helpers.Wrappers.evNumber) ->Belt.Array.map(FunctionRegistry_Helpers.Wrappers.evNumber)
->FunctionRegistry_Helpers.Wrappers.evArray ->FunctionRegistry_Helpers.Wrappers.evArray
// Diminishing returns // Diminishing returns
// Helpers // Helpers
type diminishingReturnsAccumulatorInner = { type diminishingReturnsAccumulatorInner = {
@ -359,14 +360,11 @@ module Internals = {
} }
} }
let library = [ let library = [
Combinatorics.Lib.laplace, Combinatorics.Lib.laplace,
Combinatorics.Lib.factorial, Combinatorics.Lib.factorial,
Combinatorics.Lib.choose, Combinatorics.Lib.choose,
Combinatorics.Lib.binomial, Combinatorics.Lib.binomial,
// Diminishing marginal return functions // Diminishing marginal return functions
// There are functions diminishingMarginalReturnsForFunctions2 through diminishingMarginalReturnsForFunctions7 // There are functions diminishingMarginalReturnsForFunctions2 through diminishingMarginalReturnsForFunctions7
// Because of this bug: <https://github.com/quantified-uncertainty/squiggle/issues/1090> // Because of this bug: <https://github.com/quantified-uncertainty/squiggle/issues/1090>