(rebase): documented ratio of lognormals

This commit is contained in:
Quinn Dougherty 2022-04-11 17:37:40 -04:00
parent a637fe5dff
commit 9d857bf79b
3 changed files with 38 additions and 5 deletions

View File

@ -31,7 +31,7 @@ let algebraicSubtract = algebraicSubtract(~env)
let algebraicLogarithm = algebraicLogarithm(~env) let algebraicLogarithm = algebraicLogarithm(~env)
let algebraicPower = algebraicPower(~env) let algebraicPower = algebraicPower(~env)
describe("Addition of distributions", () => { describe("(Algebraic) addition of distributions", () => {
describe("mean", () => { describe("mean", () => {
test("normal(mean=5) + normal(mean=20)", () => { test("normal(mean=5) + normal(mean=20)", () => {
@ -44,6 +44,39 @@ describe("Addition of distributions", () => {
-> expect -> expect
-> toBe(Some(2.5e1)) -> toBe(Some(2.5e1))
}) })
test("uniform(low=9, high=10) + beta(alpha=2, beta=5)", () => {
// let uniformMean = (9.0 +. 10.0) /. 2.0
// let betaMean = 1.0 /. (1.0 +. 5.0 /. 2.0)
let received = uniformDist
-> algebraicAdd(betaDist)
-> E.R2.fmap(GenericDist_Types.Constructors.UsingDists.mean)
-> E.R2.fmap(run)
-> E.R2.fmap(toFloat)
-> E.R.toExn
switch received {
| None => false -> expect -> toBe(true)
// This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad.
// sometimes it works with ~digits=2.
| Some(x) => x -> expect -> toBeSoCloseTo(0.1884273175239643, ~digits=1) // (uniformMean +. betaMean)
}
})
test("beta(alpha=2, beta=5) + uniform(low=9, high=10)", () => {
// let uniformMean = (9.0 +. 10.0) /. 2.0
// let betaMean = 1.0 /. (1.0 +. 5.0 /. 2.0)
let received = betaDist
-> algebraicAdd(uniformDist)
-> E.R2.fmap(GenericDist_Types.Constructors.UsingDists.mean)
-> E.R2.fmap(run)
-> E.R2.fmap(toFloat)
-> E.R.toExn
switch received {
| None => false -> expect -> toBe(true)
// This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad.
// sometimes it works with ~digits=2.
| Some(x) => x -> expect -> toBeSoCloseTo(0.19708465087256619, ~digits=1) // (uniformMean +. betaMean)
}
})
}) })
describe("pdf", () => { describe("pdf", () => {
testAll("(normal(mean=5) + normal(mean=5)).pdf (imprecise)", list{8e0, 1e1, 1.2e1, 1.4e1}, x => { testAll("(normal(mean=5) + normal(mean=5)).pdf (imprecise)", list{8e0, 1e1, 1.2e1, 1.4e1}, x => {
@ -192,7 +225,5 @@ describe("Addition of distributions", () => {
} }
} }
}) })
}) })
}) })

View File

@ -11,8 +11,8 @@ let {toFloat, toDist, toString, toError, fmap} = module(DistributionOperation.Ou
let fnImage = (theFn, inps) => Js.Array.map(theFn, inps) let fnImage = (theFn, inps) => Js.Array.map(theFn, inps)
let env: DistributionOperation.env = { let env: DistributionOperation.env = {
sampleCount: 100, sampleCount: 100000,
xyPointLength: 100, xyPointLength: 1000,
} }
let run = DistributionOperation.run(~env) let run = DistributionOperation.run(~env)

View File

@ -141,6 +141,8 @@ module Lognormal = {
} }
let divide = (l1, l2) => { let divide = (l1, l2) => {
let mu = l1.mu -. l2.mu let mu = l1.mu -. l2.mu
// We believe the ratiands will have covariance zero.
// See here https://stats.stackexchange.com/questions/21735/what-are-the-mean-and-variance-of-the-ratio-of-two-lognormal-variables for details
let sigma = l1.sigma +. l2.sigma let sigma = l1.sigma +. l2.sigma
#Lognormal({mu: mu, sigma: sigma}) #Lognormal({mu: mu, sigma: sigma})
} }