use crate::algebra::{ar_product, Alpha, MultiVector, Term, AR};
#[derive(Hash, Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Serialize, Deserialize)]
pub struct ArDifferential {
wrt: Vec<Alpha>,
}
impl ArDifferential {
pub fn new(wrt: &[Alpha]) -> ArDifferential {
ArDifferential {
wrt: wrt.iter().map(|w| w.inverse()).collect(),
}
}
pub fn left_apply(&self, mvec: MultiVector) -> MultiVector {
self.apply(mvec, ApplyFrom::Left)
}
pub fn right_apply(&self, mvec: MultiVector) -> MultiVector {
self.apply(mvec, ApplyFrom::Right)
}
fn apply(&self, mvec: MultiVector, side: ApplyFrom) -> MultiVector {
MultiVector::from_terms(
mvec.as_terms()
.iter()
.flat_map(|t| {
self.wrt
.as_alphas()
.iter()
.map(|w| term_partial(t, w, side))
.collect::<Vec<Term>>()
})
.collect(),
)
}
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
enum ApplyFrom {
Left,
Right,
}
fn term_partial(term: &Term, wrt: &Alpha, side: ApplyFrom) -> Term {
let a: Alpha = match side {
ApplyFrom::Left => ar_product(wrt, &term.alpha()),
ApplyFrom::Right => ar_product(&term.alpha(), wrt),
};
let mut t = term.clone();
t.add_partial(wrt);
t.set_alpha(a);
return t;
}