use std::ops::{AddAssign, Neg};
use ::Data;
#[deprecated]
pub use self::Abelian as Diff;
pub trait Semigroup : for<'a> AddAssign<&'a Self> + ::std::marker::Sized + Data + Clone {
fn is_zero(&self) -> bool;
}
impl Semigroup for isize {
#[inline] fn is_zero(&self) -> bool { self == &0 }
}
impl Semigroup for i128 {
#[inline] fn is_zero(&self) -> bool { self == &0 }
}
impl Semigroup for i64 {
#[inline] fn is_zero(&self) -> bool { self == &0 }
}
impl Semigroup for i32 {
#[inline] fn is_zero(&self) -> bool { self == &0 }
}
impl Semigroup for i16 {
#[inline] fn is_zero(&self) -> bool { self == &0 }
}
impl Semigroup for i8 {
#[inline] fn is_zero(&self) -> bool { self == &0 }
}
pub trait Monoid : Semigroup {
fn zero() -> Self;
}
impl Monoid for isize {
#[inline] fn zero() -> Self { 0 }
}
impl Monoid for i128 {
#[inline] fn zero() -> Self { 0 }
}
impl Monoid for i64 {
#[inline] fn zero() -> Self { 0 }
}
impl Monoid for i32 {
#[inline] fn zero() -> Self { 0 }
}
impl Monoid for i16 {
#[inline] fn zero() -> Self { 0 }
}
impl Monoid for i8 {
#[inline] fn zero() -> Self { 0 }
}
pub trait Abelian : Monoid + Neg<Output=Self> { }
impl<T: Monoid + Neg<Output=Self>> Abelian for T { }
pub use self::present::Present;
mod present {
#[derive(Abomonation, Copy, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Serialize, Deserialize, Hash)]
pub struct Present;
impl<'a> std::ops::AddAssign<&'a Self> for Present {
fn add_assign(&mut self, _rhs: &'a Self) { }
}
impl<T> std::ops::Mul<T> for Present {
type Output = T;
fn mul(self, rhs: T) -> T {
rhs
}
}
impl super::Semigroup for Present {
fn is_zero(&self) -> bool { false }
}
}
pub use self::pair::DiffPair;
mod pair {
use std::ops::{AddAssign, Neg, Mul};
use super::{Semigroup, Monoid};
#[derive(Abomonation, Copy, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct DiffPair<R1, R2> {
pub element1: R1,
pub element2: R2,
}
impl<R1, R2> DiffPair<R1, R2> {
#[inline] pub fn new(elt1: R1, elt2: R2) -> Self {
DiffPair {
element1: elt1,
element2: elt2,
}
}
}
impl<R1: Semigroup, R2: Semigroup> Semigroup for DiffPair<R1, R2> {
#[inline] fn is_zero(&self) -> bool {
self.element1.is_zero() && self.element2.is_zero()
}
}
impl<'a, R1: AddAssign<&'a R1>, R2: AddAssign<&'a R2>> AddAssign<&'a DiffPair<R1, R2>> for DiffPair<R1, R2> {
#[inline] fn add_assign(&mut self, rhs: &'a Self) {
self.element1 += &rhs.element1;
self.element2 += &rhs.element2;
}
}
impl<R1: Neg, R2: Neg> Neg for DiffPair<R1, R2> {
type Output = DiffPair<<R1 as Neg>::Output, <R2 as Neg>::Output>;
#[inline] fn neg(self) -> Self::Output {
DiffPair {
element1: -self.element1,
element2: -self.element2,
}
}
}
impl<T: Copy, R1: Mul<T>, R2: Mul<T>> Mul<T> for DiffPair<R1,R2> {
type Output = DiffPair<<R1 as Mul<T>>::Output, <R2 as Mul<T>>::Output>;
fn mul(self, other: T) -> Self::Output {
DiffPair::new(
self.element1 * other,
self.element2 * other,
)
}
}
impl<R1: Monoid, R2: Monoid> Monoid for DiffPair<R1, R2> {
fn zero() -> Self {
Self {
element1: R1::zero(),
element2: R2::zero(),
}
}
}
}
pub use self::vector::DiffVector;
mod vector {
use std::ops::{AddAssign, Neg, Mul};
use super::{Semigroup, Monoid};
#[derive(Abomonation, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct DiffVector<R> {
buffer: Vec<R>,
}
impl<R> DiffVector<R> {
#[inline(always)]
pub fn new(vec: Vec<R>) -> DiffVector<R> {
DiffVector { buffer: vec }
}
}
impl<R> IntoIterator for DiffVector<R> {
type Item = R;
type IntoIter = ::std::vec::IntoIter<R>;
fn into_iter(self) -> Self::IntoIter {
self.buffer.into_iter()
}
}
impl<R> std::ops::Deref for DiffVector<R> {
type Target = [R];
fn deref(&self) -> &Self::Target {
&self.buffer[..]
}
}
impl<R> std::ops::DerefMut for DiffVector<R> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer[..]
}
}
impl<R: Semigroup> Semigroup for DiffVector<R> {
#[inline] fn is_zero(&self) -> bool {
self.buffer.iter().all(|x| x.is_zero())
}
}
impl<'a, R: AddAssign<&'a R>+Clone> AddAssign<&'a DiffVector<R>> for DiffVector<R> {
#[inline]
fn add_assign(&mut self, rhs: &'a Self) {
while self.buffer.len() < rhs.buffer.len() {
let element = &rhs.buffer[self.buffer.len()];
self.buffer.push(element.clone());
}
for (index, update) in rhs.buffer.iter().enumerate() {
self.buffer[index] += update;
}
}
}
impl<R: Neg<Output=R>+Clone> Neg for DiffVector<R> {
type Output = DiffVector<<R as Neg>::Output>;
#[inline]
fn neg(mut self) -> Self::Output {
for update in self.buffer.iter_mut() {
*update = -update.clone();
}
self
}
}
impl<T: Copy, R: Mul<T>> Mul<T> for DiffVector<R> {
type Output = DiffVector<<R as Mul<T>>::Output>;
fn mul(self, other: T) -> Self::Output {
let buffer =
self.buffer
.into_iter()
.map(|x| x * other)
.collect();
DiffVector { buffer }
}
}
impl<R: Semigroup> Monoid for DiffVector<R> {
fn zero() -> Self {
Self { buffer: Vec::new() }
}
}
}