Added simple exponentiation
This commit is contained in:
parent
bcbbcf0f43
commit
e266e6557c
|
@ -45,11 +45,8 @@ let toDiscretePointMassesFromTriangulars =
|
||||||
|
|
||||||
if (inverse) {
|
if (inverse) {
|
||||||
for (i in 1 to n - 2) {
|
for (i in 1 to n - 2) {
|
||||||
Belt.Array.set(
|
Belt.Array.set(masses, i - 1, (xs[i + 1] -. xs[i - 1]) *. ys[i] /. 2.)
|
||||||
masses,
|
|> ignore;
|
||||||
i - 1,
|
|
||||||
(xs[i + 1] -. xs[i - 1]) *. ys[i] /. 2.,
|
|
||||||
) |> ignore;
|
|
||||||
|
|
||||||
// this only works when the whole triange is either on the left or on the right of zero
|
// this only works when the whole triange is either on the left or on the right of zero
|
||||||
let a = xs[i - 1];
|
let a = xs[i - 1];
|
||||||
|
@ -80,14 +77,12 @@ let toDiscretePointMassesFromTriangulars =
|
||||||
} else {
|
} else {
|
||||||
for (i in 1 to n - 2) {
|
for (i in 1 to n - 2) {
|
||||||
// area of triangle = width * height / 2
|
// area of triangle = width * height / 2
|
||||||
Belt.Array.set(
|
Belt.Array.set(masses, i - 1, (xs[i + 1] -. xs[i - 1]) *. ys[i] /. 2.)
|
||||||
masses,
|
|> ignore;
|
||||||
i - 1,
|
|
||||||
(xs[i + 1] -. xs[i - 1]) *. ys[i] /. 2.,
|
|
||||||
) |> ignore;
|
|
||||||
|
|
||||||
// means of triangle = (a + b + c) / 3
|
// means of triangle = (a + b + c) / 3
|
||||||
Belt.Array.set(means, i - 1, (xs[i - 1] +. xs[i] +. xs[i + 1]) /. 3.) |> ignore;
|
Belt.Array.set(means, i - 1, (xs[i - 1] +. xs[i] +. xs[i + 1]) /. 3.)
|
||||||
|
|> ignore;
|
||||||
|
|
||||||
// variance of triangle = (a^2 + b^2 + c^2 - ab - ac - bc) / 18
|
// variance of triangle = (a^2 + b^2 + c^2 - ab - ac - bc) / 18
|
||||||
Belt.Array.set(
|
Belt.Array.set(
|
||||||
|
@ -102,7 +97,8 @@ let toDiscretePointMassesFromTriangulars =
|
||||||
-. xsProdN2[i - 1]
|
-. xsProdN2[i - 1]
|
||||||
)
|
)
|
||||||
/. 18.,
|
/. 18.,
|
||||||
) |> ignore;
|
)
|
||||||
|
|> ignore;
|
||||||
();
|
();
|
||||||
};
|
};
|
||||||
{n: n - 2, masses, means, variances};
|
{n: n - 2, masses, means, variances};
|
||||||
|
@ -134,8 +130,10 @@ let combineShapesContinuousContinuous =
|
||||||
| `Subtract => ((m1, m2) => m1 -. m2)
|
| `Subtract => ((m1, m2) => m1 -. m2)
|
||||||
| `Multiply => ((m1, m2) => m1 *. m2)
|
| `Multiply => ((m1, m2) => m1 *. m2)
|
||||||
| `Divide => ((m1, mInv2) => m1 *. mInv2)
|
| `Divide => ((m1, mInv2) => m1 *. mInv2)
|
||||||
|
| `Exponentiate => ((m1, mInv2) => m1 ** mInv2)
|
||||||
}; // note: here, mInv2 = mean(1 / t2) ~= 1 / mean(t2)
|
}; // note: here, mInv2 = mean(1 / t2) ~= 1 / mean(t2)
|
||||||
|
|
||||||
|
// TODO: I don't know what the variances are for exponentatiation
|
||||||
// converts the variances and means of the two inputs into the variance of the output
|
// converts the variances and means of the two inputs into the variance of the output
|
||||||
let combineVariancesFn =
|
let combineVariancesFn =
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -144,6 +142,8 @@ let combineShapesContinuousContinuous =
|
||||||
| `Multiply => (
|
| `Multiply => (
|
||||||
(v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2.
|
(v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2.
|
||||||
)
|
)
|
||||||
|
| `Exponentiate =>
|
||||||
|
((v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2.);
|
||||||
| `Divide => (
|
| `Divide => (
|
||||||
(v1, vInv2, m1, mInv2) =>
|
(v1, vInv2, m1, mInv2) =>
|
||||||
v1 *. vInv2 +. v1 *. mInv2 ** 2. +. vInv2 *. m1 ** 2.
|
v1 *. vInv2 +. v1 *. mInv2 ** 2. +. vInv2 *. m1 ** 2.
|
||||||
|
@ -225,9 +225,12 @@ let toDiscretePointMassesFromDiscrete =
|
||||||
};
|
};
|
||||||
|
|
||||||
let combineShapesContinuousDiscrete =
|
let combineShapesContinuousDiscrete =
|
||||||
(op: ExpressionTypes.algebraicOperation, continuousShape: DistTypes.xyShape, discreteShape: DistTypes.xyShape)
|
(
|
||||||
|
op: ExpressionTypes.algebraicOperation,
|
||||||
|
continuousShape: DistTypes.xyShape,
|
||||||
|
discreteShape: DistTypes.xyShape,
|
||||||
|
)
|
||||||
: DistTypes.xyShape => {
|
: DistTypes.xyShape => {
|
||||||
|
|
||||||
let t1n = continuousShape |> XYShape.T.length;
|
let t1n = continuousShape |> XYShape.T.length;
|
||||||
let t2n = discreteShape |> XYShape.T.length;
|
let t2n = discreteShape |> XYShape.T.length;
|
||||||
|
|
||||||
|
@ -248,15 +251,19 @@ let combineShapesContinuousDiscrete =
|
||||||
Belt.Array.set(
|
Belt.Array.set(
|
||||||
dxyShape,
|
dxyShape,
|
||||||
i,
|
i,
|
||||||
(fn(continuousShape.xs[i], discreteShape.xs[j]),
|
(
|
||||||
continuousShape.ys[i] *. discreteShape.ys[j]),
|
fn(continuousShape.xs[i], discreteShape.xs[j]),
|
||||||
) |> ignore;
|
continuousShape.ys[i] *. discreteShape.ys[j],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|> ignore;
|
||||||
();
|
();
|
||||||
};
|
};
|
||||||
Belt.Array.set(outXYShapes, j, dxyShape) |> ignore;
|
Belt.Array.set(outXYShapes, j, dxyShape) |> ignore;
|
||||||
();
|
();
|
||||||
}
|
}
|
||||||
| `Multiply
|
| `Multiply
|
||||||
|
| `Exponentiate
|
||||||
| `Divide =>
|
| `Divide =>
|
||||||
for (j in 0 to t2n - 1) {
|
for (j in 0 to t2n - 1) {
|
||||||
// creates a new continuous shape for each one of the discrete points, and collects them in outXYShapes.
|
// creates a new continuous shape for each one of the discrete points, and collects them in outXYShapes.
|
||||||
|
@ -266,8 +273,12 @@ let combineShapesContinuousDiscrete =
|
||||||
Belt.Array.set(
|
Belt.Array.set(
|
||||||
dxyShape,
|
dxyShape,
|
||||||
i,
|
i,
|
||||||
(fn(continuousShape.xs[i], discreteShape.xs[j]), continuousShape.ys[i] *. discreteShape.ys[j] /. discreteShape.xs[j]),
|
(
|
||||||
) |> ignore;
|
fn(continuousShape.xs[i], discreteShape.xs[j]),
|
||||||
|
{continuousShape.ys[i] *. discreteShape.ys[j] /. discreteShape.xs[j]}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|> ignore;
|
||||||
();
|
();
|
||||||
};
|
};
|
||||||
Belt.Array.set(outXYShapes, j, dxyShape) |> ignore;
|
Belt.Array.set(outXYShapes, j, dxyShape) |> ignore;
|
||||||
|
@ -278,7 +289,10 @@ let combineShapesContinuousDiscrete =
|
||||||
outXYShapes
|
outXYShapes
|
||||||
|> E.A.fmap(XYShape.T.fromZippedArray)
|
|> E.A.fmap(XYShape.T.fromZippedArray)
|
||||||
|> E.A.fold_left(
|
|> E.A.fold_left(
|
||||||
XYShape.PointwiseCombination.combine((+.),
|
XYShape.PointwiseCombination.combine(
|
||||||
XYShape.XtoY.continuousInterpolator(`Linear, `UseZero)),
|
(+.),
|
||||||
XYShape.T.empty);
|
XYShape.XtoY.continuousInterpolator(`Linear, `UseZero),
|
||||||
|
),
|
||||||
|
XYShape.T.empty,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -151,7 +151,7 @@ module PointwiseCombination = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
let pointwiseMultiply = (evaluationParams: evaluationParams, t1: t, t2: t) => {
|
let pointwiseCombine = (fn, evaluationParams: evaluationParams, t1: t, t2: t) => {
|
||||||
// TODO: construct a function that we can easily sample from, to construct
|
// TODO: construct a function that we can easily sample from, to construct
|
||||||
// a RenderedDist. Use the xMin and xMax of the rendered shapes to tell the sampling function where to look.
|
// a RenderedDist. Use the xMin and xMax of the rendered shapes to tell the sampling function where to look.
|
||||||
// TODO: This should work for symbolic distributions too!
|
// TODO: This should work for symbolic distributions too!
|
||||||
|
@ -176,7 +176,8 @@ module PointwiseCombination = {
|
||||||
) => {
|
) => {
|
||||||
switch (pointwiseOp) {
|
switch (pointwiseOp) {
|
||||||
| `Add => pointwiseAdd(evaluationParams, t1, t2)
|
| `Add => pointwiseAdd(evaluationParams, t1, t2)
|
||||||
| `Multiply => pointwiseMultiply(evaluationParams, t1, t2)
|
| `Multiply => pointwiseCombine(( *. ),evaluationParams, t1, t2)
|
||||||
|
| `Exponentiate => pointwiseCombine(( *. ),evaluationParams, t1, t2)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -279,7 +280,7 @@ module Render = {
|
||||||
| `SymbolicDist(d) =>
|
| `SymbolicDist(d) =>
|
||||||
Ok(
|
Ok(
|
||||||
`RenderedDist(
|
`RenderedDist(
|
||||||
SymbolicDist.T.toShape(1234, d),
|
SymbolicDist.T.toShape(evaluationParams.samplingInputs.shapeLength, d),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
| `RenderedDist(_) as t => Ok(t) // already a rendered shape, we're done here
|
| `RenderedDist(_) as t => Ok(t) // already a rendered shape, we're done here
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
type algebraicOperation = [ | `Add | `Multiply | `Subtract | `Divide];
|
type algebraicOperation = [ | `Add | `Multiply | `Subtract | `Divide | `Exponentiate];
|
||||||
type pointwiseOperation = [ | `Add | `Multiply];
|
type pointwiseOperation = [ | `Add | `Multiply | `Exponentiate];
|
||||||
type scaleOperation = [ | `Multiply | `Exponentiate | `Log];
|
type scaleOperation = [ | `Multiply | `Exponentiate | `Log];
|
||||||
type distToFloatOperation = [
|
type distToFloatOperation = [
|
||||||
| `Pdf(float)
|
| `Pdf(float)
|
||||||
|
|
|
@ -177,11 +177,12 @@ module MathAdtToDistDst = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Error("Dotwise exponentiation needs two operands")
|
||||||
let operationParser =
|
let operationParser =
|
||||||
(
|
(
|
||||||
name: string,
|
name: string,
|
||||||
args: result(array(ExpressionTypes.ExpressionTree.node), string),
|
args: result(array(ExpressionTypes.ExpressionTree.node), string),
|
||||||
) => {
|
):result(ExpressionTypes.ExpressionTree.node,string) => {
|
||||||
let toOkAlgebraic = r => Ok(`AlgebraicCombination(r));
|
let toOkAlgebraic = r => Ok(`AlgebraicCombination(r));
|
||||||
let toOkPointwise = r => Ok(`PointwiseCombination(r));
|
let toOkPointwise = r => Ok(`PointwiseCombination(r));
|
||||||
let toOkTruncate = r => Ok(`Truncate(r));
|
let toOkTruncate = r => Ok(`Truncate(r));
|
||||||
|
@ -195,6 +196,8 @@ module MathAdtToDistDst = {
|
||||||
| ("subtract", _) => Error("Subtraction needs two operands")
|
| ("subtract", _) => Error("Subtraction needs two operands")
|
||||||
| ("multiply", [|l, r|]) => toOkAlgebraic((`Multiply, l, r))
|
| ("multiply", [|l, r|]) => toOkAlgebraic((`Multiply, l, r))
|
||||||
| ("multiply", _) => Error("Multiplication needs two operands")
|
| ("multiply", _) => Error("Multiplication needs two operands")
|
||||||
|
| ("pow", [|l,r|]) => toOkAlgebraic((`Exponentiate, l, r))
|
||||||
|
| ("pow", _) => Error("Exponentiation needs two operands")
|
||||||
| ("dotMultiply", [|l, r|]) => toOkPointwise((`Multiply, l, r))
|
| ("dotMultiply", [|l, r|]) => toOkPointwise((`Multiply, l, r))
|
||||||
| ("dotMultiply", _) =>
|
| ("dotMultiply", _) =>
|
||||||
Error("Dotwise multiplication needs two operands")
|
Error("Dotwise multiplication needs two operands")
|
||||||
|
@ -203,7 +206,6 @@ module MathAdtToDistDst = {
|
||||||
Error("Dotwise addition needs two operands")
|
Error("Dotwise addition needs two operands")
|
||||||
| ("divide", [|l, r|]) => toOkAlgebraic((`Divide, l, r))
|
| ("divide", [|l, r|]) => toOkAlgebraic((`Divide, l, r))
|
||||||
| ("divide", _) => Error("Division needs two operands")
|
| ("divide", _) => Error("Division needs two operands")
|
||||||
| ("pow", _) => Error("Exponentiation is not yet supported.")
|
|
||||||
| ("leftTruncate", [|d, `SymbolicDist(`Float(lc))|]) =>
|
| ("leftTruncate", [|d, `SymbolicDist(`Float(lc))|]) =>
|
||||||
toOkTruncate((Some(lc), None, d))
|
toOkTruncate((Some(lc), None, d))
|
||||||
| ("leftTruncate", _) =>
|
| ("leftTruncate", _) =>
|
||||||
|
|
|
@ -7,6 +7,7 @@ module Algebraic = {
|
||||||
| `Add => (+.)
|
| `Add => (+.)
|
||||||
| `Subtract => (-.)
|
| `Subtract => (-.)
|
||||||
| `Multiply => ( *. )
|
| `Multiply => ( *. )
|
||||||
|
| `Exponentiate => ( ** )
|
||||||
| `Divide => (/.);
|
| `Divide => (/.);
|
||||||
|
|
||||||
let applyFn = (t, f1, f2) => {
|
let applyFn = (t, f1, f2) => {
|
||||||
|
@ -21,6 +22,7 @@ module Algebraic = {
|
||||||
| `Add => "+"
|
| `Add => "+"
|
||||||
| `Subtract => "-"
|
| `Subtract => "-"
|
||||||
| `Multiply => "*"
|
| `Multiply => "*"
|
||||||
|
| `Exponentiate => ( "**" )
|
||||||
| `Divide => "/";
|
| `Divide => "/";
|
||||||
|
|
||||||
let format = (a, b, c) => b ++ " " ++ toString(a) ++ " " ++ c;
|
let format = (a, b, c) => b ++ " " ++ toString(a) ++ " " ++ c;
|
||||||
|
|
|
@ -125,7 +125,7 @@ module Internals = {
|
||||||
let inputsToShape = (inputs: inputs) => {
|
let inputsToShape = (inputs: inputs) => {
|
||||||
MathJsParser.fromString(inputs.guesstimatorString)
|
MathJsParser.fromString(inputs.guesstimatorString)
|
||||||
|> E.R.bind(_, g => runProgram(inputs, g))
|
|> E.R.bind(_, g => runProgram(inputs, g))
|
||||||
|> E.R.bind(_, r => E.A.last(r) |> E.O.toResult("No rendered lines"));
|
|> E.R.bind(_, r => E.A.last(r) |> E.O.toResult("No rendered lines") |> E.R.fmap(Shape.T.normalize));
|
||||||
};
|
};
|
||||||
|
|
||||||
let outputToDistPlus = (inputs: Inputs.inputs, shape: DistTypes.shape) => {
|
let outputToDistPlus = (inputs: Inputs.inputs, shape: DistTypes.shape) => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user