Response to CR

Value: [0.005 to 0.43]
This commit is contained in:
Quinn Dougherty 2022-04-26 20:30:38 -04:00
parent f0d9404a68
commit 938a10766c
2 changed files with 28 additions and 57 deletions

View File

@ -16,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
| RequestedStrategyInvalidError | RequestedStrategyInvalidError(string)
| LogarithmOfDistributionError(string) | LogarithmOfDistributionError(string)
| OtherError(string) | OtherError(string)
@ -38,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)
| RequestedStrategyInvalidError => `Requested strategy invalid` | RequestedStrategyInvalidError(err) => `Requested strategy invalid: ${err}`
| OtherError(s) => s | OtherError(s) => s
} }

View File

@ -225,55 +225,22 @@ module AlgebraicCombination = {
| _ => 1000 | _ => 1000
} }
type calculationMethod = MonteCarlo | Convolution(Operation.convolutionOperation) type calculationStrategy = MonteCarloStrat | ConvolutionStrat(Operation.convolutionOperation)
let chooseConvolutionOrMonteCarloDefault = ( let chooseConvolutionOrMonteCarloDefault = (
op: Operation.algebraicOperation, op: Operation.algebraicOperation,
t2: t, t2: t,
t1: t, t1: t,
): calculationMethod => ): calculationStrategy =>
switch op { switch op {
| #Divide | #Divide
| #Power | #Power
| #Logarithm => | #Logarithm =>
MonteCarlo MonteCarloStrat
| (#Add | #Subtract | #Multiply) as convOp => | (#Add | #Subtract | #Multiply) as convOp =>
expectedConvolutionCost(t1) * expectedConvolutionCost(t2) > 10000 expectedConvolutionCost(t1) * expectedConvolutionCost(t2) > 10000
? MonteCarlo ? MonteCarloStrat
: Convolution(convOp) : ConvolutionStrat(convOp)
}
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 tryAnalyticalSimplificationDefault = (
arithmeticOperation: Operation.algebraicOperation,
t1: t,
t2: t,
): option<result<SymbolicDistTypes.symbolicDist, Operation.Error.t>> =>
switch (t1, t2) {
| (Symbolic(d1), Symbolic(d2)) =>
switch SymbolicDist.T.tryAnalyticalSimplification(d1, d2, arithmeticOperation) {
| #AnalyticalSolution(symbolicDist) => Some(Ok(symbolicDist))
| #Error(er) => Some(Error(er))
| #NoSolution => None
}
| _ => None
} }
let tryAnalyticalSimplification = ( let tryAnalyticalSimplification = (
@ -295,16 +262,17 @@ module AlgebraicCombination = {
~arithmeticOperation, ~arithmeticOperation,
~t2: t, ~t2: t,
): result<t, error> => { ): result<t, error> => {
switch tryAnalyticalSimplificationDefault(arithmeticOperation, t1, t2) { switch tryAnalyticalSimplification(arithmeticOperation, t1, t2) {
| Some(Ok(symbolicDist)) => Ok(Symbolic(symbolicDist)) | Some(#AnalyticalSolution(symbolicDist)) => Ok(Symbolic(symbolicDist))
| Some(Error(e)) => Error(OperationError(e)) | Some(#Error(e)) => Error(OperationError(e))
| Some(#NoSolution)
| None => | None =>
switch getInvalidOperationError(t1, t2, ~toPointSetFn, ~arithmeticOperation) { switch getInvalidOperationError(t1, t2, ~toPointSetFn, ~arithmeticOperation) {
| Some(e) => Error(e) | Some(e) => Error(e)
| None => | None =>
switch chooseConvolutionOrMonteCarloDefault(arithmeticOperation, t1, t2) { switch chooseConvolutionOrMonteCarloDefault(arithmeticOperation, t1, t2) {
| MonteCarlo => runMonteCarlo(toSampleSetFn, arithmeticOperation, t1, t2) | MonteCarloStrat => runMonteCarlo(toSampleSetFn, arithmeticOperation, t1, t2)
| Convolution(convOp) => | ConvolutionStrat(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,
)) ))
@ -318,7 +286,7 @@ module AlgebraicCombination = {
t1: t, t1: t,
~toPointSetFn: toPointSetFn, ~toPointSetFn: toPointSetFn,
~toSampleSetFn: toSampleSetFn, ~toSampleSetFn: toSampleSetFn,
~arithmeticOperation, ~arithmeticOperation: Operation.algebraicOperation,
~t2: t, ~t2: t,
): result<t, error> => { ): result<t, error> => {
switch strategy { switch strategy {
@ -326,21 +294,24 @@ module AlgebraicCombination = {
| AsSymbolic => | AsSymbolic =>
switch tryAnalyticalSimplification(arithmeticOperation, t1, t2) { switch tryAnalyticalSimplification(arithmeticOperation, t1, t2) {
| Some(#AnalyticalSolution(symbolicDist)) => Ok(Symbolic(symbolicDist)) | Some(#AnalyticalSolution(symbolicDist)) => Ok(Symbolic(symbolicDist))
| Some(#NoSolution) | Some(#NoSolution) => Error(RequestedStrategyInvalidError(`No analytical solution`))
| None => | None => Error(RequestedStrategyInvalidError("Inputs were not even symbolic"))
Error(RequestedStrategyInvalidError)
| Some(#Error(err)) => Error(OperationError(err)) | Some(#Error(err)) => Error(OperationError(err))
} }
| AsConvolution | AsConvolution => {
| AsMonteCarlo => let errString = opString => `Can't convolve on ${opString}`
switch chooseConvolutionOrMonteCarlo(~strat=strategy, arithmeticOperation, t1, t2) { switch arithmeticOperation {
| Ok(MonteCarlo) => runMonteCarlo(toSampleSetFn, arithmeticOperation, t1, t2) | (#Add | #Subtract | #Multiply) as 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) | #Divide => "divide"->errString->RequestedStrategyInvalidError->Error
| #Power => "power"->errString->RequestedStrategyInvalidError->Error
| #Logarithm => "logarithm"->errString->RequestedStrategyInvalidError->Error
} }
} }
| AsMonteCarlo => runMonteCarlo(toSampleSetFn, arithmeticOperation, t1, t2)
}
} }
} }