use knok_core::{CallOp, Expr};
use super::{
context::{tuple_id, TraceVars},
tensor::{ScalarLiteral, TraceTensor, T0},
};
pub trait RandomFloatElement: ScalarLiteral {
fn zero() -> Self;
fn one() -> Self;
}
impl RandomFloatElement for f32 {
fn zero() -> Self {
0.0
}
fn one() -> Self {
1.0
}
}
impl RandomFloatElement for f64 {
fn zero() -> Self {
0.0
}
fn one() -> Self {
1.0
}
}
pub trait RandomIntElement: ScalarLiteral {}
impl RandomIntElement for i32 {}
impl RandomIntElement for i64 {}
pub fn uniform_static<Output>(seed: u64, low: Output::Elem, high: Output::Elem) -> Output
where
Output: TraceTensor,
Output::Elem: RandomFloatElement,
{
trace_static_random_uniform(seed, low, high)
}
fn trace_static_random_uniform<Output>(seed: u64, low: Output::Elem, high: Output::Elem) -> Output
where
Output: TraceTensor,
Output::Elem: RandomFloatElement,
{
Output::from_expr(Expr::Call {
op: CallOp::StaticRandomUniform {
target: Output::tensor_type(),
seed,
},
args: vec![low.const_expr(), high.const_expr()],
})
}
pub fn randint_static<Output>(seed: u64, low: Output::Elem, high: Output::Elem) -> Output
where
Output: TraceTensor,
Output::Elem: RandomIntElement,
{
trace_static_random_int(seed, low, high)
}
fn trace_static_random_int<Output>(seed: u64, low: Output::Elem, high: Output::Elem) -> Output
where
Output: TraceTensor,
Output::Elem: RandomIntElement,
{
Output::from_expr(Expr::Call {
op: CallOp::StaticRandomInt {
target: Output::tensor_type(),
seed,
},
args: vec![low.const_expr(), high.const_expr()],
})
}
pub fn uniform<Output>(key: T0<i64>, low: Output::Elem, high: Output::Elem) -> (Output, T0<i64>)
where
Output: TraceTensor,
Output::Elem: RandomFloatElement,
{
trace_random_uniform(key, low, high)
}
fn trace_random_uniform<Output>(
key: T0<i64>,
low: Output::Elem,
high: Output::Elem,
) -> (Output, T0<i64>)
where
Output: TraceTensor,
Output::Elem: RandomFloatElement,
{
let value = Expr::Call {
op: CallOp::RandomUniform(Output::tensor_type()),
args: vec![key.into_expr(), low.const_expr(), high.const_expr()],
};
<(Output, T0<i64>) as TraceVars>::from_tuple_expr(tuple_id(), value)
}
pub fn rand<Output>(key: T0<i64>) -> (Output, T0<i64>)
where
Output: TraceTensor,
Output::Elem: RandomFloatElement,
{
uniform(key, Output::Elem::zero(), Output::Elem::one())
}
pub fn randint<Output>(key: T0<i64>, low: Output::Elem, high: Output::Elem) -> (Output, T0<i64>)
where
Output: TraceTensor,
Output::Elem: RandomIntElement,
{
trace_random_int(key, low, high)
}
fn trace_random_int<Output>(
key: T0<i64>,
low: Output::Elem,
high: Output::Elem,
) -> (Output, T0<i64>)
where
Output: TraceTensor,
Output::Elem: RandomIntElement,
{
let value = Expr::Call {
op: CallOp::RandomInt(Output::tensor_type()),
args: vec![key.into_expr(), low.const_expr(), high.const_expr()],
};
<(Output, T0<i64>) as TraceVars>::from_tuple_expr(tuple_id(), value)
}