use alloc::sync::Arc;
use alloc::vec::Vec;
use core::cell::RefCell;
#[derive(Clone, Debug)]
pub(crate) struct Op {
pub inputs: [usize; 2],
pub num_inputs: u8,
pub partials: [f64; 2],
}
#[derive(Debug)]
pub struct Tape {
pub(crate) ops: RefCell<Vec<Op>>,
}
impl Tape {
pub fn new() -> Arc<Self> {
Arc::new(Self {
ops: RefCell::new(Vec::new()),
})
}
pub fn var(self: &Arc<Self>, value: f64) -> super::Var {
let mut ops = self.ops.borrow_mut();
let index = ops.len();
ops.push(Op {
inputs: [0, 0],
num_inputs: 0,
partials: [0.0, 0.0],
});
super::Var {
index,
value,
tape: Arc::clone(self),
}
}
pub(crate) fn unary(self: &Arc<Self>, input: usize, value: f64, partial: f64) -> super::Var {
let mut ops = self.ops.borrow_mut();
let index = ops.len();
ops.push(Op {
inputs: [input, 0],
num_inputs: 1,
partials: [partial, 0.0],
});
super::Var {
index,
value,
tape: Arc::clone(self),
}
}
pub(crate) fn binary(
self: &Arc<Self>,
a: usize,
b: usize,
value: f64,
da: f64,
db: f64,
) -> super::Var {
let mut ops = self.ops.borrow_mut();
let index = ops.len();
ops.push(Op {
inputs: [a, b],
num_inputs: 2,
partials: [da, db],
});
super::Var {
index,
value,
tape: Arc::clone(self),
}
}
}