A bunch of minor touches

This commit is contained in:
Ozzie Gooen 2020-08-09 14:31:09 +01:00
parent a9a13b7d54
commit 86a9c32702
8 changed files with 104 additions and 24 deletions

View File

@ -155,7 +155,7 @@ module DemoDist = {
},
~distPlusIngredients,
~environment=
[|("p", `SymbolicDist(`Float(1.0)))|]
[||]
->Belt.Map.String.fromArray,
(),
);

View File

@ -25,6 +25,7 @@ let toMixed =
let combineAlgebraically =
(op: ExpressionTypes.algebraicOperation, t1: t, t2: t): t => {
switch (t1, t2) {
| (Continuous(m1), Continuous(m2)) =>
Continuous.combineAlgebraically(op, m1, m2) |> Continuous.T.toShape;
@ -171,12 +172,13 @@ module T =
));
};
let maxX = mapToAll((Mixed.T.maxX, Discrete.T.maxX, Continuous.T.maxX));
let mapY = (~integralSumCacheFn=previousIntegralSum => None, ~integralCacheFn=previousIntegral=>None, ~fn) =>
let mapY = (~integralSumCacheFn=previousIntegralSum => None, ~integralCacheFn=previousIntegral=>None, ~fn) =>{
fmap((
Mixed.T.mapY(~integralSumCacheFn, ~integralCacheFn, ~fn),
Discrete.T.mapY(~integralSumCacheFn, ~integralCacheFn, ~fn),
Continuous.T.mapY(~integralSumCacheFn, ~integralCacheFn, ~fn),
));
}
let mean = (t: t): float =>
switch (t) {

View File

@ -95,19 +95,19 @@ module VerticalScaling = {
let operationToLeaf =
(evaluationParams: evaluationParams, scaleOp, t, scaleBy) => {
// scaleBy has to be a single float, otherwise we'll return an error.
let fn = Operation.Scale.toFn(scaleOp);
let fn = (secondary,main) => Operation.Scale.toFn(scaleOp)(main, secondary);
let integralSumCacheFn = Operation.Scale.toIntegralSumCacheFn(scaleOp);
let integralCacheFn = Operation.Scale.toIntegralCacheFn(scaleOp);
let renderedShape = Render.render(evaluationParams, t);
switch (renderedShape, scaleBy) {
| (Ok(`RenderedDist(rs)), `SymbolicDist(`Float(sm))) =>
let s = switch (renderedShape, scaleBy) {
| (Ok(`RenderedDist(rs)), `SymbolicDist(`Float(scaleBy))) =>
Ok(
`RenderedDist(
Shape.T.mapY(
~integralSumCacheFn=integralSumCacheFn(sm),
~integralCacheFn=integralCacheFn(sm),
~fn=fn(sm),
~integralSumCacheFn=integralSumCacheFn(scaleBy),
~integralCacheFn=integralCacheFn(scaleBy),
~fn=fn(scaleBy),
rs,
),
),
@ -115,6 +115,7 @@ module VerticalScaling = {
| (Error(e1), _) => Error(e1)
| (_, _) => Error("Can only scale by float values.")
};
s;
};
};

View File

@ -1,4 +1,10 @@
type algebraicOperation = [ | `Add | `Multiply | `Subtract | `Divide | `Exponentiate];
type algebraicOperation = [
| `Add
| `Multiply
| `Subtract
| `Divide
| `Exponentiate
];
type pointwiseOperation = [ | `Add | `Multiply | `Exponentiate];
type scaleOperation = [ | `Multiply | `Exponentiate | `Log];
type distToFloatOperation = [
@ -30,24 +36,42 @@ module ExpressionTree = {
sampleCount: int,
outputXYPoints: int,
kernelWidth: option(float),
shapeLength: int
shapeLength: int,
};
module SamplingInputs = {
type t = {
sampleCount: option(int),
outputXYPoints: option(int),
kernelWidth: option(float),
shapeLength: option(int),
};
let withDefaults = (t: t): samplingInputs => {
sampleCount: t.sampleCount |> E.O.default(10000),
outputXYPoints: t.outputXYPoints |> E.O.default(10000),
kernelWidth: t.kernelWidth,
shapeLength: t.shapeLength |> E.O.default(10000),
};
};
type environment = Belt.Map.String.t(node);
module Environment = {
type t = environment
type t = environment;
module MS = Belt.Map.String;
let fromArray = MS.fromArray
let empty:t = [||]->fromArray;
let mergeKeepSecond = (a:t,b:t) => MS.merge(a,b, (_,a,b) =>switch(a,b){
| (_, Some(b)) => Some(b)
| (Some(a), _) => Some(a)
| _ => None
})
let update = (t,str, fn) => MS.update(t, str, fn)
let get = (t:t,str) => MS.get(t, str)
}
let fromArray = MS.fromArray;
let empty: t = [||]->fromArray;
let mergeKeepSecond = (a: t, b: t) =>
MS.merge(a, b, (_, a, b) =>
switch (a, b) {
| (_, Some(b)) => Some(b)
| (Some(a), _) => Some(a)
| _ => None
}
);
let update = (t, str, fn) => MS.update(t, str, fn);
let get = (t: t, str) => MS.get(t, str);
};
type evaluationParams = {
samplingInputs,
@ -115,6 +139,9 @@ type simplificationResult = [
];
module Program = {
type statement = [ | `Assignment(string, ExpressionTree.node) | `Expression(ExpressionTree.node)];
type statement = [
| `Assignment(string, ExpressionTree.node)
| `Expression(ExpressionTree.node)
];
type program = array(statement);
}
};

View File

@ -192,6 +192,7 @@ module MathAdtToDistDst = {
switch (name, args) {
| ("add", [|l, r|]) => toOkAlgebraic((`Add, l, r))
| ("add", _) => Error("Addition needs two operands")
| ("unaryMinus", [|l|]) => toOkAlgebraic((`Multiply, `SymbolicDist(`Float(-1.0)), l))
| ("subtract", [|l, r|]) => toOkAlgebraic((`Subtract, l, r))
| ("subtract", _) => Error("Subtraction needs two operands")
| ("multiply", [|l, r|]) => toOkAlgebraic((`Multiply, l, r))
@ -283,6 +284,7 @@ module MathAdtToDistDst = {
| "add"
| "subtract"
| "multiply"
| "unaryMinus"
| "dotMultiply"
| "dotPow"
| "rightLogShift"

View File

@ -52,6 +52,7 @@ module DistToFloat = {
};
};
// Note that different logarithms don't really do anything.
module Scale = {
type t = scaleOperation;
let toFn =

View File

@ -8,7 +8,7 @@ module Inputs = {
shapeLength: option(int),
};
};
let defaultRecommendedLength = 10000;
let defaultRecommendedLength = 100;
let defaultShouldDownsample = true;
type ingredients = {

View File

@ -0,0 +1,47 @@
// Not yet used
type inputs = {
samplingInputs: ExpressionTypes.ExpressionTree.SamplingInputs.t,
program: string,
environment: ExpressionTypes.ExpressionTree.environment,
};
let addVariable =
({program, samplingInputs, environment}: inputs, str, node): inputs => {
samplingInputs,
program,
environment:
ExpressionTypes.ExpressionTree.Environment.update(environment, str, _ =>
Some(node)
),
};
let runNode = (inputs, node) => {
ExpressionTree.toLeaf(
ExpressionTypes.ExpressionTree.SamplingInputs.withDefaults(inputs.samplingInputs),
inputs.environment,
node,
);
};
let runProgram = (inputs: inputs, p: ExpressionTypes.Program.program) => {
let ins = ref(inputs);
p
|> E.A.fmap(
fun
| `Assignment(name, node) => {
ins := addVariable(ins^, name, node);
None;
}
| `Expression(node) =>
Some(runNode(ins^, node) |> E.R.fmap(r => (ins, r))),
)
|> E.A.O.concatSomes
|> E.A.R.firstErrorOrOpen;
};
let inputsToLeaf = (inputs: inputs) => {
MathJsParser.fromString(inputs.program)
|> E.R.bind(_, g => runProgram(inputs, g))
|> E.R.bind(_, r => E.A.last(r) |> E.O.toResult("No rendered lines"));
};