simple stuff

This commit is contained in:
Alain Zscheile 2024-01-02 03:23:36 +01:00
parent 5e7a5bd576
commit a904c932e1

View file

@ -1,3 +1,5 @@
use core::ops;
pub struct Variable {
pub name: &'static str,
}
@ -6,18 +8,68 @@ pub struct Value<'vs, T> {
vars: &'vs [Variable],
max_deriv: usize,
/// structure (e.g. 3 variables, 2 derivatives):
/// (0,0,0) - the value
/// (0,0,1) - first derivative first var
/// (0,0,2) - second derivative first var
/// (0,1,0) - first derivative second var
/// (0,1,1) - dx dy
/// (0,2,0) - second derivative second var
/// (1,0,0) - first derivative third var
/// (1,0,1) - dx dz
/// (1,1,0) - dy dz
/// (2,0,0) - second derivative third var
// structure, see `grad_enc`.
vgs: Vec<T>,
}
mod grad_enc;
impl<'vs, T> Value<'vs, T> {
pub fn same_vars<T2>(&self, oth: &Value<'vs, T2>) -> bool {
core::ptr::eq(self.vars, oth.vars)
}
}
impl<'vs, L, R, T> ops::Add<Value<'vs, R>> for Value<'vs, L>
where
L: ops::Add<R, Output = T>,
{
type Output = Value<'vs, T>;
fn add(self, oth: Value<'vs, R>) -> Value<'vs, T> {
assert!(self.same_vars(&oth));
assert_eq!(self.max_deriv, oth.max_deriv);
assert_eq!(self.vgs.len(), oth.vgs.len());
Value {
vars: self.vars,
max_deriv: self.max_deriv,
vgs: self.vgs.into_iter().zip(oth.vgs.into_iter()).map(|(a, b)| a + b).collect(),
}
}
}
impl<'vs, L, R, T> ops::Sub<Value<'vs, R>> for Value<'vs, L>
where
L: ops::Sub<R, Output = T>,
{
type Output = Value<'vs, T>;
fn sub(self, oth: Value<'vs, R>) -> Value<'vs, T> {
assert!(self.same_vars(&oth));
assert_eq!(self.max_deriv, oth.max_deriv);
assert_eq!(self.vgs.len(), oth.vgs.len());
Value {
vars: self.vars,
max_deriv: self.max_deriv,
vgs: self.vgs.into_iter().zip(oth.vgs.into_iter()).map(|(a, b)| a - b).collect(),
}
}
}
impl<'vs, T: ops::AddAssign> ops::AddAssign for Value<'vs, T> {
fn add_assign(&mut self, oth: Self) {
assert!(self.same_vars(&oth));
assert_eq!(self.max_deriv, oth.max_deriv);
assert_eq!(self.vgs.len(), oth.vgs.len());
self.vgs.iter_mut().zip(oth.vgs.into_iter()).for_each(|(a, b)| *a += b);
}
}
impl<'vs, T: ops::SubAssign> ops::SubAssign for Value<'vs, T> {
fn sub_assign(&mut self, oth: Self) {
assert!(self.same_vars(&oth));
assert_eq!(self.max_deriv, oth.max_deriv);
assert_eq!(self.vgs.len(), oth.vgs.len());
self.vgs.iter_mut().zip(oth.vgs.into_iter()).for_each(|(a, b)| *a -= b);
}
}