From 142d846223762515f64c499ce5eceb6146876c25 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 25 Mar 2022 13:08:46 +1100 Subject: [PATCH 1/9] Add interactive documentation --- packages/website/docs/Functions.mdx | 136 ++++++++++++++++++ packages/website/docs/Future-Features.md | 31 +++- packages/website/docs/Introduction.md | 10 ++ packages/website/docs/Javscript-library.md | 38 +++-- packages/website/docs/Language.md | 67 --------- packages/website/docs/Language.mdx | 51 +++++++ .../docs/Three-Types-Of-Distributions.md | 2 +- packages/website/docusaurus.config.js | 27 +++- 8 files changed, 279 insertions(+), 83 deletions(-) create mode 100644 packages/website/docs/Functions.mdx create mode 100644 packages/website/docs/Introduction.md delete mode 100644 packages/website/docs/Language.md create mode 100644 packages/website/docs/Language.mdx diff --git a/packages/website/docs/Functions.mdx b/packages/website/docs/Functions.mdx new file mode 100644 index 00000000..6a0683cd --- /dev/null +++ b/packages/website/docs/Functions.mdx @@ -0,0 +1,136 @@ +--- +sidebar_position: 7 +--- + +import { SquiggleEditor } from '@quri/squiggle-components' + +# Squiggle Functions Reference + +## Distributions + +### Normal distribution + +The `normal(mean, sd)` function creates a normal distribution with the given mean +and standard deviation. + + + +### Uniform distribution + +The `uniform(low, high)` function creates a uniform distribution between the +two given numbers: + + + + +### Lognormal distribution + +The `lognormal(mu, sigma)` returns the log of a normal distribution with parameters +mu and sigma. The log of lognormal(mu, sigma) is a normal distribution with parameters +mean mu and standard deviation sigma. + + + +An alternative format is also available. The "to" notation creates a lognormal +distribution with a 90% confidence interval between the two numbers. We add +this convinience as lognormal distributions are commonly used in practice + + + +Furthermore, it's also possible to create a lognormal from it's actual mean +and standard deviation, using `lognormalFromMeanAndStdDev`: + + + + +### Beta distribution + +The `beta(a, b)` function creates a beta distribution with parameters a and b: + + + +### Exponential distribution + +The `exponential(mean)` function creates an exponential distribution with the given +mean. + + + + +### The Triangular distribution + +The `triangular(a,b,c)` function creates a triangular distribution with lower +bound a, mode b and upper bound c: + + + +### Multimodal distriutions + +The multimodal function combines 2 or more other distributions to create a weighted +combination of the two. The first positional arguments represent the distributions +to be combined, and the last argument is how much to weigh every distribution in the +combination. + + + +It's possible to create discrete distributions using this method: + + + +As well as mixed distributions: + + + +## Other Functions + +### PDF of a distribution +The `pdf(distribution, x)` function returns the density of a distribution at the +given point x: + + + + +### Inverse of a distribution + +The `inv(distribution, prob)` gives the value x or which the probability for all values +lower than x is equal to prob. It is the inverse of `cdf` + + + +### CDF of a distribution + +The `cdf(distribution,x)` gives the cumulative probability of the distribution +or all values lower than x. It is the inverse of `inv`: + + + +### Mean of a distribution +The `mean(distribution)` function gives the mean (expected value) of a distribution: + + + +### Sampling a distribution +The `sample(distribution)` samples a given distribution: + + + +### Exponential Scaling + +The `scaleExp(distribution, factor)` function scales a distribution's PDF exponentially +in the y axis. + + + +### Multiply Scaling + +The `scaleMultiply(distribution, factor)` function scales a distribution's PDF by multiplication +in the y axis. + + + +### Log scaling + +The `scaleLog(distribution, factor)` function scales a distribution's PDF by the log +function in the y axis + + diff --git a/packages/website/docs/Future-Features.md b/packages/website/docs/Future-Features.md index 969bdf59..6370602e 100644 --- a/packages/website/docs/Future-Features.md +++ b/packages/website/docs/Future-Features.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 --- # Future Features @@ -79,3 +79,32 @@ Right now, Monte Carlo simulations are totally random. It would be nicer to be a ## Fixes - Discrete distributions are particularly buggy. Try ``mm(1,2,3,4,5,6,7,8,9,10) .* (5 to 8)`` + +## New Functions + +### Distributions +``` +cauchy() //todo +pareto() //todo +metalog() //todo +``` + +Possibly change mm to mix, or mx(). Also, change input format, maybe to mx([a,b,c], [a,b,c]). + + +### Functions +``` +samples(distribution, n) //todo +toPdf(distribution) //todo +toCdf(distribution) //todo +toHash(distribution) //todo. Make hash of content, like, {xs:[], ys:[]} +trunctate(distribution, leftValue, rightValue) //todo +leftTrunctate(distribution, leftValue) //todo +rightTrunctate(distribution, rightValue) //todo +distributionFromSamples(array, params) //todo +distributionFromPoints() //todo +distributionFromHash() //todo +``` + + + diff --git a/packages/website/docs/Introduction.md b/packages/website/docs/Introduction.md new file mode 100644 index 00000000..ecfe7f02 --- /dev/null +++ b/packages/website/docs/Introduction.md @@ -0,0 +1,10 @@ +--- +sidebar_position: 1 +--- + +# Squiggle + +Squiggle is a language for writing calculations under uncertainty. It has use +cases in forecasting and writing better evaluations. + +The best way to get started with Squiggle is to [try it out yourself](https://playground.squiggle-language.com/). diff --git a/packages/website/docs/Javscript-library.md b/packages/website/docs/Javscript-library.md index 4456119d..60f70426 100644 --- a/packages/website/docs/Javscript-library.md +++ b/packages/website/docs/Javscript-library.md @@ -1,16 +1,36 @@ --- -sidebar_position: 2 +sidebar_position: 3 --- -# Javascript Library +# Javascript Libraries -There's a very simple javscript library for Squiggle here: https://www.npmjs.com/package/squiggle-experimental. +There are two JavaScript packages currently available for Squiggle: + - [`@quri/squiggle-lang`](https://www.npmjs.com/package/@quri/squiggle-lang) + - [`@quri/squiggle-components`](https://www.npmjs.com/package/@quri/squiggle-components) -You can see it live on this Observable page: [https://observablehq.com/d/a99e822870c4ca5f](https://observablehq.com/d/a99e822870c4ca5f). +Types are available for both packages. +## Squiggle Language -## Simple Example -``` -let squiggle = require("squiggle-experimental@0.1.9/dist/index.js") -squiggle.runMePlease("3 + normal(50,1)) -``` \ No newline at end of file +The `@quri/squiggle-lang` package exports a single function, `run`, which given +a string of Squiggle code, will execute the code and return any exports and the +environment created from the squiggle code. + +`run` has two optional arguments. The first optional argument allows you to set +sampling settings for Squiggle when representing distributions. The second optional +argument allows you to pass an environment previously created by another `run` +call. Passing this environment will mean that all previously declared variables +in the previous environment will be made available. + +The return type of `run` is a bit complicated, and comes from auto generated js +code that comes from rescript. I highly recommend using typescript when using +this library to help navigate the return type. + +## Squiggle Components + +The `@quri/squiggle-components` package offers several components and utilities +for people who want to embed Squiggle components into websites. This documentation +relies on `@quri/squiggle-components` frequently. + +We host [a storybook](https://components.squiggle-language.com/) with details +and usage of each of the components made available. diff --git a/packages/website/docs/Language.md b/packages/website/docs/Language.md deleted file mode 100644 index 952fddce..00000000 --- a/packages/website/docs/Language.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Squiggle Language - -## Distributions -```js -normal(a,b) -uniform(a,b) -lognormal(a,b) -lognormalFromMeanAndStdDev(mean, stdev) -beta(a,b) -exponential(a) -triangular(a,b,c) -mm(a,b,c, [1,2,3]) //todo: change to mix, or mx(). Also, change input format, maybe to mx([a,b,c], [a,b,c]). -cauchy() //todo -pareto() //todo -metalog() //todo -``` - -## Functions -```js -pdf(distribution, float) -inv(distribution, float) -cdf(distribution, float) -mean(distribution) -sample(distribution) -scaleExp(distribution, float) -scaleMultiply(distribution, float) -scaleLog(distribution, float) -samples(distribution, n) //todo -toPdf(distribution) //todo -toCdf(distribution) //todo -toHash(distribution) //todo. Make hash of content, like, {xs:[], ys:[]} -trunctate(distribution, leftValue, rightValue) //todo -leftTrunctate(distribution, leftValue) //todo -rightTrunctate(distribution, rightValue) //todo -distributionFromSamples(array, params) //todo -distributionFromPoints() //todo -distributionFromHash() //todo -log() //todo - -``` - -## Example Functions - -```js -ozzie_estimate(t) = lognormal({mean: 3 + (t+.1)^2.5, stdev: 8}) -nuño_estimate(t) = lognormal({mean: 3 + (t+.1)^2, stdev: 10}) -combined(t) = mm(ozzie_estimate(t) .+ nuño_estimate(t)) -combined -``` - -```js -us_economy_2018 = (10.5 to 10.9)T -growth_rate = 1.08 to 1.2 -us_economy(t) = us_economy_2018 * (growth_rate^t) - -us_population_2019 = 320M to 330M -us_population_growth_rate = 1.01 to 1.1 -us_population(t) = us_population_2019 * (us_population_growth_rate^t) -gdp_per_person(t) = us_economy(t)/us_population(t) -gdp_per_person - -gdp_per_person -``` diff --git a/packages/website/docs/Language.mdx b/packages/website/docs/Language.mdx new file mode 100644 index 00000000..f73a779f --- /dev/null +++ b/packages/website/docs/Language.mdx @@ -0,0 +1,51 @@ +--- +sidebar_position: 2 +--- + +import { SquiggleEditor } from '@quri/squiggle-components' + +# Squiggle Language + +The squiggle language has a very simply syntax. The best way to get to understand +it is by simply looking at examples. + + +## Basic Language + +As an example: + + + +Squiggle can declare variables (`value_of_work = 10 to 70`) and declare exports +(the lone `value_of_work` line). Variables can be used later in a squiggle program +and even in other notebooks! + +An export is rendered to the output view so you can see your result. + +the exports can be expressions, such as: + + + +## Functions + +Squiggle supports functions, including the rendering of functions: + + + +## Squiggle units + +Squiggle supports using suffixes at the end of numbers to refer to units: + + + diff --git a/packages/website/docs/Three-Types-Of-Distributions.md b/packages/website/docs/Three-Types-Of-Distributions.md index a5225e7b..a69f0b1c 100644 --- a/packages/website/docs/Three-Types-Of-Distributions.md +++ b/packages/website/docs/Three-Types-Of-Distributions.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 5 --- # Three Formats of Distributions diff --git a/packages/website/docusaurus.config.js b/packages/website/docusaurus.config.js index a859c8ca..7d1bfc54 100644 --- a/packages/website/docusaurus.config.js +++ b/packages/website/docusaurus.config.js @@ -3,18 +3,35 @@ const lightCodeTheme = require('prism-react-renderer/themes/github'); const darkCodeTheme = require('prism-react-renderer/themes/dracula'); +const path = require('path'); /** @type {import('@docusaurus/types').Config} */ const config = { title: 'Squiggle (alpha)', - tagline: "Scorable programming, for use by forecasters", - url: 'https://squiggle-documentation.netlify.app', + tagline: "Estimation language for forecasters", + url: 'https://squiggle-language.com', baseUrl: '/', onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', favicon: 'img/favicon.ico', - organizationName: 'QURI', // Usually your GitHub org/user name. - projectName: 'Squiggle', // Usually your repo name. + organizationName: 'QURIResearch', // Usually your GitHub org/user name. + projectName: 'squiggle', // Usually your repo name. + + plugins: [ + () => ({ + configureWebpack(config, isServer, utils, content) { + return { + resolve: { + alias : { + "@quri/squiggle-components": path.resolve(__dirname, "../components/src"), + "@quri/squiggle-lang": path.resolve(__dirname, "../squiggle-lang/src/js") + } + } + + }; + } + }) + ], presets: [ [ @@ -51,7 +68,7 @@ const config = { items: [ { type: 'doc', - docId: 'Language', + docId: 'Introduction', position: 'left', label: 'Documentation', }, From ce252bb2f971a37e0f6c0d723d76e798d4fe6b56 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 25 Mar 2022 14:12:14 +1100 Subject: [PATCH 2/9] Fix up build ssr and ci for docs --- .github/workflows/ci.yaml | 6 ++++-- packages/website/babel.config.js | 6 +++++- packages/website/docs/Functions.mdx | 2 +- packages/website/docs/Language.mdx | 2 +- packages/website/src/components/SquiggleEditor.jsx | 13 +++++++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 packages/website/src/components/SquiggleEditor.jsx diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 31e15df0..7bf80ead 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -79,7 +79,9 @@ jobs: working-directory: packages/website steps: - uses: actions/checkout@v2 - - name: Install dependencies - run: yarn + - name: Install dependencies from monorepo level + run: cd ../../ && yarn + - name: Build rescript in squiggle-lang + run: cd ../squiggle-lang && yarn build - name: Build website assets run: yarn build diff --git a/packages/website/babel.config.js b/packages/website/babel.config.js index e00595da..0bf9a1b9 100644 --- a/packages/website/babel.config.js +++ b/packages/website/babel.config.js @@ -1,3 +1,7 @@ module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], + presets: [ + require.resolve('@docusaurus/core/lib/babel/preset'), + ["@babel/preset-react", {"runtime": "automatic"}] + + ], }; diff --git a/packages/website/docs/Functions.mdx b/packages/website/docs/Functions.mdx index 6a0683cd..65102bc3 100644 --- a/packages/website/docs/Functions.mdx +++ b/packages/website/docs/Functions.mdx @@ -2,7 +2,7 @@ sidebar_position: 7 --- -import { SquiggleEditor } from '@quri/squiggle-components' +import { SquiggleEditor } from '../src/components/SquiggleEditor' # Squiggle Functions Reference diff --git a/packages/website/docs/Language.mdx b/packages/website/docs/Language.mdx index f73a779f..84707479 100644 --- a/packages/website/docs/Language.mdx +++ b/packages/website/docs/Language.mdx @@ -2,7 +2,7 @@ sidebar_position: 2 --- -import { SquiggleEditor } from '@quri/squiggle-components' +import { SquiggleEditor } from '../src/components/SquiggleEditor' # Squiggle Language diff --git a/packages/website/src/components/SquiggleEditor.jsx b/packages/website/src/components/SquiggleEditor.jsx new file mode 100644 index 00000000..7d69ff21 --- /dev/null +++ b/packages/website/src/components/SquiggleEditor.jsx @@ -0,0 +1,13 @@ +import BrowserOnly from '@docusaurus/BrowserOnly'; + +export function SquiggleEditor(props) { + return ( + Loading...}> + {() => { + const LibComponent = + require('@quri/squiggle-components').SquiggleEditor; + return ; + }} + + ); +} From 8aea739fd056b0109ead8999a35b3e4feeba7e62 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 25 Mar 2022 14:42:52 +1100 Subject: [PATCH 3/9] Fix exponential, beta and triangular distributions --- .../src/rescript/utility/Jstat.res | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) 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" From c4b6a8d097e67503b89f594e1a8cb5df524265a8 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 25 Mar 2022 15:35:32 +1100 Subject: [PATCH 4/9] Fix functions not rendering Fixes #59 --- packages/components/src/SquiggleChart.tsx | 6 +-- .../src/rescript/ProgramEvaluator.res | 1 + .../typeSystem/HardcodedFunctions.res | 4 +- .../rescript/symbolicDist/SymbolicDist.res | 46 +++++++++++++------ 4 files changed, 39 insertions(+), 18 deletions(-) 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/ProgramEvaluator.res b/packages/squiggle-lang/src/rescript/ProgramEvaluator.res index b2317050..a7122abd 100644 --- a/packages/squiggle-lang/src/rescript/ProgramEvaluator.res +++ b/packages/squiggle-lang/src/rescript/ProgramEvaluator.res @@ -110,6 +110,7 @@ module Internals = { inputs : Inputs.inputs, env : ASTTypes.environment) => { (input : float) => { + Js.log2("Environment", inputs); let foo: Inputs.inputs = {...inputs, environment: env}; evaluateFunction( foo, 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) From eec92b2c0cb1a64b26ad6564f1728011eac0fc4e Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 25 Mar 2022 15:37:07 +1100 Subject: [PATCH 5/9] Remove unneccesary log --- packages/squiggle-lang/src/rescript/ProgramEvaluator.res | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/ProgramEvaluator.res b/packages/squiggle-lang/src/rescript/ProgramEvaluator.res index a7122abd..b2317050 100644 --- a/packages/squiggle-lang/src/rescript/ProgramEvaluator.res +++ b/packages/squiggle-lang/src/rescript/ProgramEvaluator.res @@ -110,7 +110,6 @@ module Internals = { inputs : Inputs.inputs, env : ASTTypes.environment) => { (input : float) => { - Js.log2("Environment", inputs); let foo: Inputs.inputs = {...inputs, environment: env}; evaluateFunction( foo, From 1b4ed4f113f03f7e1c82c284541fca1e5d954cb2 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 25 Mar 2022 20:42:02 +1100 Subject: [PATCH 6/9] Remove internal and unsupported features --- packages/website/docs/Functions.mdx | 21 --------------------- packages/website/docs/Language.mdx | 14 -------------- 2 files changed, 35 deletions(-) diff --git a/packages/website/docs/Functions.mdx b/packages/website/docs/Functions.mdx index 65102bc3..ff2e393a 100644 --- a/packages/website/docs/Functions.mdx +++ b/packages/website/docs/Functions.mdx @@ -113,24 +113,3 @@ The `mean(distribution)` function gives the mean (expected value) of a distribut The `sample(distribution)` samples a given distribution: - -### Exponential Scaling - -The `scaleExp(distribution, factor)` function scales a distribution's PDF exponentially -in the y axis. - - - -### Multiply Scaling - -The `scaleMultiply(distribution, factor)` function scales a distribution's PDF by multiplication -in the y axis. - - - -### Log scaling - -The `scaleLog(distribution, factor)` function scales a distribution's PDF by the log -function in the y axis - - diff --git a/packages/website/docs/Language.mdx b/packages/website/docs/Language.mdx index 84707479..4a3c8883 100644 --- a/packages/website/docs/Language.mdx +++ b/packages/website/docs/Language.mdx @@ -35,17 +35,3 @@ Squiggle supports functions, including the rendering of functions: ozzie_estimate `} /> -## Squiggle units - -Squiggle supports using suffixes at the end of numbers to refer to units: - - - From bd53084bd8953255e780ecab8aa73315eac12c2c Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 25 Mar 2022 20:52:20 +1100 Subject: [PATCH 7/9] Remove unneccesary newline --- packages/website/docs/Language.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/website/docs/Language.mdx b/packages/website/docs/Language.mdx index 4a3c8883..51d0bab2 100644 --- a/packages/website/docs/Language.mdx +++ b/packages/website/docs/Language.mdx @@ -9,7 +9,6 @@ import { SquiggleEditor } from '../src/components/SquiggleEditor' The squiggle language has a very simply syntax. The best way to get to understand it is by simply looking at examples. - ## Basic Language As an example: From 4a62681209ee7011d82c5386b196807f2275844e Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 25 Mar 2022 08:13:56 -0400 Subject: [PATCH 8/9] Cleanup to documentation, changes to distribution colors --- .../components/src/spec-distributions.json | 3 +- packages/squiggle-lang/README.md | 6 ++++ packages/squiggle-lang/package.json | 2 +- packages/website/babel.config.js | 5 ++- packages/website/docs/Functions.mdx | 31 +++++++++--------- packages/website/docs/Future-Features.md | 32 +++++++++---------- packages/website/docs/Language.mdx | 2 +- 7 files changed, 43 insertions(+), 38 deletions(-) diff --git a/packages/components/src/spec-distributions.json b/packages/components/src/spec-distributions.json index cd842c81..a5e0bc14 100644 --- a/packages/components/src/spec-distributions.json +++ b/packages/components/src/spec-distributions.json @@ -84,7 +84,8 @@ "y": { "scale": "yscale", "field": "y" }, "y2": { "scale": "yscale", "value": 0 }, "fill": { - "signal": "{gradient: 'linear', x1: 1, y1: 1, x2: 0, y2: 1, stops: [ {offset: 0.0, color: 'steelblue'}, {offset: clamp(mousex, 0, 1), color: 'steelblue'}, {offset: clamp(mousex, 0, 1), color: 'blue'}, {offset: 1.0, color: 'blue'} ] }" + "signal": "{gradient: 'linear', x1: 1, y1: 1, x2: 0, y2: 1, stops: [ {offset: 0.0, color: '#11ac8f'}, {offset: clamp(mousex, 0, 1), color: '#11ac8f'}, {offset: clamp(mousex, 0, 1), color: '#1b6fac'}, {offset: 1.0, color: '#1b6fac'} ] }", + "color": "#000" }, "interpolate": { "value": "monotone" }, "fillOpacity": { "value": 1 } diff --git a/packages/squiggle-lang/README.md b/packages/squiggle-lang/README.md index 5d78f096..a7d0d5d0 100644 --- a/packages/squiggle-lang/README.md +++ b/packages/squiggle-lang/README.md @@ -81,3 +81,9 @@ complicated, as it has to return either a number, or a distribution, or even a representation of a function of distributions. Currently the export is simply the generated type that rescript creates, and can be quite confusing. We therefore highly recommend the use of typescript when creating tests or using this package. + +## Potential Issues +If you experiment with generating different types of .gen.ts files and similar, note that they won't be caught by git (because they are in .gitignore). Make sure you delete these extra files, once they are unecessary. +``` + rm src/rescript/**/*.gen.ts +``` \ No newline at end of file diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 3b97c854..582146b7 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -9,7 +9,7 @@ "clean": "rescript clean", "test": "jest", "test:watch": "jest --watchAll", - "all": "yarn build && yarn bundle && yarn test" + "all": "yarn build && yarn bundle && yarn test", }, "keywords": [ "Rescript" diff --git a/packages/website/babel.config.js b/packages/website/babel.config.js index 0bf9a1b9..0894ee0f 100644 --- a/packages/website/babel.config.js +++ b/packages/website/babel.config.js @@ -1,7 +1,6 @@ module.exports = { presets: [ - require.resolve('@docusaurus/core/lib/babel/preset'), - ["@babel/preset-react", {"runtime": "automatic"}] - + require.resolve('@docusaurus/core/lib/babel/preset'), + ["@babel/preset-react", { "runtime": "automatic" }] ], }; diff --git a/packages/website/docs/Functions.mdx b/packages/website/docs/Functions.mdx index ff2e393a..b2adab45 100644 --- a/packages/website/docs/Functions.mdx +++ b/packages/website/docs/Functions.mdx @@ -13,14 +13,14 @@ import { SquiggleEditor } from '../src/components/SquiggleEditor' The `normal(mean, sd)` function creates a normal distribution with the given mean and standard deviation. - + ### Uniform distribution The `uniform(low, high)` function creates a uniform distribution between the -two given numbers: +two given numbers. - + ### Lognormal distribution @@ -29,18 +29,18 @@ The `lognormal(mu, sigma)` returns the log of a normal distribution with paramet mu and sigma. The log of lognormal(mu, sigma) is a normal distribution with parameters mean mu and standard deviation sigma. - + An alternative format is also available. The "to" notation creates a lognormal distribution with a 90% confidence interval between the two numbers. We add -this convinience as lognormal distributions are commonly used in practice +this convinience as lognormal distributions are commonly used in practice. Furthermore, it's also possible to create a lognormal from it's actual mean -and standard deviation, using `lognormalFromMeanAndStdDev`: +and standard deviation, using `lognormalFromMeanAndStdDev`. - + ### Beta distribution @@ -60,7 +60,7 @@ mean. ### The Triangular distribution The `triangular(a,b,c)` function creates a triangular distribution with lower -bound a, mode b and upper bound c: +bound a, mode b and upper bound c. @@ -73,43 +73,42 @@ combination. -It's possible to create discrete distributions using this method: +It's possible to create discrete distributions using this method. As well as mixed distributions: - + ## Other Functions ### PDF of a distribution The `pdf(distribution, x)` function returns the density of a distribution at the -given point x: - +given point x. ### Inverse of a distribution The `inv(distribution, prob)` gives the value x or which the probability for all values -lower than x is equal to prob. It is the inverse of `cdf` +lower than x is equal to prob. It is the inverse of `cdf`. ### CDF of a distribution The `cdf(distribution,x)` gives the cumulative probability of the distribution -or all values lower than x. It is the inverse of `inv`: +or all values lower than x. It is the inverse of `inv`. ### Mean of a distribution -The `mean(distribution)` function gives the mean (expected value) of a distribution: +The `mean(distribution)` function gives the mean (expected value) of a distribution. ### Sampling a distribution -The `sample(distribution)` samples a given distribution: +The `sample(distribution)` samples a given distribution. diff --git a/packages/website/docs/Future-Features.md b/packages/website/docs/Future-Features.md index 6370602e..a479ddd2 100644 --- a/packages/website/docs/Future-Features.md +++ b/packages/website/docs/Future-Features.md @@ -77,33 +77,33 @@ Right now, Monte Carlo simulations are totally random. It would be nicer to be a - Possibly a decent web GUI (a much more advanced playground). - A VS Code extention and similar. -## Fixes +## Bugs - Discrete distributions are particularly buggy. Try ``mm(1,2,3,4,5,6,7,8,9,10) .* (5 to 8)`` ## New Functions ### Distributions -``` -cauchy() //todo -pareto() //todo -metalog() //todo +```js +cauchy() +pareto() +metalog() ``` Possibly change mm to mix, or mx(). Also, change input format, maybe to mx([a,b,c], [a,b,c]). ### Functions -``` -samples(distribution, n) //todo -toPdf(distribution) //todo -toCdf(distribution) //todo -toHash(distribution) //todo. Make hash of content, like, {xs:[], ys:[]} -trunctate(distribution, leftValue, rightValue) //todo -leftTrunctate(distribution, leftValue) //todo -rightTrunctate(distribution, rightValue) //todo -distributionFromSamples(array, params) //todo -distributionFromPoints() //todo -distributionFromHash() //todo +```js +samples(distribution, n) +toPdf(distribution) +toCdf(distribution) +toHash(distribution) +trunctate(distribution, leftValue, rightValue) +leftTrunctate(distribution, leftValue) +rightTrunctate(distribution, rightValue) +distributionFromSamples(array, params) +distributionFromPoints() +distributionFromHash() ``` diff --git a/packages/website/docs/Language.mdx b/packages/website/docs/Language.mdx index 51d0bab2..221bd4b5 100644 --- a/packages/website/docs/Language.mdx +++ b/packages/website/docs/Language.mdx @@ -6,7 +6,7 @@ import { SquiggleEditor } from '../src/components/SquiggleEditor' # Squiggle Language -The squiggle language has a very simply syntax. The best way to get to understand +The squiggle language has a very simple syntax. The best way to get to understand it is by simply looking at examples. ## Basic Language From 6903680e1a4739a4c3e304206b2e980302b95b36 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 25 Mar 2022 08:14:53 -0400 Subject: [PATCH 9/9] Minor fix for package.json --- packages/squiggle-lang/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 582146b7..3b97c854 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -9,7 +9,7 @@ "clean": "rescript clean", "test": "jest", "test:watch": "jest --watchAll", - "all": "yarn build && yarn bundle && yarn test", + "all": "yarn build && yarn bundle && yarn test" }, "keywords": [ "Rescript"