The proper issue326 (again)

Value: [1 to 3.6]
This commit is contained in:
Quinn Dougherty 2022-04-26 16:06:51 -04:00
parent e2da81812f
commit c53e56e773
5 changed files with 71 additions and 44 deletions

View File

@ -154,10 +154,16 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ()) ->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ())
->E.R2.fmap(r => Dist(PointSet(r))) ->E.R2.fmap(r => Dist(PointSet(r)))
->OutputLocal.fromResult ->OutputLocal.fromResult
| ToDistCombination(Algebraic, _, #Float(_)) => GenDistError(NotYetImplemented) | ToDistCombination(Algebraic(_), _, #Float(_)) => GenDistError(NotYetImplemented)
| ToDistCombination(Algebraic, arithmeticOperation, #Dist(t2)) => | ToDistCombination(Algebraic(strategy), arithmeticOperation, #Dist(t2)) =>
dist dist
->GenericDist.algebraicCombination(~toPointSetFn, ~toSampleSetFn, ~arithmeticOperation, ~t2) ->GenericDist.algebraicCombination(
~strategy,
~toPointSetFn,
~toSampleSetFn,
~arithmeticOperation,
~t2,
)
->E.R2.fmap(r => Dist(r)) ->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult ->OutputLocal.fromResult
| ToDistCombination(Pointwise, algebraicCombination, #Dist(t2)) => | ToDistCombination(Pointwise, algebraicCombination, #Dist(t2)) =>

View File

@ -4,6 +4,8 @@ type genericDist =
| SampleSet(SampleSetDist.t) | SampleSet(SampleSetDist.t)
| Symbolic(SymbolicDistTypes.symbolicDist) | Symbolic(SymbolicDistTypes.symbolicDist)
type asAlgebraicCombinationStrategy = AsDefault | AsSymbolic | AsMontecarlo | AsConvolution
@genType @genType
type error = type error =
| NotYetImplemented | NotYetImplemented
@ -14,7 +16,7 @@ type error =
| OperationError(Operation.Error.t) | OperationError(Operation.Error.t)
| PointSetConversionError(SampleSetDist.pointsetConversionError) | PointSetConversionError(SampleSetDist.pointsetConversionError)
| SparklineError(PointSetTypes.sparklineError) // This type of error is for when we find a sparkline of a discrete distribution. This should probably at some point be actually implemented | SparklineError(PointSetTypes.sparklineError) // This type of error is for when we find a sparkline of a discrete distribution. This should probably at some point be actually implemented
| RequestedModeInvalidError | RequestedStrategyInvalidError
| LogarithmOfDistributionError(string) | LogarithmOfDistributionError(string)
| OtherError(string) | OtherError(string)
@ -36,7 +38,7 @@ module Error = {
| OperationError(err) => Operation.Error.toString(err) | OperationError(err) => Operation.Error.toString(err)
| PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err) | PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err)
| SparklineError(err) => PointSetTypes.sparklineErrorToString(err) | SparklineError(err) => PointSetTypes.sparklineErrorToString(err)
| RequestedModeInvalidError => `Requested mode invalid` | RequestedStrategyInvalidError => `Requested mode invalid`
| OtherError(s) => s | OtherError(s) => s
} }
@ -55,7 +57,7 @@ module DistributionOperation = {
type pointsetXSelection = [#Linear | #ByWeight] type pointsetXSelection = [#Linear | #ByWeight]
type direction = type direction =
| Algebraic | Algebraic(asAlgebraicCombinationStrategy)
| Pointwise | Pointwise
type toFloat = [ type toFloat = [
@ -112,7 +114,7 @@ module DistributionOperation = {
| ToString(ToString) => `toString` | ToString(ToString) => `toString`
| ToString(ToSparkline(n)) => `toSparkline(${E.I.toString(n)})` | ToString(ToSparkline(n)) => `toSparkline(${E.I.toString(n)})`
| ToBool(IsNormalized) => `isNormalized` | ToBool(IsNormalized) => `isNormalized`
| ToDistCombination(Algebraic, _, _) => `algebraic` | ToDistCombination(Algebraic(_), _, _) => `algebraic`
| ToDistCombination(Pointwise, _, _) => `pointwise` | ToDistCombination(Pointwise, _, _) => `pointwise`
} }
@ -141,27 +143,27 @@ module Constructors = {
let toString = (dist): t => FromDist(ToString(ToString), dist) let toString = (dist): t => FromDist(ToString(ToString), dist)
let toSparkline = (dist, n): t => FromDist(ToString(ToSparkline(n)), dist) let toSparkline = (dist, n): t => FromDist(ToString(ToSparkline(n)), dist)
let algebraicAdd = (dist1, dist2: genericDist): t => FromDist( let algebraicAdd = (dist1, dist2: genericDist): t => FromDist(
ToDistCombination(Algebraic, #Add, #Dist(dist2)), ToDistCombination(Algebraic(AsDefault), #Add, #Dist(dist2)),
dist1, dist1,
) )
let algebraicMultiply = (dist1, dist2): t => FromDist( let algebraicMultiply = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic, #Multiply, #Dist(dist2)), ToDistCombination(Algebraic(AsDefault), #Multiply, #Dist(dist2)),
dist1, dist1,
) )
let algebraicDivide = (dist1, dist2): t => FromDist( let algebraicDivide = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic, #Divide, #Dist(dist2)), ToDistCombination(Algebraic(AsDefault), #Divide, #Dist(dist2)),
dist1, dist1,
) )
let algebraicSubtract = (dist1, dist2): t => FromDist( let algebraicSubtract = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic, #Subtract, #Dist(dist2)), ToDistCombination(Algebraic(AsDefault), #Subtract, #Dist(dist2)),
dist1, dist1,
) )
let algebraicLogarithm = (dist1, dist2): t => FromDist( let algebraicLogarithm = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic, #Logarithm, #Dist(dist2)), ToDistCombination(Algebraic(AsDefault), #Logarithm, #Dist(dist2)),
dist1, dist1,
) )
let algebraicPower = (dist1, dist2): t => FromDist( let algebraicPower = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic, #Power, #Dist(dist2)), ToDistCombination(Algebraic(AsDefault), #Power, #Dist(dist2)),
dist1, dist1,
) )
let pointwiseAdd = (dist1, dist2): t => FromDist( let pointwiseAdd = (dist1, dist2): t => FromDist(

View File

@ -5,7 +5,6 @@ type toPointSetFn = t => result<PointSetTypes.pointSetDist, error>
type toSampleSetFn = t => result<SampleSetDist.t, error> type toSampleSetFn = t => result<SampleSetDist.t, error>
type scaleMultiplyFn = (t, float) => result<t, error> type scaleMultiplyFn = (t, float) => result<t, error>
type pointwiseAddFn = (t, t) => result<t, error> type pointwiseAddFn = (t, t) => result<t, error>
type asMode = AsSymbolic | AsMontecarlo | AsConvolution
let sampleN = (t: t, n) => let sampleN = (t: t, n) =>
switch t { switch t {
@ -243,7 +242,7 @@ module AlgebraicCombination = {
type calculationMethod = MonteCarlo | Convolution(Operation.convolutionOperation) type calculationMethod = MonteCarlo | Convolution(Operation.convolutionOperation)
let chooseConvolutionOrMonteCarlo = ( let chooseConvolutionOrMonteCarloDefault = (
op: Operation.algebraicOperation, op: Operation.algebraicOperation,
t2: t, t2: t,
t1: t, t1: t,
@ -259,7 +258,26 @@ module AlgebraicCombination = {
: Convolution(convOp) : Convolution(convOp)
} }
let run' = ( let chooseConvolutionOrMonteCarlo = (
~strat: DistributionTypes.asAlgebraicCombinationStrategy,
op: Operation.algebraicOperation,
t2: t,
t1: t,
): result<calculationMethod, error> => {
switch strat {
| AsDefault => Ok(chooseConvolutionOrMonteCarloDefault(op, t2, t1))
| AsConvolution =>
switch op {
| #Divide | #Power | #Logarithm => Error(RequestedStrategyInvalidError)
| (#Add | #Subtract | #Multiply) as convOp => Ok(Convolution(convOp))
}
| AsMontecarlo => Ok(MonteCarlo)
| AsSymbolic => Error(RequestedStrategyInvalidError)
}
}
let run = (
~strategy: DistributionTypes.asAlgebraicCombinationStrategy,
t1: t, t1: t,
~toPointSetFn: toPointSetFn, ~toPointSetFn: toPointSetFn,
~toSampleSetFn: toSampleSetFn, ~toSampleSetFn: toSampleSetFn,
@ -273,35 +291,37 @@ module AlgebraicCombination = {
switch getInvalidOperationError(t1, t2, ~toPointSetFn, ~arithmeticOperation) { switch getInvalidOperationError(t1, t2, ~toPointSetFn, ~arithmeticOperation) {
| Some(e) => Error(e) | Some(e) => Error(e)
| None => | None =>
switch chooseConvolutionOrMonteCarlo(arithmeticOperation, t1, t2) { switch chooseConvolutionOrMonteCarlo(~strat=strategy, arithmeticOperation, t1, t2) {
| MonteCarlo => runMonteCarlo(toSampleSetFn, arithmeticOperation, t1, t2) | Ok(MonteCarlo) => runMonteCarlo(toSampleSetFn, arithmeticOperation, t1, t2)
| Convolution(convOp) => | Ok(Convolution(convOp)) =>
runConvolution(toPointSetFn, convOp, t1, t2)->E.R2.fmap(r => DistributionTypes.PointSet( runConvolution(toPointSetFn, convOp, t1, t2)->E.R2.fmap(r => DistributionTypes.PointSet(
r, r,
)) ))
| Error(RequestedStrategyInvalidError) => Error(RequestedStrategyInvalidError)
| Error(err) => Error(err)
} }
} }
} }
} }
let run = ( // let run = (
~mode: option<asMode>=?, // ~mode: option<asMode>=?,
t1: t, // t1: t,
~toPointSetFn: toPointSetFn, // ~toPointSetFn: toPointSetFn,
~toSampleSetFn: toSampleSetFn, // ~toSampleSetFn: toSampleSetFn,
~arithmeticOperation, // ~arithmeticOperation,
~t2: t, // ~t2: t,
): result<t, error> => { // ): result<t, error> => {
let algebraicResult = run'(t1, ~toPointSetFn, ~toSampleSetFn, ~arithmeticOperation, ~t2) // let algebraicResult = run'(t1, ~toPointSetFn, ~toSampleSetFn, ~arithmeticOperation, ~t2)
switch (mode, algebraicResult) { // switch (mode, algebraicResult) {
| (None, _) // | (None, _)
| (Some(AsSymbolic), Ok(Symbolic(_))) // | (Some(AsSymbolic), Ok(Symbolic(_)))
| (Some(AsMontecarlo), Ok(DistributionTypes.SampleSet(_))) // | (Some(AsMontecarlo), Ok(DistributionTypes.SampleSet(_)))
| (Some(AsConvolution), Ok(DistributionTypes.PointSet(_))) // | (Some(AsConvolution), Ok(DistributionTypes.PointSet(_)))
| (Some(_), Error(_)) => algebraicResult // | (Some(_), Error(_)) => algebraicResult
| (Some(_), Ok(_)) => Error(RequestedModeInvalidError) // | (Some(_), Ok(_)) => Error(RequestedModeInvalidError)
} // }
} // }
} }
let algebraicCombination = AlgebraicCombination.run let algebraicCombination = AlgebraicCombination.run

View File

@ -4,7 +4,6 @@ type toPointSetFn = t => result<PointSetTypes.pointSetDist, error>
type toSampleSetFn = t => result<SampleSetDist.t, error> type toSampleSetFn = t => result<SampleSetDist.t, error>
type scaleMultiplyFn = (t, float) => result<t, error> type scaleMultiplyFn = (t, float) => result<t, error>
type pointwiseAddFn = (t, t) => result<t, error> type pointwiseAddFn = (t, t) => result<t, error>
type asMode = AsSymbolic | AsMontecarlo | AsConvolution
let sampleN: (t, int) => array<float> let sampleN: (t, int) => array<float>
@ -43,7 +42,7 @@ let truncate: (
) => result<t, error> ) => result<t, error>
let algebraicCombination: ( let algebraicCombination: (
~mode: asMode=?, ~strategy: DistributionTypes.asAlgebraicCombinationStrategy,
t, t,
~toPointSetFn: toPointSetFn, ~toPointSetFn: toPointSetFn,
~toSampleSetFn: toSampleSetFn, ~toSampleSetFn: toSampleSetFn,

View File

@ -208,7 +208,7 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option<
Helpers.toStringFn(ToSparkline(Belt.Float.toInt(n)), dist) Helpers.toStringFn(ToSparkline(Belt.Float.toInt(n)), dist)
| ("exp", [EvDistribution(a)]) => | ("exp", [EvDistribution(a)]) =>
// https://mathjs.org/docs/reference/functions/exp.html // https://mathjs.org/docs/reference/functions/exp.html
Helpers.twoDiststoDistFn(Algebraic, "pow", GenericDist.fromFloat(Math.e), a)->Some Helpers.twoDiststoDistFn(Algebraic(AsDefault), "pow", GenericDist.fromFloat(Math.e), a)->Some
| ("normalize", [EvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist) | ("normalize", [EvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist)
| ("isNormalized", [EvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist) | ("isNormalized", [EvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist)
| ("toPointSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist) | ("toPointSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist)
@ -228,14 +228,14 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option<
Helpers.toDistFn(Truncate(Some(float1), Some(float2)), dist) Helpers.toDistFn(Truncate(Some(float1), Some(float2)), dist)
| ("mx" | "mixture", args) => Helpers.mixture(args)->Some | ("mx" | "mixture", args) => Helpers.mixture(args)->Some
| ("log", [EvDistribution(a)]) => | ("log", [EvDistribution(a)]) =>
Helpers.twoDiststoDistFn(Algebraic, "log", a, GenericDist.fromFloat(Math.e))->Some Helpers.twoDiststoDistFn(Algebraic(AsDefault), "log", a, GenericDist.fromFloat(Math.e))->Some
| ("log10", [EvDistribution(a)]) => | ("log10", [EvDistribution(a)]) =>
Helpers.twoDiststoDistFn(Algebraic, "log", a, GenericDist.fromFloat(10.0))->Some Helpers.twoDiststoDistFn(Algebraic(AsDefault), "log", a, GenericDist.fromFloat(10.0))->Some
| ("unaryMinus", [EvDistribution(a)]) => | ("unaryMinus", [EvDistribution(a)]) =>
Helpers.twoDiststoDistFn(Algebraic, "multiply", a, GenericDist.fromFloat(-1.0))->Some Helpers.twoDiststoDistFn(Algebraic(AsDefault), "multiply", a, GenericDist.fromFloat(-1.0))->Some
| (("add" | "multiply" | "subtract" | "divide" | "pow" | "log") as arithmetic, [_, _] as args) => | (("add" | "multiply" | "subtract" | "divide" | "pow" | "log") as arithmetic, [_, _] as args) =>
Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) => Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) =>
Helpers.twoDiststoDistFn(Algebraic, arithmetic, fst, snd) Helpers.twoDiststoDistFn(Algebraic(AsDefault), arithmetic, fst, snd)
) )
| ( | (
("dotAdd" ("dotAdd"