Compare commits
2 Commits
8b88beae88
...
7ff3b2148e
Author | SHA1 | Date | |
---|---|---|---|
7ff3b2148e | |||
c335917226 |
123
README.md
123
README.md
|
@ -1,17 +1,23 @@
|
||||||
# A minimalist calculator for f estimation
|
# A minimalist calculator for fermi estimation
|
||||||
|
|
||||||
This project is a minimalist, stack-based DSL for f estimation. It can multiply and divide scalars, lognormals and beta distributions.
|
This project is a minimalist, stack-based DSL for fermi estimation. It can multiply, divide, add and substract scalars, lognormals and beta distributions.
|
||||||
|
|
||||||
## Motivation
|
## Motivation
|
||||||
|
|
||||||
Sometimes, [Squiggle](https://github.com/quantified-uncertainty/squiggle), [simple squiggle](https://git.nunosempere.com/quantified.uncertainty/simple-squiggle) or [squiggle.c](https://git.nunosempere.com/personal/squiggle.c) are still too complicated and un-unix-like.
|
Sometimes, [Squiggle](https://github.com/quantified-uncertainty/squiggle), [simple squiggle](https://git.nunosempere.com/quantified.uncertainty/simple-squiggle) or [squiggle.c](https://git.nunosempere.com/personal/squiggle.c) are still too complicated and un-unix-like.
|
||||||
|
|
||||||
## Usage
|
## Installation
|
||||||
|
|
||||||
Here is an example
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ go run f.go
|
make build
|
||||||
|
sudo make install
|
||||||
|
fermi
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
$ fermi
|
||||||
5000000 12000000
|
5000000 12000000
|
||||||
=> 5.0M 12.0M
|
=> 5.0M 12.0M
|
||||||
* beta 1 200
|
* beta 1 200
|
||||||
|
@ -31,18 +37,18 @@ $ go run f.go
|
||||||
Perhaps this example is more understandable with comments and better units:
|
Perhaps this example is more understandable with comments and better units:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ sed -u "s|#.*||" | sed -u 's|M|000000|g' | go run f.go
|
$ fermi
|
||||||
5M 12M # number of people living in Chicago
|
5M 12M # number of people living in Chicago
|
||||||
=> 5.0M 12.0M
|
=> 5.0M 12.0M
|
||||||
* beta 1 200 # fraction of people that have a piano
|
* beta 1 200 # fraction of people that have a piano
|
||||||
1.9K 123.1K
|
1.9K 123.1K
|
||||||
30 180 # minutes it takes to tune a piano, including travel time
|
30 180 # minutes it takes to tune a piano, including travel time
|
||||||
122.9K 11.7M
|
122.9K 11.7M
|
||||||
/ 48 52 # weeks a year pianotuners work for
|
/ 48 52 # weeks a year pianotuners work for
|
||||||
2.5K 234.6K
|
2.5K 234.6K
|
||||||
/ 6 8 # hours a day
|
/ 6 8 # hours a day
|
||||||
353.9 34.1K
|
353.9 34.1K
|
||||||
/ 60 # minutes to an hour
|
/ 60 # minutes to an hour
|
||||||
5.9 568.3
|
5.9 568.3
|
||||||
=: piano_tuners_in_Chicago
|
=: piano_tuners_in_Chicago
|
||||||
piano_tuners_in_Chicago => 5.9 568.3
|
piano_tuners_in_Chicago => 5.9 568.3
|
||||||
|
@ -51,6 +57,7 @@ piano_tuners_in_Chicago => 5.9 568.3
|
||||||
Here is instead an example using beta distributions and variables:
|
Here is instead an example using beta distributions and variables:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
$ fermi
|
||||||
1 2
|
1 2
|
||||||
=> 1.0 2.0
|
=> 1.0 2.0
|
||||||
* 1_000_000_000
|
* 1_000_000_000
|
||||||
|
@ -77,69 +84,41 @@ The difference between `=: x` and `=. y` is that `=.` clears the stack after the
|
||||||
If you type "help", you can see a small grammar:
|
If you type "help", you can see a small grammar:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
$ fermi
|
||||||
help
|
help
|
||||||
Operation | Variable assignment | Special
|
Operation | Variable assignment | Special
|
||||||
Operation: operator operand
|
Operation: operator operand
|
||||||
operator: (empty) | * | / | + | -
|
operator: (empty) | * | / | + | -
|
||||||
operand: scalar | lognormal | beta | variable
|
operand: scalar | lognormal | beta | variable
|
||||||
lognormal: low high
|
lognormal: low high
|
||||||
beta: beta alpha beta
|
beta: beta alpha beta
|
||||||
Variable assignment: =: variable_name
|
Variable assignment: =: variable_name
|
||||||
Clear stack: . | c | clear
|
Variable assignment and clear stack: =. variable_name
|
||||||
Variable assignment and clear stack: =. variable_name
|
Special:
|
||||||
Other special operations: help | debug | exit
|
Clear stack: clear | c | .
|
||||||
Examples:
|
Print this help message: help | h
|
||||||
+ 2
|
Print debug info: debug | d
|
||||||
/ 2.5
|
Exit: exit | e
|
||||||
* 1 10 (interpreted as lognormal)
|
Comment: # this is a comment
|
||||||
+ 1 10
|
Examples:
|
||||||
* beta 1 10
|
+ 2
|
||||||
1 10 (multiplication taken as default operation)
|
/ 2.5
|
||||||
=: x
|
* 1 10 (interpreted as lognormal)
|
||||||
.
|
+ 1 10
|
||||||
1 100
|
* beta 1 10
|
||||||
+ x
|
1 10 (multiplication taken as default operation)
|
||||||
exit
|
=: x
|
||||||
|
.
|
||||||
|
1 100
|
||||||
|
+ x
|
||||||
|
# this is a comment
|
||||||
|
* 1 12 # this is an operation followed by a comment
|
||||||
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
make build
|
|
||||||
sudo make install
|
|
||||||
f # rather than the previous go run f.go
|
|
||||||
```
|
|
||||||
|
|
||||||
Why use make instead of the built-in go commands? Because the point of make is to be able to share command-line recipes.
|
|
||||||
|
|
||||||
## Usage together with standard Linux utilities
|
|
||||||
|
|
||||||
```bash
|
|
||||||
f
|
|
||||||
sed -u "s|#.*||" | sed -u 's|M|000000|g' | f
|
|
||||||
|
|
||||||
cat more/piano-tuners.f | f
|
|
||||||
cat more/piano-tuners-commented.f | sed -u "s|#.*||" | sed -u 's|M|000000|g' | f
|
|
||||||
|
|
||||||
tee -a input.log | go run f.go | tee -a output.log
|
|
||||||
tee -a io.log | go run f.go | tee -a io.log
|
|
||||||
|
|
||||||
function f(){
|
|
||||||
sed -u "s|#.*||" |
|
|
||||||
sed -u "s|//.*||" |
|
|
||||||
sed -u 's|K|000|g' |
|
|
||||||
sed -u 's|M|000000|g' |
|
|
||||||
sed -u 's|B|000000000|g' |
|
|
||||||
/usr/bin/f
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that these sed commands are just hacks, and won't parse e.g., `3.5K` correctly—it will just substitute for 3.5000
|
|
||||||
|
|
||||||
## Tips & tricks
|
## Tips & tricks
|
||||||
|
|
||||||
- It's conceptually clearer to have all the multiplications first and then all the divisions
|
- It's conceptually clearer to have all the multiplications first and then all the divisions
|
||||||
- Sums and divisions now also supported
|
|
||||||
- For things between 0 and 1, consider using a beta distribution
|
- For things between 0 and 1, consider using a beta distribution
|
||||||
|
|
||||||
## Different levels of complexity
|
## Different levels of complexity
|
||||||
|
@ -159,6 +138,7 @@ Done:
|
||||||
- [x] Save to file?
|
- [x] Save to file?
|
||||||
- [x] Allow comments?
|
- [x] Allow comments?
|
||||||
- [x] Use a sed filter?
|
- [x] Use a sed filter?
|
||||||
|
- [x] Add proper comment processing
|
||||||
- [x] Add show more info version
|
- [x] Add show more info version
|
||||||
- [x] Scalar multiplication and division
|
- [x] Scalar multiplication and division
|
||||||
- [x] Think how to integrate with squiggle.c to draw samples
|
- [x] Think how to integrate with squiggle.c to draw samples
|
||||||
|
@ -169,6 +149,7 @@ Done:
|
||||||
- [x] Consider the following: make this into a stack-based DSL, with:
|
- [x] Consider the following: make this into a stack-based DSL, with:
|
||||||
- [x] Variables that can be saved to and then displayed
|
- [x] Variables that can be saved to and then displayed
|
||||||
- [x] Other types of distributions, particularly beta distributions? => But then this requires moving to bags of samples. It could still be ~instantaneous though.
|
- [x] Other types of distributions, particularly beta distributions? => But then this requires moving to bags of samples. It could still be ~instantaneous though.
|
||||||
|
- [x] Added bags of samples to support addition and multiplication of betas and lognormals
|
||||||
- [x] Figure out go syntax for
|
- [x] Figure out go syntax for
|
||||||
- Maps
|
- Maps
|
||||||
- Joint types
|
- Joint types
|
||||||
|
@ -176,11 +157,11 @@ Done:
|
||||||
- [x] Fix correlation problem, by spinning up a new randomness thing every time some serial computation is done.
|
- [x] Fix correlation problem, by spinning up a new randomness thing every time some serial computation is done.
|
||||||
- [x] Clean up error code. Right now only needed for division
|
- [x] Clean up error code. Right now only needed for division
|
||||||
- [x] Maintain *both* a more complex thing that's more featureful *and* the more simple multiplication of lognormals thing.
|
- [x] Maintain *both* a more complex thing that's more featureful *and* the more simple multiplication of lognormals thing.
|
||||||
|
- [x] Allow input with K/M/T
|
||||||
|
|
||||||
To (possibly) do:
|
To (possibly) do:
|
||||||
|
|
||||||
- [ ] Document parenthesis syntax
|
- [ ] Document parenthesis syntax
|
||||||
- [ ] Allow input with K/M/T
|
|
||||||
- [ ] Add functions. Now easier to do with an explicit representation of the stakc
|
- [ ] Add functions. Now easier to do with an explicit representation of the stakc
|
||||||
- [ ] Think about how to draw a histogram from samples
|
- [ ] Think about how to draw a histogram from samples
|
||||||
- [ ] Dump samples to file
|
- [ ] Dump samples to file
|
||||||
|
|
24
f.go
24
f.go
|
@ -71,9 +71,15 @@ const HELP_MSG = " Operation | Variable assignment | Special\n" +
|
||||||
" lognormal: low high\n" +
|
" lognormal: low high\n" +
|
||||||
" beta: beta alpha beta\n" +
|
" beta: beta alpha beta\n" +
|
||||||
" Variable assignment: =: variable_name\n" +
|
" Variable assignment: =: variable_name\n" +
|
||||||
" Clear stack: . | c | clear\n" +
|
|
||||||
" Variable assignment and clear stack: =. variable_name\n" +
|
" Variable assignment and clear stack: =. variable_name\n" +
|
||||||
" Other special operations: help | debug | exit\n" +
|
" Special: \n" +
|
||||||
|
" Comment: # this is a comment\n" +
|
||||||
|
" Clear stack: clear | c | .\n" +
|
||||||
|
" Print debug info: debug | d\n" +
|
||||||
|
" Print help message: help | h\n" +
|
||||||
|
" Start additional stack: operator (\n" +
|
||||||
|
" Return from additional stack )\n" +
|
||||||
|
" Exit: exit | e\n" +
|
||||||
" Examples: \n" +
|
" Examples: \n" +
|
||||||
" + 2\n" +
|
" + 2\n" +
|
||||||
" / 2.5\n" +
|
" / 2.5\n" +
|
||||||
|
@ -85,7 +91,14 @@ const HELP_MSG = " Operation | Variable assignment | Special\n" +
|
||||||
" .\n" +
|
" .\n" +
|
||||||
" 1 100\n" +
|
" 1 100\n" +
|
||||||
" + x\n" +
|
" + x\n" +
|
||||||
|
" # this is a comment\n" +
|
||||||
|
" * 1 12 # this is an operation followed by a comment\n" +
|
||||||
|
" * (\n" +
|
||||||
|
" 1 10\n" +
|
||||||
|
" + beta 1 100\n" +
|
||||||
|
" )\n" +
|
||||||
" exit\n"
|
" exit\n"
|
||||||
|
|
||||||
const NORMAL90CONFIDENCE = 1.6448536269514727
|
const NORMAL90CONFIDENCE = 1.6448536269514727
|
||||||
const INIT_DIST Scalar = Scalar(1)
|
const INIT_DIST Scalar = Scalar(1)
|
||||||
const N_SAMPLES = 1_000_000
|
const N_SAMPLES = 1_000_000
|
||||||
|
@ -345,9 +358,12 @@ func runRepl(stack Stack, reader *bufio.Reader) Stack {
|
||||||
replForLoop:
|
replForLoop:
|
||||||
for {
|
for {
|
||||||
new_line, _ := reader.ReadString('\n')
|
new_line, _ := reader.ReadString('\n')
|
||||||
words := strings.Split(strings.TrimSpace(new_line), " ")
|
new_line_before_comments, _, _ := strings.Cut(new_line, "#")
|
||||||
|
new_line_trimmed := strings.TrimSpace(new_line_before_comments)
|
||||||
|
words := strings.Split(new_line_trimmed, " ")
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case strings.TrimSpace(new_line) == "": /* Empty line case */
|
case strings.TrimSpace(new_line_trimmed) == "": /* Empty line case */
|
||||||
/* Parenthesis */
|
/* Parenthesis */
|
||||||
case len(words) == 2 && (words[0] == "*" || words[0] == "+" || words[0] == "-" || words[0] == "/") && words[1] == "(":
|
case len(words) == 2 && (words[0] == "*" || words[0] == "+" || words[0] == "-" || words[0] == "/") && words[1] == "(":
|
||||||
new_stack := runRepl(Stack{old_dist: INIT_DIST, vars: stack.vars}, reader)
|
new_stack := runRepl(Stack{old_dist: INIT_DIST, vars: stack.vars}, reader)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user