use crate::{variable::Variable, Arity, Vertex};
use std::cell::RefCell;
#[derive(Debug, Clone)]
pub struct Graph {
pub vertices: RefCell<Vec<Vertex>>,
}
impl Default for Graph {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl Graph {
#[must_use]
#[inline]
pub const fn new() -> Self {
Self {
vertices: RefCell::new(Vec::new()),
}
}
#[must_use]
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Graph {
vertices: RefCell::new(Vec::with_capacity(capacity)),
}
}
#[must_use]
#[inline]
pub fn join(&self, other: &Self) -> Self {
let graph = self.clone();
let other = other.vertices.borrow_mut().clone();
graph.vertices.borrow_mut().extend(other);
graph
}
#[inline]
pub fn var(&self, value: f64) -> Variable {
Variable {
graph: self,
value,
index: self.push(Arity::Nullary, &[], &[]),
}
}
#[inline]
pub fn vars<'v>(&'v self, values: &[f64]) -> Vec<Variable<'v>> {
values.iter().map(|&val| self.var(val)).collect()
}
#[inline]
pub fn len(&self) -> usize {
self.vertices.borrow().len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.vertices.borrow().len() == 0
}
#[inline]
pub fn clear(&self) {
self.vertices.borrow_mut().clear();
}
#[inline]
pub fn zero(&self) {
self.vertices
.borrow_mut()
.iter_mut()
.for_each(|vertex| vertex.partials = [0.0; 2]);
}
#[inline]
pub fn push(&self, arity: Arity, parents: &[usize], partials: &[f64]) -> usize {
let mut vertices = self.vertices.borrow_mut();
let len = vertices.len();
let vertex = match arity {
Arity::Nullary => {
assert!(parents.is_empty());
Vertex {
partials: [0.0, 0.0],
parents: [len, len],
}
}
Arity::Unary => {
assert!(parents.len() == 1);
Vertex {
partials: [partials[0], 0.0],
parents: [parents[0], len],
}
}
Arity::Binary => {
assert!(parents.len() == 2);
Vertex {
partials: [partials[0], partials[1]],
parents: [parents[0], parents[1]],
}
}
};
vertices.push(vertex);
len
}
}