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 pointwiseFmap = (fn, t: t) =>
t |> xyShape |> XYShape.T.pointwiseMap(fn) |> fromShape;
let truncate = i =>
shapeMap(CdfLibrary.Distribution.convertToNewLength(i));
let truncate = i => shapeMap(XYShape.T.convertToNewLength(i));
let toShape = (t: t): DistTypes.shape => Continuous(t);
let xToY = (f, {interpolation, xyShape}: t) =>
switch (interpolation) {

View File

@ -50,7 +50,33 @@ module T = {
let findY = (x: float, t: t): float => {
// 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);
switch (firstHigherIndex) {
| None => maxY(t) |> E.O.default(0.0)
@ -75,25 +101,39 @@ module T = {
let findX = (y: float, t: t): float => {
let firstHigherIndex = Belt.Array.getIndexBy(ys(t), e => e >= y);
switch (firstHigherIndex) {
| None => maxX(t) |> E.O.default(0.0)
| Some(0) => minX(t) |> E.O.default(0.0)
| Some(firstHigherIndex) =>
let lowerOrEqualIndex =
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
let needsInterpolation = ys(t)[lowerOrEqualIndex] != y;
if (needsInterpolation) {
Functions.interpolate(
ys(t)[lowerOrEqualIndex],
ys(t)[firstHigherIndex],
ys(t)[lowerOrEqualIndex],
ys(t)[firstHigherIndex],
y,
);
} else {
xs(t)[lowerOrEqualIndex];
let f: float =
switch (firstHigherIndex) {
| None => maxX(t) |> E.O.default(0.0)
| Some(0) => minX(t) |> E.O.default(0.0)
| Some(firstHigherIndex) =>
let lowerOrEqualIndex =
firstHigherIndex - 1 < 0 ? 0 : firstHigherIndex - 1;
let needsInterpolation = ys(t)[lowerOrEqualIndex] != y;
if (needsInterpolation) {
Functions.interpolate(
ys(t)[lowerOrEqualIndex],
ys(t)[firstHigherIndex],
ys(t)[lowerOrEqualIndex],
ys(t)[firstHigherIndex],
y,
);
} 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 = {

View File

@ -138,7 +138,6 @@ module J = {
let fromNumber = Js.Json.number;
module O = {
let fromString = (str: string) =>
switch (str) {
| "" => None
@ -287,6 +286,18 @@ module A = {
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 = {

View File

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

View File

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