Minor changes of optionals in distributions

This commit is contained in:
Ozzie Gooen 2020-03-28 21:29:02 +00:00
parent 29d8e40693
commit 786ee1fded
10 changed files with 43 additions and 83 deletions

View File

@ -16,8 +16,8 @@ describe("Shape", () => {
describe("Continuous", () => {
open Distributions.Continuous;
let continuous = make(shape, `Linear);
makeTest("minX", T.minX(continuous), Some(1.0));
makeTest("maxX", T.maxX(continuous), Some(8.0));
makeTest("minX", T.minX(continuous), 1.0);
makeTest("maxX", T.maxX(continuous), 8.0);
makeTest(
"mapY",
T.mapY(r => r *. 2.0, continuous) |> getShape |> (r => r.ys),
@ -127,8 +127,8 @@ describe("Shape", () => {
ys: [|0.3, 0.5, 0.2|],
};
let discrete = shape;
makeTest("minX", T.minX(discrete), Some(1.0));
makeTest("maxX", T.maxX(discrete), Some(8.0));
makeTest("minX", T.minX(discrete), 1.0);
makeTest("maxX", T.maxX(discrete), 8.0);
makeTest(
"mapY",
T.mapY(r => r *. 2.0, discrete) |> (r => r.ys),
@ -210,8 +210,8 @@ describe("Shape", () => {
},
)
|> E.O.toExn("");
makeTest("minX", T.minX(mixed), Some(1.0));
makeTest("maxX", T.maxX(mixed), Some(14.0));
makeTest("minX", T.minX(mixed), 1.0);
makeTest("maxX", T.maxX(mixed), 14.0);
makeTest(
"mapY",
T.mapY(r => r *. 2.0, mixed),
@ -320,8 +320,8 @@ describe("Shape", () => {
~guesstimatorString=None,
(),
);
makeTest("minX", T.minX(distPlus), Some(1.0));
makeTest("maxX", T.maxX(distPlus), Some(14.0));
makeTest("minX", T.minX(distPlus), 1.0);
makeTest("maxX", T.maxX(distPlus), 14.0);
makeTest(
"xToY at 4.0",
T.xToY(4., distPlus),

View File

@ -267,11 +267,7 @@ module IntegralChart = {
|> Distributions.Continuous.toLinear
|> E.O.fmap(Distributions.Continuous.getShape);
let range = T.xTotalRange(distPlus);
let minX =
switch (T.minX(distPlus), range) {
| (Some(min), Some(range)) => Some(min -. range *. 0.001)
| _ => None
};
let minX = T.minX(distPlus) -. range *. 0.001;
let maxX = integral |> Distributions.Continuous.T.maxX;
let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson;
<DistributionPlot

View File

@ -1,8 +1,8 @@
module type dist = {
type t;
type integral;
let minX: t => option(float);
let maxX: t => option(float);
let minX: t => float;
let maxX: t => float;
let mapY: (float => float, t) => t;
let xToY: (float, t) => DistTypes.mixedPoint;
let toShape: t => DistTypes.shape;
@ -24,11 +24,7 @@ module Dist = (T: dist) => {
type integral = T.integral;
let minX = T.minX;
let maxX = T.maxX;
let xTotalRange = (t: t) =>
switch (minX(t), maxX(t)) {
| (Some(min), Some(max)) => Some(max -. min)
| _ => None
};
let xTotalRange = (t: t) => maxX(t) -. minX(t);
let mapY = T.mapY;
let xToY = T.xToY;
let truncate = T.truncate;
@ -60,7 +56,6 @@ module Dist = (T: dist) => {
module Continuous = {
type t = DistTypes.continuousShape;
let xyShape = (t: t) => t.xyShape;
let getShape = (t: t) => t.xyShape;
let interpolation = (t: t) => t.interpolation;
let make = (xyShape, interpolation): t => {xyShape, interpolation};
@ -69,8 +64,7 @@ module Continuous = {
xyShape: fn(xyShape),
interpolation,
};
let lastY = (t: t) =>
t |> xyShape |> XYShape.Pairs.unsafeLast |> (((_, y)) => y);
let lastY = (t: t) => t |> getShape |> XYShape.T.lastY;
let oShapeMap =
(fn, {xyShape, interpolation}: t): option(DistTypes.continuousShape) =>
fn(xyShape) |> E.O.fmap(make(_, interpolation));
@ -84,17 +78,17 @@ module Continuous = {
| {interpolation: `Linear, _} => Some(t)
};
};
let shapeFn = (fn, t: t) => t |> xyShape |> fn;
let shapeFn = (fn, t: t) => t |> getShape |> fn;
module T =
Dist({
type t = DistTypes.continuousShape;
type integral = DistTypes.continuousShape;
let minX = shapeFn(XYShape.T.minX);
let maxX = shapeFn(XYShape.T.maxX);
let minX = shapeFn(r => r |> XYShape.T.minX);
let maxX = shapeFn(r => r |> XYShape.T.maxX);
let toDiscreteProbabilityMass = _ => 0.0;
let mapY = (fn, t: t) =>
t |> xyShape |> XYShape.T.mapY(fn) |> fromShape;
t |> getShape |> XYShape.T.mapY(fn) |> fromShape;
let toShape = (t: t): DistTypes.shape => Continuous(t);
let xToY = (f, {interpolation, xyShape}: t) =>
switch (interpolation) {
@ -121,7 +115,7 @@ module Continuous = {
| Some(cache) => cache
| None =>
t
|> xyShape
|> getShape
|> XYShape.Range.integrateWithTriangles
|> E.O.toExt("This should not have happened")
|> fromShape

View File

@ -8,16 +8,19 @@ let interpolate =
yMin *. minProportion +. yMax *. maxProportion;
};
// TODO: Make sure that shapes cannot be empty.
let extImp = E.O.toExt("Should not be possible");
module T = {
type t = xyShape;
type ts = array(xyShape);
let xs = (t: t) => t.xs;
let ys = (t: t) => t.ys;
let minX = (t: t) => t |> xs |> E.A.Sorted.min;
let maxX = (t: t) => t |> xs |> E.A.Sorted.max;
let minY = (t: t) => t |> ys |> E.A.Sorted.min;
let maxY = (t: t) => t |> ys |> E.A.Sorted.max;
let xTotalRange = (t: t) => t |> xs |> E.A.Sorted.range;
let minX = (t: t) => t |> xs |> E.A.Sorted.min |> extImp;
let maxX = (t: t) => t |> xs |> E.A.Sorted.max |> extImp;
let firstY = (t: t) => t |> ys |> E.A.first |> extImp;
let lastY = (t: t) => t |> ys |> E.A.last |> extImp;
let xTotalRange = (t: t) => maxX(t) -. minX(t);
let mapX = (fn, t: t): t => {xs: E.A.fmap(fn, t.xs), ys: t.ys};
let mapY = (fn, t: t): t => {xs: t.xs, ys: E.A.fmap(fn, t.ys)};
let zip = ({xs, ys}: t) => Belt.Array.zip(xs, ys);
@ -29,11 +32,7 @@ module T = {
let fromZippedArray = (pairs: array((float, float))): t =>
pairs |> Belt.Array.unzip |> fromArray;
let equallyDividedXs = (t: t, newLength) => {
E.A.Floats.range(
minX(t) |> E.O.toExt("Unsafe"),
maxX(t) |> E.O.toExt("Unsafe"),
newLength,
);
E.A.Floats.range(minX(t), maxX(t), newLength);
};
let toJs = (t: t) => {
{"xs": t.xs, "ys": t.ys};
@ -42,18 +41,8 @@ module T = {
module Ts = {
type t = T.ts;
let minX = (t: t) =>
t
|> E.A.fmap(T.minX)
|> E.A.O.concatSomes
|> E.A.min
|> E.O.toExt("Unsafe");
let maxX = (t: t) =>
t
|> E.A.fmap(T.maxX)
|> E.A.O.concatSomes
|> E.A.max
|> E.O.toExt("Unsafe");
let minX = (t: t) => t |> E.A.fmap(T.minX) |> E.A.min |> extImp;
let maxX = (t: t) => t |> E.A.fmap(T.maxX) |> E.A.max |> extImp;
let equallyDividedXs = (t: t, newLength) => {
E.A.Floats.range(minX(t), maxX(t), newLength);
};
@ -63,19 +52,8 @@ module Ts = {
module Pairs = {
let x = fst;
let y = snd;
let first = (t: T.t) =>
switch (T.minX(t), T.minY(t)) {
| (Some(x), Some(y)) => Some((x, y))
| _ => None
};
let last = (t: T.t) =>
switch (T.maxX(t), T.maxY(t)) {
| (Some(x), Some(y)) => Some((x, y))
| _ => None
};
let unsafeFirst = (t: T.t) => first(t) |> E.O.toExn("Unsafe operation");
let unsafeLast = (t: T.t) => last(t) |> E.O.toExn("Unsafe operation");
let first = (t: T.t) => (T.minX(t), T.firstY(t));
let last = (t: T.t) => (T.maxX(t), T.lastY(t));
let getBy = (t: T.t, fn) => t |> T.zip |> E.A.getBy(_, fn);
@ -99,8 +77,8 @@ module YtoX = {
E.A.Sorted.binarySearchFirstElementGreaterIndex(T.ys(t), y);
let foundX =
switch (firstHigherIndex) {
| `overMax => T.maxX(t) |> E.O.default(0.0)
| `underMin => T.minX(t) |> E.O.default(0.0)
| `overMax => T.maxX(t)
| `underMin => T.minX(t)
| `firstHigher(firstHigherIndex) =>
let lowerOrEqualIndex =
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
@ -135,8 +113,8 @@ module XtoY = {
E.A.Sorted.binarySearchFirstElementGreaterIndex(T.xs(t), x);
let n =
switch (firstHigherIndex) {
| `overMax => T.maxY(t) |> E.O.default(0.0)
| `underMin => T.minY(t) |> E.O.default(0.0)
| `overMax => T.lastY(t)
| `underMin => T.firstY(t)
| `firstHigher(firstHigherIndex) =>
let lowerOrEqualIndex =
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
@ -180,10 +158,10 @@ module XsConversion = {
module Zipped = {
type zipped = array((float, float));
let sortByY = (t: zipped) =>
t |> E.A.stableSortBy(_, ((_, y1), (_, y2)) => y1 > y2 ? 1 : 0);
let sortByX = (t: zipped) =>
t |> E.A.stableSortBy(_, ((x1, _), (x2, _)) => x1 > x2 ? 1 : 0);
let compareYs = ((_, y1), (_, y2)) => y1 > y2 ? 1 : 0;
let compareXs = ((x1, _), (x2, _)) => x1 > x2 ? 1 : 0;
let sortByY = (t: zipped) => t |> E.A.stableSortBy(_, compareYs);
let sortByX = (t: zipped) => t |> E.A.stableSortBy(_, compareXs);
};
module Combine = {
@ -282,10 +260,10 @@ module Range = {
// TODO: It would be nicer if this the diff didn't change the first element, and also maybe if there were a more elegant way of doing this.
let stepsToContinuous = t => {
let diff = T.xTotalRange(t) |> E.O.fmap(r => r *. 0.00001);
let diff = T.xTotalRange(t) |> (r => r *. 0.00001);
let items =
switch (diff, E.A.toRanges(Belt.Array.zip(t.xs, t.ys))) {
| (Some(diff), Ok(items)) =>
switch (E.A.toRanges(Belt.Array.zip(t.xs, t.ys))) {
| Ok(items) =>
Some(
items
|> Belt.Array.map(_, rangePointAssumingSteps)
@ -321,5 +299,5 @@ let logScorePoint = (sampleCount, t1, t2) =>
)
|> Range.integrateWithTriangles
|> E.O.fmap(T.accumulateYs((+.)))
|> E.O.bind(_, Pairs.last)
|> E.O.fmap(Pairs.last)
|> E.O.fmap(Pairs.y);

View File

@ -215,7 +215,6 @@ module L = {
let toArray = Array.of_list;
let fmapi = List.mapi;
let concat = List.concat;
let append = List.append;
let drop = Rationale.RList.drop;
let remove = Rationale.RList.remove;
let find = List.find;

View File

@ -1,7 +0,0 @@
let interpolate =
(xMin: float, xMax: float, yMin: float, yMax: float, xIntended: float)
: float => {
let minProportion = (xMax -. xIntended) /. (xMax -. xMin);
let maxProportion = (xIntended -. xMin) /. (xMax -. xMin);
yMin *. minProportion +. yMax *. maxProportion;
};