Merge branch 'develop' into vscode
* develop: fix SquigglePlayground in storybook Ran formatter Added scaleMultiply to docs Added scaleMultiply useSquiggle and useSquigglePartial hooks v0.2.11 fix: Make lodash a dependency, rather than a dev dependency Ran formatting Normalize after trunctae Ran formatter Added descriptions to last API types Fixed link that was breaking build Small edits to guides section More progress on DistGeneric Ran format Added key math variables, all lowercase Removed the definitions tags in documentation Minor cleanup on distributions Lots of documentation tweaks
This commit is contained in:
commit
0bd407d3f4
|
@ -1,5 +1,5 @@
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React, { FC } from "react";
|
import React, { FC, useMemo } from "react";
|
||||||
import AceEditor from "react-ace";
|
import AceEditor from "react-ace";
|
||||||
|
|
||||||
import "ace-builds/src-noconflict/mode-golang";
|
import "ace-builds/src-noconflict/mode-golang";
|
||||||
|
@ -21,14 +21,15 @@ export const CodeEditor: FC<CodeEditorProps> = ({
|
||||||
showGutter = false,
|
showGutter = false,
|
||||||
height,
|
height,
|
||||||
}) => {
|
}) => {
|
||||||
let lineCount = value.split("\n").length;
|
const lineCount = value.split("\n").length;
|
||||||
let id = _.uniqueId();
|
const id = useMemo(() => _.uniqueId(), []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AceEditor
|
<AceEditor
|
||||||
value={value}
|
value={value}
|
||||||
mode="golang"
|
mode="golang"
|
||||||
theme="github"
|
theme="github"
|
||||||
width={"100%"}
|
width="100%"
|
||||||
fontSize={14}
|
fontSize={14}
|
||||||
height={String(height) + "px"}
|
height={String(height) + "px"}
|
||||||
minLines={oneLine ? lineCount : undefined}
|
minLines={oneLine ? lineCount : undefined}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import {
|
||||||
run,
|
|
||||||
errorValueToString,
|
|
||||||
squiggleExpression,
|
squiggleExpression,
|
||||||
bindings,
|
bindings,
|
||||||
environment,
|
environment,
|
||||||
|
@ -9,253 +7,11 @@ import {
|
||||||
defaultImports,
|
defaultImports,
|
||||||
defaultBindings,
|
defaultBindings,
|
||||||
defaultEnvironment,
|
defaultEnvironment,
|
||||||
declaration,
|
|
||||||
} from "@quri/squiggle-lang";
|
} from "@quri/squiggle-lang";
|
||||||
import { NumberShower } from "./NumberShower";
|
import { FunctionChartSettings } from "./FunctionChart";
|
||||||
import { DistributionChart } from "./DistributionChart";
|
import { useSquiggle } from "../lib/hooks";
|
||||||
import { ErrorAlert } from "./Alert";
|
import { SquiggleErrorAlert } from "./SquiggleErrorAlert";
|
||||||
import { FunctionChart, FunctionChartSettings } from "./FunctionChart";
|
import { SquiggleItem } from "./SquiggleItem";
|
||||||
|
|
||||||
function getRange<a>(x: declaration<a>) {
|
|
||||||
let first = x.args[0];
|
|
||||||
switch (first.tag) {
|
|
||||||
case "Float": {
|
|
||||||
return { floats: { min: first.value.min, max: first.value.max } };
|
|
||||||
}
|
|
||||||
case "Date": {
|
|
||||||
return { time: { min: first.value.min, max: first.value.max } };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getChartSettings<a>(x: declaration<a>): FunctionChartSettings {
|
|
||||||
let range = getRange(x);
|
|
||||||
let min = range.floats ? range.floats.min : 0;
|
|
||||||
let max = range.floats ? range.floats.max : 10;
|
|
||||||
return {
|
|
||||||
start: min,
|
|
||||||
stop: max,
|
|
||||||
count: 20,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface VariableBoxProps {
|
|
||||||
heading: string;
|
|
||||||
children: React.ReactNode;
|
|
||||||
showTypes: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const VariableBox: React.FC<VariableBoxProps> = ({
|
|
||||||
heading = "Error",
|
|
||||||
children,
|
|
||||||
showTypes = false,
|
|
||||||
}) => {
|
|
||||||
if (showTypes) {
|
|
||||||
return (
|
|
||||||
<div className="bg-white border border-grey-200 m-2">
|
|
||||||
<div className="border-b border-grey-200 p-3">
|
|
||||||
<header className="font-mono">{heading}</header>
|
|
||||||
</div>
|
|
||||||
<div className="p-3">{children}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return <div>{children}</div>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface SquiggleItemProps {
|
|
||||||
/** The input string for squiggle */
|
|
||||||
expression: squiggleExpression;
|
|
||||||
width?: number;
|
|
||||||
height: number;
|
|
||||||
/** Whether to show a summary of statistics for distributions */
|
|
||||||
showSummary: boolean;
|
|
||||||
/** Whether to show type information */
|
|
||||||
showTypes: boolean;
|
|
||||||
/** Whether to show users graph controls (scale etc) */
|
|
||||||
showControls: boolean;
|
|
||||||
/** Settings for displaying functions */
|
|
||||||
chartSettings: FunctionChartSettings;
|
|
||||||
/** Environment for further function executions */
|
|
||||||
environment: environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SquiggleItem: React.FC<SquiggleItemProps> = ({
|
|
||||||
expression,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
showSummary,
|
|
||||||
showTypes = false,
|
|
||||||
showControls = false,
|
|
||||||
chartSettings,
|
|
||||||
environment,
|
|
||||||
}) => {
|
|
||||||
switch (expression.tag) {
|
|
||||||
case "number":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Number" showTypes={showTypes}>
|
|
||||||
<div className="font-semibold text-slate-600">
|
|
||||||
<NumberShower precision={3} number={expression.value} />
|
|
||||||
</div>
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "distribution": {
|
|
||||||
let distType = expression.value.type();
|
|
||||||
return (
|
|
||||||
<VariableBox
|
|
||||||
heading={`Distribution (${distType})`}
|
|
||||||
showTypes={showTypes}
|
|
||||||
>
|
|
||||||
{distType === "Symbolic" && showTypes ? (
|
|
||||||
<div>{expression.value.toString()}</div>
|
|
||||||
) : null}
|
|
||||||
<DistributionChart
|
|
||||||
distribution={expression.value}
|
|
||||||
height={height}
|
|
||||||
width={width}
|
|
||||||
showSummary={showSummary}
|
|
||||||
showControls={showControls}
|
|
||||||
/>
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "string":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="String" showTypes={showTypes}>
|
|
||||||
<span className="text-slate-400">"</span>
|
|
||||||
<span className="text-slate-600 font-semibold">
|
|
||||||
{expression.value}
|
|
||||||
</span>
|
|
||||||
<span className="text-slate-400">"</span>
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "boolean":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Boolean" showTypes={showTypes}>
|
|
||||||
{expression.value.toString()}
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "symbol":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Symbol" showTypes={showTypes}>
|
|
||||||
<span className="text-slate-500 mr-2">Undefined Symbol:</span>
|
|
||||||
<span className="text-slate-600">{expression.value}</span>
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "call":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Call" showTypes={showTypes}>
|
|
||||||
{expression.value}
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "array":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Array" showTypes={showTypes}>
|
|
||||||
{expression.value.map((r, i) => (
|
|
||||||
<div key={i} className="flex pt-1">
|
|
||||||
<div className="flex-none bg-slate-100 rounded-sm px-1">
|
|
||||||
<header className="text-slate-400 font-mono">{i}</header>
|
|
||||||
</div>
|
|
||||||
<div className="px-2 mb-2 grow">
|
|
||||||
<SquiggleItem
|
|
||||||
key={i}
|
|
||||||
expression={r}
|
|
||||||
width={width !== undefined ? width - 20 : width}
|
|
||||||
height={50}
|
|
||||||
showTypes={showTypes}
|
|
||||||
showControls={showControls}
|
|
||||||
chartSettings={chartSettings}
|
|
||||||
environment={environment}
|
|
||||||
showSummary={showSummary}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "record":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Record" showTypes={showTypes}>
|
|
||||||
<div className="space-y-3">
|
|
||||||
{Object.entries(expression.value).map(([key, r]) => (
|
|
||||||
<div key={key} className="flex space-x-2">
|
|
||||||
<div className="flex-none">
|
|
||||||
<header className="text-slate-500 font-mono">{key}:</header>
|
|
||||||
</div>
|
|
||||||
<div className="px-2 grow bg-gray-50 border border-gray-100 rounded-sm">
|
|
||||||
<SquiggleItem
|
|
||||||
expression={r}
|
|
||||||
width={width !== undefined ? width - 20 : width}
|
|
||||||
height={height / 3}
|
|
||||||
showTypes={showTypes}
|
|
||||||
showSummary={showSummary}
|
|
||||||
showControls={showControls}
|
|
||||||
chartSettings={chartSettings}
|
|
||||||
environment={environment}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "arraystring":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Array String" showTypes={showTypes}>
|
|
||||||
{expression.value.map((r) => `"${r}"`).join(", ")}
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "date":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Date" showTypes={showTypes}>
|
|
||||||
{expression.value.toDateString()}
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "timeDuration": {
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Time Duration" showTypes={showTypes}>
|
|
||||||
<NumberShower precision={3} number={expression.value} />
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "lambda":
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Function" showTypes={showTypes}>
|
|
||||||
<div className="text-amber-700 bg-amber-100 rounded-md font-mono p-1 pl-2 mb-3 mt-1 text-sm">{`function(${expression.value.parameters.join(
|
|
||||||
","
|
|
||||||
)})`}</div>
|
|
||||||
<FunctionChart
|
|
||||||
fn={expression.value}
|
|
||||||
chartSettings={chartSettings}
|
|
||||||
height={height}
|
|
||||||
environment={{
|
|
||||||
sampleCount: environment.sampleCount / 10,
|
|
||||||
xyPointLength: environment.xyPointLength / 10,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
case "lambdaDeclaration": {
|
|
||||||
return (
|
|
||||||
<VariableBox heading="Function Declaration" showTypes={showTypes}>
|
|
||||||
<FunctionChart
|
|
||||||
fn={expression.value.fn}
|
|
||||||
chartSettings={getChartSettings(expression.value)}
|
|
||||||
height={height}
|
|
||||||
environment={{
|
|
||||||
sampleCount: environment.sampleCount / 10,
|
|
||||||
xyPointLength: environment.xyPointLength / 10,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</VariableBox>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return <>Should be unreachable</>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface SquiggleChartProps {
|
export interface SquiggleChartProps {
|
||||||
/** The input string for squiggle */
|
/** The input string for squiggle */
|
||||||
|
@ -266,8 +22,8 @@ export interface SquiggleChartProps {
|
||||||
environment?: environment;
|
environment?: environment;
|
||||||
/** If the result is a function, where the function starts, ends and the amount of stops */
|
/** If the result is a function, where the function starts, ends and the amount of stops */
|
||||||
chartSettings?: FunctionChartSettings;
|
chartSettings?: FunctionChartSettings;
|
||||||
/** When the environment changes */
|
/** When the squiggle code gets reevaluated */
|
||||||
onChange?(expr: squiggleExpression): void;
|
onChange?(expr: squiggleExpression | undefined): void;
|
||||||
/** CSS width of the element */
|
/** CSS width of the element */
|
||||||
width?: number;
|
width?: number;
|
||||||
height?: number;
|
height?: number;
|
||||||
|
@ -275,7 +31,7 @@ export interface SquiggleChartProps {
|
||||||
bindings?: bindings;
|
bindings?: bindings;
|
||||||
/** JS imported parameters */
|
/** JS imported parameters */
|
||||||
jsImports?: jsImports;
|
jsImports?: jsImports;
|
||||||
/** Whether to show a summary of the distirbution */
|
/** Whether to show a summary of the distribution */
|
||||||
showSummary?: boolean;
|
showSummary?: boolean;
|
||||||
/** Whether to show type information about returns, default false */
|
/** Whether to show type information about returns, default false */
|
||||||
showTypes?: boolean;
|
showTypes?: boolean;
|
||||||
|
@ -283,12 +39,13 @@ export interface SquiggleChartProps {
|
||||||
showControls?: boolean;
|
showControls?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultOnChange = () => {};
|
||||||
const defaultChartSettings = { start: 0, stop: 10, count: 20 };
|
const defaultChartSettings = { start: 0, stop: 10, count: 20 };
|
||||||
|
|
||||||
export const SquiggleChart: React.FC<SquiggleChartProps> = ({
|
export const SquiggleChart: React.FC<SquiggleChartProps> = ({
|
||||||
squiggleString = "",
|
squiggleString = "",
|
||||||
environment,
|
environment,
|
||||||
onChange = () => {},
|
onChange = defaultOnChange, // defaultOnChange must be constant, don't move its definition here
|
||||||
height = 200,
|
height = 200,
|
||||||
bindings = defaultBindings,
|
bindings = defaultBindings,
|
||||||
jsImports = defaultImports,
|
jsImports = defaultImports,
|
||||||
|
@ -298,28 +55,28 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
|
||||||
showControls = false,
|
showControls = false,
|
||||||
chartSettings = defaultChartSettings,
|
chartSettings = defaultChartSettings,
|
||||||
}) => {
|
}) => {
|
||||||
let expressionResult = run(squiggleString, bindings, environment, jsImports);
|
const { result } = useSquiggle({
|
||||||
if (expressionResult.tag !== "Ok") {
|
code: squiggleString,
|
||||||
return (
|
bindings,
|
||||||
<ErrorAlert heading={"Parse Error"}>
|
environment,
|
||||||
{errorValueToString(expressionResult.value)}
|
jsImports,
|
||||||
</ErrorAlert>
|
onChange,
|
||||||
);
|
});
|
||||||
|
|
||||||
|
if (result.tag !== "Ok") {
|
||||||
|
return <SquiggleErrorAlert error={result.value} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
let e = environment ?? defaultEnvironment;
|
|
||||||
let expression = expressionResult.value;
|
|
||||||
onChange(expression);
|
|
||||||
return (
|
return (
|
||||||
<SquiggleItem
|
<SquiggleItem
|
||||||
expression={expression}
|
expression={result.value}
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
showSummary={showSummary}
|
showSummary={showSummary}
|
||||||
showTypes={showTypes}
|
showTypes={showTypes}
|
||||||
showControls={showControls}
|
showControls={showControls}
|
||||||
chartSettings={chartSettings}
|
chartSettings={chartSettings}
|
||||||
environment={e}
|
environment={environment ?? defaultEnvironment}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,39 +1,51 @@
|
||||||
import * as React from "react";
|
import React, { useState } from "react";
|
||||||
import * as ReactDOM from "react-dom";
|
import * as ReactDOM from "react-dom";
|
||||||
import { SquiggleChart } from "./SquiggleChart";
|
|
||||||
import { CodeEditor } from "./CodeEditor";
|
import { CodeEditor } from "./CodeEditor";
|
||||||
import type {
|
import {
|
||||||
squiggleExpression,
|
squiggleExpression,
|
||||||
environment,
|
environment,
|
||||||
bindings,
|
bindings,
|
||||||
jsImports,
|
jsImports,
|
||||||
|
defaultEnvironment,
|
||||||
} from "@quri/squiggle-lang";
|
} from "@quri/squiggle-lang";
|
||||||
import {
|
import { defaultImports, defaultBindings } from "@quri/squiggle-lang";
|
||||||
runPartial,
|
|
||||||
errorValueToString,
|
|
||||||
defaultImports,
|
|
||||||
defaultBindings,
|
|
||||||
} from "@quri/squiggle-lang";
|
|
||||||
import { ErrorAlert } from "./Alert";
|
|
||||||
import { SquiggleContainer } from "./SquiggleContainer";
|
import { SquiggleContainer } from "./SquiggleContainer";
|
||||||
|
import { useSquiggle, useSquigglePartial } from "../lib/hooks";
|
||||||
|
import { SquiggleErrorAlert } from "./SquiggleErrorAlert";
|
||||||
|
import { SquiggleItem } from "./SquiggleItem";
|
||||||
|
|
||||||
|
const WrappedCodeEditor: React.FC<{
|
||||||
|
code: string;
|
||||||
|
setCode: (code: string) => void;
|
||||||
|
}> = ({ code, setCode }) => (
|
||||||
|
<div className="border border-grey-200 p-2 m-4">
|
||||||
|
<CodeEditor
|
||||||
|
value={code}
|
||||||
|
onChange={setCode}
|
||||||
|
oneLine={true}
|
||||||
|
showGutter={false}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
export interface SquiggleEditorProps {
|
export interface SquiggleEditorProps {
|
||||||
/** The input string for squiggle */
|
/** The input string for squiggle */
|
||||||
initialSquiggleString?: string;
|
initialSquiggleString?: string;
|
||||||
/** If the output requires monte carlo sampling, the amount of samples */
|
/** The width of the element */
|
||||||
environment?: environment;
|
width?: number;
|
||||||
/** If the result is a function, where the function starts */
|
/** If the result is a function, where the function starts */
|
||||||
diagramStart?: number;
|
diagramStart?: number;
|
||||||
/** If the result is a function, where the function ends */
|
/** If the result is a function, where the function ends */
|
||||||
diagramStop?: number;
|
diagramStop?: number;
|
||||||
/** If the result is a function, how many points along the function it samples */
|
/** If the result is a function, how many points along the function it samples */
|
||||||
diagramCount?: number;
|
diagramCount?: number;
|
||||||
/** when the environment changes. Used again for notebook magic*/
|
/** When the environment changes. Used again for notebook magic */
|
||||||
onChange?(expr: squiggleExpression): void;
|
onChange?(expr: squiggleExpression | undefined): void;
|
||||||
/** The width of the element */
|
|
||||||
width?: number;
|
|
||||||
/** Previous variable declarations */
|
/** Previous variable declarations */
|
||||||
bindings?: bindings;
|
bindings?: bindings;
|
||||||
|
/** If the output requires monte carlo sampling, the amount of samples */
|
||||||
|
environment?: environment;
|
||||||
/** JS Imports */
|
/** JS Imports */
|
||||||
jsImports?: jsImports;
|
jsImports?: jsImports;
|
||||||
/** Whether to show detail about types of the returns, default false */
|
/** Whether to show detail about types of the returns, default false */
|
||||||
|
@ -44,169 +56,109 @@ export interface SquiggleEditorProps {
|
||||||
showSummary?: boolean;
|
showSummary?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export let SquiggleEditor: React.FC<SquiggleEditorProps> = ({
|
export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
|
||||||
initialSquiggleString = "",
|
initialSquiggleString = "",
|
||||||
width,
|
width,
|
||||||
environment,
|
|
||||||
diagramStart = 0,
|
diagramStart = 0,
|
||||||
diagramStop = 10,
|
diagramStop = 10,
|
||||||
diagramCount = 20,
|
diagramCount = 20,
|
||||||
onChange,
|
onChange,
|
||||||
bindings = defaultBindings,
|
bindings = defaultBindings,
|
||||||
|
environment,
|
||||||
jsImports = defaultImports,
|
jsImports = defaultImports,
|
||||||
showTypes = false,
|
showTypes = false,
|
||||||
showControls = false,
|
showControls = false,
|
||||||
showSummary = false,
|
showSummary = false,
|
||||||
}: SquiggleEditorProps) => {
|
}: SquiggleEditorProps) => {
|
||||||
const [expression, setExpression] = React.useState(initialSquiggleString);
|
const [code, setCode] = useState(initialSquiggleString);
|
||||||
|
|
||||||
|
const { result, observableRef } = useSquiggle({
|
||||||
|
code,
|
||||||
|
bindings,
|
||||||
|
environment,
|
||||||
|
jsImports,
|
||||||
|
onChange,
|
||||||
|
});
|
||||||
|
|
||||||
const chartSettings = {
|
const chartSettings = {
|
||||||
start: diagramStart,
|
start: diagramStart,
|
||||||
stop: diagramStop,
|
stop: diagramStop,
|
||||||
count: diagramCount,
|
count: diagramCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div ref={observableRef}>
|
||||||
<SquiggleContainer>
|
<SquiggleContainer>
|
||||||
<div>
|
<WrappedCodeEditor code={code} setCode={setCode} />
|
||||||
<div className="border border-grey-200 p-2 m-4">
|
{result.tag === "Ok" ? (
|
||||||
<CodeEditor
|
<SquiggleItem
|
||||||
value={expression}
|
expression={result.value}
|
||||||
onChange={setExpression}
|
|
||||||
oneLine={true}
|
|
||||||
showGutter={false}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<SquiggleChart
|
|
||||||
width={width}
|
width={width}
|
||||||
environment={environment}
|
height={200}
|
||||||
squiggleString={expression}
|
showSummary={showSummary}
|
||||||
chartSettings={chartSettings}
|
|
||||||
onChange={onChange}
|
|
||||||
bindings={bindings}
|
|
||||||
jsImports={jsImports}
|
|
||||||
showTypes={showTypes}
|
showTypes={showTypes}
|
||||||
showControls={showControls}
|
showControls={showControls}
|
||||||
showSummary={showSummary}
|
chartSettings={chartSettings}
|
||||||
|
environment={environment ?? defaultEnvironment}
|
||||||
/>
|
/>
|
||||||
</div>
|
) : (
|
||||||
|
<SquiggleErrorAlert error={result.value} />
|
||||||
|
)}
|
||||||
</SquiggleContainer>
|
</SquiggleContainer>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function renderSquiggleEditorToDom(props: SquiggleEditorProps) {
|
export function renderSquiggleEditorToDom(props: SquiggleEditorProps) {
|
||||||
let parent = document.createElement("div");
|
const parent = document.createElement("div");
|
||||||
ReactDOM.render(
|
ReactDOM.render(<SquiggleEditor {...props} />, parent);
|
||||||
<SquiggleEditor
|
|
||||||
{...props}
|
|
||||||
onChange={(expr) => {
|
|
||||||
// Typescript complains on two levels here.
|
|
||||||
// - Div elements don't have a value property
|
|
||||||
// - Even if it did (like it was an input element), it would have to
|
|
||||||
// be a string
|
|
||||||
//
|
|
||||||
// Which are reasonable in most web contexts.
|
|
||||||
//
|
|
||||||
// However we're using observable, neither of those things have to be
|
|
||||||
// true there. div elements can contain the value property, and can have
|
|
||||||
// the value be any datatype they wish.
|
|
||||||
//
|
|
||||||
// This is here to get the 'viewof' part of:
|
|
||||||
// viewof env = cell('normal(0,1)')
|
|
||||||
// to work
|
|
||||||
// @ts-ignore
|
|
||||||
parent.value = expr;
|
|
||||||
|
|
||||||
parent.dispatchEvent(new CustomEvent("input"));
|
|
||||||
if (props.onChange) props.onChange(expr);
|
|
||||||
}}
|
|
||||||
/>,
|
|
||||||
parent
|
|
||||||
);
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SquigglePartialProps {
|
export interface SquigglePartialProps {
|
||||||
/** The input string for squiggle */
|
/** The input string for squiggle */
|
||||||
initialSquiggleString?: string;
|
initialSquiggleString?: string;
|
||||||
/** If the output requires monte carlo sampling, the amount of samples */
|
|
||||||
environment?: environment;
|
|
||||||
/** If the result is a function, where the function starts */
|
|
||||||
diagramStart?: number;
|
|
||||||
/** If the result is a function, where the function ends */
|
|
||||||
diagramStop?: number;
|
|
||||||
/** If the result is a function, how many points along the function it samples */
|
|
||||||
diagramCount?: number;
|
|
||||||
/** when the environment changes. Used again for notebook magic*/
|
/** when the environment changes. Used again for notebook magic*/
|
||||||
onChange?(expr: bindings): void;
|
onChange?(expr: bindings | undefined): void;
|
||||||
/** Previously declared variables */
|
/** Previously declared variables */
|
||||||
bindings?: bindings;
|
bindings?: bindings;
|
||||||
|
/** If the output requires monte carlo sampling, the amount of samples */
|
||||||
|
environment?: environment;
|
||||||
/** Variables imported from js */
|
/** Variables imported from js */
|
||||||
jsImports?: jsImports;
|
jsImports?: jsImports;
|
||||||
/** Whether to give users access to graph controls */
|
|
||||||
showControls?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export let SquigglePartial: React.FC<SquigglePartialProps> = ({
|
export const SquigglePartial: React.FC<SquigglePartialProps> = ({
|
||||||
initialSquiggleString = "",
|
initialSquiggleString = "",
|
||||||
onChange,
|
onChange,
|
||||||
bindings = defaultBindings,
|
bindings = defaultBindings,
|
||||||
environment,
|
environment,
|
||||||
jsImports = defaultImports,
|
jsImports = defaultImports,
|
||||||
}: SquigglePartialProps) => {
|
}: SquigglePartialProps) => {
|
||||||
const [expression, setExpression] = React.useState(initialSquiggleString);
|
const [code, setCode] = useState(initialSquiggleString);
|
||||||
const [error, setError] = React.useState<string | null>(null);
|
|
||||||
|
|
||||||
const runSquiggleAndUpdateBindings = () => {
|
const { result, observableRef } = useSquigglePartial({
|
||||||
const squiggleResult = runPartial(
|
code,
|
||||||
expression,
|
|
||||||
bindings,
|
bindings,
|
||||||
environment,
|
environment,
|
||||||
jsImports
|
jsImports,
|
||||||
);
|
onChange,
|
||||||
if (squiggleResult.tag === "Ok") {
|
});
|
||||||
if (onChange) onChange(squiggleResult.value);
|
|
||||||
setError(null);
|
|
||||||
} else {
|
|
||||||
setError(errorValueToString(squiggleResult.value));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(runSquiggleAndUpdateBindings, [expression]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div ref={observableRef}>
|
||||||
<SquiggleContainer>
|
<SquiggleContainer>
|
||||||
<div>
|
<WrappedCodeEditor code={code} setCode={setCode} />
|
||||||
<div className="border border-grey-200 p-2 m-4">
|
{result.tag !== "Ok" ? (
|
||||||
<CodeEditor
|
<SquiggleErrorAlert error={result.value} />
|
||||||
value={expression}
|
|
||||||
onChange={setExpression}
|
|
||||||
oneLine={true}
|
|
||||||
showGutter={false}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{error !== null ? (
|
|
||||||
<ErrorAlert heading="Error">{error}</ErrorAlert>
|
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
|
||||||
</SquiggleContainer>
|
</SquiggleContainer>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function renderSquigglePartialToDom(props: SquigglePartialProps) {
|
export function renderSquigglePartialToDom(props: SquigglePartialProps) {
|
||||||
let parent = document.createElement("div");
|
const parent = document.createElement("div");
|
||||||
ReactDOM.render(
|
ReactDOM.render(<SquigglePartial {...props} />, parent);
|
||||||
<SquigglePartial
|
|
||||||
{...props}
|
|
||||||
onChange={(bindings) => {
|
|
||||||
// @ts-ignore
|
|
||||||
parent.value = bindings;
|
|
||||||
|
|
||||||
parent.dispatchEvent(new CustomEvent("input"));
|
|
||||||
if (props.onChange) props.onChange(bindings);
|
|
||||||
}}
|
|
||||||
/>,
|
|
||||||
parent
|
|
||||||
);
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
11
packages/components/src/components/SquiggleErrorAlert.tsx
Normal file
11
packages/components/src/components/SquiggleErrorAlert.tsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { errorValue, errorValueToString } from "@quri/squiggle-lang";
|
||||||
|
import React from "react";
|
||||||
|
import { ErrorAlert } from "./Alert";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
error: errorValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SquiggleErrorAlert: React.FC<Props> = ({ error }) => {
|
||||||
|
return <ErrorAlert heading="Error">{errorValueToString(error)}</ErrorAlert>;
|
||||||
|
};
|
250
packages/components/src/components/SquiggleItem.tsx
Normal file
250
packages/components/src/components/SquiggleItem.tsx
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import {
|
||||||
|
squiggleExpression,
|
||||||
|
environment,
|
||||||
|
declaration,
|
||||||
|
} from "@quri/squiggle-lang";
|
||||||
|
import { NumberShower } from "./NumberShower";
|
||||||
|
import { DistributionChart } from "./DistributionChart";
|
||||||
|
import { FunctionChart, FunctionChartSettings } from "./FunctionChart";
|
||||||
|
|
||||||
|
function getRange<a>(x: declaration<a>) {
|
||||||
|
const first = x.args[0];
|
||||||
|
switch (first.tag) {
|
||||||
|
case "Float": {
|
||||||
|
return { floats: { min: first.value.min, max: first.value.max } };
|
||||||
|
}
|
||||||
|
case "Date": {
|
||||||
|
return { time: { min: first.value.min, max: first.value.max } };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChartSettings<a>(x: declaration<a>): FunctionChartSettings {
|
||||||
|
const range = getRange(x);
|
||||||
|
const min = range.floats ? range.floats.min : 0;
|
||||||
|
const max = range.floats ? range.floats.max : 10;
|
||||||
|
return {
|
||||||
|
start: min,
|
||||||
|
stop: max,
|
||||||
|
count: 20,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VariableBoxProps {
|
||||||
|
heading: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
showTypes: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const VariableBox: React.FC<VariableBoxProps> = ({
|
||||||
|
heading = "Error",
|
||||||
|
children,
|
||||||
|
showTypes = false,
|
||||||
|
}) => {
|
||||||
|
if (showTypes) {
|
||||||
|
return (
|
||||||
|
<div className="bg-white border border-grey-200 m-2">
|
||||||
|
<div className="border-b border-grey-200 p-3">
|
||||||
|
<header className="font-mono">{heading}</header>
|
||||||
|
</div>
|
||||||
|
<div className="p-3">{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <div>{children}</div>;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface SquiggleItemProps {
|
||||||
|
/** The input string for squiggle */
|
||||||
|
expression: squiggleExpression;
|
||||||
|
width?: number;
|
||||||
|
height: number;
|
||||||
|
/** Whether to show a summary of statistics for distributions */
|
||||||
|
showSummary: boolean;
|
||||||
|
/** Whether to show type information */
|
||||||
|
showTypes: boolean;
|
||||||
|
/** Whether to show users graph controls (scale etc) */
|
||||||
|
showControls: boolean;
|
||||||
|
/** Settings for displaying functions */
|
||||||
|
chartSettings: FunctionChartSettings;
|
||||||
|
/** Environment for further function executions */
|
||||||
|
environment: environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SquiggleItem: React.FC<SquiggleItemProps> = ({
|
||||||
|
expression,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
showSummary,
|
||||||
|
showTypes = false,
|
||||||
|
showControls = false,
|
||||||
|
chartSettings,
|
||||||
|
environment,
|
||||||
|
}) => {
|
||||||
|
switch (expression.tag) {
|
||||||
|
case "number":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Number" showTypes={showTypes}>
|
||||||
|
<div className="font-semibold text-slate-600">
|
||||||
|
<NumberShower precision={3} number={expression.value} />
|
||||||
|
</div>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "distribution": {
|
||||||
|
const distType = expression.value.type();
|
||||||
|
return (
|
||||||
|
<VariableBox
|
||||||
|
heading={`Distribution (${distType})`}
|
||||||
|
showTypes={showTypes}
|
||||||
|
>
|
||||||
|
{distType === "Symbolic" && showTypes ? (
|
||||||
|
<div>{expression.value.toString()}</div>
|
||||||
|
) : null}
|
||||||
|
<DistributionChart
|
||||||
|
distribution={expression.value}
|
||||||
|
height={height}
|
||||||
|
width={width}
|
||||||
|
showSummary={showSummary}
|
||||||
|
showControls={showControls}
|
||||||
|
/>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case "string":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="String" showTypes={showTypes}>
|
||||||
|
<span className="text-slate-400">"</span>
|
||||||
|
<span className="text-slate-600 font-semibold">
|
||||||
|
{expression.value}
|
||||||
|
</span>
|
||||||
|
<span className="text-slate-400">"</span>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "boolean":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Boolean" showTypes={showTypes}>
|
||||||
|
{expression.value.toString()}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "symbol":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Symbol" showTypes={showTypes}>
|
||||||
|
<span className="text-slate-500 mr-2">Undefined Symbol:</span>
|
||||||
|
<span className="text-slate-600">{expression.value}</span>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "call":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Call" showTypes={showTypes}>
|
||||||
|
{expression.value}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "array":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Array" showTypes={showTypes}>
|
||||||
|
{expression.value.map((r, i) => (
|
||||||
|
<div key={i} className="flex pt-1">
|
||||||
|
<div className="flex-none bg-slate-100 rounded-sm px-1">
|
||||||
|
<header className="text-slate-400 font-mono">{i}</header>
|
||||||
|
</div>
|
||||||
|
<div className="px-2 mb-2 grow">
|
||||||
|
<SquiggleItem
|
||||||
|
key={i}
|
||||||
|
expression={r}
|
||||||
|
width={width !== undefined ? width - 20 : width}
|
||||||
|
height={50}
|
||||||
|
showTypes={showTypes}
|
||||||
|
showControls={showControls}
|
||||||
|
chartSettings={chartSettings}
|
||||||
|
environment={environment}
|
||||||
|
showSummary={showSummary}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "record":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Record" showTypes={showTypes}>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{Object.entries(expression.value).map(([key, r]) => (
|
||||||
|
<div key={key} className="flex space-x-2">
|
||||||
|
<div className="flex-none">
|
||||||
|
<header className="text-slate-500 font-mono">{key}:</header>
|
||||||
|
</div>
|
||||||
|
<div className="px-2 grow bg-gray-50 border border-gray-100 rounded-sm">
|
||||||
|
<SquiggleItem
|
||||||
|
expression={r}
|
||||||
|
width={width !== undefined ? width - 20 : width}
|
||||||
|
height={height / 3}
|
||||||
|
showTypes={showTypes}
|
||||||
|
showSummary={showSummary}
|
||||||
|
showControls={showControls}
|
||||||
|
chartSettings={chartSettings}
|
||||||
|
environment={environment}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "arraystring":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Array String" showTypes={showTypes}>
|
||||||
|
{expression.value.map((r) => `"${r}"`).join(", ")}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "date":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Date" showTypes={showTypes}>
|
||||||
|
{expression.value.toDateString()}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "timeDuration": {
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Time Duration" showTypes={showTypes}>
|
||||||
|
<NumberShower precision={3} number={expression.value} />
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case "lambda":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Function" showTypes={showTypes}>
|
||||||
|
<div className="text-amber-700 bg-amber-100 rounded-md font-mono p-1 pl-2 mb-3 mt-1 text-sm">{`function(${expression.value.parameters.join(
|
||||||
|
","
|
||||||
|
)})`}</div>
|
||||||
|
<FunctionChart
|
||||||
|
fn={expression.value}
|
||||||
|
chartSettings={chartSettings}
|
||||||
|
height={height}
|
||||||
|
environment={{
|
||||||
|
sampleCount: environment.sampleCount / 10,
|
||||||
|
xyPointLength: environment.xyPointLength / 10,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "lambdaDeclaration": {
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Function Declaration" showTypes={showTypes}>
|
||||||
|
<FunctionChart
|
||||||
|
fn={expression.value.fn}
|
||||||
|
chartSettings={getChartSettings(expression.value)}
|
||||||
|
height={height}
|
||||||
|
environment={{
|
||||||
|
sampleCount: environment.sampleCount / 10,
|
||||||
|
xyPointLength: environment.xyPointLength / 10,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return <>Should be unreachable</>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -193,7 +193,7 @@ function Checkbox<T>({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SquigglePlayground: FC<PlaygroundProps> = ({
|
export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
initialSquiggleString = "",
|
initialSquiggleString = "",
|
||||||
height = 500,
|
height = 500,
|
||||||
showTypes = false,
|
showTypes = false,
|
||||||
|
@ -214,9 +214,9 @@ const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
sampleCount: 1000,
|
sampleCount: 1000,
|
||||||
xyPointLength: 1000,
|
xyPointLength: 1000,
|
||||||
chartHeight: 150,
|
chartHeight: 150,
|
||||||
showTypes: showTypes,
|
showTypes,
|
||||||
showControls: showControls,
|
showControls,
|
||||||
showSummary: showSummary,
|
showSummary,
|
||||||
leftSizePercent: 50,
|
leftSizePercent: 50,
|
||||||
showSettingsPage: false,
|
showSettingsPage: false,
|
||||||
diagramStart: 0,
|
diagramStart: 0,
|
||||||
|
@ -429,9 +429,9 @@ const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
height={vars.chartHeight}
|
height={vars.chartHeight}
|
||||||
showTypes={vars.showTypes}
|
showTypes={vars.showTypes}
|
||||||
showControls={vars.showControls}
|
showControls={vars.showControls}
|
||||||
|
showSummary={vars.showSummary}
|
||||||
bindings={defaultBindings}
|
bindings={defaultBindings}
|
||||||
jsImports={imports}
|
jsImports={imports}
|
||||||
showSummary={vars.showSummary}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -441,7 +441,6 @@ const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SquigglePlayground;
|
|
||||||
export function renderSquigglePlaygroundToDom(props: PlaygroundProps) {
|
export function renderSquigglePlaygroundToDom(props: PlaygroundProps) {
|
||||||
const parent = document.createElement("div");
|
const parent = document.createElement("div");
|
||||||
ReactDOM.render(<SquigglePlayground {...props} />, parent);
|
ReactDOM.render(<SquigglePlayground {...props} />, parent);
|
||||||
|
|
|
@ -6,7 +6,7 @@ export {
|
||||||
renderSquigglePartialToDom,
|
renderSquigglePartialToDom,
|
||||||
} from "./components/SquiggleEditor";
|
} from "./components/SquiggleEditor";
|
||||||
export {
|
export {
|
||||||
default as SquigglePlayground,
|
SquigglePlayground,
|
||||||
renderSquigglePlaygroundToDom,
|
renderSquigglePlaygroundToDom,
|
||||||
} from "./components/SquigglePlayground";
|
} from "./components/SquigglePlayground";
|
||||||
export { SquiggleContainer } from "./components/SquiggleContainer";
|
export { SquiggleContainer } from "./components/SquiggleContainer";
|
||||||
|
|
63
packages/components/src/lib/hooks.ts
Normal file
63
packages/components/src/lib/hooks.ts
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import {
|
||||||
|
bindings,
|
||||||
|
environment,
|
||||||
|
jsImports,
|
||||||
|
run,
|
||||||
|
runPartial,
|
||||||
|
} from "@quri/squiggle-lang";
|
||||||
|
import { useEffect, useMemo, useRef } from "react";
|
||||||
|
|
||||||
|
type SquiggleArgs<T extends ReturnType<typeof run | typeof runPartial>> = {
|
||||||
|
code: string;
|
||||||
|
bindings?: bindings;
|
||||||
|
jsImports?: jsImports;
|
||||||
|
environment?: environment;
|
||||||
|
onChange?: (expr: Extract<T, { tag: "Ok" }>["value"] | undefined) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useSquiggleAny = <T extends ReturnType<typeof run | typeof runPartial>>(
|
||||||
|
args: SquiggleArgs<T>,
|
||||||
|
f: (...args: Parameters<typeof run>) => T
|
||||||
|
) => {
|
||||||
|
// We're using observable, where div elements can have a `value` property:
|
||||||
|
// https://observablehq.com/@observablehq/introduction-to-views
|
||||||
|
//
|
||||||
|
// This is here to get the 'viewof' part of:
|
||||||
|
// viewof env = cell('normal(0,1)')
|
||||||
|
// to work
|
||||||
|
const ref = useRef<
|
||||||
|
HTMLDivElement & { value?: Extract<T, { tag: "Ok" }>["value"] }
|
||||||
|
>(null);
|
||||||
|
const result: T = useMemo<T>(
|
||||||
|
() => f(args.code, args.bindings, args.environment, args.jsImports),
|
||||||
|
[f, args.code, args.bindings, args.environment, args.jsImports]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ref.current) return;
|
||||||
|
ref.current.value = result.tag === "Ok" ? result.value : undefined;
|
||||||
|
|
||||||
|
ref.current.dispatchEvent(new CustomEvent("input"));
|
||||||
|
}, [result]);
|
||||||
|
|
||||||
|
const { onChange } = args;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onChange?.(result.tag === "Ok" ? result.value : undefined);
|
||||||
|
}, [result, onChange]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
result, // squiggleExpression or externalBindings
|
||||||
|
observableRef: ref, // can be passed to outermost <div> if you want to use your component as an observablehq's view
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSquigglePartial = (
|
||||||
|
args: SquiggleArgs<ReturnType<typeof runPartial>>
|
||||||
|
) => {
|
||||||
|
return useSquiggleAny(args, runPartial);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSquiggle = (args: SquiggleArgs<ReturnType<typeof run>>) => {
|
||||||
|
return useSquiggleAny(args, run);
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
import SquigglePlayground from "../components/SquigglePlayground";
|
import { SquigglePlayground } from "../components/SquigglePlayground";
|
||||||
import { Canvas, Meta, Story, Props } from "@storybook/addon-docs";
|
import { Canvas, Meta, Story, Props } from "@storybook/addon-docs";
|
||||||
|
|
||||||
<Meta title="Squiggle/SquigglePlayground" component={SquigglePlayground} />
|
<Meta title="Squiggle/SquigglePlayground" component={SquigglePlayground} />
|
||||||
|
|
|
@ -80,6 +80,7 @@ describe("eval on distribution functions", () => {
|
||||||
testEval("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
testEval("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
||||||
testEval("truncateRight(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
testEval("truncateRight(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
||||||
testEval("truncate(normal(5,2), 3, 8)", "Ok(Point Set Distribution)")
|
testEval("truncate(normal(5,2), 3, 8)", "Ok(Point Set Distribution)")
|
||||||
|
testEval("isNormalized(truncate(normal(5,2), 3, 8))", "Ok(true)")
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("exp", () => {
|
describe("exp", () => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@quri/squiggle-lang",
|
"name": "@quri/squiggle-lang",
|
||||||
"version": "0.2.9",
|
"version": "0.2.11",
|
||||||
"homepage": "https://squiggle-language.com",
|
"homepage": "https://squiggle-language.com",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -38,6 +38,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stdlib/stats": "^0.0.13",
|
"@stdlib/stats": "^0.0.13",
|
||||||
"jstat": "^1.9.5",
|
"jstat": "^1.9.5",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"mathjs": "^10.6.0",
|
"mathjs": "^10.6.0",
|
||||||
"pdfast": "^0.2.0",
|
"pdfast": "^0.2.0",
|
||||||
"rescript": "^9.1.4"
|
"rescript": "^9.1.4"
|
||||||
|
@ -53,7 +54,6 @@
|
||||||
"fast-check": "^2.25.0",
|
"fast-check": "^2.25.0",
|
||||||
"gentype": "^4.4.0",
|
"gentype": "^4.4.0",
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"moduleserve": "^0.9.1",
|
"moduleserve": "^0.9.1",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"peggy": "^2.0.1",
|
"peggy": "^2.0.1",
|
||||||
|
|
|
@ -182,6 +182,11 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
|
||||||
)
|
)
|
||||||
->E.R2.fmap(r => Dist(r))
|
->E.R2.fmap(r => Dist(r))
|
||||||
->OutputLocal.fromResult
|
->OutputLocal.fromResult
|
||||||
|
| ToDist(Scale(#Multiply, f)) =>
|
||||||
|
dist
|
||||||
|
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Multiply, ~f)
|
||||||
|
->E.R2.fmap(r => Dist(r))
|
||||||
|
->OutputLocal.fromResult
|
||||||
| ToDist(Scale(#Logarithm, f)) =>
|
| ToDist(Scale(#Logarithm, f)) =>
|
||||||
dist
|
dist
|
||||||
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Logarithm, ~f)
|
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Logarithm, ~f)
|
||||||
|
@ -298,6 +303,7 @@ module Constructors = {
|
||||||
let algebraicLogarithm = (~env, dist1, dist2) =>
|
let algebraicLogarithm = (~env, dist1, dist2) =>
|
||||||
C.algebraicLogarithm(dist1, dist2)->run(~env)->toDistR
|
C.algebraicLogarithm(dist1, dist2)->run(~env)->toDistR
|
||||||
let algebraicPower = (~env, dist1, dist2) => C.algebraicPower(dist1, dist2)->run(~env)->toDistR
|
let algebraicPower = (~env, dist1, dist2) => C.algebraicPower(dist1, dist2)->run(~env)->toDistR
|
||||||
|
let scaleMultiply = (~env, dist, n) => C.scaleMultiply(dist, n)->run(~env)->toDistR
|
||||||
let scalePower = (~env, dist, n) => C.scalePower(dist, n)->run(~env)->toDistR
|
let scalePower = (~env, dist, n) => C.scalePower(dist, n)->run(~env)->toDistR
|
||||||
let scaleLogarithm = (~env, dist, n) => C.scaleLogarithm(dist, n)->run(~env)->toDistR
|
let scaleLogarithm = (~env, dist, n) => C.scaleLogarithm(dist, n)->run(~env)->toDistR
|
||||||
let pointwiseAdd = (~env, dist1, dist2) => C.pointwiseAdd(dist1, dist2)->run(~env)->toDistR
|
let pointwiseAdd = (~env, dist1, dist2) => C.pointwiseAdd(dist1, dist2)->run(~env)->toDistR
|
||||||
|
|
|
@ -102,6 +102,8 @@ module Constructors: {
|
||||||
@genType
|
@genType
|
||||||
let scaleLogarithm: (~env: env, genericDist, float) => result<genericDist, error>
|
let scaleLogarithm: (~env: env, genericDist, float) => result<genericDist, error>
|
||||||
@genType
|
@genType
|
||||||
|
let scaleMultiply: (~env: env, genericDist, float) => result<genericDist, error>
|
||||||
|
@genType
|
||||||
let scalePower: (~env: env, genericDist, float) => result<genericDist, error>
|
let scalePower: (~env: env, genericDist, float) => result<genericDist, error>
|
||||||
@genType
|
@genType
|
||||||
let pointwiseAdd: (~env: env, genericDist, genericDist) => result<genericDist, error>
|
let pointwiseAdd: (~env: env, genericDist, genericDist) => result<genericDist, error>
|
||||||
|
|
|
@ -76,6 +76,7 @@ module DistributionOperation = {
|
||||||
]
|
]
|
||||||
|
|
||||||
type toScaleFn = [
|
type toScaleFn = [
|
||||||
|
| #Multiply
|
||||||
| #Power
|
| #Power
|
||||||
| #Logarithm
|
| #Logarithm
|
||||||
| #LogarithmWithThreshold(float)
|
| #LogarithmWithThreshold(float)
|
||||||
|
@ -138,11 +139,12 @@ module DistributionOperation = {
|
||||||
| ToDist(Truncate(_, _)) => `truncate`
|
| ToDist(Truncate(_, _)) => `truncate`
|
||||||
| ToDist(Inspect) => `inspect`
|
| ToDist(Inspect) => `inspect`
|
||||||
| ToDist(Scale(#Power, r)) => `scalePower(${E.Float.toFixed(r)})`
|
| ToDist(Scale(#Power, r)) => `scalePower(${E.Float.toFixed(r)})`
|
||||||
|
| ToDist(Scale(#Multiply, r)) => `scaleMultiply(${E.Float.toFixed(r)})`
|
||||||
| ToDist(Scale(#Logarithm, r)) => `scaleLog(${E.Float.toFixed(r)})`
|
| ToDist(Scale(#Logarithm, r)) => `scaleLog(${E.Float.toFixed(r)})`
|
||||||
| ToDist(Scale(#LogarithmWithThreshold(eps), r)) =>
|
| ToDist(Scale(#LogarithmWithThreshold(eps), r)) =>
|
||||||
`scaleLogWithThreshold(${E.Float.toFixed(r)}, epsilon=${E.Float.toFixed(eps)})`
|
`scaleLogWithThreshold(${E.Float.toFixed(r)}, epsilon=${E.Float.toFixed(eps)})`
|
||||||
| ToString(ToString) => `toString`
|
| ToString(ToString) => `toString`
|
||||||
| ToString(ToSparkline(n)) => `toSparkline(${E.I.toString(n)})`
|
| ToString(ToSparkline(n)) => `sparkline(${E.I.toString(n)})`
|
||||||
| ToBool(IsNormalized) => `isNormalized`
|
| ToBool(IsNormalized) => `isNormalized`
|
||||||
| ToDistCombination(Algebraic(_), _, _) => `algebraic`
|
| ToDistCombination(Algebraic(_), _, _) => `algebraic`
|
||||||
| ToDistCombination(Pointwise, _, _) => `pointwise`
|
| ToDistCombination(Pointwise, _, _) => `pointwise`
|
||||||
|
@ -179,6 +181,7 @@ module Constructors = {
|
||||||
ToScore(LogScore(answer, prior)),
|
ToScore(LogScore(answer, prior)),
|
||||||
prediction,
|
prediction,
|
||||||
)
|
)
|
||||||
|
let scaleMultiply = (dist, n): t => FromDist(ToDist(Scale(#Multiply, n)), dist)
|
||||||
let scalePower = (dist, n): t => FromDist(ToDist(Scale(#Power, n)), dist)
|
let scalePower = (dist, n): t => FromDist(ToDist(Scale(#Power, n)), dist)
|
||||||
let scaleLogarithm = (dist, n): t => FromDist(ToDist(Scale(#Logarithm, n)), dist)
|
let scaleLogarithm = (dist, n): t => FromDist(ToDist(Scale(#Logarithm, n)), dist)
|
||||||
let scaleLogarithmWithThreshold = (dist, n, eps): t => FromDist(
|
let scaleLogarithmWithThreshold = (dist, n, eps): t => FromDist(
|
||||||
|
|
|
@ -214,7 +214,9 @@ module Truncate = {
|
||||||
| Some(r) => Ok(r)
|
| Some(r) => Ok(r)
|
||||||
| None =>
|
| None =>
|
||||||
toPointSetFn(t)->E.R2.fmap(t => {
|
toPointSetFn(t)->E.R2.fmap(t => {
|
||||||
DistributionTypes.PointSet(PointSetDist.T.truncate(leftCutoff, rightCutoff, t))
|
DistributionTypes.PointSet(
|
||||||
|
PointSetDist.T.truncate(leftCutoff, rightCutoff, t)->PointSetDist.T.normalize,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,7 +295,7 @@ module Float = {
|
||||||
let inv = (p, t: t) => p < t ? 0.0 : 1.0
|
let inv = (p, t: t) => p < t ? 0.0 : 1.0
|
||||||
let mean = (t: t) => Ok(t)
|
let mean = (t: t) => Ok(t)
|
||||||
let sample = (t: t) => t
|
let sample = (t: t) => t
|
||||||
let toString = (t: t) => j`Delta($t)`
|
let toString = (t: t) => j`PointMass($t)`
|
||||||
let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Discrete(
|
let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Discrete(
|
||||||
Discrete.make(~integralSumCache=Some(1.0), {xs: [t], ys: [1.0]}),
|
Discrete.make(~integralSumCache=Some(1.0), {xs: [t], ys: [1.0]}),
|
||||||
)
|
)
|
||||||
|
|
|
@ -221,9 +221,9 @@ let dispatchToGenericOutput = (
|
||||||
}
|
}
|
||||||
| ("integralSum", [EvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist, ~env)
|
| ("integralSum", [EvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist, ~env)
|
||||||
| ("toString", [EvDistribution(dist)]) => Helpers.toStringFn(ToString, dist, ~env)
|
| ("toString", [EvDistribution(dist)]) => Helpers.toStringFn(ToString, dist, ~env)
|
||||||
| ("toSparkline", [EvDistribution(dist)]) =>
|
| ("sparkline", [EvDistribution(dist)]) =>
|
||||||
Helpers.toStringFn(ToSparkline(MagicNumbers.Environment.sparklineLength), dist, ~env)
|
Helpers.toStringFn(ToSparkline(MagicNumbers.Environment.sparklineLength), dist, ~env)
|
||||||
| ("toSparkline", [EvDistribution(dist), EvNumber(n)]) =>
|
| ("sparkline", [EvDistribution(dist), EvNumber(n)]) =>
|
||||||
Helpers.toStringFn(ToSparkline(Belt.Float.toInt(n)), dist, ~env)
|
Helpers.toStringFn(ToSparkline(Belt.Float.toInt(n)), dist, ~env)
|
||||||
| ("exp", [EvDistribution(a)]) =>
|
| ("exp", [EvDistribution(a)]) =>
|
||||||
// https://mathjs.org/docs/reference/functions/exp.html
|
// https://mathjs.org/docs/reference/functions/exp.html
|
||||||
|
@ -266,6 +266,8 @@ let dispatchToGenericOutput = (
|
||||||
Helpers.toDistFn(Scale(#Logarithm, float), dist, ~env)
|
Helpers.toDistFn(Scale(#Logarithm, float), dist, ~env)
|
||||||
| ("scaleLogWithThreshold", [EvDistribution(dist), EvNumber(base), EvNumber(eps)]) =>
|
| ("scaleLogWithThreshold", [EvDistribution(dist), EvNumber(base), EvNumber(eps)]) =>
|
||||||
Helpers.toDistFn(Scale(#LogarithmWithThreshold(eps), base), dist, ~env)
|
Helpers.toDistFn(Scale(#LogarithmWithThreshold(eps), base), dist, ~env)
|
||||||
|
| ("scaleMultiply", [EvDistribution(dist), EvNumber(float)]) =>
|
||||||
|
Helpers.toDistFn(Scale(#Multiply, float), dist, ~env)
|
||||||
| ("scalePow", [EvDistribution(dist), EvNumber(float)]) =>
|
| ("scalePow", [EvDistribution(dist), EvNumber(float)]) =>
|
||||||
Helpers.toDistFn(Scale(#Power, float), dist, ~env)
|
Helpers.toDistFn(Scale(#Power, float), dist, ~env)
|
||||||
| ("scaleExp", [EvDistribution(dist)]) =>
|
| ("scaleExp", [EvDistribution(dist)]) =>
|
||||||
|
@ -273,6 +275,8 @@ let dispatchToGenericOutput = (
|
||||||
| ("cdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist, ~env)
|
| ("cdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist, ~env)
|
||||||
| ("pdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist, ~env)
|
| ("pdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist, ~env)
|
||||||
| ("inv", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env)
|
| ("inv", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env)
|
||||||
|
| ("quantile", [EvDistribution(dist), EvNumber(float)]) =>
|
||||||
|
Helpers.toFloatFn(#Inv(float), dist, ~env)
|
||||||
| ("toSampleSet", [EvDistribution(dist), EvNumber(float)]) =>
|
| ("toSampleSet", [EvDistribution(dist), EvNumber(float)]) =>
|
||||||
Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist, ~env)
|
Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist, ~env)
|
||||||
| ("toSampleSet", [EvDistribution(dist)]) =>
|
| ("toSampleSet", [EvDistribution(dist)]) =>
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
module Bindings = Reducer_Category_Bindings
|
module Bindings = Reducer_Category_Bindings
|
||||||
module Module = Reducer_Category_Module
|
module Module = Reducer_Category_Module
|
||||||
|
|
||||||
let m =
|
let availableNumbers: array<(string, float)> = [
|
||||||
Module.emptyModule->Module.defineNumber("pi", Js.Math._PI)->Module.defineNumber("e", Js.Math._E)
|
("pi", Js.Math._PI),
|
||||||
|
("e", Js.Math._E),
|
||||||
|
("ln2", Js.Math._LN2),
|
||||||
|
("ln10", Js.Math._LN10),
|
||||||
|
("log2e", Js.Math._LOG2E),
|
||||||
|
("log10e", Js.Math._LOG10E),
|
||||||
|
("sqrt2", Js.Math._SQRT2),
|
||||||
|
("sqrt1_2", Js.Math._SQRT1_2),
|
||||||
|
("phi", 1.618033988749895),
|
||||||
|
("tau", 6.283185307179586),
|
||||||
|
]
|
||||||
|
|
||||||
|
let mathBindings: Bindings.ExpressionT.bindings =
|
||||||
|
availableNumbers
|
||||||
|
->E.A2.fmap(((name, v)) => (name, ReducerInterface_ExpressionValue.EvNumber(v)))
|
||||||
|
->Belt.Map.String.fromArray
|
||||||
|
|
||||||
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
||||||
previousBindings->Bindings.defineModule("Math", m)
|
previousBindings->Bindings.defineModule("Math", mathBindings)
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
.docusaurus
|
.docusaurus
|
||||||
build
|
build
|
||||||
|
docs/Api/.*
|
|
@ -3,8 +3,12 @@ sidebar_position: 1
|
||||||
title: Date
|
title: Date
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Squiggle date types are a very simple implementation on [Javascript's Date type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). It's mainly here for early experimentation. There are more relevant functions for the [Duration](/docs/Api/Duration) type.
|
||||||
|
|
||||||
### makeFromYear
|
### makeFromYear
|
||||||
|
|
||||||
|
(Now `makeDateFromYear`)
|
||||||
|
|
||||||
```
|
```
|
||||||
Date.makeFromYear: (number) => date
|
Date.makeFromYear: (number) => date
|
||||||
```
|
```
|
||||||
|
@ -19,6 +23,16 @@ makeFromYear(2022.32);
|
||||||
toString: (date) => string
|
toString: (date) => string
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### add
|
||||||
|
|
||||||
|
```
|
||||||
|
add: (date, duration) => date
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
makeFromYear(2022.32) + years(5);
|
||||||
|
```
|
||||||
|
|
||||||
### subtract
|
### subtract
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -30,13 +44,3 @@ subtract: (date, duration) => date
|
||||||
makeFromYear(2040) - makeFromYear(2020); // 20 years
|
makeFromYear(2040) - makeFromYear(2020); // 20 years
|
||||||
makeFromYear(2040) - years(20); // 2020
|
makeFromYear(2040) - years(20); // 2020
|
||||||
```
|
```
|
||||||
|
|
||||||
### add
|
|
||||||
|
|
||||||
```
|
|
||||||
add: (date, duration) => date
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
makeFromYear(2022.32) + years(5);
|
|
||||||
```
|
|
||||||
|
|
|
@ -3,6 +3,34 @@ sidebar_position: 2
|
||||||
title: Dictionary
|
title: Dictionary
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Squiggle dictionaries work similar to Python dictionaries. The syntax is similar to objects in Javascript.
|
||||||
|
|
||||||
|
Dictionaries are unordered and duplicates are not allowed. They are meant to be immutable, like most types in Squiggle.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
valueFromOfficeItems = {
|
||||||
|
keyboard: 1,
|
||||||
|
chair: 0.01 to 0.5,
|
||||||
|
headphones: "ToDo"
|
||||||
|
}
|
||||||
|
|
||||||
|
valueFromHomeItems = {
|
||||||
|
monitor: 1,
|
||||||
|
bed: 0.2 to 0.6,
|
||||||
|
lights: 0.02 to 0.2,
|
||||||
|
coffee: 5 to 20
|
||||||
|
}
|
||||||
|
|
||||||
|
homeToItemsConversion = 0.1 to 0.4
|
||||||
|
|
||||||
|
conversionFn(i) = [i[0], i[1] * homeToItemsConversion]
|
||||||
|
updatedValueFromHomeItems = valueFromHomeItems |> Dict.toList |> map(conversionFn) |> Dict.fromList
|
||||||
|
|
||||||
|
allItems = merge(valueFromOfficeItems, updatedValueFromHomeItems)
|
||||||
|
```
|
||||||
|
|
||||||
### toList
|
### toList
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -3,50 +3,47 @@ sidebar_position: 3
|
||||||
title: Distribution
|
title: Distribution
|
||||||
---
|
---
|
||||||
|
|
||||||
|
import Admonition from "@theme/Admonition";
|
||||||
import TOCInline from "@theme/TOCInline";
|
import TOCInline from "@theme/TOCInline";
|
||||||
|
|
||||||
|
Distributions are the flagship data type in Squiggle. The distribution type is a generic data type that contains one of three different formats of distributions.
|
||||||
|
These subtypes are [point set](/docs/Api/DistPointSet), [sample set](/docs/Api/DistSampleSet), and symbolic. The first two of these have a few custom functions that only work on them. You can read more about the differences between these formats [here](/docs/Discussions/Three-Formats-Of-Distributions).
|
||||||
|
|
||||||
|
Several functions below only can work on particular distribution formats.
|
||||||
|
For example, scoring and pointwise math requires the point set format. When this happens, the types are automatically converted to the correct format. These conversions are lossy.
|
||||||
|
|
||||||
<TOCInline toc={toc} />
|
<TOCInline toc={toc} />
|
||||||
|
|
||||||
## Distribution Creation
|
## Distribution Creation
|
||||||
|
|
||||||
### Normal Distribution
|
These are functions for creating primative distributions. Many of these could optionally take in distributions as inputs. In these cases, Monte Carlo Sampling will be used to generate the greater distribution. This can be used for simple hierarchical models.
|
||||||
|
|
||||||
**Definitions**
|
See a longer tutorial on creating distributions [here](/docs/Guides/DistributionCreation).
|
||||||
|
|
||||||
|
### normal
|
||||||
|
|
||||||
```javascript
|
|
||||||
normal: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
normal: (distribution|number, distribution|number) => distribution
|
||||||
```javascript
|
normal: (dict<{p5: distribution|number, p95: distribution|number}>) => distribution
|
||||||
normal: (dict<{p5: frValueDistOrNumber, p95: frValueDistOrNumber}>) => distribution
|
normal: (dict<{mean: distribution|number, stdev: distribution|number}>) => distribution
|
||||||
```
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
normal: (dict<{mean: frValueDistOrNumber, stdev: frValueDistOrNumber}>) => distribution
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
normal(5, 1);
|
normal(5, 1)
|
||||||
normal({ p5: 4, p95: 10 });
|
normal({ p5: 4, p95: 10 })
|
||||||
normal({ mean: 5, stdev: 2 });
|
normal({ mean: 5, stdev: 2 })
|
||||||
|
normal(5 to 10, normal(3, 2))
|
||||||
|
normal({ mean: uniform(5, 9), stdev: 3 })
|
||||||
```
|
```
|
||||||
|
|
||||||
### Lognormal Distribution
|
### lognormal
|
||||||
|
|
||||||
**Definitions**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
lognormal: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
lognormal: (distribution|number, distribution|number) => distribution
|
||||||
```javascript
|
lognormal: (dict<{p5: distribution|number, p95: distribution|number}>) => distribution
|
||||||
lognormal: (dict<{p5: frValueDistOrNumber, p95: frValueDistOrNumber}>) => distribution
|
lognormal: (dict<{mean: distribution|number, stdev: distribution|number}>) => distribution
|
||||||
```
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
lognormal: (dict<{mean: frValueDistOrNumber, stdev: frValueDistOrNumber}>) => distribution
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -57,12 +54,10 @@ lognormal({ p5: 4, p95: 10 });
|
||||||
lognormal({ mean: 5, stdev: 2 });
|
lognormal({ mean: 5, stdev: 2 });
|
||||||
```
|
```
|
||||||
|
|
||||||
### Uniform Distribution
|
### uniform
|
||||||
|
|
||||||
**Definitions**
|
```
|
||||||
|
uniform: (distribution|number, distribution|number) => distribution
|
||||||
```javascript
|
|
||||||
uniform: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -71,12 +66,10 @@ uniform: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
||||||
uniform(10, 12);
|
uniform(10, 12);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Beta Distribution
|
### beta
|
||||||
|
|
||||||
**Definitions**
|
```
|
||||||
|
beta: (distribution|number, distribution|number) => distribution
|
||||||
```javascript
|
|
||||||
beta: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -85,12 +78,10 @@ beta: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
||||||
beta(20, 25);
|
beta(20, 25);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Cauchy Distribution
|
### cauchy
|
||||||
|
|
||||||
**Definitions**
|
```
|
||||||
|
cauchy: (distribution|number, distribution|number) => distribution
|
||||||
```javascript
|
|
||||||
cauchy: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -99,12 +90,22 @@ cauchy: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
||||||
cauchy(5, 1);
|
cauchy(5, 1);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Gamma Distribution
|
### gamma
|
||||||
|
|
||||||
**Definitions**
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
gamma: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
gamma: (distribution|number, distribution|number) => distribution
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```js
|
||||||
|
gamma(5, 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
### logistic
|
||||||
|
|
||||||
|
```
|
||||||
|
logistic: (distribution|number, distribution|number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -113,30 +114,53 @@ gamma: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
||||||
gamma(5, 1);
|
gamma(5, 1);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logistic Distribution
|
### exponential
|
||||||
|
|
||||||
**Definitions**
|
```
|
||||||
|
exponential: (distribution|number) => distribution
|
||||||
```javascript
|
|
||||||
logistic: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
gamma(5, 1);
|
exponential(2);
|
||||||
```
|
```
|
||||||
|
|
||||||
### To (Distribution)
|
### bernoulli
|
||||||
|
|
||||||
**Definitions**
|
```
|
||||||
|
bernoulli: (distribution|number) => distribution
|
||||||
```javascript
|
|
||||||
to: (frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
credibleIntervalToDistribution(frValueDistOrNumber, frValueDistOrNumber) => distribution;
|
bernoulli(0.5);
|
||||||
|
```
|
||||||
|
|
||||||
|
### triangular
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
triangular: (number, number, number) => distribution;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
triangular(5, 10, 20);
|
||||||
|
```
|
||||||
|
|
||||||
|
### to / credibleIntervalToDistribution
|
||||||
|
|
||||||
|
The `to` function is an easy way to generate simple distributions using predicted _5th_ and _95th_ percentiles.
|
||||||
|
|
||||||
|
If both values are above zero, a `lognormal` distribution is used. If not, a `normal` distribution is used.
|
||||||
|
|
||||||
|
`To` is an alias for `credibleIntervalToDistribution`. However, because of its frequent use, it is recommended to use the shorter name.
|
||||||
|
|
||||||
|
```
|
||||||
|
to: (distribution|number, distribution|number) => distribution
|
||||||
|
credibleIntervalToDistribution(distribution|number, distribution|number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -147,97 +171,29 @@ to(5,10)
|
||||||
-5 to 5
|
-5 to 5
|
||||||
```
|
```
|
||||||
|
|
||||||
### Exponential
|
### mixture
|
||||||
|
|
||||||
**Definitions**
|
```
|
||||||
|
mixture: (...distributionLike, weights?:list<float>) => distribution
|
||||||
```javascript
|
mixture: (list<distributionLike>, weights?:list<float>) => distribution
|
||||||
exponential: (frValueDistOrNumber) => distribution;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
exponential(2);
|
mixture(normal(5, 1), normal(10, 1), 8);
|
||||||
```
|
mx(normal(5, 1), normal(10, 1), [0.3, 0.7]);
|
||||||
|
mx([normal(5, 1), normal(10, 1)], [0.3, 0.7]);
|
||||||
### Bernoulli
|
|
||||||
|
|
||||||
**Definitions**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
bernoulli: (frValueDistOrNumber) => distribution;
|
|
||||||
```
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
bernoulli(0.5);
|
|
||||||
```
|
|
||||||
|
|
||||||
### toContinuousPointSet
|
|
||||||
|
|
||||||
Converts a set of points to a continuous distribution
|
|
||||||
|
|
||||||
**Definitions**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
toContinuousPointSet: (array<dict<{x: numeric, y: numeric}>>) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
toContinuousPointSet([
|
|
||||||
{ x: 0, y: 0.1 },
|
|
||||||
{ x: 1, y: 0.2 },
|
|
||||||
{ x: 2, y: 0.15 },
|
|
||||||
{ x: 3, y: 0.1 },
|
|
||||||
]);
|
|
||||||
```
|
|
||||||
|
|
||||||
### toDiscretePointSet
|
|
||||||
|
|
||||||
Converts a set of points to a discrete distribution
|
|
||||||
|
|
||||||
**Definitions**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
toDiscretePointSet: (array<dict<{x: numeric, y: numeric}>>) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
toDiscretePointSet([
|
|
||||||
{ x: 0, y: 0.1 },
|
|
||||||
{ x: 1, y: 0.2 },
|
|
||||||
{ x: 2, y: 0.15 },
|
|
||||||
{ x: 3, y: 0.1 },
|
|
||||||
]);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
### mixture
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
mixture: (...distributionLike, weights:list<float>) => distribution
|
|
||||||
```
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
mixture(normal(5, 1), normal(10, 1));
|
|
||||||
mx(normal(5, 1), normal(10, 1), [0.3, 0.7]);
|
|
||||||
```
|
|
||||||
|
|
||||||
### sample
|
### sample
|
||||||
|
|
||||||
Get one random sample from the distribution
|
One random sample from the distribution
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
sample(distribution) => number
|
sample: (distribution) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -248,66 +204,70 @@ sample(normal(5, 2));
|
||||||
|
|
||||||
### sampleN
|
### sampleN
|
||||||
|
|
||||||
Get n random samples from the distribution
|
N random samples from the distribution
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
sampleN: (distribution, number) => list<number>
|
sampleN: (distribution, number) => list<number>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
sample: normal(5, 2), 100;
|
sampleN(normal(5, 2), 100);
|
||||||
```
|
```
|
||||||
|
|
||||||
### mean
|
### mean
|
||||||
|
|
||||||
Get the distribution mean
|
The distribution mean
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
mean: (distribution) => number;
|
mean: (distribution) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
mean: normal(5, 2);
|
mean(normal(5, 2));
|
||||||
```
|
```
|
||||||
|
|
||||||
### stdev
|
### stdev
|
||||||
|
|
||||||
```javascript
|
Standard deviation. Only works now on sample set distributions (so converts other distributions into sample set in order to calculate.)
|
||||||
stdev: (distribution) => number;
|
|
||||||
|
```
|
||||||
|
stdev: (distribution) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### variance
|
### variance
|
||||||
|
|
||||||
```javascript
|
Variance. Similar to stdev, only works now on sample set distributions.
|
||||||
variance: (distribution) => number;
|
|
||||||
|
```
|
||||||
|
variance: (distribution) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### mode
|
### mode
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
mode: (distribution) => number;
|
mode: (distribution) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### cdf
|
### cdf
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
cdf: (distribution, number) => number;
|
cdf: (distribution, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
cdf: normal(5, 2), 3;
|
cdf(normal(5, 2), 3);
|
||||||
```
|
```
|
||||||
|
|
||||||
### pdf
|
### pdf
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
pdf: (distribution, number) => number;
|
pdf: (distribution, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -316,24 +276,26 @@ pdf: (distribution, number) => number;
|
||||||
pdf(normal(5, 2), 3);
|
pdf(normal(5, 2), 3);
|
||||||
```
|
```
|
||||||
|
|
||||||
### inv
|
### quantile
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
inv: (distribution, number) => number;
|
quantile: (distribution, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
inv(normal(5, 2), 0.5);
|
quantile(normal(5, 2), 0.5);
|
||||||
```
|
```
|
||||||
|
|
||||||
### toPointSet
|
### toPointSet
|
||||||
|
|
||||||
Converts a distribution to the pointSet format
|
**TODO: Will soon be called "PointSet.make"**
|
||||||
|
|
||||||
```javascript
|
Converts a distribution to the pointSet format.
|
||||||
toPointSet: (distribution) => pointSetDistribution;
|
|
||||||
|
```
|
||||||
|
toPointSet: (distribution) => pointSetDistribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -344,10 +306,12 @@ toPointSet(normal(5, 2));
|
||||||
|
|
||||||
### toSampleSet
|
### toSampleSet
|
||||||
|
|
||||||
Converts a distribution to the sampleSet format, with n samples
|
**TODO: Will soon be called "SampleSet.make"**
|
||||||
|
|
||||||
```javascript
|
Converts a distribution to the sampleSet format, with n samples.
|
||||||
toSampleSet: (distribution, number) => sampleSetDistribution;
|
|
||||||
|
```
|
||||||
|
toSampleSet: (distribution, number) => sampleSetDistribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -360,7 +324,7 @@ toSampleSet(normal(5, 2), 1000);
|
||||||
|
|
||||||
Truncates the left side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
|
Truncates the left side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
truncateLeft: (distribution, l => number) => distribution
|
truncateLeft: (distribution, l => number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -374,7 +338,7 @@ truncateLeft(normal(5, 2), 3);
|
||||||
|
|
||||||
Truncates the right side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
|
Truncates the right side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
truncateRight: (distribution, r => number) => distribution
|
truncateRight: (distribution, r => number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -384,14 +348,12 @@ truncateRight: (distribution, r => number) => distribution
|
||||||
truncateLeft(normal(5, 2), 6);
|
truncateLeft(normal(5, 2), 6);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Scoring
|
|
||||||
|
|
||||||
### klDivergence
|
### klDivergence
|
||||||
|
|
||||||
Kullback–Leibler divergence between two distributions
|
[Kullback–Leibler divergence](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) between two distributions.
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
klDivergence: (distribution, distribution) => number;
|
klDivergence: (distribution, distribution) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -404,8 +366,8 @@ klDivergence(normal(5, 2), normal(5, 4)); // returns 0.57
|
||||||
|
|
||||||
### toString
|
### toString
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
toString: (distribution) => string;
|
toString: (distribution) => string
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -414,42 +376,46 @@ toString: (distribution) => string;
|
||||||
toString(normal(5, 2));
|
toString(normal(5, 2));
|
||||||
```
|
```
|
||||||
|
|
||||||
### toSparkline
|
### sparkline
|
||||||
|
|
||||||
Produce a sparkline of length n
|
Produce a sparkline of length n. For example, `▁▁▁▁▁▂▄▆▇██▇▆▄▂▁▁▁▁▁`. These can be useful for testing or quick text visualizations.
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
toSparkline: (distribution, n = 20) => string;
|
sparkline: (distribution, n = 20) => string
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
toSparkline(normal(5, 2), 10);
|
toSparkline(truncateLeft(normal(5, 2), 3), 20); // produces ▁▇█████▇▅▄▃▂▂▁▁▁▁▁▁▁
|
||||||
```
|
```
|
||||||
|
|
||||||
### inspect
|
### inspect
|
||||||
|
|
||||||
Prints the value of the distribution to the Javascript console, then returns the distribution.
|
Prints the value of the distribution to the Javascript console, then returns the distribution. Useful for debugging.
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
inspect: (distribution) => distribution;
|
inspect: (distribution) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
inspect(normal(5, 2));
|
inspect(normal(5, 2)); // logs "normal(5, 2)" to the javascript console and returns the distribution.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Normalization
|
## Normalization
|
||||||
|
|
||||||
|
There are some situations where computation will return unnormalized distributions. This means that their cumulative sums are not equal to 1.0. Unnormalized distributions are not valid for many relevant functions; for example, klDivergence and scoring.
|
||||||
|
|
||||||
|
The only functions that do not return normalized distributions are the pointwise arithmetic operations and the scalewise arithmetic operations. If you use these functions, it is recommended that you consider normalizing the resulting distributions.
|
||||||
|
|
||||||
### normalize
|
### normalize
|
||||||
|
|
||||||
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1.
|
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1.
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
normalize: (distribution) => distribution;
|
normalize: (distribution) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -462,8 +428,8 @@ normalize(normal(5, 2));
|
||||||
|
|
||||||
Check of a distribution is normalized. Most distributions are typically normalized, but there are some commands that could produce non-normalized distributions.
|
Check of a distribution is normalized. Most distributions are typically normalized, but there are some commands that could produce non-normalized distributions.
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
isNormalized: (distribution) => bool;
|
isNormalized: (distribution) => bool
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -474,10 +440,12 @@ isNormalized(normal(5, 2)); // returns true
|
||||||
|
|
||||||
### integralSum
|
### integralSum
|
||||||
|
|
||||||
Get the sum of the integral of a distribution. If the distribution is normalized, this will be 1.
|
**Note: If you have suggestions for better names for this, please let us know.**
|
||||||
|
|
||||||
```javascript
|
Get the sum of the integral of a distribution. If the distribution is normalized, this will be 1.0. This is useful for understanding unnormalized distributions.
|
||||||
integralSum: (distribution) => number;
|
|
||||||
|
```
|
||||||
|
integralSum: (distribution) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -486,151 +454,214 @@ integralSum: (distribution) => number;
|
||||||
integralSum(normal(5, 2));
|
integralSum(normal(5, 2));
|
||||||
```
|
```
|
||||||
|
|
||||||
## Algebraic Operations
|
## Regular Arithmetic Operations
|
||||||
|
|
||||||
|
Regular arithmetic operations cover the basic mathematical operations on distributions. They work much like their equivalent operations on numbers.
|
||||||
|
|
||||||
|
The infixes `+`,`-`, `*`, `/`, `^` are supported for addition, subtraction, multiplication, division, power, and unaryMinus.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
pointMass(5 + 10) == pointMass(5) + pointMass(10);
|
||||||
|
```
|
||||||
|
|
||||||
### add
|
### add
|
||||||
|
|
||||||
|
```
|
||||||
|
add: (distributionLike, distributionLike) => distribution
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
add: (distributionLike, distributionLike) => distribution;
|
normal(0, 1) + normal(1, 3); // returns normal(1, 3.16...)
|
||||||
|
add(normal(0, 1), normal(1, 3)); // returns normal(1, 3.16...)
|
||||||
```
|
```
|
||||||
|
|
||||||
### sum
|
### sum
|
||||||
|
|
||||||
```javascript
|
**Todo: Not yet implemented**
|
||||||
|
|
||||||
|
```
|
||||||
sum: (list<distributionLike>) => distribution
|
sum: (list<distributionLike>) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
sum([normal(0, 1), normal(1, 3), uniform(10, 1)]);
|
||||||
|
```
|
||||||
|
|
||||||
### multiply
|
### multiply
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
multiply: (distributionLike, distributionLike) => distribution;
|
multiply: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### product
|
### product
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
product: (list<distributionLike>) => distribution
|
product: (list<distributionLike>) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### subtract
|
### subtract
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
subtract: (distributionLike, distributionLike) => distribution;
|
subtract: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### divide
|
### divide
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
divide: (distributionLike, distributionLike) => distribution;
|
divide: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### pow
|
### pow
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
pow: (distributionLike, distributionLike) => distribution;
|
pow: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### exp
|
### exp
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
exp: (distributionLike, distributionLike) => distribution;
|
exp: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### log
|
### log
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
log: (distributionLike, distributionLike) => distribution;
|
log: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### log10
|
### log10
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
log10: (distributionLike, distributionLike) => distribution;
|
log10: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### unaryMinus
|
### unaryMinus
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
unaryMinus: (distribution) => distribution;
|
unaryMinus: (distribution) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pointwise Operations
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
-normal(5, 2); // same as normal(-5, 2)
|
||||||
|
unaryMinus(normal(5, 2)); // same as normal(-5, 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pointwise Arithmetic Operations
|
||||||
|
|
||||||
|
<Admonition type="caution" title="Unnormalized Results">
|
||||||
|
<p>
|
||||||
|
Pointwise arithmetic operations typically return unnormalized or completely
|
||||||
|
invalid distributions. For example, the operation{" "}
|
||||||
|
<code>normal(5,2) .- uniform(10,12)</code> results in a distribution-like
|
||||||
|
object with negative probability mass.
|
||||||
|
</p>
|
||||||
|
</Admonition>
|
||||||
|
|
||||||
|
Pointwise arithmetic operations cover the standard arithmetic operations, but work in a different way than the regular operations. These operate on the y-values of the distributions instead of the x-values. A pointwise addition would add the y-values of two distributions.
|
||||||
|
|
||||||
|
The infixes `.+`,`.-`, `.*`, `./`, `.^` are supported for their respective operations.
|
||||||
|
|
||||||
|
The `mixture` methods works with pointwise addition.
|
||||||
|
|
||||||
### dotAdd
|
### dotAdd
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
dotAdd: (distributionLike, distributionLike) => distribution;
|
dotAdd: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### dotMultiply
|
### dotMultiply
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
dotMultiply: (distributionLike, distributionLike) => distribution;
|
dotMultiply: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### dotSubtract
|
### dotSubtract
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
dotSubtract: (distributionLike, distributionLike) => distribution;
|
dotSubtract: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### dotDivide
|
### dotDivide
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
dotDivide: (distributionLike, distributionLike) => distribution;
|
dotDivide: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### dotPow
|
### dotPow
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
dotPow: (distributionLike, distributionLike) => distribution;
|
dotPow: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### dotExp
|
### dotExp
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
dotExp: (distributionLike, distributionLike) => distribution;
|
dotExp: (distributionLike, distributionLike) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
## Scale Operations
|
## Scale Arithmetic Operations
|
||||||
|
|
||||||
|
<Admonition type="caution" title="Likely to change">
|
||||||
|
<p>
|
||||||
|
We're planning on removing scale operations in favor of more general
|
||||||
|
functions soon.
|
||||||
|
</p>
|
||||||
|
</Admonition>
|
||||||
|
|
||||||
|
Scale operations are similar to pointwise operations, but operate on a constant y-value instead of y-values coming from a distribution. You can think about this as scaling a distribution vertically by a constant.
|
||||||
|
|
||||||
|
The following items would be equivalent.
|
||||||
|
|
||||||
|
```js
|
||||||
|
scalePow(normal(5,2), 2)
|
||||||
|
mapY(normal(5,2), {|y| y ^ 2}) // Not yet available
|
||||||
|
```
|
||||||
|
|
||||||
### scaleMultiply
|
### scaleMultiply
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
scaleMultiply: (distributionLike, number) => distribution;
|
scaleMultiply: (distributionLike, number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### scalePow
|
### scalePow
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
scalePow: (distributionLike, number) => distribution;
|
scalePow: (distributionLike, number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### scaleExp
|
### scaleExp
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
scaleExp: (distributionLike, number) => distribution;
|
scaleExp: (distributionLike, number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### scaleLog
|
### scaleLog
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
scaleLog: (distributionLike, number) => distribution;
|
scaleLog: (distributionLike, number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
### scaleLog10
|
### scaleLog10
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
scaleLog10: (distributionLike, number) => distribution;
|
scaleLog10: (distributionLike, number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
## Special
|
## Special
|
||||||
|
|
||||||
### Declaration (Continuous Function)
|
### Declaration (Continuous Functions)
|
||||||
|
|
||||||
Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making predictions. It allows you to limit the domain that your prediction will be used and scored within.
|
Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making formal predictions. It allows you to limit the domain that your prediction will be used and scored within.
|
||||||
|
|
||||||
```javascript
|
Declarations are currently experimental and will likely be removed or changed in the future.
|
||||||
|
|
||||||
|
```
|
||||||
declareFn: (dict<{fn: lambda, inputs: array<dict<{min: number, max: number}>>}>) => declaration
|
declareFn: (dict<{fn: lambda, inputs: array<dict<{min: number, max: number}>>}>) => declaration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -3,20 +3,56 @@ sidebar_position: 4
|
||||||
title: Point Set Distribution
|
title: Point Set Distribution
|
||||||
---
|
---
|
||||||
|
|
||||||
|
:::danger
|
||||||
|
These functions aren't yet implemented with these specific names. This should be changed soon
|
||||||
|
:::
|
||||||
|
|
||||||
|
Point set distributions are one of the three distribution formats. They are stored as a list of x-y coordinates representing both discrete and continuous distributions.
|
||||||
|
|
||||||
|
One complication is that it's possible to represent invalid probability distributions in the point set format. For example, you can represent shapes with negative values, or shapes that are not normalized.
|
||||||
|
|
||||||
### make
|
### make
|
||||||
|
|
||||||
|
Converts the distribution in question into a point set distribution. If the distribution is symbolic, then it does this by taking the quantiles. If the distribution is a sample set, then it uses a version of kernel density estimation to approximate the point set format. One complication of this latter process is that if there is a high proportion of overlapping samples (samples that are exactly the same as each other), it will convert these samples into discrete point masses. Eventually we'd like to add further methods to help adjust this process.
|
||||||
|
|
||||||
```
|
```
|
||||||
PointSet.make: (distribution) => pointSetDist
|
PointSet.make: (distribution) => pointSetDist
|
||||||
```
|
```
|
||||||
|
|
||||||
### makeContinuous
|
### makeContinuous
|
||||||
|
|
||||||
|
**TODO: Now called "toContinuousPointSet"**
|
||||||
|
|
||||||
|
Converts a set of x-y coordinates directly into a continuous distribution.
|
||||||
|
|
||||||
```
|
```
|
||||||
PointSet.makeContinuous: (list<{x: number, y: number}>) => pointSetDist
|
PointSet.makeContinuous: (list<{x: number, y: number}>) => pointSetDist
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
PointSet.makeContinuous([
|
||||||
|
{ x: 0, y: 0.1 },
|
||||||
|
{ x: 1, y: 0.2 },
|
||||||
|
{ x: 2, y: 0.15 },
|
||||||
|
{ x: 3, y: 0.1 },
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
### makeDiscrete
|
### makeDiscrete
|
||||||
|
|
||||||
|
**TODO: Now called "toDiscretePointSet"**
|
||||||
|
|
||||||
|
Converts a set of x-y coordinates directly into a discrete distribution.
|
||||||
|
|
||||||
```
|
```
|
||||||
PointSet.makeDiscrete: (list<{x: number, y: number}>) => pointSetDist
|
PointSet.makeDiscrete: (list<{x: number, y: number}>) => pointSetDist
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
PointSet.makeDiscrete([
|
||||||
|
{ x: 0, y: 0.1 },
|
||||||
|
{ x: 1, y: 0.2 },
|
||||||
|
{ x: 2, y: 0.15 },
|
||||||
|
{ x: 3, y: 0.1 },
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
|
@ -3,12 +3,22 @@ sidebar_position: 5
|
||||||
title: Sample Set Distribution
|
title: Sample Set Distribution
|
||||||
---
|
---
|
||||||
|
|
||||||
|
:::danger
|
||||||
|
These functions aren't yet implemented with these specific names. This should be added soon.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Sample set distributions are one of the three distribution formats. Internally, they are stored as a list of numbers. It's useful to distinguish point set distributions from arbitrary lists of numbers to make it clear which functions are applicable.
|
||||||
|
|
||||||
|
Monte Carlo calculations typically result in sample set distributions.
|
||||||
|
|
||||||
|
All regular distribution function work on sample set distributions. In addition, there are several functions that only work on sample set distributions.
|
||||||
|
|
||||||
### make
|
### make
|
||||||
|
|
||||||
```
|
```
|
||||||
SampleSet.make: (distribution) => sampleSet
|
SampleSet.make: (distribution) => sampleSet
|
||||||
SampleSet.make: (() => number) => sampleSet
|
|
||||||
SampleSet.make: (list<number>) => sampleSet
|
SampleSet.make: (list<number>) => sampleSet
|
||||||
|
SampleSet.make: (() => number) => sampleSet // not yet implemented
|
||||||
```
|
```
|
||||||
|
|
||||||
### map
|
### map
|
||||||
|
@ -35,7 +45,7 @@ SampleSet.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => n
|
||||||
SampleSet.toList: (sampleSet) => list<number>
|
SampleSet.toList: (sampleSet) => list<number>
|
||||||
```
|
```
|
||||||
|
|
||||||
Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length. Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length.
|
Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length.
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@ sidebar_position: 6
|
||||||
title: Duration
|
title: Duration
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Duration works with the [Date](/docs/Api/Date) type. Similar to the Date implementation, the Duration functions are early and experimental. There is no support yet for date or duration probability distributions.
|
||||||
|
|
||||||
|
Durations are stored in Unix milliseconds.
|
||||||
|
|
||||||
import TOCInline from "@theme/TOCInline";
|
import TOCInline from "@theme/TOCInline";
|
||||||
|
|
||||||
<TOCInline toc={toc} />
|
<TOCInline toc={toc} />
|
||||||
|
|
|
@ -3,13 +3,21 @@ sidebar_position: 7
|
||||||
title: List
|
title: List
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Squiggle lists are a lot like Python lists or Ruby arrays. They accept all types.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
myList = [3, normal(5, 2), "random"];
|
||||||
|
```
|
||||||
|
|
||||||
### make
|
### make
|
||||||
|
|
||||||
|
**Note: currently just called `makeList`, without the preix**
|
||||||
|
|
||||||
```
|
```
|
||||||
List.make: (number, 'a) => list<'a>
|
List.make: (number, 'a) => list<'a>
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns an array of size `n` filled with value `e`.
|
Returns an array of size `n` filled with the value.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
List.make(4, 1); // creates the list [1, 1, 1, 1]
|
List.make(4, 1); // creates the list [1, 1, 1, 1]
|
||||||
|
@ -31,6 +39,8 @@ length: (list<'a>) => number
|
||||||
|
|
||||||
### up to
|
### up to
|
||||||
|
|
||||||
|
**Note: currently just called `upTo`, without the preix**
|
||||||
|
|
||||||
```
|
```
|
||||||
List.upTo: (low:number, high:number) => list<number>
|
List.upTo: (low:number, high:number) => list<number>
|
||||||
```
|
```
|
||||||
|
|
|
@ -6,7 +6,7 @@ title: Math
|
||||||
### E
|
### E
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.E:
|
Math.e:
|
||||||
```
|
```
|
||||||
|
|
||||||
Euler's number; ≈ 2.718281828459045
|
Euler's number; ≈ 2.718281828459045
|
||||||
|
@ -14,7 +14,7 @@ Euler's number; ≈ 2.718281828459045
|
||||||
### LN2
|
### LN2
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.LN2:
|
Math.ln2:
|
||||||
```
|
```
|
||||||
|
|
||||||
Natural logarithm of 2; ≈ 0.6931471805599453
|
Natural logarithm of 2; ≈ 0.6931471805599453
|
||||||
|
@ -22,7 +22,7 @@ Natural logarithm of 2; ≈ 0.6931471805599453
|
||||||
### LN10
|
### LN10
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.LN10:
|
Math.ln10:
|
||||||
```
|
```
|
||||||
|
|
||||||
Natural logarithm of 10; ≈ 2.302585092994046
|
Natural logarithm of 10; ≈ 2.302585092994046
|
||||||
|
@ -30,7 +30,7 @@ Natural logarithm of 10; ≈ 2.302585092994046
|
||||||
### LOG2E
|
### LOG2E
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.LOG2E:
|
Math.log2e:
|
||||||
```
|
```
|
||||||
|
|
||||||
Base 2 logarithm of E; ≈ 1.4426950408889634Base 2 logarithm of E; ≈ 1.4426950408889634
|
Base 2 logarithm of E; ≈ 1.4426950408889634Base 2 logarithm of E; ≈ 1.4426950408889634
|
||||||
|
@ -38,7 +38,7 @@ Base 2 logarithm of E; ≈ 1.4426950408889634Base 2 logarithm of E; ≈ 1.442695
|
||||||
### LOG10E
|
### LOG10E
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.LOG10E:
|
Math.log10e:
|
||||||
```
|
```
|
||||||
|
|
||||||
Base 10 logarithm of E; ≈ 0.4342944819032518
|
Base 10 logarithm of E; ≈ 0.4342944819032518
|
||||||
|
@ -46,7 +46,7 @@ Base 10 logarithm of E; ≈ 0.4342944819032518
|
||||||
### PI
|
### PI
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.PI:
|
Math.pi:
|
||||||
```
|
```
|
||||||
|
|
||||||
Pi - ratio of the circumference to the diameter of a circle; ≈ 3.141592653589793
|
Pi - ratio of the circumference to the diameter of a circle; ≈ 3.141592653589793
|
||||||
|
@ -54,7 +54,7 @@ Pi - ratio of the circumference to the diameter of a circle; ≈ 3.1415926535897
|
||||||
### SQRT1_2
|
### SQRT1_2
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.SQRT1_2:
|
Math.sqrt1_2:
|
||||||
```
|
```
|
||||||
|
|
||||||
Square root of 1/2; ≈ 0.7071067811865476
|
Square root of 1/2; ≈ 0.7071067811865476
|
||||||
|
@ -62,7 +62,7 @@ Square root of 1/2; ≈ 0.7071067811865476
|
||||||
### SQRT2
|
### SQRT2
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.SQRT2:
|
Math.sqrt2:
|
||||||
```
|
```
|
||||||
|
|
||||||
Square root of 2; ≈ 1.4142135623730951
|
Square root of 2; ≈ 1.4142135623730951
|
||||||
|
@ -70,7 +70,7 @@ Square root of 2; ≈ 1.4142135623730951
|
||||||
### PHI
|
### PHI
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.PHI:
|
Math.phi:
|
||||||
```
|
```
|
||||||
|
|
||||||
Phi is the golden ratio. 1.618033988749895
|
Phi is the golden ratio. 1.618033988749895
|
||||||
|
@ -78,7 +78,7 @@ Phi is the golden ratio. 1.618033988749895
|
||||||
### TAU
|
### TAU
|
||||||
|
|
||||||
```
|
```
|
||||||
Math.TAU:
|
Math.tau:
|
||||||
```
|
```
|
||||||
|
|
||||||
Tau is the ratio constant of a circle's circumference to radius, equal to 2 \* pi. 6.283185307179586
|
Tau is the ratio constant of a circle's circumference to radius, equal to 2 \* pi. 6.283185307179586
|
||||||
|
|
|
@ -3,63 +3,67 @@ sidebar_position: 9
|
||||||
title: Number
|
title: Number
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Squiggle `numbers` are Javascript floats.
|
||||||
|
|
||||||
|
Many of the functions below work on lists or pairs of numbers.
|
||||||
|
|
||||||
import TOCInline from "@theme/TOCInline";
|
import TOCInline from "@theme/TOCInline";
|
||||||
|
|
||||||
<TOCInline toc={toc} />
|
<TOCInline toc={toc} />
|
||||||
|
|
||||||
### ceil
|
### ceil
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
ceil: (number) => number;
|
ceil: (number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### floor
|
### floor
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
floor: (number) => number;
|
floor: (number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### abs
|
### abs
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
abs: (number) => number;
|
abs: (number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### round
|
### round
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
round: (number) => number;
|
round: (number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
## Statistics
|
## Statistics
|
||||||
|
|
||||||
### max
|
### max
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
max: (list<number>) => number
|
max: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### min
|
### min
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
min: (list<number>) => number
|
min: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### mean
|
### mean
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
mean: (list<number>) => number
|
mean: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### stdev
|
### stdev
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
stdev: (list<number>) => number
|
stdev: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### variance
|
### variance
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
variance: (list<number>) => number
|
variance: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -67,25 +71,25 @@ variance: (list<number>) => number
|
||||||
|
|
||||||
### unaryMinus
|
### unaryMinus
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
unaryMinus: (number) => number;
|
unaryMinus: (number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### equal
|
### equal
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
equal: (number, number) => boolean;
|
equal: (number, number) => boolean
|
||||||
```
|
```
|
||||||
|
|
||||||
### add
|
### add
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
add: (number, number) => number;
|
add: (number, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### sum
|
### sum
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
sum: (list<number>) => number
|
sum: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -97,13 +101,13 @@ cumsum: (list<number>) => list<number>
|
||||||
|
|
||||||
### multiply
|
### multiply
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
multiply: (number, number) => number;
|
multiply: (number, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### product
|
### product
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
product: (list<number>) => number
|
product: (list<number>) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -115,30 +119,30 @@ cumprod: (list<number>) => list<number>
|
||||||
|
|
||||||
### subtract
|
### subtract
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
subtract: (number, number) => number;
|
subtract: (number, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### divide
|
### divide
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
divide: (number, number) => number;
|
divide: (number, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### pow
|
### pow
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
pow: (number, number) => number;
|
pow: (number, number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### exp
|
### exp
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
exp: (number) => number;
|
exp: (number) => number
|
||||||
```
|
```
|
||||||
|
|
||||||
### log
|
### log
|
||||||
|
|
||||||
```javascript
|
```
|
||||||
log: (number) => number;
|
log: (number) => number
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
title: "Distribution Creation"
|
title: "Distribution Creation"
|
||||||
sidebar_position: 20
|
sidebar_position: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
import { SquiggleEditor } from "../../src/components/SquiggleEditor";
|
import { SquiggleEditor } from "../../src/components/SquiggleEditor";
|
||||||
|
@ -91,7 +91,7 @@ The `mixture` mixes combines multiple distributions to create a mixture. You can
|
||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
- `distributions`: A set of distributions or numbers, each passed as a paramater. Numbers will be converted into Delta distributions.
|
- `distributions`: A set of distributions or numbers, each passed as a paramater. Numbers will be converted into point mass distributions.
|
||||||
- `weights`: An optional array of numbers, each representing the weight of its corresponding distribution. The weights will be re-scaled to add to `1.0`. If a weights array is provided, it must be the same length as the distribution paramaters.
|
- `weights`: An optional array of numbers, each representing the weight of its corresponding distribution. The weights will be re-scaled to add to `1.0`. If a weights array is provided, it must be the same length as the distribution paramaters.
|
||||||
|
|
||||||
### Aliases
|
### Aliases
|
||||||
|
@ -221,22 +221,22 @@ Creates a [uniform distribution](<https://en.wikipedia.org/wiki/Uniform_distribu
|
||||||
</p>
|
</p>
|
||||||
</Admonition>
|
</Admonition>
|
||||||
|
|
||||||
## Delta
|
## Point Mass
|
||||||
|
|
||||||
`delta(value:number)`
|
`pointMass(value:number)`
|
||||||
|
|
||||||
Creates a discrete distribution with all of its probability mass at point `value`.
|
Creates a discrete distribution with all of its probability mass at point `value`.
|
||||||
|
|
||||||
Few Squiggle users call the function `delta()` directly. Numbers are converted into delta distributions automatically, when it is appropriate.
|
Few Squiggle users call the function `pointMass()` directly. Numbers are converted into point mass distributions automatically, when it is appropriate.
|
||||||
|
|
||||||
For example, in the function `mixture(1,2,normal(5,2))`, the first two arguments will get converted into delta distributions
|
For example, in the function `mixture(1,2,normal(5,2))`, the first two arguments will get converted into point mass distributions
|
||||||
with values at 1 and 2. Therefore, this is the same as `mixture(delta(1),delta(2),normal(5,2))`.
|
with values at 1 and 2. Therefore, this is the same as `mixture(pointMass(1),pointMass(2),pointMass(5,2))`.
|
||||||
|
|
||||||
`Delta()` distributions are currently the only discrete distributions accessible in Squiggle.
|
`pointMass()` distributions are currently the only discrete distributions accessible in Squiggle.
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<TabItem value="ex1" label="delta(3)" default>
|
<TabItem value="ex1" label="pointMass(3)" default>
|
||||||
<SquiggleEditor initialSquiggleString="delta(3)" />
|
<SquiggleEditor initialSquiggleString="pointMass(3)" />
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem value="ex3" label="mixture(1,3,5)">
|
<TabItem value="ex3" label="mixture(1,3,5)">
|
||||||
<SquiggleEditor initialSquiggleString="mixture(1,3,5)" />
|
<SquiggleEditor initialSquiggleString="mixture(1,3,5)" />
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: "Functions Reference"
|
title: "Distribution Functions"
|
||||||
sidebar_position: 3
|
sidebar_position: 3
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ given point x.
|
||||||
### Cumulative density function
|
### Cumulative density function
|
||||||
|
|
||||||
The `cdf(dist, x)` gives the cumulative probability of the distribution
|
The `cdf(dist, 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 `quantile`.
|
||||||
|
|
||||||
<SquiggleEditor initialSquiggleString="cdf(normal(0,1),0)" />
|
<SquiggleEditor initialSquiggleString="cdf(normal(0,1),0)" />
|
||||||
|
|
||||||
|
@ -179,13 +179,13 @@ or all values lower than x. It is the inverse of `inv`.
|
||||||
- `x` must be a scalar
|
- `x` must be a scalar
|
||||||
- `dist` must be a distribution
|
- `dist` must be a distribution
|
||||||
|
|
||||||
### Inverse CDF
|
### Quantile
|
||||||
|
|
||||||
The `inv(dist, prob)` gives the value x or which the probability for all values
|
The `quantile(dist, 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`. In the literature, it
|
lower than x is equal to prob. It is the inverse of `cdf`. In the literature, it
|
||||||
is also known as the quantiles function.
|
is also known as the quantiles function.
|
||||||
|
|
||||||
<SquiggleEditor initialSquiggleString="inv(normal(0,1),0.5)" />
|
<SquiggleEditor initialSquiggleString="quantile(normal(0,1),0.5)" />
|
||||||
|
|
||||||
#### Validity
|
#### Validity
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,6 @@ ozzie_estimate(1) * nuno_estimate(1, 1)`}
|
||||||
|
|
||||||
## See more
|
## See more
|
||||||
|
|
||||||
- [Distribution creation](./Distributions)
|
- [Distribution creation](./DistributionCreation)
|
||||||
- [Functions reference](./Functions)
|
- [Functions reference](./Functions)
|
||||||
- [Gallery](../Discussions/Gallery)
|
- [Gallery](../Discussions/Gallery)
|
||||||
|
|
|
@ -122,14 +122,14 @@ TODO
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
## `pdf`, `cdf`, and `inv`
|
## `pdf`, `cdf`, and `quantile`
|
||||||
|
|
||||||
With $\forall dist, pdf := x \mapsto \texttt{pdf}(dist, x) \land cdf := x \mapsto \texttt{cdf}(dist, x) \land inv := p \mapsto \texttt{inv}(dist, p)$,
|
With $\forall dist, pdf := x \mapsto \texttt{pdf}(dist, x) \land cdf := x \mapsto \texttt{cdf}(dist, x) \land quantile := p \mapsto \texttt{quantile}(dist, p)$,
|
||||||
|
|
||||||
### `cdf` and `inv` are inverses
|
### `cdf` and `quantile` are inverses
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\forall x \in (0,1), cdf(inv(x)) = x \land \forall x \in \texttt{dom}(cdf), x = inv(cdf(x))
|
\forall x \in (0,1), cdf(quantile(x)) = x \land \forall x \in \texttt{dom}(cdf), x = quantile(cdf(x))
|
||||||
$$
|
$$
|
||||||
|
|
||||||
### The codomain of `cdf` equals the open interval `(0,1)` equals the codomain of `pdf`
|
### The codomain of `cdf` equals the open interval `(0,1)` equals the codomain of `pdf`
|
||||||
|
|
|
@ -25,7 +25,7 @@ $$
|
||||||
a \cdot Normal(\mu, \sigma) = Normal(a \cdot \mu, |a| \cdot \sigma)
|
a \cdot Normal(\mu, \sigma) = Normal(a \cdot \mu, |a| \cdot \sigma)
|
||||||
$$
|
$$
|
||||||
|
|
||||||
We can now look at the inverse cdf of a $Normal(0,1)$. We find that the 95% point is reached at $1.6448536269514722$. ([source](https://stackoverflow.com/questions/20626994/how-to-calculate-the-inverse-of-the-normal-cumulative-distribution-function-in-p)) This means that the 90% confidence interval is $[-1.6448536269514722, 1.6448536269514722]$, which has a width of $2 \cdot 1.6448536269514722$.
|
We can now look at the quantile of a $Normal(0,1)$. We find that the 95% point is reached at $1.6448536269514722$. ([source](https://stackoverflow.com/questions/20626994/how-to-calculate-the-inverse-of-the-normal-cumulative-distribution-function-in-p)) This means that the 90% confidence interval is $[-1.6448536269514722, 1.6448536269514722]$, which has a width of $2 \cdot 1.6448536269514722$.
|
||||||
|
|
||||||
So then, if we take a $Normal(0,1)$ and we multiply it by $\frac{(high -. low)}{(2. *. 1.6448536269514722)}$, it's 90% confidence interval will be multiplied by the same amount. Then we just have to shift it by the mean to get our target normal.
|
So then, if we take a $Normal(0,1)$ and we multiply it by $\frac{(high -. low)}{(2. *. 1.6448536269514722)}$, it's 90% confidence interval will be multiplied by the same amount. Then we just have to shift it by the mean to get our target normal.
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ const config = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "doc",
|
type: "doc",
|
||||||
docId: "Api/Dictionary",
|
docId: "Api/DistGeneric",
|
||||||
position: "left",
|
position: "left",
|
||||||
label: "API",
|
label: "API",
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,6 +26,11 @@ const sidebars = {
|
||||||
id: "Introduction",
|
id: "Introduction",
|
||||||
label: "Introduction",
|
label: "Introduction",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "doc",
|
||||||
|
id: "Node-Packages",
|
||||||
|
label: "Node Packages",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "category",
|
type: "category",
|
||||||
label: "Guides",
|
label: "Guides",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user