squiggle/packages/squiggle-lang/src/rescript/Utility/Operation.res

122 lines
2.9 KiB
Plaintext
Raw Normal View History

// This file has no dependencies. It's used outside of the interpreter, but the interpreter depends on it.
2022-03-22 02:33:28 +00:00
@genType
type algebraicOperation = [
| #Add
| #Multiply
| #Subtract
| #Divide
2022-04-09 16:37:26 +00:00
| #Power
| #Logarithm
]
2022-03-22 02:33:28 +00:00
@genType
2022-04-09 16:37:26 +00:00
type pointwiseOperation = [#Add | #Multiply | #Power]
type scaleOperation = [#Multiply | #Power | #Logarithm | #Divide]
type distToFloatOperation = [
| #Pdf(float)
| #Cdf(float)
| #Inv(float)
| #Mean
| #Sample
]
2022-02-06 23:10:39 +00:00
module Algebraic = {
type t = algebraicOperation
let toFn: (t, float, float) => float = x =>
switch x {
| #Add => \"+."
| #Subtract => \"-."
| #Multiply => \"*."
2022-04-09 16:37:26 +00:00
| #Power => \"**"
2022-02-06 23:10:39 +00:00
| #Divide => \"/."
| #Logarithm => (a, b) => log(a) /. log(b)
2022-02-06 23:10:39 +00:00
}
let applyFn = (t, f1, f2) =>
switch (t, f1, f2) {
| (#Divide, _, 0.) => Error("Cannot divide $v1 by zero.")
| _ => Ok(toFn(t, f1, f2))
}
let toString = x =>
switch x {
| #Add => "+"
| #Subtract => "-"
| #Multiply => "*"
2022-04-09 16:37:26 +00:00
| #Power => "**"
2022-02-06 23:10:39 +00:00
| #Divide => "/"
| #Logarithm => "log"
2022-02-06 23:10:39 +00:00
}
let format = (a, b, c) => b ++ (" " ++ (toString(a) ++ (" " ++ c)))
}
module Pointwise = {
type t = pointwiseOperation
let toString = x =>
switch x {
| #Add => "+"
2022-04-10 00:36:33 +00:00
| #Power => "**"
2022-02-06 23:10:39 +00:00
| #Multiply => "*"
}
let format = (a, b, c) => b ++ (" " ++ (toString(a) ++ (" " ++ c)))
}
module DistToFloat = {
type t = distToFloatOperation
let format = (operation, value) =>
switch operation {
| #Cdf(f) => j`cdf(x=$f,$value)`
| #Pdf(f) => j`pdf(x=$f,$value)`
| #Inv(f) => j`inv(x=$f,$value)`
| #Sample => "sample($value)"
| #Mean => "mean($value)"
}
}
// Note that different logarithms don't really do anything.
module Scale = {
type t = scaleOperation
let toFn = x =>
switch x {
| #Multiply => \"*."
| #Divide => \"/."
2022-04-09 16:37:26 +00:00
| #Power => \"**"
| #Logarithm => (a, b) => log(a) /. log(b)
2022-02-06 23:10:39 +00:00
}
let format = (operation: t, value, scaleBy) =>
switch operation {
| #Multiply => j`verticalMultiply($value, $scaleBy) `
| #Divide => j`verticalDivide($value, $scaleBy) `
2022-04-09 16:37:26 +00:00
| #Power => j`verticalPower($value, $scaleBy) `
| #Logarithm => j`verticalLog($value, $scaleBy) `
2022-02-06 23:10:39 +00:00
}
let toIntegralSumCacheFn = x =>
switch x {
| #Multiply => (a, b) => Some(a *. b)
| #Divide => (a, b) => Some(a /. b)
2022-04-09 16:37:26 +00:00
| #Power => (_, _) => None
| #Logarithm => (_, _) => None
2022-02-06 23:10:39 +00:00
}
let toIntegralCacheFn = x =>
switch x {
2022-02-17 14:50:43 +00:00
| #Multiply => (_, _) => None // TODO: this could probably just be multiplied out (using Continuous.scaleBy)
| #Divide => (_, _) => None
2022-04-09 16:37:26 +00:00
| #Power => (_, _) => None
| #Logarithm => (_, _) => None
2022-02-06 23:10:39 +00:00
}
}
module Truncate = {
let toString = (left: option<float>, right: option<float>, nodeToString) => {
2022-02-06 23:10:39 +00:00
let left = left |> E.O.dimap(Js.Float.toString, () => "-inf")
let right = right |> E.O.dimap(Js.Float.toString, () => "inf")
j`truncate($nodeToString, $left, $right)`
}
2022-03-22 02:33:28 +00:00
}