mwchase icon

LC:NN upload 3 - node_defs.rs

mwchase | PRO | 03/20/17 02:29:07 AM UTC | 0 ⭐ | 859 👁️ | Never ⏰ | []
Rust |

6.37 KB

|

None

|

0 👍

/

0 👎

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::cmp::Ordering;
use std::sync::Arc;
 
use num::{Integer, Signed};
 
pub type Container<T> = Arc<T>;
 
pub fn container<T>(data: T) -> Container<T> {
    Arc::new(data)
}
 
pub trait NodeData {
    type Constant: Hash + Ord + Clone + Signed;
    type Exponent: Hash + Clone + Integer;
    type Input: Hash + Ord + Clone;
    type SystemVariable: Hash + Ord + Clone;
    type Parameter: Hash + Ord + Clone;
}
 
pub struct Sum<T: NodeData> {
    pub pre_hash: u64, //I would like these fields to be private if possible.
    pub minus: bool,
    pub constant: T::Constant,
    pub terms: Vec<Container<Product<T>>>,
}
 
pub struct Product<T: NodeData> {
    pub pre_hash: u64, //I would like these fields to be private if possible.
    pub coefficient: T::Constant,
    pub powers: Vec<Container<Power<T>>>,
}
 
pub struct Power<T: NodeData> {
    pub exponent: T::Exponent,
    pub primitive: Container<Primitive<T>>,
}
 
pub enum Primitive<T: NodeData> {
    Input(T::Input),
    SystemVariable(T::SystemVariable),
    Parameter(T::Parameter),
    Sigmoid(bool, Container<Sum<T>>),
}
 
impl<T: NodeData> PartialOrd for Sum<T> {
    fn partial_cmp(&self, other: &Sum<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl<T: NodeData> PartialOrd for Product<T> {
    fn partial_cmp(&self, other: &Product<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl<T: NodeData> PartialOrd for Power<T> {
    fn partial_cmp(&self, other: &Power<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl<T: NodeData> PartialOrd for Primitive<T> {
    fn partial_cmp(&self, other: &Primitive<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
 
impl<T: NodeData> PartialEq for Sum<T> {
    fn eq(&self, other: &Sum<T>) -> bool {
        self.minus == other.minus && self.constant == other.constant && self.terms == other.terms
    }
}
 
impl<T: NodeData> PartialEq for Product<T> {
    fn eq(&self, other: &Product<T>) -> bool {
        self.coefficient == other.coefficient && self.powers == other.powers
    }
}
 
impl<T: NodeData> PartialEq for Power<T> {
    fn eq(&self, other: &Power<T>) -> bool {
        self.exponent == other.exponent && self.primitive == other.primitive
    }
}
 
impl<T: NodeData> PartialEq for Primitive<T> {
    fn eq(&self, other: &Primitive<T>) -> bool {
        match (self, other) {
            (&Primitive::Input(ref a), &Primitive::Input(ref b)) => a == b,
            (&Primitive::SystemVariable(ref a), &Primitive::SystemVariable(ref b)) => a == b,
            (&Primitive::Parameter(ref a), &Primitive::Parameter(ref b)) => a == b,
            (&Primitive::Sigmoid(minus_a, ref a), &Primitive::Sigmoid(minus_b, ref b)) => {
                minus_a == minus_b && a == b
            }
            _ => false,
        }
    }
}
 
impl<T: NodeData> Eq for Sum<T> {}
impl<T: NodeData> Eq for Product<T> {}
impl<T: NodeData> Eq for Power<T> {}
impl<T: NodeData> Eq for Primitive<T> {}
 
impl<T: NodeData> Hash for Sum<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.pre_hash.hash(state);
    }
}
 
impl<T: NodeData> Hash for Product<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.pre_hash.hash(state);
    }
}
 
impl<T: NodeData> Hash for Power<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.exponent.hash(state);
        self.primitive.hash(state);
    }
}
 
impl<T: NodeData> Hash for Primitive<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match self {
            &Primitive::Input(ref a) => {
                "Input".hash(state);
                a.hash(state)
            }
            &Primitive::SystemVariable(ref a) => {
                "SystemVariable".hash(state);
                a.hash(state)
            }
            &Primitive::Parameter(ref a) => {
                "Parameter".hash(state);
                a.hash(state)
            }
            &Primitive::Sigmoid(minus, ref a) => {
                "Sigmoid".hash(state);
                minus.hash(state);
                a.hash(state)
            }
        }
    }
}
 
impl<T: NodeData> Clone for Sum<T> {
    fn clone(&self) -> Sum<T> {
        Sum {
            pre_hash: self.pre_hash.clone(),
            minus: self.minus.clone(),
            constant: self.constant.clone(),
            terms: self.terms.clone(),
        }
    }
}
 
impl<T: NodeData> Clone for Product<T> {
    fn clone(&self) -> Product<T> {
        Product {
            pre_hash: self.pre_hash.clone(),
            coefficient: self.coefficient.clone(),
            powers: self.powers.clone(),
        }
    }
}
 
impl<T: NodeData> Clone for Power<T> {
    fn clone(&self) -> Power<T> {
        Power {
            exponent: self.exponent.clone(),
            primitive: self.primitive.clone(),
        }
    }
}
 
impl<T: NodeData> Clone for Primitive<T> {
    fn clone(&self) -> Primitive<T> {
        match self {
            &Primitive::Input(ref a) => Primitive::Input(a.clone()),
            &Primitive::SystemVariable(ref a) => Primitive::SystemVariable(a.clone()),
            &Primitive::Parameter(ref a) => Primitive::Parameter(a.clone()),
            &Primitive::Sigmoid(minus, ref a) => Primitive::Sigmoid(minus, a.clone()),
        }
    }
}
 
impl<T: NodeData> Sum<T> {
    pub fn new(minus: bool, constant: T::Constant, terms: Vec<Container<Product<T>>>) -> Sum<T> {
        let mut s = DefaultHasher::new();
        minus.hash(&mut s);
        constant.hash(&mut s);
        terms.hash(&mut s);
        Sum {
            pre_hash: s.finish(),
            minus: minus,
            constant: constant,
            terms: terms,
        }
    }
}
 
impl<T: NodeData> Product<T> {
    pub fn new(coefficient: T::Constant, powers: Vec<Container<Power<T>>>) -> Product<T> {
        let mut s = DefaultHasher::new();
        coefficient.hash(&mut s);
        powers.hash(&mut s);
        Product {
            pre_hash: s.finish(),
            coefficient: coefficient,
            powers: powers,
        }
    }
}
 
impl<T: NodeData> Power<T> {
    pub fn new(exponent: T::Exponent, primitive: Container<Primitive<T>>) -> Power<T> {
        Power {
            exponent: exponent,
            primitive: primitive,
        }
    }
}

Comments