diff --git a/packages/components/src/SquiggleChart.tsx b/packages/components/src/SquiggleChart.tsx index 27823b12..47087481 100644 --- a/packages/components/src/SquiggleChart.tsx +++ b/packages/components/src/SquiggleChart.tsx @@ -163,7 +163,7 @@ export const SquiggleChart: React.FC = (props) => { // We are looking at a function. In this case, we draw a Percentiles chart let start = props.diagramStart ? props.diagramStart : 0; let stop = props.diagramStop ? props.diagramStop : 10; - let count = props.diagramCount ? props.diagramCount : 0.1; + let count = props.diagramCount ? props.diagramCount : 100; let step = (stop - start) / count; let data = _.range(start, stop, step).map((x) => { if (chartResult.NAME == "Function") { @@ -192,10 +192,10 @@ export const SquiggleChart: React.FC = (props) => { p99: percentiles[12], }; } + return null; } - return 0; }); - return ; + return x !== null) }} />; } }); return <>{chartResults}; diff --git a/packages/squiggle-lang/src/rescript/interpreter/typeSystem/HardcodedFunctions.res b/packages/squiggle-lang/src/rescript/interpreter/typeSystem/HardcodedFunctions.res index ecd89397..f6741bab 100644 --- a/packages/squiggle-lang/src/rescript/interpreter/typeSystem/HardcodedFunctions.res +++ b/packages/squiggle-lang/src/rescript/interpreter/typeSystem/HardcodedFunctions.res @@ -22,7 +22,7 @@ let makeSymbolicFromTwoFloats = (name, fn) => ~inputTypes=[#Float, #Float], ~run=x => switch x { - | [#Float(a), #Float(b)] => Ok(#SymbolicDist(fn(a, b))) + | [#Float(a), #Float(b)] => fn(a, b) |> E.R.fmap(r => (#SymbolicDist(r))) | e => wrongInputsError(e) }, (), @@ -35,7 +35,7 @@ let makeSymbolicFromOneFloat = (name, fn) => ~inputTypes=[#Float], ~run=x => switch x { - | [#Float(a)] => Ok(#SymbolicDist(fn(a))) + | [#Float(a)] => fn(a) |> E.R.fmap(r => #SymbolicDist(r)) | e => wrongInputsError(e) }, (), diff --git a/packages/squiggle-lang/src/rescript/symbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/symbolicDist/SymbolicDist.res index 3da6bd02..1336a601 100644 --- a/packages/squiggle-lang/src/rescript/symbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/symbolicDist/SymbolicDist.res @@ -2,7 +2,10 @@ open SymbolicDistTypes module Normal = { type t = normal - let make = (mean, stdev): symbolicDist => #Normal({mean: mean, stdev: stdev}) + let make = (mean: float, stdev: float): result => + stdev > 0.0 + ? Ok(#Normal({mean: mean, stdev: stdev})) + : Error("Standard deviation of normal distribution must be larger than 0") let pdf = (x, t: t) => Jstat.Normal.pdf(x, t.mean, t.stdev) let cdf = (x, t: t) => Jstat.Normal.cdf(x, t.mean, t.stdev) @@ -45,10 +48,12 @@ module Normal = { module Exponential = { type t = exponential - let make = (rate: float): symbolicDist => - #Exponential({ - rate: rate, - }) + let make = (rate: float): result => + rate > 0.0 + ? Ok(#Exponential({ + rate: rate, + })) + : Error("Exponential distributions mean must be larger than 0") let pdf = (x, t: t) => Jstat.Exponential.pdf(x, t.rate) let cdf = (x, t: t) => Jstat.Exponential.cdf(x, t.rate) let inv = (p, t: t) => Jstat.Exponential.inv(p, t.rate) @@ -84,7 +89,10 @@ module Triangular = { module Beta = { type t = beta - let make = (alpha, beta) => #Beta({alpha: alpha, beta: beta}) + let make = (alpha, beta) => + alpha > 0.0 && beta > 0.0 + ? Ok(#Beta({alpha: alpha, beta: beta})) + : Error("Beta distribution parameters must be positive") let pdf = (x, t: t) => Jstat.Beta.pdf(x, t.alpha, t.beta) let cdf = (x, t: t) => Jstat.Beta.cdf(x, t.alpha, t.beta) let inv = (p, t: t) => Jstat.Beta.inv(p, t.alpha, t.beta) @@ -95,7 +103,10 @@ module Beta = { module Lognormal = { type t = lognormal - let make = (mu, sigma) => #Lognormal({mu: mu, sigma: sigma}) + let make = (mu, sigma) => + sigma > 0.0 + ? Ok(#Lognormal({mu: mu, sigma: sigma})) + : Error("Lognormal standard deviation must be larger than 0") let pdf = (x, t: t) => Jstat.Lognormal.pdf(x, t.mu, t.sigma) let cdf = (x, t: t) => Jstat.Lognormal.cdf(x, t.mu, t.sigma) let inv = (p, t: t) => Jstat.Lognormal.inv(p, t.mu, t.sigma) @@ -110,11 +121,16 @@ module Lognormal = { #Lognormal({mu: mu, sigma: sigma}) } let fromMeanAndStdev = (mean, stdev) => { - let variance = Js.Math.pow_float(~base=stdev, ~exp=2.0) - let meanSquared = Js.Math.pow_float(~base=mean, ~exp=2.0) - let mu = Js.Math.log(mean) -. 0.5 *. Js.Math.log(variance /. meanSquared +. 1.0) - let sigma = Js.Math.pow_float(~base=Js.Math.log(variance /. meanSquared +. 1.0), ~exp=0.5) - #Lognormal({mu: mu, sigma: sigma}) + if stdev > 0.0 { + let variance = Js.Math.pow_float(~base=stdev, ~exp=2.0) + let meanSquared = Js.Math.pow_float(~base=mean, ~exp=2.0) + let mu = Js.Math.log(mean) -. 0.5 *. Js.Math.log(variance /. meanSquared +. 1.0) + let sigma = Js.Math.pow_float(~base=Js.Math.log(variance /. meanSquared +. 1.0), ~exp=0.5) + Ok(#Lognormal({mu: mu, sigma: sigma})) + } + else { + Error("Lognormal standard deviation must be larger than 0") + } } let multiply = (l1, l2) => { @@ -137,7 +153,11 @@ module Lognormal = { module Uniform = { type t = uniform - let make = (low, high) => #Uniform({low: low, high: high}) + let make = (low, high) => + high > low + ? Ok(#Uniform({low: low, high: high})) + : Error("High must be larger than low") + let pdf = (x, t: t) => Jstat.Uniform.pdf(x, t.low, t.high) let cdf = (x, t: t) => Jstat.Uniform.cdf(x, t.low, t.high) let inv = (p, t: t) => Jstat.Uniform.inv(p, t.low, t.high) diff --git a/packages/squiggle-lang/src/rescript/utility/Jstat.res b/packages/squiggle-lang/src/rescript/utility/Jstat.res index cd35b203..0fc31d6d 100644 --- a/packages/squiggle-lang/src/rescript/utility/Jstat.res +++ b/packages/squiggle-lang/src/rescript/utility/Jstat.res @@ -25,61 +25,61 @@ module Uniform = { type beta module Beta = { - @module("jstat") @scope("uniform") external pdf: (float, float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float, float) => float = "cdf" - @module("jstat") @scope("uniform") external inv: (float, float, float) => float = "inv" - @module("jstat") @scope("uniform") external sample: (float, float) => float = "sample" - @module("jstat") @scope("uniform") external mean: (float, float) => float = "mean" + @module("jstat") @scope("beta") external pdf: (float, float, float) => float = "pdf" + @module("jstat") @scope("beta") external cdf: (float, float, float) => float = "cdf" + @module("jstat") @scope("beta") external inv: (float, float, float) => float = "inv" + @module("jstat") @scope("beta") external sample: (float, float) => float = "sample" + @module("jstat") @scope("beta") external mean: (float, float) => float = "mean" } module Exponential = { - @module("jstat") @scope("uniform") external pdf: (float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float) => float = "cdf" - @module("jstat") @scope("uniform") external inv: (float, float) => float = "inv" - @module("jstat") @scope("uniform") external sample: (float) => float = "sample" - @module("jstat") @scope("uniform") external mean: (float) => float = "mean" + @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 inv: (float, float) => float = "inv" + @module("jstat") @scope("exponential") external sample: (float) => float = "sample" + @module("jstat") @scope("exponential") external mean: (float) => float = "mean" } module Cauchy = { - @module("jstat") @scope("uniform") external pdf: (float, float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float, float) => float = "cdf" - @module("jstat") @scope("uniform") external inv: (float, float, float) => float = "inv" - @module("jstat") @scope("uniform") external sample: (float, float) => float = "sample" - @module("jstat") @scope("uniform") external mean: (float, float) => float = "mean" + @module("jstat") @scope("cauchy") external pdf: (float, float, float) => float = "pdf" + @module("jstat") @scope("cauchy") external cdf: (float, float, float) => float = "cdf" + @module("jstat") @scope("cauchy") external inv: (float, float, float) => float = "inv" + @module("jstat") @scope("cauchy") external sample: (float, float) => float = "sample" + @module("jstat") @scope("cauchy") external mean: (float, float) => float = "mean" } module Triangular = { - @module("jstat") @scope("uniform") external pdf: (float, float, float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float, float, float) => float = "cdf" - @module("jstat") @scope("uniform") external inv: (float, float, float, float) => float = "inv" - @module("jstat") @scope("uniform") external sample: (float, float, float) => float = "sample" - @module("jstat") @scope("uniform") external mean: (float, float, float) => float = "mean" + @module("jstat") @scope("triangular") external pdf: (float, float, float, float) => float = "pdf" + @module("jstat") @scope("triangular") external cdf: (float, float, float, float) => float = "cdf" + @module("jstat") @scope("triangular") external inv: (float, float, float, float) => float = "inv" + @module("jstat") @scope("triangular") external sample: (float, float, float) => float = "sample" + @module("jstat") @scope("triangular") external mean: (float, float, float) => float = "mean" } module Pareto = { - @module("jstat") @scope("uniform") external pdf: (float, float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float, float) => float = "cdf" - @module("jstat") @scope("uniform") external inv: (float, float, float) => float = "inv" + @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 inv: (float, float, float) => float = "inv" } module Poisson = { - @module("jstat") @scope("uniform") external pdf: (float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float) => float = "cdf" - @module("jstat") @scope("uniform") external sample: (float) => float = "sample" - @module("jstat") @scope("uniform") external mean: (float) => float = "mean" + @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 sample: (float) => float = "sample" + @module("jstat") @scope("poisson") external mean: (float) => float = "mean" } module Weibull = { - @module("jstat") @scope("uniform") external pdf: (float, float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float,float ) => float = "cdf" - @module("jstat") @scope("uniform") external sample: (float,float) => float = "sample" - @module("jstat") @scope("uniform") external mean: (float,float) => float = "mean" + @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 sample: (float,float) => float = "sample" + @module("jstat") @scope("weibull") external mean: (float,float) => float = "mean" } module Binomial = { - @module("jstat") @scope("uniform") external pdf: (float, float, float) => float = "pdf" - @module("jstat") @scope("uniform") external cdf: (float, float,float ) => float = "cdf" + @module("jstat") @scope("binomial") external pdf: (float, float, float) => float = "pdf" + @module("jstat") @scope("binomial") external cdf: (float, float,float ) => float = "cdf" } @module("jstat") external sum: array => float = "sum"