feat: kl function but no dealing with errors yet

This commit is contained in:
NunoSempere 2022-05-06 10:49:04 -04:00
parent b393af8762
commit cc3db79a2a
2 changed files with 49 additions and 12 deletions

View File

@ -55,6 +55,7 @@ type operationError =
| ComplexNumberError | ComplexNumberError
| InfinityError | InfinityError
| NegativeInfinityError | NegativeInfinityError
| LogicallyInconsistentPathwayError
@genType @genType
module Error = { module Error = {
@ -67,6 +68,7 @@ module Error = {
| ComplexNumberError => "Operation returned complex result" | ComplexNumberError => "Operation returned complex result"
| InfinityError => "Operation returned positive infinity" | InfinityError => "Operation returned positive infinity"
| NegativeInfinityError => "Operation returned negative infinity" | NegativeInfinityError => "Operation returned negative infinity"
| LogicallyInconsistentPathwayError => "This pathway should have been logically unreachable"
} }
} }

View File

@ -455,25 +455,60 @@ module PointwiseCombination = {
T.filterOkYs(newXs, newYs)->Ok T.filterOkYs(newXs, newYs)->Ok
} }
let iterpolator2: (xyShape, float) => option<float> = (dist: xyShape, x: float) => { let getApproximatePdfOfContinuousDistributionAtPoint: (xyShape, float) => option<float> = (
let l = E.A.length(dist.xs) dist: xyShape,
let firstPoint = dist.xs[0] point: float,
let lastPoint = dist.xs[l - 1] ) => {
switch (firstPoint < x, lastPoint > x) { let closestFromBelowIndex = E.A.reducei(dist.xs, None, (accumulator, item, index) =>
| (false, false) => Some(0.0) item < point ? Some(index) : accumulator
| (false, true) => Some(0.0) ) // This could be made more efficient by taking advantage of the fact that these are ordered
| (true, false) => Some(0.0) let closestFromAboveIndexOption = Belt.Array.getIndexBy(dist.xs, item => item > point)
| (true, true) => None
let weightedMean = (
point: float,
closestFromBelow: float,
closestFromAbove: float,
valueclosestFromBelow,
valueclosestFromAbove,
): float => {
let distance = closestFromAbove -. closestFromBelow
let w1 = (point -. closestFromBelow) /. distance
let w2 = (closestFromAbove -. point) /. distance
let result = w1 *. valueclosestFromAbove +. w2 *. valueclosestFromBelow
result
} }
let result = switch (closestFromBelowIndex, closestFromAboveIndexOption) {
| (None, None) => None // all are smaller, and all are larger
| (None, Some(i)) => Some(0.0) // none are smaller, all are larger
| (Some(i), None) => Some(0.0) // all are smaller, none are larger
| (Some(i), Some(j)) =>
Some(weightedMean(point, dist.xs[i], dist.xs[j], dist.ys[i], dist.ys[j])) // there is a lowerBound and an upperBound.
}
result
} }
let combineAlongSupportOfSecondArgument2: ( let combineAlongSupportOfSecondArgument2: (
(float, float) => result<float, Operation.Error.t>, (float, float) => result<float, Operation.Error.t>,
interpolator,
T.t, T.t,
T.t, T.t,
) => result<T.t, Operation.Error.t> = (fn, interpolator, t1, t2) => { ) => result<T.t, Operation.Error.t> = (fn, prediction, answer) => {
T.filterOkYs([], [])->Ok let newXs = answer.xs
let combineWithFn = (x: float, i: int) => {
let answerX = x
let answerY = answer.ys[i]
let predictionY = getApproximatePdfOfContinuousDistributionAtPoint(prediction, answerX)
let wrappedResult = E.O.fmap(x => fn(x, answerY), predictionY)
let result = switch wrappedResult {
| Some(x) => x
| None => Error(Operation.LogicallyInconsistentPathwayError)
}
result
}
let newYs = Js.Array.mapi((x, i) => combineWithFn(x, i), answer.xs)
T.filterOkYs(newXs, newYs)->Ok
} }
let addCombine = (interpolator: interpolator, t1: T.t, t2: T.t): T.t => let addCombine = (interpolator: interpolator, t1: T.t, t2: T.t): T.t =>