Probly is a Python-like mini-language for probabilistic estimation. It's based on Starlark and implemented in Go.
You may use any Starlark syntax. There are only the following differences to Starlark:
math
module is imported by default, so you can directly use it e.g. math.sqrt(2)
. Probly also has a built-in sum
function not available in Starlark.This page will show you the probability distributions of all the numeric (scalar or distribution) global variables in your program (except those starting with an underscore). The values are taken at the end of the program's execution.
Name | to p10 to p90 |
pm plus/minus |
td times/divide |
Quantiles | Notes | |||||
---|---|---|---|---|---|---|---|---|---|---|
Normal |
mean |
sd |
2 | |||||||
LogNormal |
mu |
sigma |
2 | Alternatively: mean , sd |
||||||
Beta |
alpha |
beta |
||||||||
PERT |
min |
mode |
max |
[lambd] |
Like the triangular, but smoother (Wikipedia) | |||||
Uniform |
a |
b |
2 | a need not be less than b |
||||||
LogUniform |
a |
b |
2 | a need not be less than b |
||||||
Bernoulli |
p |
|||||||||
Binomial |
n |
p |
||||||||
Discrete |
x_1 |
p_1 |
x_2 |
p_2 |
... | Generic discrete distribution over any finite set of values |
These mathematical functions and constants are available in the math
module:
pow(x, y)
- Returns x raised to the power of yexp(x)
sqrt(x)
log(x, [base])
- Natural logarithm by default if base is not specifiede
pi
ceil(x)
floor(x)
fabs(x)
- Returns the absolute value of x as floatcopysign(x, y)
- Returns a value with the magnitude of x and the sign of ymod(x, y)
- Returns x
modulo y
remainder(x, y)
round(x)
- Returns the nearest integer, rounding half away from zeroacos(x)
asin(x)
atan(x)
atan2(y, x)
- Returns atan(y / x). The result is between -pi and picos(x)
sin(x)
tan(x)
degrees(x)
- Converts angle x from radians to degreesradians(x)
- Converts angle x from degrees to radiansacosh(x)
asinh(x)
atanh(x)
cosh(x)
sinh(x)
tanh(x)
hypot(x, y)
- Returns the Euclidean norm, sqrt(x^2 + y^2); the distance from the origin to (x, y)gamma(x)
- Returns the Gamma function at xThis code provides an example of the syntax of Starlark:
# Define a number
number = 18
# Define a list
numbers = [1, 2, 3, 4, 5]
# List comprehension
halves = [n / 2 for n in numbers]
# Define a function
def is_even(n):
"""Return True if n is even."""
return n % 2 == 0
# Define a dictionary
people = {
"Alice": 22,
"Bob": 40,
"Charlie": 55,
"Dave": 14,
}
names = ", ".join(people.keys()) # Alice, Bob, Charlie, Dave
# Modify a variable in a loop
sum_even_ages = 0
for age in people.values():
if is_even(age):
sum_even_ages += age
# Append to a list in a loop
over_30_names = []
for name, age in people.items():
if age > 30:
over_30_names.append(name)
If you've ever used Python, this should look very familiar. In fact, the code above is also valid Python code. Still, this short example shows most of the language. Starlark is a very small language that implements a limited subset of Python.
For our purposes, one notable difference to Python is that the exponentiation operator **
is not supported. You have to use math.pow
.
You can also look at the Starlark language specification.
Though not designed for speed, Probly is fast enough for practical purposes: around 10 milliseconds for 3,000 samples, for most examples on this page. This is due to being implemented in Go.
The time taken to return results on this page is spent overwhelmingly in web application code, not in Probly evaluation.
Interestingly, Probly is still slower than Python code that uses entirely numpy
array operations, which are very well optimised.
This should only begin to matter at very large scales, or if latency is critical.
It's not currently possible to obtain and manipulate properties of a distribution within an Probly program, like so:
x = Normal(1 to 10)
y = x.std() # Not possible
Supporting this would require some fundamental changes to the implementation of Probly, which is currently very simplistic.
The to
binary operator was inspired by Squiggle.
This example follows Section 3 of Dissolving the Fermi Paradox (Sandberg and colleagues, 2018).
From the abstract:
[The Fermi paradox] arises from the use of Drake-like equations, which implicitly assume certainty regarding highly uncertain parameters. ... When the model is recast to represent realistic distributions of uncertainty, we find a substantial ex ante probability of there being no other intelligent life in our observable universe, and thus that there should be little surprise when we fail to detect any signs of it.
The results of our simulation should approximately match Figure 2 of the paper:
The mean for N is [...] 27 million, but the median is now only 0.32 – less than one civilization per galaxy like our own. The probability of N<1 is now 52%.
Mean | 20.8 E 6 |
Std. dev. | 277 E 6 |
Variance | 76.9 E 15 |
Quantile | |
---|---|
0.05 | 0 |
0.25 | 79.4 E -12 |
0.50 | 1.98 |
0.75 | 6 360 |
0.95 | 9.11 E 6 |
Mean | 550 E 6 |
Std. dev. | 1.57 E 9 |
Variance | 2.46 E 18 |
Quantile | |
---|---|
0.05 | 253 |
0.25 | 10 600 |
0.50 | 1.00 E 6 |
0.75 | 118 E 6 |
0.95 | 3.81 E 9 |
Mean | 0.210 |
Std. dev. | 0.246 |
Variance | 0.060 5 |
Quantile | |
---|---|
0.05 | 0.012 9 |
0.25 | 0.032 8 |
0.50 | 0.099 7 |
0.75 | 0.300 |
0.95 | 0.796 |
Mean | 0.148 |
Std. dev. | 0.232 |
Variance | 0.053 7 |
Quantile | |
---|---|
0.05 | 0.001 35 |
0.25 | 0.005 52 |
0.50 | 0.031 2 |
0.75 | 0.179 |
0.95 | 0.714 |
Mean | 0.515 |
Std. dev. | 0.495 |
Variance | 0.245 |
Quantile | |
---|---|
0.05 | 0 |
0.25 | 49.2 E -15 |
0.50 | 0.981 |
0.75 | 1.00 |
0.95 | 1.00 |
Mean | 1.97 E 69 |
Std. dev. | 108 E 69 |
Variance | 11.6 E 141 |
Quantile | |
---|---|
0.05 | 8.12 E -36 |
0.25 | 49.2 E -15 |
0.50 | 3.95 |
0.75 | 1.46 E 15 |
0.95 | 2.17 E 36 |
Mean | 0.387 |
Std. dev. | 0.245 |
Variance | 0.060 2 |
Quantile | |
---|---|
0.05 | 0.112 |
0.25 | 0.179 |
0.50 | 0.319 |
0.75 | 0.544 |
0.95 | 0.887 |
Mean | 0.387 |
Std. dev. | 0.253 |
Variance | 0.064 0 |
Quantile | |
---|---|
0.05 | 0.112 |
0.25 | 0.173 |
0.50 | 0.310 |
0.75 | 0.554 |
0.95 | 0.902 |
Mean | 21.8 |
Std. dev. | 25.5 |
Variance | 652 |
Quantile | |
---|---|
0.05 | 1.26 |
0.25 | 2.95 |
0.50 | 9.68 |
0.75 | 32.0 |
0.95 | 80.3 |
star_formation | planet | habitable | r_life | ... | intelligence | detectable | longevity | n | |
---|---|---|---|---|---|---|---|---|---|
0 | 9.68 | 0.329 | 0.553 | 49.3 E 9 | ... | 0.638 | 0.809 | 98.0 E 6 | 89.0 E 6 |
1 | 1.61 | 0.164 | 0.533 | 352 E 24 | ... | 0.001 30 | 0.419 | 11 300 | 0.869 |
2 | 30.2 | 0.965 | 0.756 | 762 | ... | 0.603 | 0.114 | 148 E 6 | 224 E 6 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2997 | 6.77 | 0.569 | 0.133 | 5.05 E 6 | ... | 0.016 5 | 0.013 1 | 1.38 E 9 | 152 000 |
2998 | 48.6 | 0.299 | 0.380 | 13.0 E 39 | ... | 0.160 | 0.090 4 | 336 | 26.7 |
2999 | 1.20 | 0.159 | 0.222 | 2.32 E -27 | ... | 0.036 4 | 0.095 3 | 6.10 E 6 | 0 |
Get the simulation data (and more) in a machine-readable format:
/api/sim/PVWUyjzGpQgmwfGSzzcGZV/