Improves sparklines by integrating them more deeply to the codebase
This commit is contained in:
parent
b8d07bd8a4
commit
0fa954ae63
|
@ -5,7 +5,7 @@ let {normalDist, uniformDist, betaDist, lognormalDist, cauchyDist, triangularDis
|
||||||
|
|
||||||
let runTest = (name: string, dist : GenericDist_Types.genericDist, expected: string) => {
|
let runTest = (name: string, dist : GenericDist_Types.genericDist, expected: string) => {
|
||||||
test(name, () => {
|
test(name, () => {
|
||||||
let result = GenericDist.toSparkline(~sampleCount=100, ~buckets=20, dist)
|
let result = GenericDist.toSparkline(dist, ~sampleCount=100, ~buckets=20, ())
|
||||||
switch result {
|
switch result {
|
||||||
| Ok(sparkline) => expect(sparkline)->toEqual(expected)
|
| Ok(sparkline) => expect(sparkline)->toEqual(expected)
|
||||||
| Error(err) => expect("Error")->toEqual(expected)
|
| Error(err) => expect("Error")->toEqual(expected)
|
||||||
|
@ -14,11 +14,11 @@ let runTest = (name: string, dist : GenericDist_Types.genericDist, expected: str
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("sparkline of generic distribution", () => {
|
describe("sparkline of generic distribution", () => {
|
||||||
runTest("normal", normalDist, `▁▃▄▅▆▇████████▇▆▅▄▃▁`)
|
runTest("normal", normalDist, `▁▁▁▁▁▂▄▆▇██▇▆▄▂▁▁▁▁▁`)
|
||||||
runTest("uniform", uniformDist, `▁██▁`)
|
runTest("uniform", uniformDist, `████████████████████`)
|
||||||
runTest("beta", betaDist, `▁▅▇█████████▇▇▆▅▄▃▂▁`)
|
runTest("beta", betaDist, `▁▄▇████▇▆▅▄▃▃▂▁▁▁▁▁▁`)
|
||||||
runTest("lognormal", lognormalDist, `▁▇████▇▇▆▆▅▄▄▃▃▂▂▁▁▁`)
|
runTest("lognormal", lognormalDist, `▁█▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁`)
|
||||||
runTest("cauchy", cauchyDist, `▁▁▁▂▄▅▆▇████▇▆▅▄▂▁▁▁`)
|
runTest("cauchy", cauchyDist, `▁▁▁▁▁▁▁▁▁██▁▁▁▁▁▁▁▁▁`)
|
||||||
runTest("triangular", triangularDist, `▁▃▄▅▆▆▇██████▇▆▆▅▄▃▁`)
|
runTest("triangular", triangularDist, `▁▁▂▃▄▅▆▇████▇▆▅▄▃▂▁▁`)
|
||||||
runTest("exponential", exponentialDist, `███▇▇▆▆▆▅▅▄▄▃▃▃▂▂▁▁▁`)
|
runTest("exponential", exponentialDist, `█▅▄▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁`)
|
||||||
})
|
})
|
||||||
|
|
|
@ -114,6 +114,10 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
|
||||||
->E.R2.fmap(r => Float(r))
|
->E.R2.fmap(r => Float(r))
|
||||||
->OutputLocal.fromResult
|
->OutputLocal.fromResult
|
||||||
| ToString => dist->GenericDist.toString->String
|
| ToString => dist->GenericDist.toString->String
|
||||||
|
| ToSparkline(buckets) =>
|
||||||
|
GenericDist.toSparkline(dist, ~sampleCount, ~buckets, ())
|
||||||
|
->E.R2.fmap(r => String(r))
|
||||||
|
->OutputLocal.fromResult
|
||||||
| ToDist(Inspect) => {
|
| ToDist(Inspect) => {
|
||||||
Js.log2("Console log requested: ", dist)
|
Js.log2("Console log requested: ", dist)
|
||||||
Dist(dist)
|
Dist(dist)
|
||||||
|
@ -127,7 +131,7 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
|
||||||
dist->GenericDist.sampleN(n)->E.R2.fmap(r => Dist(SampleSet(r)))->OutputLocal.fromResult
|
dist->GenericDist.sampleN(n)->E.R2.fmap(r => Dist(SampleSet(r)))->OutputLocal.fromResult
|
||||||
| ToDist(ToPointSet) =>
|
| ToDist(ToPointSet) =>
|
||||||
dist
|
dist
|
||||||
->GenericDist.toPointSet(~xyPointLength, ~sampleCount)
|
->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ())
|
||||||
->E.R2.fmap(r => Dist(PointSet(r)))
|
->E.R2.fmap(r => Dist(PointSet(r)))
|
||||||
->OutputLocal.fromResult
|
->OutputLocal.fromResult
|
||||||
| ToDistCombination(Algebraic, _, #Float(_)) => GenDistError(NotYetImplemented)
|
| ToDistCombination(Algebraic, _, #Float(_)) => GenDistError(NotYetImplemented)
|
||||||
|
|
|
@ -52,10 +52,16 @@ let toFloatOperation = (
|
||||||
//Todo: If it's a pointSet, but the xyPointLength is different from what it has, it should change.
|
//Todo: If it's a pointSet, but the xyPointLength is different from what it has, it should change.
|
||||||
// This is tricky because the case of discrete distributions.
|
// This is tricky because the case of discrete distributions.
|
||||||
// Also, change the outputXYPoints/pointSetDistLength details
|
// Also, change the outputXYPoints/pointSetDistLength details
|
||||||
let toPointSet = (~xyPointLength, ~sampleCount, t): result<PointSetTypes.pointSetDist, error> => {
|
let toPointSet = (
|
||||||
|
t,
|
||||||
|
~xyPointLength,
|
||||||
|
~sampleCount,
|
||||||
|
~xSelection: GenericDist_Types.Operation.pointsetXSelection=#ByWeight,
|
||||||
|
unit,
|
||||||
|
): result<PointSetTypes.pointSetDist, error> => {
|
||||||
switch (t: t) {
|
switch (t: t) {
|
||||||
| PointSet(pointSet) => Ok(pointSet)
|
| PointSet(pointSet) => Ok(pointSet)
|
||||||
| Symbolic(r) => Ok(SymbolicDist.T.toPointSetDist(xyPointLength, r))
|
| Symbolic(r) => Ok(SymbolicDist.T.toPointSetDist(~xSelection, xyPointLength, r))
|
||||||
| SampleSet(r) => {
|
| SampleSet(r) => {
|
||||||
let response = SampleSet.toPointSetDist(
|
let response = SampleSet.toPointSetDist(
|
||||||
~samples=r,
|
~samples=r,
|
||||||
|
@ -75,10 +81,10 @@ let toPointSet = (~xyPointLength, ~sampleCount, t): result<PointSetTypes.pointSe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let toSparkline = (~sampleCount: int, ~buckets: int = 20, t: t) : result<string, error> =>
|
let toSparkline = (t: t, ~sampleCount: int, ~buckets: int=20, unit): result<string, error> =>
|
||||||
toPointSet(~xyPointLength=buckets, ~sampleCount, t)
|
t
|
||||||
-> E.R.bind(x => x -> PointSetDist.T.toContinuous -> E.O2.toResult(GenericDist_Types.Other("Could not convert to continuous")))
|
->toPointSet(~xSelection=#Linear, ~xyPointLength=buckets, ~sampleCount, ())
|
||||||
-> E.R2.fmap(c => Sparklines.create(Continuous.getShape(c).ys, ()))
|
->E.R.bind(r => r->PointSetDist.toSparkline->E.R2.errMap(r => Error(GenericDist_Types.Other(r))))
|
||||||
|
|
||||||
module Truncate = {
|
module Truncate = {
|
||||||
let trySymbolicSimplification = (leftCutoff, rightCutoff, t: t): option<t> =>
|
let trySymbolicSimplification = (leftCutoff, rightCutoff, t: t): option<t> =>
|
||||||
|
|
|
@ -20,22 +20,20 @@ let toFloatOperation: (
|
||||||
) => result<float, error>
|
) => result<float, error>
|
||||||
|
|
||||||
let toPointSet: (
|
let toPointSet: (
|
||||||
|
t,
|
||||||
~xyPointLength: int,
|
~xyPointLength: int,
|
||||||
~sampleCount: int,
|
~sampleCount: int,
|
||||||
t,
|
~xSelection: GenericDist_Types.Operation.pointsetXSelection=?,
|
||||||
|
unit,
|
||||||
) => result<PointSetTypes.pointSetDist, error>
|
) => result<PointSetTypes.pointSetDist, error>
|
||||||
let toSparkline: (
|
let toSparkline: (t, ~sampleCount: int, ~buckets: int=?, unit) => result<string, error>
|
||||||
~sampleCount: int,
|
|
||||||
~buckets: int=?,
|
|
||||||
t,
|
|
||||||
) => result<string, error>
|
|
||||||
|
|
||||||
let truncate: (
|
let truncate: (
|
||||||
t,
|
t,
|
||||||
~toPointSetFn: toPointSetFn,
|
~toPointSetFn: toPointSetFn,
|
||||||
~leftCutoff: option<float>=?,
|
~leftCutoff: option<float>=?,
|
||||||
~rightCutoff: option<float>=?,
|
~rightCutoff: option<float>=?,
|
||||||
unit
|
unit,
|
||||||
) => result<t, error>
|
) => result<t, error>
|
||||||
|
|
||||||
let algebraicCombination: (
|
let algebraicCombination: (
|
||||||
|
|
|
@ -41,6 +41,8 @@ module Operation = {
|
||||||
| #Sample
|
| #Sample
|
||||||
]
|
]
|
||||||
|
|
||||||
|
type pointsetXSelection = [#Linear | #ByWeight]
|
||||||
|
|
||||||
type toDist =
|
type toDist =
|
||||||
| Normalize
|
| Normalize
|
||||||
| ToPointSet
|
| ToPointSet
|
||||||
|
@ -55,6 +57,7 @@ module Operation = {
|
||||||
| ToDist(toDist)
|
| ToDist(toDist)
|
||||||
| ToDistCombination(direction, arithmeticOperation, [#Dist(genericDist) | #Float(float)])
|
| ToDistCombination(direction, arithmeticOperation, [#Dist(genericDist) | #Float(float)])
|
||||||
| ToString
|
| ToString
|
||||||
|
| ToSparkline(int)
|
||||||
|
|
||||||
type singleParamaterFunction =
|
type singleParamaterFunction =
|
||||||
| FromDist(fromDist)
|
| FromDist(fromDist)
|
||||||
|
@ -78,6 +81,7 @@ module Operation = {
|
||||||
| ToDist(Truncate(_, _)) => `truncate`
|
| ToDist(Truncate(_, _)) => `truncate`
|
||||||
| ToDist(Inspect) => `inspect`
|
| ToDist(Inspect) => `inspect`
|
||||||
| ToString => `toString`
|
| ToString => `toString`
|
||||||
|
| ToSparkline(n) => `toSparkline(${E.I.toString(n)})`
|
||||||
| ToDistCombination(Algebraic, _, _) => `algebraic`
|
| ToDistCombination(Algebraic, _, _) => `algebraic`
|
||||||
| ToDistCombination(Pointwise, _, _) => `pointwise`
|
| ToDistCombination(Pointwise, _, _) => `pointwise`
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,3 +202,8 @@ let operate = (distToFloatOp: Operation.distToFloatOperation, s): float =>
|
||||||
| #Sample => sample(s)
|
| #Sample => sample(s)
|
||||||
| #Mean => T.mean(s)
|
| #Mean => T.mean(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let toSparkline = (t: t) =>
|
||||||
|
T.toContinuous(t)
|
||||||
|
->E.O2.toResult("toContinous Error: Could not convert into continuous distribution")
|
||||||
|
->E.R2.fmap(r => Continuous.getShape(r).ys->Sparklines.create())
|
|
@ -346,11 +346,11 @@ module T = {
|
||||||
| _ => #NoSolution
|
| _ => #NoSolution
|
||||||
}
|
}
|
||||||
|
|
||||||
let toPointSetDist = (sampleCount, d: symbolicDist): PointSetTypes.pointSetDist =>
|
let toPointSetDist = (~xSelection=#ByWeight, sampleCount, d: symbolicDist): PointSetTypes.pointSetDist =>
|
||||||
switch d {
|
switch d {
|
||||||
| #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]}))
|
| #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]}))
|
||||||
| _ =>
|
| _ =>
|
||||||
let xs = interpolateXs(~xSelection=#ByWeight, d, sampleCount)
|
let xs = interpolateXs(~xSelection, d, sampleCount)
|
||||||
let ys = xs |> E.A.fmap(x => pdf(x, d))
|
let ys = xs |> E.A.fmap(x => pdf(x, d))
|
||||||
Continuous(Continuous.make(~integralSumCache=Some(1.0), {xs: xs, ys: ys}))
|
Continuous(Continuous.make(~integralSumCache=Some(1.0), {xs: xs, ys: ys}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,12 @@ module R = {
|
||||||
module R2 = {
|
module R2 = {
|
||||||
let fmap = (a,b) => R.fmap(b,a)
|
let fmap = (a,b) => R.fmap(b,a)
|
||||||
let bind = (a, b) => R.bind(b, a)
|
let bind = (a, b) => R.bind(b, a)
|
||||||
|
|
||||||
|
//Converts result type to change error type only
|
||||||
|
let errMap = (a, map) => switch(a){
|
||||||
|
| Ok(r) => Ok(r)
|
||||||
|
| Error(e) => map(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let safe_fn_of_string = (fn, s: string): option<'a> =>
|
let safe_fn_of_string = (fn, s: string): option<'a> =>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user