Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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,
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement