Small changes to hopefully improve CDF.re

This commit is contained in:
Ozzie Gooen 2020-03-16 20:20:39 +00:00
parent c682fff280
commit fff473b27c
5 changed files with 83 additions and 31 deletions

View File

@ -112,8 +112,7 @@ module Continuous = {
let toDiscreteProbabilityMass = _ => 0.0; let toDiscreteProbabilityMass = _ => 0.0;
let pointwiseFmap = (fn, t: t) => let pointwiseFmap = (fn, t: t) =>
t |> xyShape |> XYShape.T.pointwiseMap(fn) |> fromShape; t |> xyShape |> XYShape.T.pointwiseMap(fn) |> fromShape;
let truncate = i => let truncate = i => shapeMap(XYShape.T.convertToNewLength(i));
shapeMap(CdfLibrary.Distribution.convertToNewLength(i));
let toShape = (t: t): DistTypes.shape => Continuous(t); let toShape = (t: t): DistTypes.shape => Continuous(t);
let xToY = (f, {interpolation, xyShape}: t) => let xToY = (f, {interpolation, xyShape}: t) =>
switch (interpolation) { switch (interpolation) {

View File

@ -50,7 +50,33 @@ module T = {
let findY = (x: float, t: t): float => { let findY = (x: float, t: t): float => {
// todo: change getIndexBy to realize it's sorted // todo: change getIndexBy to realize it's sorted
// Belt.SortArray.binarySearchBy let firstHigherIndex =
E.A.Sorted.binarySearchFirstElementGreaterIndex(xs(t), x);
let n =
switch (firstHigherIndex) {
| `overMax => maxY(t) |> E.O.default(0.0)
| `underMin => minY(t) |> E.O.default(0.0)
| `firstHigher(firstHigherIndex) =>
let lowerOrEqualIndex =
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
let needsInterpolation = xs(t)[lowerOrEqualIndex] != x;
if (needsInterpolation) {
Functions.interpolate(
xs(t)[lowerOrEqualIndex],
xs(t)[firstHigherIndex],
ys(t)[lowerOrEqualIndex],
ys(t)[firstHigherIndex],
x,
);
} else {
ys(t)[lowerOrEqualIndex];
};
};
n;
};
let findYA = (x: float, t: t): float => {
// todo: change getIndexBy to realize it's sorted
let firstHigherIndex = Belt.Array.getIndexBy(xs(t), e => e >= x); let firstHigherIndex = Belt.Array.getIndexBy(xs(t), e => e >= x);
switch (firstHigherIndex) { switch (firstHigherIndex) {
| None => maxY(t) |> E.O.default(0.0) | None => maxY(t) |> E.O.default(0.0)
@ -75,25 +101,39 @@ module T = {
let findX = (y: float, t: t): float => { let findX = (y: float, t: t): float => {
let firstHigherIndex = Belt.Array.getIndexBy(ys(t), e => e >= y); let firstHigherIndex = Belt.Array.getIndexBy(ys(t), e => e >= y);
switch (firstHigherIndex) { let f: float =
| None => maxX(t) |> E.O.default(0.0) switch (firstHigherIndex) {
| Some(0) => minX(t) |> E.O.default(0.0) | None => maxX(t) |> E.O.default(0.0)
| Some(firstHigherIndex) => | Some(0) => minX(t) |> E.O.default(0.0)
let lowerOrEqualIndex = | Some(firstHigherIndex) =>
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1; let lowerOrEqualIndex =
let needsInterpolation = ys(t)[lowerOrEqualIndex] != y; firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
if (needsInterpolation) { let needsInterpolation = ys(t)[lowerOrEqualIndex] != y;
Functions.interpolate( if (needsInterpolation) {
ys(t)[lowerOrEqualIndex], Functions.interpolate(
ys(t)[firstHigherIndex], ys(t)[lowerOrEqualIndex],
ys(t)[lowerOrEqualIndex], ys(t)[firstHigherIndex],
ys(t)[firstHigherIndex], ys(t)[lowerOrEqualIndex],
y, ys(t)[firstHigherIndex],
); y,
} else { );
xs(t)[lowerOrEqualIndex]; } else {
xs(t)[lowerOrEqualIndex];
};
}; };
}; f;
};
let convertWithAlternativeXs = (newXs: array(float), t: t): t => {
let newYs = Belt.Array.map(newXs, f => findY(f, t));
{xs: newXs, ys: newYs};
};
let convertToNewLength = (newLength: int, t: t): DistTypes.xyShape => {
Functions.(
range(min(xs(t)), max(xs(t)), newLength)
|> convertWithAlternativeXs(_, t)
);
}; };
module XtoY = { module XtoY = {

View File

@ -138,7 +138,6 @@ module J = {
let fromNumber = Js.Json.number; let fromNumber = Js.Json.number;
module O = { module O = {
let fromString = (str: string) => let fromString = (str: string) =>
switch (str) { switch (str) {
| "" => None | "" => None
@ -287,6 +286,18 @@ module A = {
bringErrorUp |> Belt.Result.map(_, forceOpen); bringErrorUp |> Belt.Result.map(_, forceOpen);
}; };
}; };
module Sorted = {
let binarySearchFirstElementGreaterIndex = (ar: array('a), el: 'a) => {
let el = Belt.SortArray.binarySearchBy(ar, el, compare);
let el = el < 0 ? el * (-1) - 1 : el;
switch (el) {
| e when e >= length(ar) => `overMax
| e when e == 0 => `underMin
| e => `firstHigher(e)
};
};
};
}; };
module JsArray = { module JsArray = {

View File

@ -131,7 +131,7 @@ let toMixed =
~cuttoff=0.995, ~cuttoff=0.995,
(), (),
) => { ) => {
let truncateTo = None; // let truncateTo = None;
let start = Js.Date.now(); let start = Js.Date.now();
let timeMessage = message => Js.log2(message, Js.Date.now() -. start); let timeMessage = message => Js.log2(message, Js.Date.now() -. start);
timeMessage("Starting"); timeMessage("Starting");

View File

@ -35,11 +35,12 @@ module Make = (Config: Config) => {
let minY = () => get(ys, 0); let minY = () => get(ys, 0);
let maxY = () => get(ys, len(ys) - 1); let maxY = () => get(ys, len(ys) - 1);
let findY = (x: float): float => { let findY = (x: float): float => {
let firstHigherIndex = Belt.Array.getIndexBy(xs, e => e >= x); let firstHigherIndex =
E.A.Sorted.binarySearchFirstElementGreaterIndex(xs, x);
switch (firstHigherIndex) { switch (firstHigherIndex) {
| None => maxY() | `overMax => maxY()
| Some(0) => minY() | `underMin => minY()
| Some(firstHigherIndex) => | `firstHigher(firstHigherIndex) =>
let lowerOrEqualIndex = let lowerOrEqualIndex =
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1; firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
let needsInterpolation = get(xs, lowerOrEqualIndex) != x; let needsInterpolation = get(xs, lowerOrEqualIndex) != x;
@ -57,11 +58,12 @@ module Make = (Config: Config) => {
}; };
}; };
let findX = (y: float): float => { let findX = (y: float): float => {
let firstHigherIndex = Belt.Array.getIndexBy(ys, e => e >= y); let firstHigherIndex =
E.A.Sorted.binarySearchFirstElementGreaterIndex(ys, y);
switch (firstHigherIndex) { switch (firstHigherIndex) {
| None => maxX() | `overMax => maxX()
| Some(0) => minX() | `underMin => minX()
| Some(firstHigherIndex) => | `firstHigher(firstHigherIndex) =>
let lowerOrEqualIndex = let lowerOrEqualIndex =
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1; firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
let needsInterpolation = get(ys, lowerOrEqualIndex) != y; let needsInterpolation = get(ys, lowerOrEqualIndex) != y;