yarn format
				
					
				
			This commit is contained in:
		
							parent
							
								
									550acb552a
								
							
						
					
					
						commit
						4f95c019eb
					
				| 
						 | 
					@ -4,10 +4,10 @@ open Expect
 | 
				
			||||||
describe("Bandwidth", () => {
 | 
					describe("Bandwidth", () => {
 | 
				
			||||||
  test("nrd0()", () => {
 | 
					  test("nrd0()", () => {
 | 
				
			||||||
    let data = [1., 4., 3., 2.]
 | 
					    let data = [1., 4., 3., 2.]
 | 
				
			||||||
    expect(SampleSetDist_Bandwidth.nrd0(data)) -> toEqual(0.7625801874014622)
 | 
					    expect(SampleSetDist_Bandwidth.nrd0(data))->toEqual(0.7625801874014622)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  test("nrd()", () => {
 | 
					  test("nrd()", () => {
 | 
				
			||||||
    let data = [1., 4., 3., 2.]
 | 
					    let data = [1., 4., 3., 2.]
 | 
				
			||||||
    expect(SampleSetDist_Bandwidth.nrd(data)) -> toEqual(0.8981499984950554)
 | 
					    expect(SampleSetDist_Bandwidth.nrd(data))->toEqual(0.8981499984950554)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@ let normalDist: GenericDist_Types.genericDist = normalDist5
 | 
				
			||||||
let betaDist: GenericDist_Types.genericDist = Symbolic(#Beta({alpha: 2.0, beta: 5.0}))
 | 
					let betaDist: GenericDist_Types.genericDist = Symbolic(#Beta({alpha: 2.0, beta: 5.0}))
 | 
				
			||||||
let lognormalDist: GenericDist_Types.genericDist = Symbolic(#Lognormal({mu: 0.0, sigma: 1.0}))
 | 
					let lognormalDist: GenericDist_Types.genericDist = Symbolic(#Lognormal({mu: 0.0, sigma: 1.0}))
 | 
				
			||||||
let cauchyDist: GenericDist_Types.genericDist = Symbolic(#Cauchy({local: 1.0, scale: 1.0}))
 | 
					let cauchyDist: GenericDist_Types.genericDist = Symbolic(#Cauchy({local: 1.0, scale: 1.0}))
 | 
				
			||||||
let triangularDist: GenericDist_Types.genericDist = Symbolic(#Triangular({low: 1.0, medium: 2.0, high: 3.0}))
 | 
					let triangularDist: GenericDist_Types.genericDist = Symbolic(
 | 
				
			||||||
 | 
					  #Triangular({low: 1.0, medium: 2.0, high: 3.0}),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
let exponentialDist: GenericDist_Types.genericDist = Symbolic(#Exponential({rate: 2.0}))
 | 
					let exponentialDist: GenericDist_Types.genericDist = Symbolic(#Exponential({rate: 2.0}))
 | 
				
			||||||
let uniformDist: GenericDist_Types.genericDist = Symbolic(#Uniform({low: 9.0, high: 10.0}))
 | 
					let uniformDist: GenericDist_Types.genericDist = Symbolic(#Uniform({low: 9.0, high: 10.0}))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,14 +11,20 @@ let mkCauchy = (local, scale) => GenericDist_Types.Symbolic(#Cauchy({local: loca
 | 
				
			||||||
let mkLognormal = (mu, sigma) => GenericDist_Types.Symbolic(#Lognormal({mu: mu, sigma: sigma}))
 | 
					let mkLognormal = (mu, sigma) => GenericDist_Types.Symbolic(#Lognormal({mu: mu, sigma: sigma}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("mixture", () => {
 | 
					describe("mixture", () => {
 | 
				
			||||||
  testAll("fair mean of two normal distributions", list{(0.0, 1e2), (-1e1, -1e-4), (-1e1, 1e2), (-1e1, 1e1)}, tup => {  // should be property
 | 
					  testAll(
 | 
				
			||||||
 | 
					    "fair mean of two normal distributions",
 | 
				
			||||||
 | 
					    list{(0.0, 1e2), (-1e1, -1e-4), (-1e1, 1e2), (-1e1, 1e1)},
 | 
				
			||||||
 | 
					    tup => {
 | 
				
			||||||
 | 
					      // should be property
 | 
				
			||||||
      let (mean1, mean2) = tup
 | 
					      let (mean1, mean2) = tup
 | 
				
			||||||
      let meanValue = {
 | 
					      let meanValue = {
 | 
				
			||||||
        run(Mixture([(mkNormal(mean1, 9e-1), 0.5), (mkNormal(mean2, 9e-1), 0.5)])) 
 | 
					        run(Mixture([(mkNormal(mean1, 9e-1), 0.5), (mkNormal(mean2, 9e-1), 0.5)]))->outputMap(
 | 
				
			||||||
        -> outputMap(FromDist(ToFloat(#Mean)))
 | 
					          FromDist(ToFloat(#Mean)),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    meanValue -> unpackFloat -> expect -> toBeSoCloseTo((mean1 +. mean2) /. 2.0, ~digits=-1) 
 | 
					      meanValue->unpackFloat->expect->toBeSoCloseTo((mean1 +. mean2) /. 2.0, ~digits=-1)
 | 
				
			||||||
  })
 | 
					    },
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
  testAll(
 | 
					  testAll(
 | 
				
			||||||
    "weighted mean of a beta and an exponential",
 | 
					    "weighted mean of a beta and an exponential",
 | 
				
			||||||
    // This would not survive property testing, it was easy for me to find cases that NaN'd out.
 | 
					    // This would not survive property testing, it was easy for me to find cases that NaN'd out.
 | 
				
			||||||
| 
						 | 
					@ -28,43 +34,40 @@ describe("mixture", () => {
 | 
				
			||||||
      let betaWeight = 0.25
 | 
					      let betaWeight = 0.25
 | 
				
			||||||
      let exponentialWeight = 0.75
 | 
					      let exponentialWeight = 0.75
 | 
				
			||||||
      let meanValue = {
 | 
					      let meanValue = {
 | 
				
			||||||
          run(Mixture(
 | 
					        run(
 | 
				
			||||||
              [
 | 
					          Mixture([(mkBeta(alpha, beta), betaWeight), (mkExponential(rate), exponentialWeight)]),
 | 
				
			||||||
                (mkBeta(alpha, beta), betaWeight), 
 | 
					        )->outputMap(FromDist(ToFloat(#Mean)))
 | 
				
			||||||
                (mkExponential(rate), exponentialWeight)
 | 
					 | 
				
			||||||
              ]
 | 
					 | 
				
			||||||
          )) -> outputMap(FromDist(ToFloat(#Mean)))
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      let betaMean = 1.0 /. (1.0 +. beta /. alpha)
 | 
					      let betaMean = 1.0 /. (1.0 +. beta /. alpha)
 | 
				
			||||||
      let exponentialMean = 1.0 /. rate
 | 
					      let exponentialMean = 1.0 /. rate
 | 
				
			||||||
      meanValue
 | 
					      meanValue
 | 
				
			||||||
        -> unpackFloat 
 | 
					      ->unpackFloat
 | 
				
			||||||
        -> expect 
 | 
					      ->expect
 | 
				
			||||||
        -> toBeSoCloseTo(
 | 
					      ->toBeSoCloseTo(betaWeight *. betaMean +. exponentialWeight *. exponentialMean, ~digits=-1)
 | 
				
			||||||
            betaWeight *. betaMean +. exponentialWeight *. exponentialMean, 
 | 
					    },
 | 
				
			||||||
            ~digits=-1
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  testAll(
 | 
					  testAll(
 | 
				
			||||||
    "weighted mean of lognormal and uniform",
 | 
					    "weighted mean of lognormal and uniform",
 | 
				
			||||||
    // Would not survive property tests: very easy to find cases that NaN out.
 | 
					    // Would not survive property tests: very easy to find cases that NaN out.
 | 
				
			||||||
      list{((-1e2,1e1), (2e0,1e0)), ((-1e-16,1e-16), (1e-8,1e0)), ((0.0,1e0), (1e0,1e-2))}, 
 | 
					    list{((-1e2, 1e1), (2e0, 1e0)), ((-1e-16, 1e-16), (1e-8, 1e0)), ((0.0, 1e0), (1e0, 1e-2))},
 | 
				
			||||||
    tup => {
 | 
					    tup => {
 | 
				
			||||||
      let ((low, high), (mu, sigma)) = tup
 | 
					      let ((low, high), (mu, sigma)) = tup
 | 
				
			||||||
      let uniformWeight = 0.6
 | 
					      let uniformWeight = 0.6
 | 
				
			||||||
      let lognormalWeight = 0.4
 | 
					      let lognormalWeight = 0.4
 | 
				
			||||||
      let meanValue = {
 | 
					      let meanValue = {
 | 
				
			||||||
              run(Mixture([(mkUniform(low, high), uniformWeight), (mkLognormal(mu, sigma), lognormalWeight)]))
 | 
					        run(
 | 
				
			||||||
              -> outputMap(FromDist(ToFloat(#Mean)))
 | 
					          Mixture([
 | 
				
			||||||
 | 
					            (mkUniform(low, high), uniformWeight),
 | 
				
			||||||
 | 
					            (mkLognormal(mu, sigma), lognormalWeight),
 | 
				
			||||||
 | 
					          ]),
 | 
				
			||||||
 | 
					        )->outputMap(FromDist(ToFloat(#Mean)))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      let uniformMean = (low +. high) /. 2.0
 | 
					      let uniformMean = (low +. high) /. 2.0
 | 
				
			||||||
      let lognormalMean = mu +. sigma ** 2.0 /. 2.0
 | 
					      let lognormalMean = mu +. sigma ** 2.0 /. 2.0
 | 
				
			||||||
      meanValue
 | 
					      meanValue
 | 
				
			||||||
          -> unpackFloat
 | 
					      ->unpackFloat
 | 
				
			||||||
          -> expect
 | 
					      ->expect
 | 
				
			||||||
          -> toBeSoCloseTo(uniformWeight *. uniformMean +. lognormalWeight *. lognormalMean, ~digits=-1)
 | 
					      ->toBeSoCloseTo(uniformWeight *. uniformMean +. lognormalWeight *. lognormalMean, ~digits=-1)
 | 
				
			||||||
      }
 | 
					    },
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,4 +38,3 @@ describe("Continuous and discrete splits", () => {
 | 
				
			||||||
  let toArr2 = discrete2 |> E.FloatFloatMap.toArray
 | 
					  let toArr2 = discrete2 |> E.FloatFloatMap.toArray
 | 
				
			||||||
  makeTest("splitMedium at count=500", toArr2 |> Belt.Array.length, 500)
 | 
					  makeTest("splitMedium at count=500", toArr2 |> Belt.Array.length, 500)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,121 +9,105 @@ describe("(Symbolic) normalize", () => {
 | 
				
			||||||
  testAll("has no impact on normal distributions", list{-1e8, -1e-2, 0.0, 1e-4, 1e16}, mean => {
 | 
					  testAll("has no impact on normal distributions", list{-1e8, -1e-2, 0.0, 1e-4, 1e16}, mean => {
 | 
				
			||||||
    let normalValue = mkNormal(mean, 2.0)
 | 
					    let normalValue = mkNormal(mean, 2.0)
 | 
				
			||||||
    let normalizedValue = run(FromDist(ToDist(Normalize), normalValue))
 | 
					    let normalizedValue = run(FromDist(ToDist(Normalize), normalValue))
 | 
				
			||||||
    normalizedValue 
 | 
					    normalizedValue->unpackDist->expect->toEqual(normalValue)
 | 
				
			||||||
    -> unpackDist
 | 
					 | 
				
			||||||
    -> expect
 | 
					 | 
				
			||||||
    -> toEqual(normalValue)
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("(Symbolic) mean", () => {
 | 
					describe("(Symbolic) mean", () => {
 | 
				
			||||||
  testAll("of normal distributions", list{-1e8, -16.0, -1e-2, 0.0, 1e-4, 32.0, 1e16}, mean => {
 | 
					  testAll("of normal distributions", list{-1e8, -16.0, -1e-2, 0.0, 1e-4, 32.0, 1e16}, mean => {
 | 
				
			||||||
    run(FromDist(ToFloat(#Mean), mkNormal(mean, 4.0))) 
 | 
					    run(FromDist(ToFloat(#Mean), mkNormal(mean, 4.0)))->unpackFloat->expect->toBeCloseTo(mean)
 | 
				
			||||||
    -> unpackFloat 
 | 
					 | 
				
			||||||
    -> expect 
 | 
					 | 
				
			||||||
    -> toBeCloseTo(mean)
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Skip.test("of normal(0, -1) (it NaNs out)", () => {
 | 
					  Skip.test("of normal(0, -1) (it NaNs out)", () => {
 | 
				
			||||||
    run(FromDist(ToFloat(#Mean), mkNormal(1e1, -1e0)))
 | 
					    run(FromDist(ToFloat(#Mean), mkNormal(1e1, -1e0)))->unpackFloat->expect->ExpectJs.toBeFalsy
 | 
				
			||||||
    -> unpackFloat
 | 
					 | 
				
			||||||
    -> expect
 | 
					 | 
				
			||||||
    -> ExpectJs.toBeFalsy
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test("of normal(0, 1e-8) (it doesn't freak out at tiny stdev)", () => {
 | 
					  test("of normal(0, 1e-8) (it doesn't freak out at tiny stdev)", () => {
 | 
				
			||||||
    run(FromDist(ToFloat(#Mean), mkNormal(0.0, 1e-8)))
 | 
					    run(FromDist(ToFloat(#Mean), mkNormal(0.0, 1e-8)))->unpackFloat->expect->toBeCloseTo(0.0)
 | 
				
			||||||
    -> unpackFloat
 | 
					 | 
				
			||||||
    -> expect
 | 
					 | 
				
			||||||
    -> toBeCloseTo(0.0)
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  testAll("of exponential distributions", list{1e-7, 2.0, 10.0, 100.0}, rate => {
 | 
					  testAll("of exponential distributions", list{1e-7, 2.0, 10.0, 100.0}, rate => {
 | 
				
			||||||
    let meanValue = run(FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Exponential({rate: rate}))))
 | 
					    let meanValue = run(
 | 
				
			||||||
    meanValue -> unpackFloat -> expect -> toBeCloseTo(1.0 /. rate)  // https://en.wikipedia.org/wiki/Exponential_distribution#Mean,_variance,_moments,_and_median
 | 
					      FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Exponential({rate: rate}))),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. rate) // https://en.wikipedia.org/wiki/Exponential_distribution#Mean,_variance,_moments,_and_median
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test("of a cauchy distribution", () => {
 | 
					  test("of a cauchy distribution", () => {
 | 
				
			||||||
    let meanValue = run(FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Cauchy({local: 1.0, scale: 1.0}))))
 | 
					    let meanValue = run(
 | 
				
			||||||
    meanValue
 | 
					      FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Cauchy({local: 1.0, scale: 1.0}))),
 | 
				
			||||||
    -> unpackFloat
 | 
					    )
 | 
				
			||||||
    -> expect
 | 
					    meanValue->unpackFloat->expect->toBeCloseTo(2.01868297874546)
 | 
				
			||||||
    -> toBeCloseTo(2.01868297874546)
 | 
					 | 
				
			||||||
    //-> toBe(GenDistError(Other("Cauchy distributions may have no mean value.")))
 | 
					    //-> toBe(GenDistError(Other("Cauchy distributions may have no mean value.")))
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  testAll("of triangular distributions", list{(1.0,2.0,3.0), (-1e7,-1e-7,1e-7), (-1e-7,1e0,1e7), (-1e-16,0.0,1e-16)}, tup => {
 | 
					  testAll(
 | 
				
			||||||
 | 
					    "of triangular distributions",
 | 
				
			||||||
 | 
					    list{(1.0, 2.0, 3.0), (-1e7, -1e-7, 1e-7), (-1e-7, 1e0, 1e7), (-1e-16, 0.0, 1e-16)},
 | 
				
			||||||
 | 
					    tup => {
 | 
				
			||||||
      let (low, medium, high) = tup
 | 
					      let (low, medium, high) = tup
 | 
				
			||||||
    let meanValue = run(FromDist(
 | 
					      let meanValue = run(
 | 
				
			||||||
 | 
					        FromDist(
 | 
				
			||||||
          ToFloat(#Mean),
 | 
					          ToFloat(#Mean),
 | 
				
			||||||
      GenericDist_Types.Symbolic(#Triangular({low: low, medium: medium, high: high}))
 | 
					          GenericDist_Types.Symbolic(#Triangular({low: low, medium: medium, high: high})),
 | 
				
			||||||
    ))
 | 
					        ),
 | 
				
			||||||
    meanValue 
 | 
					      )
 | 
				
			||||||
    -> unpackFloat 
 | 
					      meanValue->unpackFloat->expect->toBeCloseTo((low +. medium +. high) /. 3.0) // https://www.statology.org/triangular-distribution/
 | 
				
			||||||
    -> expect 
 | 
					    },
 | 
				
			||||||
    -> toBeCloseTo((low +. medium +. high) /. 3.0)  // https://www.statology.org/triangular-distribution/
 | 
					  )
 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: nonpositive inputs are SUPPOSED to crash.
 | 
					  // TODO: nonpositive inputs are SUPPOSED to crash.
 | 
				
			||||||
  testAll("of beta distributions", list{(1e-4, 6.4e1), (1.28e2, 1e0), (1e-16, 1e-16), (1e16, 1e16), (-1e4, 1e1), (1e1, -1e4)}, tup => {
 | 
					  testAll(
 | 
				
			||||||
 | 
					    "of beta distributions",
 | 
				
			||||||
 | 
					    list{(1e-4, 6.4e1), (1.28e2, 1e0), (1e-16, 1e-16), (1e16, 1e16), (-1e4, 1e1), (1e1, -1e4)},
 | 
				
			||||||
 | 
					    tup => {
 | 
				
			||||||
      let (alpha, beta) = tup
 | 
					      let (alpha, beta) = tup
 | 
				
			||||||
    let meanValue = run(FromDist(
 | 
					      let meanValue = run(
 | 
				
			||||||
      ToFloat(#Mean), 
 | 
					        FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Beta({alpha: alpha, beta: beta}))),
 | 
				
			||||||
      GenericDist_Types.Symbolic(#Beta({alpha: alpha, beta: beta}))
 | 
					      )
 | 
				
			||||||
    ))
 | 
					      meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. (1.0 +. beta /. alpha)) // https://en.wikipedia.org/wiki/Beta_distribution#Mean
 | 
				
			||||||
    meanValue 
 | 
					    },
 | 
				
			||||||
    -> unpackFloat 
 | 
					  )
 | 
				
			||||||
    -> expect 
 | 
					 | 
				
			||||||
    -> toBeCloseTo(1.0 /. (1.0 +. (beta /. alpha)))  // https://en.wikipedia.org/wiki/Beta_distribution#Mean
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: When we have our theory of validators we won't want this to be NaN but to be an error.
 | 
					  // TODO: When we have our theory of validators we won't want this to be NaN but to be an error.
 | 
				
			||||||
  test("of beta(0, 0)", () => {
 | 
					  test("of beta(0, 0)", () => {
 | 
				
			||||||
    let meanValue = run(FromDist(
 | 
					    let meanValue = run(
 | 
				
			||||||
      ToFloat(#Mean), 
 | 
					      FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Beta({alpha: 0.0, beta: 0.0}))),
 | 
				
			||||||
      GenericDist_Types.Symbolic(#Beta({alpha: 0.0, beta: 0.0}))
 | 
					    )
 | 
				
			||||||
    ))
 | 
					    meanValue->unpackFloat->expect->ExpectJs.toBeFalsy
 | 
				
			||||||
    meanValue
 | 
					 | 
				
			||||||
    -> unpackFloat
 | 
					 | 
				
			||||||
    -> expect
 | 
					 | 
				
			||||||
    -> ExpectJs.toBeFalsy
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  testAll("of lognormal distributions", list{(2.0, 4.0), (1e-7, 1e-2), (-1e6, 10.0), (1e3, -1e2), (-1e8, -1e4), (1e2, 1e-5)}, tup => { 
 | 
					  testAll(
 | 
				
			||||||
 | 
					    "of lognormal distributions",
 | 
				
			||||||
 | 
					    list{(2.0, 4.0), (1e-7, 1e-2), (-1e6, 10.0), (1e3, -1e2), (-1e8, -1e4), (1e2, 1e-5)},
 | 
				
			||||||
 | 
					    tup => {
 | 
				
			||||||
      let (mu, sigma) = tup
 | 
					      let (mu, sigma) = tup
 | 
				
			||||||
    let meanValue = run(FromDist(
 | 
					      let meanValue = run(
 | 
				
			||||||
      ToFloat(#Mean), 
 | 
					        FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Lognormal({mu: mu, sigma: sigma}))),
 | 
				
			||||||
      GenericDist_Types.Symbolic(#Lognormal({mu: mu, sigma: sigma}))
 | 
					      )
 | 
				
			||||||
    ))
 | 
					      meanValue->unpackFloat->expect->toBeCloseTo(Js.Math.exp(mu +. sigma ** 2.0 /. 2.0)) // https://brilliant.org/wiki/log-normal-distribution/
 | 
				
			||||||
    meanValue 
 | 
					    },
 | 
				
			||||||
    -> unpackFloat 
 | 
					  )
 | 
				
			||||||
    -> expect 
 | 
					 | 
				
			||||||
    -> toBeCloseTo(Js.Math.exp(mu +. sigma ** 2.0 /. 2.0 ))  // https://brilliant.org/wiki/log-normal-distribution/
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  testAll("of uniform distributions", list{(1e-5, 12.345), (-1e4, 1e4), (-1e16, -1e2), (5.3e3, 9e9)}, tup => {
 | 
					  testAll(
 | 
				
			||||||
 | 
					    "of uniform distributions",
 | 
				
			||||||
 | 
					    list{(1e-5, 12.345), (-1e4, 1e4), (-1e16, -1e2), (5.3e3, 9e9)},
 | 
				
			||||||
 | 
					    tup => {
 | 
				
			||||||
      let (low, high) = tup
 | 
					      let (low, high) = tup
 | 
				
			||||||
    let meanValue = run(FromDist(
 | 
					      let meanValue = run(
 | 
				
			||||||
      ToFloat(#Mean), 
 | 
					        FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Uniform({low: low, high: high}))),
 | 
				
			||||||
      GenericDist_Types.Symbolic(#Uniform({low: low, high: high}))
 | 
					      )
 | 
				
			||||||
    ))
 | 
					      meanValue->unpackFloat->expect->toBeCloseTo((low +. high) /. 2.0) // https://en.wikipedia.org/wiki/Continuous_uniform_distribution#Moments
 | 
				
			||||||
    meanValue 
 | 
					    },
 | 
				
			||||||
    -> unpackFloat 
 | 
					  )
 | 
				
			||||||
    -> expect 
 | 
					 | 
				
			||||||
    -> toBeCloseTo((low +. high) /. 2.0)  // https://en.wikipedia.org/wiki/Continuous_uniform_distribution#Moments
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test("of a float", () => {
 | 
					  test("of a float", () => {
 | 
				
			||||||
    let meanValue = run(FromDist(
 | 
					    let meanValue = run(FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Float(7.7))))
 | 
				
			||||||
      ToFloat(#Mean), 
 | 
					    meanValue->unpackFloat->expect->toBeCloseTo(7.7)
 | 
				
			||||||
      GenericDist_Types.Symbolic(#Float(7.7))
 | 
					 | 
				
			||||||
    ))
 | 
					 | 
				
			||||||
    meanValue -> unpackFloat -> expect -> toBeCloseTo(7.7)
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("Normal distribution with sparklines", () => {
 | 
					describe("Normal distribution with sparklines", () => {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  let parameterWiseAdditionPdf = (n1: SymbolicDistTypes.normal, n2: SymbolicDistTypes.normal) => {
 | 
					  let parameterWiseAdditionPdf = (n1: SymbolicDistTypes.normal, n2: SymbolicDistTypes.normal) => {
 | 
				
			||||||
    let normalDistAtSumMeanConstr = SymbolicDist.Normal.add(n1, n2)
 | 
					    let normalDistAtSumMeanConstr = SymbolicDist.Normal.add(n1, n2)
 | 
				
			||||||
    let normalDistAtSumMean: SymbolicDistTypes.normal = switch normalDistAtSumMeanConstr {
 | 
					    let normalDistAtSumMean: SymbolicDistTypes.normal = switch normalDistAtSumMeanConstr {
 | 
				
			||||||
| 
						 | 
					@ -140,22 +124,23 @@ describe("Normal distribution with sparklines", () => {
 | 
				
			||||||
    let pdfNormalDistAtMean5 = x => SymbolicDist.Normal.pdf(x, normalDistAtMean5)
 | 
					    let pdfNormalDistAtMean5 = x => SymbolicDist.Normal.pdf(x, normalDistAtMean5)
 | 
				
			||||||
    let sparklineMean5 = fnImage(pdfNormalDistAtMean5, range20Float)
 | 
					    let sparklineMean5 = fnImage(pdfNormalDistAtMean5, range20Float)
 | 
				
			||||||
    Sparklines.create(sparklineMean5, ())
 | 
					    Sparklines.create(sparklineMean5, ())
 | 
				
			||||||
    -> expect 
 | 
					    ->expect
 | 
				
			||||||
    -> toEqual(`▁▂▃▆██▇▅▂▁▁▁▁▁▁▁▁▁▁▁`)
 | 
					    ->toEqual(`▁▂▃▆██▇▅▂▁▁▁▁▁▁▁▁▁▁▁`)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test("parameter-wise addition of two normal distributions", () => {
 | 
					  test("parameter-wise addition of two normal distributions", () => {
 | 
				
			||||||
    let sparklineMean15 = normalDistAtMean5 -> parameterWiseAdditionPdf(normalDistAtMean10) -> fnImage(range20Float)
 | 
					    let sparklineMean15 =
 | 
				
			||||||
 | 
					      normalDistAtMean5->parameterWiseAdditionPdf(normalDistAtMean10)->fnImage(range20Float)
 | 
				
			||||||
    Sparklines.create(sparklineMean15, ())
 | 
					    Sparklines.create(sparklineMean15, ())
 | 
				
			||||||
    -> expect
 | 
					    ->expect
 | 
				
			||||||
    -> toEqual(`▁▁▁▁▁▁▁▁▁▂▃▄▆███▇▅▄▂`)
 | 
					    ->toEqual(`▁▁▁▁▁▁▁▁▁▂▃▄▆███▇▅▄▂`)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test("mean=10 cdf", () => {
 | 
					  test("mean=10 cdf", () => {
 | 
				
			||||||
    let cdfNormalDistAtMean10 = x => SymbolicDist.Normal.cdf(x, normalDistAtMean10)
 | 
					    let cdfNormalDistAtMean10 = x => SymbolicDist.Normal.cdf(x, normalDistAtMean10)
 | 
				
			||||||
    let sparklineMean10 = fnImage(cdfNormalDistAtMean10, range20Float)
 | 
					    let sparklineMean10 = fnImage(cdfNormalDistAtMean10, range20Float)
 | 
				
			||||||
    Sparklines.create(sparklineMean10, ())
 | 
					    Sparklines.create(sparklineMean10, ())
 | 
				
			||||||
    -> expect
 | 
					    ->expect
 | 
				
			||||||
    -> toEqual(`▁▁▁▁▁▁▁▁▂▄▅▇████████`)
 | 
					    ->toEqual(`▁▁▁▁▁▁▁▁▂▄▅▇████████`)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@ open Expect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let makeTest = (~only=false, str, item1, item2) =>
 | 
					let makeTest = (~only=false, str, item1, item2) =>
 | 
				
			||||||
  only
 | 
					  only
 | 
				
			||||||
    ? 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))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("Lodash", () =>
 | 
					describe("Lodash", () =>
 | 
				
			||||||
  describe("Lodash", () => {
 | 
					  describe("Lodash", () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,7 @@ open Expect
 | 
				
			||||||
let expectEvalToBe = (expr: string, answer: string) =>
 | 
					let expectEvalToBe = (expr: string, answer: string) =>
 | 
				
			||||||
  Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
 | 
					  Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let testEval = (expr, answer) =>
 | 
					let testEval = (expr, answer) => test(expr, () => expectEvalToBe(expr, answer))
 | 
				
			||||||
  test(expr, () => expectEvalToBe(expr, answer))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("builtin", () => {
 | 
					describe("builtin", () => {
 | 
				
			||||||
  // All MathJs operators and functions are available for string, number and boolean
 | 
					  // All MathJs operators and functions are available for string, number and boolean
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,8 @@ let testDescriptionParse = (desc, expr, answer) => test(desc, () => expectParseT
 | 
				
			||||||
module MySkip = {
 | 
					module MySkip = {
 | 
				
			||||||
  let testParse = (expr, answer) => Skip.test(expr, () => expectParseToBe(expr, answer))
 | 
					  let testParse = (expr, answer) => Skip.test(expr, () => expectParseToBe(expr, answer))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let testDescriptionParse = (desc, expr, answer) => Skip.test(desc, () => expectParseToBe(expr, answer))
 | 
					  let testDescriptionParse = (desc, expr, answer) =>
 | 
				
			||||||
 | 
					    Skip.test(desc, () => expectParseToBe(expr, answer))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("MathJs parse", () => {
 | 
					describe("MathJs parse", () => {
 | 
				
			||||||
| 
						 | 
					@ -60,7 +61,8 @@ describe("MathJs parse", () => {
 | 
				
			||||||
    MySkip.testDescriptionParse("define", "# This is a comment", "???")
 | 
					    MySkip.testDescriptionParse("define", "# This is a comment", "???")
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe("if statement", () => { // TODO Tertiary operator instead
 | 
					  describe("if statement", () => {
 | 
				
			||||||
 | 
					    // TODO Tertiary operator instead
 | 
				
			||||||
    MySkip.testDescriptionParse("define", "if (true) { 1 } else { 0 }", "???")
 | 
					    MySkip.testDescriptionParse("define", "if (true) { 1 } else { 0 }", "???")
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,8 @@ open Reducer_TestHelpers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let testParseToBe = (expr, answer) => test(expr, () => expectParseToBe(expr, answer))
 | 
					let testParseToBe = (expr, answer) => test(expr, () => expectParseToBe(expr, answer))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let testDescriptionParseToBe = (desc, expr, answer) => test(desc, () => expectParseToBe(expr, answer))
 | 
					let testDescriptionParseToBe = (desc, expr, answer) =>
 | 
				
			||||||
 | 
					  test(desc, () => expectParseToBe(expr, answer))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let testEvalToBe = (expr, answer) => test(expr, () => expectEvalToBe(expr, answer))
 | 
					let testEvalToBe = (expr, answer) => test(expr, () => expectEvalToBe(expr, answer))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,13 +45,21 @@ describe("reducer using mathjs parse", () => {
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  describe("multi-line", () => {
 | 
					  describe("multi-line", () => {
 | 
				
			||||||
    testParseToBe("1; 2", "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) 1) 2))")
 | 
					    testParseToBe("1; 2", "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) 1) 2))")
 | 
				
			||||||
    testParseToBe("1+1; 2+1", "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:add 1 1)) (:add 2 1)))")
 | 
					    testParseToBe(
 | 
				
			||||||
 | 
					      "1+1; 2+1",
 | 
				
			||||||
 | 
					      "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:add 1 1)) (:add 2 1)))",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  describe("assignment", () => {
 | 
					  describe("assignment", () => {
 | 
				
			||||||
    testParseToBe("x=1; x", "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x 1)) :x))")
 | 
					    testParseToBe(
 | 
				
			||||||
    testParseToBe("x=1+1; x+1", "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x (:add 1 1))) (:add :x 1)))")
 | 
					      "x=1; x",
 | 
				
			||||||
 | 
					      "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x 1)) :x))",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    testParseToBe(
 | 
				
			||||||
 | 
					      "x=1+1; x+1",
 | 
				
			||||||
 | 
					      "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x (:add 1 1))) (:add :x 1)))",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe("eval", () => {
 | 
					describe("eval", () => {
 | 
				
			||||||
| 
						 | 
					@ -101,5 +110,9 @@ describe("test exceptions", () => {
 | 
				
			||||||
    "javascriptraise('div by 0')",
 | 
					    "javascriptraise('div by 0')",
 | 
				
			||||||
    "Error(JS Exception: Error: 'div by 0')",
 | 
					    "Error(JS Exception: Error: 'div by 0')",
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  testDescriptionEvalToBe("rescript exception", "rescriptraise()", "Error(TODO: unhandled rescript exception)")
 | 
					  testDescriptionEvalToBe(
 | 
				
			||||||
 | 
					    "rescript exception",
 | 
				
			||||||
 | 
					    "rescriptraise()",
 | 
				
			||||||
 | 
					    "Error(TODO: unhandled rescript exception)",
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,7 +111,11 @@ describe("parse on distribution functions", () => {
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  describe("pointwise arithmetic expressions", () => {
 | 
					  describe("pointwise arithmetic expressions", () => {
 | 
				
			||||||
    testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))")
 | 
					    testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))")
 | 
				
			||||||
    testParse(~skip=true, "normal(5,2) .- normal(5,1)", "Ok((:dotSubtract (:normal 5 2) (:normal 5 1)))")
 | 
					    testParse(
 | 
				
			||||||
 | 
					      ~skip=true,
 | 
				
			||||||
 | 
					      "normal(5,2) .- normal(5,1)",
 | 
				
			||||||
 | 
					      "Ok((:dotSubtract (:normal 5 2) (:normal 5 1)))",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    testParse("normal(5,2) .* normal(5,1)", "Ok((:dotMultiply (:normal 5 2) (:normal 5 1)))")
 | 
					    testParse("normal(5,2) .* normal(5,1)", "Ok((:dotMultiply (:normal 5 2) (:normal 5 1)))")
 | 
				
			||||||
    testParse("normal(5,2) ./ normal(5,1)", "Ok((:dotDivide (:normal 5 2) (:normal 5 1)))")
 | 
					    testParse("normal(5,2) ./ normal(5,1)", "Ok((:dotDivide (:normal 5 2) (:normal 5 1)))")
 | 
				
			||||||
    testParse("normal(5,2) .^ normal(5,1)", "Ok((:dotPow (:normal 5 2) (:normal 5 1)))")
 | 
					    testParse("normal(5,2) .^ normal(5,1)", "Ok((:dotPow (:normal 5 2) (:normal 5 1)))")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,8 @@ open Expect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let makeTest = (~only=false, str, item1, item2) =>
 | 
					let makeTest = (~only=false, str, item1, item2) =>
 | 
				
			||||||
  only
 | 
					  only
 | 
				
			||||||
    ? 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 {toFloat, toDist, toString, toError, fmap} = module(DistributionOperation.Output)
 | 
					let {toFloat, toDist, toString, toError, fmap} = module(DistributionOperation.Output)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +19,9 @@ let run = DistributionOperation.run(~env)
 | 
				
			||||||
let outputMap = fmap(~env)
 | 
					let outputMap = fmap(~env)
 | 
				
			||||||
let unreachableInTestFileMessage = "Should be impossible to reach (This error is in test file)"
 | 
					let unreachableInTestFileMessage = "Should be impossible to reach (This error is in test file)"
 | 
				
			||||||
let toExtFloat: option<float> => float = E.O.toExt(unreachableInTestFileMessage)
 | 
					let toExtFloat: option<float> => float = E.O.toExt(unreachableInTestFileMessage)
 | 
				
			||||||
let toExtDist: option<GenericDist_Types.genericDist> => GenericDist_Types.genericDist = E.O.toExt(unreachableInTestFileMessage)
 | 
					let toExtDist: option<GenericDist_Types.genericDist> => GenericDist_Types.genericDist = E.O.toExt(
 | 
				
			||||||
 | 
					  unreachableInTestFileMessage,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
// let toExt: option<'a> => 'a = E.O.toExt(unreachableInTestFileMessage)
 | 
					// let toExt: option<'a> => 'a = E.O.toExt(unreachableInTestFileMessage)
 | 
				
			||||||
let unpackFloat = x => x -> toFloat -> toExtFloat
 | 
					let unpackFloat = x => x->toFloat->toExtFloat
 | 
				
			||||||
let unpackDist = y => y -> toDist -> toExtDist
 | 
					let unpackDist = y => y->toDist->toExtDist
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@ open Expect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let makeTest = (~only=false, str, item1, item2) =>
 | 
					let makeTest = (~only=false, str, item1, item2) =>
 | 
				
			||||||
  only
 | 
					  only
 | 
				
			||||||
    ? 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 pointSetDist1: PointSetTypes.xyShape = {xs: [1., 4., 8.], ys: [0.2, 0.4, 0.8]}
 | 
					let pointSetDist1: PointSetTypes.xyShape = {xs: [1., 4., 8.], ys: [0.2, 0.4, 0.8]}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,11 @@ let pointSetDist3: PointSetTypes.xyShape = {
 | 
				
			||||||
describe("XYShapes", () => {
 | 
					describe("XYShapes", () => {
 | 
				
			||||||
  describe("logScorePoint", () => {
 | 
					  describe("logScorePoint", () => {
 | 
				
			||||||
    makeTest("When identical", XYShape.logScorePoint(30, pointSetDist1, pointSetDist1), Some(0.0))
 | 
					    makeTest("When identical", XYShape.logScorePoint(30, pointSetDist1, pointSetDist1), Some(0.0))
 | 
				
			||||||
    makeTest("When similar", XYShape.logScorePoint(30, pointSetDist1, pointSetDist2), Some(1.658971191043856))
 | 
					    makeTest(
 | 
				
			||||||
 | 
					      "When similar",
 | 
				
			||||||
 | 
					      XYShape.logScorePoint(30, pointSetDist1, pointSetDist2),
 | 
				
			||||||
 | 
					      Some(1.658971191043856),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    makeTest(
 | 
					    makeTest(
 | 
				
			||||||
      "When very different",
 | 
					      "When very different",
 | 
				
			||||||
      XYShape.logScorePoint(30, pointSetDist1, pointSetDist3),
 | 
					      XYShape.logScorePoint(30, pointSetDist1, pointSetDist3),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,12 +56,7 @@ module Constructors: {
 | 
				
			||||||
  @genType
 | 
					  @genType
 | 
				
			||||||
  let toSampleSet: (~env: env, genericDist, int) => result<genericDist, error>
 | 
					  let toSampleSet: (~env: env, genericDist, int) => result<genericDist, error>
 | 
				
			||||||
  @genType
 | 
					  @genType
 | 
				
			||||||
    let truncate: (
 | 
					  let truncate: (~env: env, genericDist, option<float>, option<float>) => result<genericDist, error>
 | 
				
			||||||
      ~env: env,
 | 
					 | 
				
			||||||
      genericDist,
 | 
					 | 
				
			||||||
      option<float>,
 | 
					 | 
				
			||||||
      option<float>,
 | 
					 | 
				
			||||||
    ) => result<genericDist, error>
 | 
					 | 
				
			||||||
  @genType
 | 
					  @genType
 | 
				
			||||||
  let inspect: (~env: env, genericDist) => result<genericDist, error>
 | 
					  let inspect: (~env: env, genericDist) => result<genericDist, error>
 | 
				
			||||||
  @genType
 | 
					  @genType
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,11 @@ module DistributionOperation = {
 | 
				
			||||||
  type fromDist =
 | 
					  type fromDist =
 | 
				
			||||||
    | ToFloat(Operation.toFloat)
 | 
					    | ToFloat(Operation.toFloat)
 | 
				
			||||||
    | ToDist(toDist)
 | 
					    | ToDist(toDist)
 | 
				
			||||||
    | ToDistCombination(Operation.direction, Operation.arithmeticOperation, [#Dist(genericDist) | #Float(float)])
 | 
					    | ToDistCombination(
 | 
				
			||||||
 | 
					        Operation.direction,
 | 
				
			||||||
 | 
					        Operation.arithmeticOperation,
 | 
				
			||||||
 | 
					        [#Dist(genericDist) | #Float(float)],
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
    | ToString
 | 
					    | ToString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  type singleParamaterFunction =
 | 
					  type singleParamaterFunction =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,6 @@ let combineShapesContinuousContinuous = (
 | 
				
			||||||
  s1: PointSetTypes.xyShape,
 | 
					  s1: PointSetTypes.xyShape,
 | 
				
			||||||
  s2: PointSetTypes.xyShape,
 | 
					  s2: PointSetTypes.xyShape,
 | 
				
			||||||
): PointSetTypes.xyShape => {
 | 
					): PointSetTypes.xyShape => {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // if we add the two distributions, we should probably use normal filters.
 | 
					  // if we add the two distributions, we should probably use normal filters.
 | 
				
			||||||
  // if we multiply the two distributions, we should probably use lognormal filters.
 | 
					  // if we multiply the two distributions, we should probably use lognormal filters.
 | 
				
			||||||
  let t1m = toDiscretePointMassesFromTriangulars(s1)
 | 
					  let t1m = toDiscretePointMassesFromTriangulars(s1)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -235,18 +235,10 @@ module T = Dist({
 | 
				
			||||||
    let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 2.0 /. 2.0
 | 
					    let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 2.0 /. 2.0
 | 
				
			||||||
    let indefiniteIntegralLinear = (p, a, b) => a *. p ** 2.0 /. 2.0 +. b *. p ** 3.0 /. 3.0
 | 
					    let indefiniteIntegralLinear = (p, a, b) => a *. p ** 2.0 /. 2.0 +. b *. p ** 3.0 /. 3.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Analysis.integrate(
 | 
					    Analysis.integrate(~indefiniteIntegralStepwise, ~indefiniteIntegralLinear, t)
 | 
				
			||||||
      ~indefiniteIntegralStepwise,
 | 
					 | 
				
			||||||
      ~indefiniteIntegralLinear,
 | 
					 | 
				
			||||||
      t,
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  let variance = (t: t): float =>
 | 
					  let variance = (t: t): float =>
 | 
				
			||||||
    XYShape.Analysis.getVarianceDangerously(
 | 
					    XYShape.Analysis.getVarianceDangerously(t, mean, Analysis.getMeanOfSquares)
 | 
				
			||||||
      t,
 | 
					 | 
				
			||||||
      mean,
 | 
					 | 
				
			||||||
      Analysis.getMeanOfSquares,
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let downsampleEquallyOverX = (length, t): t =>
 | 
					let downsampleEquallyOverX = (length, t): t =>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -212,8 +212,7 @@ module T = Dist({
 | 
				
			||||||
    let totalIntegralSum = discreteIntegralSum +. continuousIntegralSum
 | 
					    let totalIntegralSum = discreteIntegralSum +. continuousIntegralSum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let getMeanOfSquares = ({discrete, continuous}: t) => {
 | 
					    let getMeanOfSquares = ({discrete, continuous}: t) => {
 | 
				
			||||||
      let discreteMean =
 | 
					      let discreteMean = discrete |> Discrete.shapeMap(XYShape.T.square) |> Discrete.T.mean
 | 
				
			||||||
        discrete |> Discrete.shapeMap(XYShape.T.square) |> Discrete.T.mean
 | 
					 | 
				
			||||||
      let continuousMean = continuous |> Continuous.Analysis.getMeanOfSquares
 | 
					      let continuousMean = continuous |> Continuous.Analysis.getMeanOfSquares
 | 
				
			||||||
      (discreteMean *. discreteIntegralSum +. continuousMean *. continuousIntegralSum) /.
 | 
					      (discreteMean *. discreteIntegralSum +. continuousMean *. continuousIntegralSum) /.
 | 
				
			||||||
        totalIntegralSum
 | 
					        totalIntegralSum
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,10 +14,10 @@ type distributionType = [
 | 
				
			||||||
  | #CDF
 | 
					  | #CDF
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type xyShape = XYShape.xyShape;
 | 
					type xyShape = XYShape.xyShape
 | 
				
			||||||
type interpolationStrategy = XYShape.interpolationStrategy;
 | 
					type interpolationStrategy = XYShape.interpolationStrategy
 | 
				
			||||||
type extrapolationStrategy = XYShape.extrapolationStrategy;
 | 
					type extrapolationStrategy = XYShape.extrapolationStrategy
 | 
				
			||||||
type interpolator = XYShape.extrapolationStrategy;
 | 
					type interpolator = XYShape.extrapolationStrategy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@genType
 | 
					@genType
 | 
				
			||||||
type rec continuousShape = {
 | 
					type rec continuousShape = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -346,7 +346,11 @@ module T = {
 | 
				
			||||||
    | _ => #NoSolution
 | 
					    | _ => #NoSolution
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let toPointSetDist = (~xSelection=#ByWeight, 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]}))
 | 
				
			||||||
    | _ =>
 | 
					    | _ =>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ let makeSymbolicFromTwoFloats = (name, fn) =>
 | 
				
			||||||
    ~inputTypes=[#Float, #Float],
 | 
					    ~inputTypes=[#Float, #Float],
 | 
				
			||||||
    ~run=x =>
 | 
					    ~run=x =>
 | 
				
			||||||
      switch x {
 | 
					      switch x {
 | 
				
			||||||
      | [#Float(a), #Float(b)] => fn(a, b) |> E.R.fmap(r => (#SymbolicDist(r)))
 | 
					      | [#Float(a), #Float(b)] => fn(a, b) |> E.R.fmap(r => #SymbolicDist(r))
 | 
				
			||||||
      | e => wrongInputsError(e)
 | 
					      | e => wrongInputsError(e)
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    (),
 | 
					    (),
 | 
				
			||||||
| 
						 | 
					@ -90,7 +90,8 @@ let floatFromDist = (
 | 
				
			||||||
  switch t {
 | 
					  switch t {
 | 
				
			||||||
  | #SymbolicDist(s) =>
 | 
					  | #SymbolicDist(s) =>
 | 
				
			||||||
    SymbolicDist.T.operate(distToFloatOp, s) |> E.R.bind(_, v => Ok(#SymbolicDist(#Float(v))))
 | 
					    SymbolicDist.T.operate(distToFloatOp, s) |> E.R.bind(_, v => Ok(#SymbolicDist(#Float(v))))
 | 
				
			||||||
  | #RenderedDist(rs) => PointSetDist.operate(distToFloatOp, rs) |> (v => Ok(#SymbolicDist(#Float(v))))
 | 
					  | #RenderedDist(rs) =>
 | 
				
			||||||
 | 
					    PointSetDist.operate(distToFloatOp, rs) |> (v => Ok(#SymbolicDist(#Float(v))))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let verticalScaling = (scaleOp, rs, scaleBy) => {
 | 
					let verticalScaling = (scaleOp, rs, scaleBy) => {
 | 
				
			||||||
| 
						 | 
					@ -125,10 +126,15 @@ module Multimodal = {
 | 
				
			||||||
        ->E.R.bind(TypeSystem.TypedValue.toArray)
 | 
					        ->E.R.bind(TypeSystem.TypedValue.toArray)
 | 
				
			||||||
        ->E.R.bind(r => r |> E.A.fmap(TypeSystem.TypedValue.toFloat) |> E.A.R.firstErrorOrOpen)
 | 
					        ->E.R.bind(r => r |> E.A.fmap(TypeSystem.TypedValue.toFloat) |> E.A.R.firstErrorOrOpen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        E.R.merge(dists, weights) -> E.R.bind(((a, b)) =>
 | 
					      E.R.merge(dists, weights)->E.R.bind(((a, b)) =>
 | 
				
			||||||
          E.A.length(b) > E.A.length(a) ?
 | 
					        E.A.length(b) > E.A.length(a)
 | 
				
			||||||
            Error("Too many weights provided") :
 | 
					          ? Error("Too many weights provided")
 | 
				
			||||||
            Ok(E.A.zipMaxLength(a, b) |> E.A.fmap(((a, b)) => (a |> E.O.toExn(""), b |> E.O.default(1.0))))
 | 
					          : Ok(
 | 
				
			||||||
 | 
					              E.A.zipMaxLength(a, b) |> E.A.fmap(((a, b)) => (
 | 
				
			||||||
 | 
					                a |> E.O.toExn(""),
 | 
				
			||||||
 | 
					                b |> E.O.default(1.0),
 | 
				
			||||||
 | 
					              )),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    | _ => Error("Needs items")
 | 
					    | _ => Error("Needs items")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,11 +86,7 @@ module TypedValue = {
 | 
				
			||||||
      |> E.R.fmap(r => #Array(r))
 | 
					      |> E.R.fmap(r => #Array(r))
 | 
				
			||||||
    | (#Hash(named), #Hash(r)) =>
 | 
					    | (#Hash(named), #Hash(r)) =>
 | 
				
			||||||
      let keyValues =
 | 
					      let keyValues =
 | 
				
			||||||
        named |> E.A.fmap(((name, intendedType)) => (
 | 
					        named |> E.A.fmap(((name, intendedType)) => (name, intendedType, Hash.getByName(r, name)))
 | 
				
			||||||
          name,
 | 
					 | 
				
			||||||
          intendedType,
 | 
					 | 
				
			||||||
          Hash.getByName(r, name),
 | 
					 | 
				
			||||||
        ))
 | 
					 | 
				
			||||||
      let typedHash =
 | 
					      let typedHash =
 | 
				
			||||||
        keyValues
 | 
					        keyValues
 | 
				
			||||||
        |> E.A.fmap(((name, intendedType, optionNode)) =>
 | 
					        |> E.A.fmap(((name, intendedType, optionNode)) =>
 | 
				
			||||||
| 
						 | 
					@ -180,11 +176,7 @@ module Function = {
 | 
				
			||||||
        _coerceInputNodes(evaluationParams, t.inputTypes, t.shouldCoerceTypes),
 | 
					        _coerceInputNodes(evaluationParams, t.inputTypes, t.shouldCoerceTypes),
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let run = (
 | 
					    let run = (evaluationParams: ASTTypes.evaluationParams, inputNodes: inputNodes, t: t) =>
 | 
				
			||||||
      evaluationParams: ASTTypes.evaluationParams,
 | 
					 | 
				
			||||||
      inputNodes: inputNodes,
 | 
					 | 
				
			||||||
      t: t,
 | 
					 | 
				
			||||||
    ) =>
 | 
					 | 
				
			||||||
      inputsToTypedValues(evaluationParams, inputNodes, t)->E.R.bind(t.run)
 | 
					      inputsToTypedValues(evaluationParams, inputNodes, t)->E.R.bind(t.run)
 | 
				
			||||||
        |> (
 | 
					        |> (
 | 
				
			||||||
          x =>
 | 
					          x =>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,11 +179,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
 | 
					  //Converts result type to change error type only
 | 
				
			||||||
  let errMap = (a, map) => switch(a){
 | 
					  let errMap = (a, map) =>
 | 
				
			||||||
 | 
					    switch a {
 | 
				
			||||||
    | Ok(r) => Ok(r)
 | 
					    | Ok(r) => Ok(r)
 | 
				
			||||||
    | Error(e) => map(e)
 | 
					    | Error(e) => map(e)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -300,7 +301,6 @@ module A = {
 | 
				
			||||||
      |> Rationale.Result.return
 | 
					      |> Rationale.Result.return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // This zips while taking the longest elements of each array.
 | 
					  // This zips while taking the longest elements of each array.
 | 
				
			||||||
  let zipMaxLength = (array1, array2) => {
 | 
					  let zipMaxLength = (array1, array2) => {
 | 
				
			||||||
    let maxLength = Int.max(length(array1), length(array2))
 | 
					    let maxLength = Int.max(length(array1), length(array2))
 | 
				
			||||||
| 
						 | 
					@ -456,7 +456,6 @@ module A = {
 | 
				
			||||||
    let diff = (arr: array<float>): array<float> =>
 | 
					    let diff = (arr: array<float>): array<float> =>
 | 
				
			||||||
      Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left)
 | 
					      Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    exception RangeError(string)
 | 
					    exception RangeError(string)
 | 
				
			||||||
    let range = (min: float, max: float, n: int): array<float> =>
 | 
					    let range = (min: float, max: float, n: int): array<float> =>
 | 
				
			||||||
      switch n {
 | 
					      switch n {
 | 
				
			||||||
| 
						 | 
					@ -474,7 +473,7 @@ module A = {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module A2 = {
 | 
					module A2 = {
 | 
				
			||||||
  let fmap = (a,b) => A.fmap(b,a)
 | 
					  let fmap = (a, b) => A.fmap(b, a)
 | 
				
			||||||
  let joinWith = (a, b) => A.joinWith(b, a)
 | 
					  let joinWith = (a, b) => A.joinWith(b, a)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,8 +36,8 @@ module Exponential = {
 | 
				
			||||||
  @module("jstat") @scope("exponential") external pdf: (float, float) => float = "pdf"
 | 
					  @module("jstat") @scope("exponential") external pdf: (float, float) => float = "pdf"
 | 
				
			||||||
  @module("jstat") @scope("exponential") external cdf: (float, float) => float = "cdf"
 | 
					  @module("jstat") @scope("exponential") external cdf: (float, float) => float = "cdf"
 | 
				
			||||||
  @module("jstat") @scope("exponential") external inv: (float, float) => float = "inv"
 | 
					  @module("jstat") @scope("exponential") external inv: (float, float) => float = "inv"
 | 
				
			||||||
  @module("jstat") @scope("exponential") external sample: (float) => float = "sample"
 | 
					  @module("jstat") @scope("exponential") external sample: float => float = "sample"
 | 
				
			||||||
  @module("jstat") @scope("exponential") external mean: (float) => float = "mean"
 | 
					  @module("jstat") @scope("exponential") external mean: float => float = "mean"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module Cauchy = {
 | 
					module Cauchy = {
 | 
				
			||||||
| 
						 | 
					@ -56,7 +56,6 @@ module Triangular = {
 | 
				
			||||||
  @module("jstat") @scope("triangular") external mean: (float, float, float) => float = "mean"
 | 
					  @module("jstat") @scope("triangular") external mean: (float, float, float) => float = "mean"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
module Pareto = {
 | 
					module Pareto = {
 | 
				
			||||||
  @module("jstat") @scope("pareto") external pdf: (float, float, float) => float = "pdf"
 | 
					  @module("jstat") @scope("pareto") external pdf: (float, float, float) => float = "pdf"
 | 
				
			||||||
  @module("jstat") @scope("pareto") external cdf: (float, float, float) => float = "cdf"
 | 
					  @module("jstat") @scope("pareto") external cdf: (float, float, float) => float = "cdf"
 | 
				
			||||||
| 
						 | 
					@ -66,20 +65,20 @@ module Pareto = {
 | 
				
			||||||
module Poisson = {
 | 
					module Poisson = {
 | 
				
			||||||
  @module("jstat") @scope("poisson") external pdf: (float, float) => float = "pdf"
 | 
					  @module("jstat") @scope("poisson") external pdf: (float, float) => float = "pdf"
 | 
				
			||||||
  @module("jstat") @scope("poisson") external cdf: (float, float) => float = "cdf"
 | 
					  @module("jstat") @scope("poisson") external cdf: (float, float) => float = "cdf"
 | 
				
			||||||
  @module("jstat") @scope("poisson") external sample: (float) => float = "sample"
 | 
					  @module("jstat") @scope("poisson") external sample: float => float = "sample"
 | 
				
			||||||
  @module("jstat") @scope("poisson") external mean: (float) => float = "mean"
 | 
					  @module("jstat") @scope("poisson") external mean: float => float = "mean"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module Weibull = {
 | 
					module Weibull = {
 | 
				
			||||||
  @module("jstat") @scope("weibull") external pdf: (float, float, float) => float = "pdf"
 | 
					  @module("jstat") @scope("weibull") external pdf: (float, float, float) => float = "pdf"
 | 
				
			||||||
  @module("jstat") @scope("weibull") external cdf: (float, float,float ) => float = "cdf"
 | 
					  @module("jstat") @scope("weibull") external cdf: (float, float, float) => float = "cdf"
 | 
				
			||||||
  @module("jstat") @scope("weibull") external sample: (float,float) => float = "sample"
 | 
					  @module("jstat") @scope("weibull") external sample: (float, float) => float = "sample"
 | 
				
			||||||
  @module("jstat") @scope("weibull") external mean: (float,float) => float = "mean"
 | 
					  @module("jstat") @scope("weibull") external mean: (float, float) => float = "mean"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module Binomial = {
 | 
					module Binomial = {
 | 
				
			||||||
  @module("jstat") @scope("binomial") external pdf: (float, float, float) => float = "pdf"
 | 
					  @module("jstat") @scope("binomial") external pdf: (float, float, float) => float = "pdf"
 | 
				
			||||||
  @module("jstat") @scope("binomial") external cdf: (float, float,float ) => float = "cdf"
 | 
					  @module("jstat") @scope("binomial") external cdf: (float, float, float) => float = "cdf"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@module("jstat") external sum: array<float> => float = "sum"
 | 
					@module("jstat") external sum: array<float> => float = "sum"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user