most of the refactor based on @OAGr's comments

This commit is contained in:
Quinn Dougherty 2022-03-29 15:10:20 -04:00
parent bcff646e54
commit 320b8da91a
3 changed files with 37 additions and 35 deletions

View File

@ -8,23 +8,27 @@ let makeTest = (~only=false, str, item1, item2) =>
? Only.test(str, () => expect(item1) -> toEqual(item2)) ? Only.test(str, () => expect(item1) -> toEqual(item2))
: test(str, () => expect(item1) -> toEqual(item2)) : test(str, () => expect(item1) -> toEqual(item2))
let normalParams1: SymbolicDistTypes.normal = {mean: 5.0, stdev: 2.0} let pdfImage = (thePdf, inps) => map(thePdf, inps)
// let normalParams2: SymbolicDistTypes.normal = {mean: 10.0, stdev: 2.0}
let normalParams3: SymbolicDistTypes.normal = {mean: 20.0, stdev: 2.0}
let range20 = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0]
let forSparkline = (thisPdf, inps) => map(thisPdf, inps)
describe("Normal with Sparklines", () => { let parameterWiseAdditionHelper = (n1: SymbolicDistTypes.normal, n2: SymbolicDistTypes.normal) => {
let pdf1 = x => Normal.pdf(x, normalParams1) let normalDistAtSumMeanConstr = Normal.add(n1, n2)
let forSparkline1 = forSparkline(pdf1, range20) let normalDistAtSumMean: SymbolicDistTypes.normal = switch normalDistAtSumMeanConstr {
makeTest("mean=5", Sparklines.sparkly(forSparkline1, ~options={minimum: None, maximum: None}), `▁▂▃▅███▅▃▂▁▁▁▁▁▁▁▁▁▁▁`)
let normal4 = Normal.add(normalParams1, normalParams3)
let normalParams4 = switch normal4 {
| #Normal(params) => params | #Normal(params) => params
| _ => {mean: 0.0, stdev: 1.0}
} }
let pdf4 = x => Normal.pdf(x, normalParams4) x => Normal.pdf(x, normalDistAtSumMean)
let forSparkline4 = forSparkline(pdf4, range20) }
makeTest("mixture of two normals", Sparklines.sparkly(forSparkline4, ~options={minimum: None, maximum: None}), `▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▅█`)
describe("Normal distribution with sparklines", () => {
let normalDistAtMean5: SymbolicDistTypes.normal = {mean: 5.0, stdev: 2.0}
let normalDistAtMean10: SymbolicDistTypes.normal = {mean: 10.0, stdev: 2.0}
let range20Float = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,]
let pdfNormalDistAtMean5 = x => Normal.pdf(x, normalDistAtMean5)
let sparklineMean5 = pdfImage(pdfNormalDistAtMean5, range20Float)
makeTest("mean=5", Sparklines.create(sparklineMean5, ()), `▁▂▃▅███▅▃▂▁▁▁▁▁▁▁▁▁▁`)
let sparklineMean15 = normalDistAtMean5 -> parameterWiseAdditionHelper(normalDistAtMean10) -> pdfImage(range20Float)
// let sparklineMean15 = pdfImage(pdfNormalDistAtMean15, range20Float)
makeTest("parameter-wise addition of two normal distributions", Sparklines.create(sparklineMean15, ()), `▁▁▁▁▁▁▁▁▁▁▂▃▅▇███▇▅▃`)
}) })

View File

@ -323,6 +323,7 @@ module A = {
} }
) )
let filter = (o, e) => Js.Array.filter(o, e) let filter = (o, e) => Js.Array.filter(o, e)
let joinWith = (fill, arr) => Js.Array.joinWith(fill, arr)
module O = { module O = {
let concatSomes = (optionals: array<option<'a>>): array<'a> => let concatSomes = (optionals: array<option<'a>>): array<'a> =>

View File

@ -2,31 +2,28 @@
// reference implementation: https://github.com/sindresorhus/sparkly // reference implementation: https://github.com/sindresorhus/sparkly
// Omitting rgb "fire" style, so no `chalk` dependency // Omitting rgb "fire" style, so no `chalk` dependency
type sparklyConfig = { let create = (
minimum: option<float>,
maximum: option<float>
}
let sparkly = (
numbers: array<float>, numbers: array<float>,
~options = {minimum: None, maximum: None} ~minimum=?,
~maximum=?,
()
) => { ) => {
// Unlike reference impl, we assume that all numbers are finite, i.e. no NaN. // Unlike reference impl, we assume that all numbers are finite, i.e. no NaN.
let ticks = [`▁`, `▂`, `▃`, `▄`, `▅`, `▆`, `▇`, `█`] let ticks = [`▁`, `▂`, `▃`, `▄`, `▅`, `▆`, `▇`, `█`]
let minimum = E.O.default(Js.Math.minMany_float(numbers), options.minimum) let minimum = E.O.default(Js.Math.minMany_float(numbers), minimum)
let maximum = E.O.default(Js.Math.maxMany_float(numbers), options.maximum) let maximum = E.O.default(Js.Math.maxMany_float(numbers), maximum)
// Use a high tick if data is constant and max is not equal // // Use a high tick if data is constant and max is not equal to min or zero
let ticks = if minimum == maximum && maximum != 0.0 { // let ticks = if minimum == maximum && maximum != 0.0 {
[ticks[4]] // [ticks[4]]
} else { // } else {
ticks // ticks
} // }
let toMapWith = (number: float) => { let toHeight = (number: float) => {
let tickIndex = Js.Math.ceil_int((number /. maximum) *. Belt.Int.toFloat(Belt.Array.length(ticks))) - 1 let tickIndex = Js.Math.ceil_int((number /. maximum) *. (ticks -> Belt.Array.length -> Belt.Int.toFloat)) - 1
let tickIndex = if maximum == 0.0 || tickIndex < 0 { let tickIndex = if maximum == 0.0 || tickIndex < 0 {
0 0
@ -36,5 +33,5 @@ let sparkly = (
ticks[tickIndex] ticks[tickIndex]
} }
Js.Array.joinWith("", Belt.Array.map(numbers, toMapWith)) toHeight -> E.A.fmap(numbers) -> (arr => E.A.joinWith("", arr))
} }