<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Simple bitset library like C++.

pub struct BitSet {
    bits:   Vec<u64>,
    nbits: usize,
}

impl Default for BitSet {
    #[inline]
    fn default() -> Self { BitSet { bits: Vec::new(), nbits: 0 } }
}

fn bit_count64(u: u64) -> u64 {
    let mut x: u64 = u - ((u >> 1) & 0x5555555555555555u64);
    x = (x & 0x3333333333333333u64) + ((x >> 2) & 0x3333333333333333u64);
    (((x + (x >> 4)) & 0xF0F0F0F0F0F0F0Fu64).wrapping_mul(0x101010101010101u64)) >> 56
}

// Private functions
impl BitSet {
    fn blocks(&self) -> usize {
        if self.nbits % 64 == 0 {
            self.nbits / 64
        }
        else {
            self.nbits / 64 + 1
        }
    }
}

// Public functions
impl BitSet {
	/// Create a new BitSet with *ZERO* bit.
	///
	/// # Example
	///
	/// ```
	/// use bitset::BitSet;
	/// ...
	/// 	let bs = BitSet::new();
	/// ```
    pub fn new() -> Self {
        Self::default()
    }

	/// Create a new BitSet with `nbits` bits with all bit initialized by `0`.
	///
	/// # Arguments
	///
	/// * `nbits` - A integer, which value is the bits count `BitSet` will hold.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// ```
    pub fn with_capacity(nbits: usize) -> Self {
        let mut bitset = BitSet {
            bits: Vec::new(),
            nbits: nbits
        };
        for _ in 0..bitset.blocks() {
            bitset.bits.push(0);
        }
        bitset
    }

	/// Return the actual bits count.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// assert!(bs.size() == 100);
	/// ```
    pub fn size(&self) -> usize {
        self.nbits
    }

	/// Return the count of `1`.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// assert!(bs.count() == 0);
	/// ```
    pub fn count(&self) -> u64 {
        (0..self.blocks()).map(|n| bit_count64(self.bits[n]))
                                .fold(0, |sum, i| sum + i)
    }

	/// Return if the given bit index has been set to `1`.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// assert!(bs.test(99) == false);
	/// ```
    pub fn test(&self, bit_idx: usize) -> bool {
        let (block_idx, mod_bit_idx) = (bit_idx / 64, bit_idx % 64);
        let n: u64 = self.bits[block_idx];
        (n >> mod_bit_idx) & 0x1 == 0x1
    }

	/// Return if there is one bit has been set to `1` in the whole bitset..
	///
	/// # Example
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// assert!(bs.any() == false);
	/// ```
    pub fn any(&self) -> bool {
        for i in 0..self.blocks() {
            if self.bits[i] != 0 {
                return true;
            }
        }
        false
    }

	/// Return if all bits are set to `0`.
	///
	/// # Example
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// assert!(bs.none() == true);
	/// ```
    pub fn none(&self) -> bool {
        !self.any()
    }

    // // bit vec operations
    // fn union(&mut self, vec: &Vec<u64>) {
    //     //TODO
    // }

    // fn intersect(&mut self, vec: Vec<u64>) {
    //     //TODO
    // }

    // bit operations
	/// Set the bit specified by `bit_idx` to `v`, which is `true` or `false`.
	///
	/// # Arguments
	///
	/// * `bit_idx` - the bit index we want to set.
	/// * `v` - the value we want to set. `true` or `false`.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// bs.set(99, true);
	/// assert!(bs.test(99) == true);
	/// ```
    pub fn set(&mut self, bit_idx: usize, v: bool) {
        let (block_idx, mod_bit_idx) = (bit_idx / 64, bit_idx % 64);
        if let Some(n) = self.bits.get_mut(block_idx) {
            if v {
                *n |= 0x1 << mod_bit_idx;
            }
            else {
                *n &= !(0x1 << mod_bit_idx);
            }
        }
    }

	/// Reset all bits to `0`.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// bs.set(99, true);
	/// assert!(bs.test(99) == true);
	/// bs.reset();
	/// assert!(bs.test(99) == false);
	/// ```
    pub fn reset(&mut self) {
        for i in 0..self.blocks() {
            self.bits[i] = 0;
        }
    }

	/// Flip the bit specified by `bit_idx` to the reverse value.
	/// If the bit value is `true`, then it will be flipped to `false`.
	/// The other case is like the same.
	///
	/// # Arguments
	///
	/// `bit_idx` - the index of the bit we want to flip.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
	/// assert!(bs.test(99) == false);
	/// bs.flip(99);
	/// assert!(bs.test(99) == true);
	/// ```
    pub fn flip(&mut self, bit_idx: usize) {
        let (block_idx, mod_bit_idx) = (bit_idx / 64, bit_idx % 64);
        if let Some(n) = self.bits.get_mut(block_idx) {
            if (*n >> mod_bit_idx) & 0x1 == 0x1 {
                *n &= !(0x1 << mod_bit_idx);
            }
            else {
                *n |= 0x1 << mod_bit_idx;
            }
        }
    }

	/// Flip all bits in the bitset. It may run time-costly.
	///
	/// # Example
	///
	/// ```
	/// let bs = BitSet::with_capacity(100);
    /// bitset.flip_all();
	/// for i in 0..100 {
    ///     assert!(bitset.test(i) == true);
    /// }
    /// bitset.flip_all();
    /// for i in 0..100 {
    ///     assert!(bitset.test(i) == false);
    /// }
	/// ```
    pub fn flip_all(&mut self) {
        for i in 0..self.blocks() {
            self.bits[i] = !self.bits[i];
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_bit_count64() {
        assert!(bit_count64(0) == 0);
        assert!(bit_count64(1) == 1);
        assert!(bit_count64(3) == 2);
        assert!(bit_count64(u64::max_value()) == 64);
    }

    #[test]
    fn test_new() {
        let bitset = BitSet::new();
        assert!(bitset.count() == 0);
        assert!(bitset.size() == 0);
    }

    #[test]
    fn test_with_capacity() {
        let mut bitset = BitSet::with_capacity(100);

        // set/reset/test
        assert!(bitset.test(99) == false);
        bitset.set(0, true);
        assert!(bitset.test(0) == true);
        bitset.set(0, false);
        assert!(bitset.test(0) == false);
        bitset.set(99, true);
        assert!(bitset.test(99) == true);
        bitset.set(99, false);
        assert!(bitset.test(99) == false);
        bitset.reset();
        bitset.set(0, true);
        assert!(bitset.test(0) == true);

        // any/none
        bitset.reset();
        assert!(bitset.any() == false);
        assert!(bitset.none() == true);
        bitset.flip(0);
        assert!(bitset.any() == true);
        assert!(bitset.none() == false);

        // flip
        bitset.reset();
        bitset.set(99, true);
        assert!(bitset.test(99) == true);
        bitset.flip(99);
        assert!(bitset.test(99) == false);
        bitset.flip(99);
        assert!(bitset.test(99) == true);

        // flip_all
        bitset.reset();
        bitset.flip_all();
        for i in 0..100 {
            assert!(bitset.test(i) == true);
        }
        bitset.flip_all();
        for i in 0..100 {
            assert!(bitset.test(i) == false);
        }
    }
}
<commit_msg>code fmt fixed.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Simple bitset library like C++.

pub struct BitSet {
    bits:   Vec<u64>,
    nbits: usize,
}

impl Default for BitSet {
    #[inline]
    fn default() -> Self { BitSet { bits: Vec::new(), nbits: 0 } }
}

fn bit_count64(u: u64) -> u64 {
    let mut x: u64 = u - ((u >> 1) & 0x5555555555555555u64);
    x = (x & 0x3333333333333333u64) + ((x >> 2) & 0x3333333333333333u64);
    (((x + (x >> 4)) & 0xF0F0F0F0F0F0F0Fu64).wrapping_mul(0x101010101010101u64)) >> 56
}

// Private functions
impl BitSet {
    fn blocks(&self) -> usize {
        if self.nbits % 64 == 0 {
            self.nbits / 64
        }
        else {
            self.nbits / 64 + 1
        }
    }
}

// Public functions
impl BitSet {
    /// Create a new BitSet with *ZERO* bit.
    ///
    /// # Example
    ///
    /// ```
    /// use bitset::BitSet;
    /// ...
    /// 	let bs = BitSet::new();
    /// ```
    pub fn new() -> Self {
        Self::default()
    }

    /// Create a new BitSet with `nbits` bits with all bit initialized by `0`.
    ///
    /// # Arguments
    ///
    /// * `nbits` - A integer, which value is the bits count `BitSet` will hold.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// ```
    pub fn with_capacity(nbits: usize) -> Self {
        let mut bitset = BitSet {
            bits: Vec::new(),
            nbits: nbits
        };
        for _ in 0..bitset.blocks() {
            bitset.bits.push(0);
        }
        bitset
    }

    /// Return the actual bits count.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// assert!(bs.size() == 100);
    /// ```
    pub fn size(&self) -> usize {
        self.nbits
    }

    /// Return the count of `1`.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// assert!(bs.count() == 0);
    /// ```
    pub fn count(&self) -> u64 {
        (0..self.blocks()).map(|n| bit_count64(self.bits[n]))
                                .fold(0, |sum, i| sum + i)
    }

    /// Return if the given bit index has been set to `1`.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// assert!(bs.test(99) == false);
    /// ```
    pub fn test(&self, bit_idx: usize) -> bool {
        let (block_idx, mod_bit_idx) = (bit_idx / 64, bit_idx % 64);
        let n: u64 = self.bits[block_idx];
        (n >> mod_bit_idx) & 0x1 == 0x1
    }

    /// Return if there is one bit has been set to `1` in the whole bitset..
    ///
    /// # Example
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// assert!(bs.any() == false);
    /// ```
    pub fn any(&self) -> bool {
        for i in 0..self.blocks() {
            if self.bits[i] != 0 {
                return true;
            }
        }
        false
    }

    /// Return if all bits are set to `0`.
    ///
    /// # Example
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// assert!(bs.none() == true);
    /// ```
    pub fn none(&self) -> bool {
        !self.any()
    }

    // // bit vec operations
    // fn union(&mut self, vec: &Vec<u64>) {
    //     //TODO
    // }

    // fn intersect(&mut self, vec: Vec<u64>) {
    //     //TODO
    // }

    // bit operations
    /// Set the bit specified by `bit_idx` to `v`, which is `true` or `false`.
    ///
    /// # Arguments
    ///
    /// * `bit_idx` - the bit index we want to set.
    /// * `v` - the value we want to set. `true` or `false`.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// bs.set(99, true);
    /// assert!(bs.test(99) == true);
    /// ```
    pub fn set(&mut self, bit_idx: usize, v: bool) {
        let (block_idx, mod_bit_idx) = (bit_idx / 64, bit_idx % 64);
        if let Some(n) = self.bits.get_mut(block_idx) {
            if v {
                *n |= 0x1 << mod_bit_idx;
            }
            else {
                *n &= !(0x1 << mod_bit_idx);
            }
        }
    }

    /// Reset all bits to `0`.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// bs.set(99, true);
    /// assert!(bs.test(99) == true);
    /// bs.reset();
    /// assert!(bs.test(99) == false);
    /// ```
    pub fn reset(&mut self) {
        for i in 0..self.blocks() {
            self.bits[i] = 0;
        }
    }

    /// Flip the bit specified by `bit_idx` to the reverse value.
    /// If the bit value is `true`, then it will be flipped to `false`.
    /// The other case is like the same.
    ///
    /// # Arguments
    ///
    /// `bit_idx` - the index of the bit we want to flip.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// assert!(bs.test(99) == false);
    /// bs.flip(99);
    /// assert!(bs.test(99) == true);
    /// ```
    pub fn flip(&mut self, bit_idx: usize) {
        let (block_idx, mod_bit_idx) = (bit_idx / 64, bit_idx % 64);
        if let Some(n) = self.bits.get_mut(block_idx) {
            if (*n >> mod_bit_idx) & 0x1 == 0x1 {
                *n &= !(0x1 << mod_bit_idx);
            }
            else {
                *n |= 0x1 << mod_bit_idx;
            }
        }
    }

    /// Flip all bits in the bitset. It may run time-costly.
    ///
    /// # Example
    ///
    /// ```
    /// let bs = BitSet::with_capacity(100);
    /// bitset.flip_all();
    /// for i in 0..100 {
    ///     assert!(bitset.test(i) == true);
    /// }
    /// bitset.flip_all();
    /// for i in 0..100 {
    ///     assert!(bitset.test(i) == false);
    /// }
    /// ```
    pub fn flip_all(&mut self) {
        for i in 0..self.blocks() {
            self.bits[i] = !self.bits[i];
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_bit_count64() {
        assert!(bit_count64(0) == 0);
        assert!(bit_count64(1) == 1);
        assert!(bit_count64(3) == 2);
        assert!(bit_count64(u64::max_value()) == 64);
    }

    #[test]
    fn test_new() {
        let bitset = BitSet::new();
        assert!(bitset.count() == 0);
        assert!(bitset.size() == 0);
    }

    #[test]
    fn test_with_capacity() {
        let mut bitset = BitSet::with_capacity(100);

        // set/reset/test
        assert!(bitset.test(99) == false);
        bitset.set(0, true);
        assert!(bitset.test(0) == true);
        bitset.set(0, false);
        assert!(bitset.test(0) == false);
        bitset.set(99, true);
        assert!(bitset.test(99) == true);
        bitset.set(99, false);
        assert!(bitset.test(99) == false);
        bitset.reset();
        bitset.set(0, true);
        assert!(bitset.test(0) == true);

        // any/none
        bitset.reset();
        assert!(bitset.any() == false);
        assert!(bitset.none() == true);
        bitset.flip(0);
        assert!(bitset.any() == true);
        assert!(bitset.none() == false);

        // flip
        bitset.reset();
        bitset.set(99, true);
        assert!(bitset.test(99) == true);
        bitset.flip(99);
        assert!(bitset.test(99) == false);
        bitset.flip(99);
        assert!(bitset.test(99) == true);

        // flip_all
        bitset.reset();
        bitset.flip_all();
        for i in 0..100 {
            assert!(bitset.test(i) == true);
        }
        bitset.flip_all();
        for i in 0..100 {
            assert!(bitset.test(i) == false);
        }
    }
}
<|endoftext|>


<commit_before>//! Additive and multiplicative identities

#![deny(missing_docs, warnings)]
#![feature(macro_rules)]

/// Multiplicative identity
pub trait One {
    /// Returns one
    fn one() -> Self;
}

/// Additive identity
pub trait Zero {
    /// Returns zero
    fn zero() -> Self;
}

macro_rules! float {
    ($($ty:ty),+) => {$(
        impl One for $ty { fn one() -> $ty { 1. } }
        impl Zero for $ty { fn zero() -> $ty { 0. } })+
    }
}

float!(f32, f64);

macro_rules! int {
    ($($ty:ty),+) => {$(
        impl One for $ty { fn one() -> $ty { 1 } }
        impl Zero for $ty { fn zero() -> $ty { 0 } })+
    }
}

int!(i8, i16, i32, i64, int, u8, u16, u32, u64);
<commit_msg>fix: update to rust nightly<commit_after>//! Additive and multiplicative identities

#![allow(unstable)]
#![deny(missing_docs, warnings)]

/// Multiplicative identity
pub trait One {
    /// Returns one
    fn one() -> Self;
}

/// Additive identity
pub trait Zero {
    /// Returns zero
    fn zero() -> Self;
}

macro_rules! float {
    ($($ty:ty),+) => {$(
        impl One for $ty { fn one() -> $ty { 1. } }
        impl Zero for $ty { fn zero() -> $ty { 0. } })+
    }
}

float!(f32, f64);

macro_rules! int {
    ($($ty:ty),+) => {$(
        impl One for $ty { fn one() -> $ty { 1 } }
        impl Zero for $ty { fn zero() -> $ty { 0 } })+
    }
}

int!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
<|endoftext|>


<commit_before>#[macro_use] extern crate nickel;

use nickel::Nickel;

pub fn server() {
    let mut server = Nickel::new();

    server.utilize(router! {
        get "**" => |_req, _res| {
            "Hello world!"
        }
    });

    server.listen("127.0.0.1:6767");
}
<commit_msg>add route<commit_after>#[macro_use] extern crate nickel;

use nickel::Nickel;

pub fn server() {
    let mut server = Nickel::new();

    server.utilize(router! {
        get "/" => |_req, _res| {
            "Hello world!"
        }
        get "/foo" => |_req, _res| {
            "Hello world!2"
        }
    });

    server.listen("127.0.0.1:6767");
}
<|endoftext|>


<commit_before>extern crate rand;
use HaltCondition::{ Epochs, MSE };
use UpdateRule::{ Stochastic, Batch };
use std::iter::{Zip, Enumerate};
use std::slice;
use std::num::Float;

static DEFAULT_LEARNING_RATE: f64 = 0.3f64;
static DEFAULT_MOMENTUM: f64 = 0f64;
static DEFAULT_EPOCHS: usize = 1000;

type Node = Vec<f64>;
type Layer = Vec<Node>;

#[derive(Debug)]
#[derive(Clone)]
pub enum HaltCondition {
    Epochs(usize),
    MSE(f64),
}

#[derive(Debug)]
#[derive(Clone)]
pub enum UpdateRule {
    Stochastic,
    Batch
}

#[derive(Debug)]
pub struct Trainer<'a,'b> {
    examples: &'b [(Vec<f64>, Vec<f64>)],
    rate: f64,
    momentum: f64,
    log_interval: Option<usize>,
    halt_condition: HaltCondition,
    update_rule: UpdateRule,
    threads: usize,
    nn: &'a mut NN,
}

impl<'a,'b> Trainer<'a,'b>  {

    pub fn rate(&mut self, rate: f64) -> &mut Trainer<'a,'b> {
        self.rate = rate;
        self
    }

    pub fn momentum(&mut self, momentum: f64) -> &mut Trainer<'a,'b> {
        self.momentum = momentum;
        self
    }

    pub fn log_interval(&mut self, log_interval: Option<usize>) -> &mut Trainer<'a,'b> {
        self.log_interval = log_interval;
        self
    }

    pub fn halt_condition(&mut self, halt_condition: HaltCondition) -> &mut Trainer<'a,'b> {
        self.halt_condition = halt_condition;
        self
    }

    pub fn update_rule(&mut self, update_rule: UpdateRule) -> &mut Trainer<'a,'b> {
        self.update_rule = update_rule;
        self
    }

    pub fn threads(&mut self, threads: usize) -> &mut Trainer<'a,'b> {
        self.threads = threads;
        self
    }

    pub fn go(&mut self) -> f64 {
        self.nn.train_details(
            self.examples,
            self.rate,
            self.momentum,
            self.log_interval,
            self.halt_condition.clone(),
            self.update_rule.clone(),
            self.threads
        )
    }

}

#[derive(Debug)]
#[derive(Clone)]
pub struct NN {
    layers: Vec<Layer>,
    num_inputs: usize,
}

impl NN {
    pub fn run(&self, inputs: &Vec<f64>) -> Vec<f64> {
        if inputs.len() != self.num_inputs {
            panic!("input has a different length than the network's input layer");
        }
        self.do_run(inputs).pop().unwrap()
    }

    pub fn train<'b>(&'b mut self, examples: &'b [(Vec<f64>, Vec<f64>)]) -> Trainer {
        Trainer {
            examples: examples,
            rate: DEFAULT_LEARNING_RATE,
            momentum: DEFAULT_MOMENTUM,
            log_interval: None,
            halt_condition: Epochs(DEFAULT_EPOCHS),
            update_rule: Stochastic,
            threads: 1,
            nn: self
        }
    }

    fn train_details(&mut self, examples: &[(Vec<f64>, Vec<f64>)], rate: f64, momentum: f64, log_interval: Option<usize>,
                    halt_condition: HaltCondition, update_rule: UpdateRule, threads: usize) -> f64 {

        let mut epochs = 0;
        let mut error_rate = 0f64;

        // check that input and output sizes are correct
        let input_layer_size = self.num_inputs;
        let output_layer_size = self.layers[self.layers.len() - 1].len();
        for &(ref inputs, ref outputs) in examples.iter() {
            if inputs.len() != input_layer_size {
                panic!("input has a different length than the network's input layer");
            }
            if outputs.len() != output_layer_size {
                panic!("output has a different length than the network's output layer");
            }
        }

        loop {

            // log error rate if neccessary
            match log_interval {
                Some(interval) if epochs>0 && epochs % interval == 0 => {
                    println!("error rate: {}", error_rate);
                },
                _ => (),
            }

            // check if we've met the halt condition yet
            match halt_condition {
                Epochs(epochs_halt) => {
                    if epochs == epochs_halt { return error_rate }
                },
                MSE(target_error) => {
                    if target_error == error_rate { return error_rate }
                }
            }

            error_rate = 0f64;

            let mut prev_deltas = self.make_weights_tracker(0.0f64);
            let mut batch_data = self.make_weights_tracker(0.0f64);

            for &(ref inputs, ref targets) in examples.iter() {
                let results = self.do_run(&inputs);
                let weight_updates = self.calculate_weight_updates(&results, &targets);
                error_rate += calculate_error(&results, &targets);
                match update_rule {
                    Batch => update_batch_data(&mut batch_data, &weight_updates),
                    Stochastic => self.update_weights(&weight_updates, &mut prev_deltas, rate, momentum),
                }
            }

            // if we're in batch mode, update the weights now
            match update_rule {
                Batch => self.update_weights(&batch_data, &mut prev_deltas, rate, momentum),
                Stochastic => (),
            }

            epochs += 1;
        }
    }

    fn do_run(&self, inputs: &Vec<f64>) -> Vec<Vec<f64>> {
        let mut results = Vec::new();
        results.push(inputs.clone());
        for (layer_index, layer) in self.layers.iter().enumerate() {
            let mut layer_results = Vec::new();
            for node in layer.iter() {
                layer_results.push( sigmoid(modified_dotprod(&node, &results[layer_index])) )
            }
            results.push(layer_results);
        }
        results
    }

    // updates all weights in the network
    fn update_weights(&mut self, network_weight_updates: &Vec<Vec<Vec<f64>>>, prev_deltas: &mut Vec<Vec<Vec<f64>>>, rate: f64, momentum: f64) {
        for layer_index in 0..self.layers.len() {
            let mut layer = &mut self.layers[layer_index];
            let layer_weight_updates = &network_weight_updates[layer_index];
            for node_index in 0..layer.len() {
                let mut node = &mut layer[node_index];
                let node_weight_updates = &layer_weight_updates[node_index];
                for weight_index in 0..node.len() {
                    let weight_update = node_weight_updates[weight_index];
                    let prev_delta = prev_deltas[layer_index][node_index][weight_index];
                    let delta = (rate * weight_update) + (momentum * prev_delta);
                    node[weight_index] += delta;
                    prev_deltas[layer_index][node_index][weight_index] = delta;
                }
            }
        }
    }

    // calculates all weight updates by backpropagation
    fn calculate_weight_updates(&self, results: &Vec<Vec<f64>>, targets: &[f64]) -> Vec<Vec<Vec<f64>>> {
        let mut network_errors:Vec<Vec<f64>> = Vec::new();
        let mut network_weight_updates = Vec::new();
        let layers = &self.layers;
        let network_results = &results[1..]; // skip the input layer

        let mut next_layer_nodes: Option<&Layer> = None;

        for (layer_index, (layer_nodes, layer_results)) in iter_zip_enum(layers, network_results).rev() {
            let prev_layer_results = &results[layer_index];
            let mut layer_errors = Vec::new();
            let mut layer_weight_updates = Vec::new();

            for (node_index, (node, &result)) in iter_zip_enum(layer_nodes, layer_results) {
                let mut node_weight_updates = Vec::new();
                let mut node_error;

                // calculate error for this node
                if layer_index == layers.len() - 1 {
                    node_error = result * (1f64 - result) * (targets[node_index] - result);
                } else {
                    let mut sum = 0f64;
                    for (next_node, &next_node_error_data) in next_layer_nodes.unwrap().iter().zip((&network_errors[layer_index]).iter()) {
                        sum += next_node[node_index+1] * next_node_error_data; // +1 because the 0th weight is the threshold
                    }
                    node_error = result * (1f64 - result) * sum;
                }

                // calculate weight updates for this node
                for weight_index in 0..node.len() {
                    let mut prev_layer_result;
                    if weight_index == 0 {
                        prev_layer_result = 1f64; // theshold
                    } else {
                        prev_layer_result = prev_layer_results[weight_index-1];
                    }
                    let weight_update = node_error * prev_layer_result;
                    node_weight_updates.push(weight_update);
                }

                layer_errors.push(node_error);
                layer_weight_updates.push(node_weight_updates);
            }

            network_errors.push(layer_errors);
            network_weight_updates.push(layer_weight_updates);
            next_layer_nodes = Some(&layer_nodes);
        }

        // updates were built by backpropagation so reverse them
        network_weight_updates.reverse();

        network_weight_updates
    }

    fn make_weights_tracker<T: Clone>(&self, place_holder: T) -> Vec<Vec<Vec<T>>> {
        let mut network_level = Vec::new();
        for layer in self.layers.iter() {
            let mut layer_level = Vec::new();
            for node in layer.iter() {
                let mut node_level = Vec::new();
                for _ in node.iter() {
                    node_level.push(place_holder.clone());
                }
                layer_level.push(node_level);
            }
            network_level.push(layer_level);
        }

        network_level
    }
}

fn modified_dotprod(node: &Node, values: &Vec<f64>) -> f64 {
    let mut it = node.iter();
    let mut total = *it.next().unwrap(); // for the threshold weight
    for (weight, value) in it.zip(values.iter()) {
        total += weight * value;
    }
    total
}

fn sigmoid(y: f64) -> f64 {
    1f64 / (1f64 + Float::exp(-y))
}

// adds new network weight updates into the update updates already collected
fn update_batch_data(batch_data: &mut Vec<Vec<Vec<f64>>> , network_weight_updates: &Vec<Vec<Vec<f64>>>) {
    for layer_index in 0..batch_data.len() {
        let mut batch_layer = &mut batch_data[layer_index];
        let layer_weight_updates = &network_weight_updates[layer_index];
        for node_index in 0..batch_layer.len() {
            let mut batch_node = &mut batch_layer[node_index];
            let node_weight_updates = &layer_weight_updates[node_index];
            for weight_index in 0..batch_node.len() {
                batch_node[weight_index] += node_weight_updates[weight_index];
            }
        }
    }
}

// takes two arrays and enumerates the iterator produced by zipping each of
// their iterators together
fn iter_zip_enum<'s, 't, S: 's, T: 't>(s: &'s [S], t: &'t [T]) ->
    Enumerate<Zip<slice::Iter<'s, S>, slice::Iter<'t, T>>>  {
    s.iter().zip(t.iter()).enumerate()
}

fn calculate_error(results: &Vec<Vec<f64>>, targets: &[f64]) -> f64 {
    let ref last_resutls = results[results.len()-1];
    let mut total:f64 = 0f64;
    for (&result, &target) in last_resutls.iter().zip(targets.iter()) {
        total += (target - result).powi(2);
    }
    0.5 * total
}

pub fn new(layers_sizes: &[usize]) -> NN {
    if layers_sizes.len() < 2 {
        panic!("must have at least two layers");
    }
    let mut layers = Vec::new();
    let mut it = layers_sizes.iter();
    // get the first layer size
    let first_layer_size = *it.next().unwrap();

    // setup the rest of the layers
    let mut prev_layer_size = first_layer_size;
    for &layer_size in it {
        let mut layer: Layer = Vec::new();
        for _ in 0..layer_size {
            let mut node: Node = Vec::new();
            for _ in 0..prev_layer_size+1 {
                let random_weight: f64 = rand::random();
                node.push(random_weight);
            }
            node.shrink_to_fit();
            layer.push(node)
        }
        layer.shrink_to_fit();
        layers.push(layer);
        prev_layer_size = layer_size;
    }
    layers.shrink_to_fit();
    NN { layers: layers, num_inputs: first_layer_size }
}<commit_msg>split training strategies into seperate functions<commit_after>extern crate rand;
use HaltCondition::{ Epochs, MSE };
use UpdateRule::{ Stochastic, Batch };
use std::iter::{Zip, Enumerate};
use std::slice;
use std::num::Float;
use std::thread;

static DEFAULT_LEARNING_RATE: f64 = 0.3f64;
static DEFAULT_MOMENTUM: f64 = 0f64;
static DEFAULT_EPOCHS: usize = 1000;

type Node = Vec<f64>;
type Layer = Vec<Node>;

#[derive(Debug, Copy, Clone)]
pub enum HaltCondition {
    Epochs(usize),
    MSE(f64),
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum UpdateRule {
    Stochastic,
    Batch
}

#[derive(Debug)]
pub struct Trainer<'a,'b> {
    examples: &'b [(Vec<f64>, Vec<f64>)],
    rate: f64,
    momentum: f64,
    log_interval: Option<usize>,
    halt_condition: HaltCondition,
    update_rule: UpdateRule,
    threads: usize,
    nn: &'a mut NN,
}

impl<'a,'b> Trainer<'a,'b>  {

    pub fn rate(&mut self, rate: f64) -> &mut Trainer<'a,'b> {
        self.rate = rate;
        self
    }

    pub fn momentum(&mut self, momentum: f64) -> &mut Trainer<'a,'b> {
        self.momentum = momentum;
        self
    }

    pub fn log_interval(&mut self, log_interval: Option<usize>) -> &mut Trainer<'a,'b> {
        self.log_interval = log_interval;
        self
    }

    pub fn halt_condition(&mut self, halt_condition: HaltCondition) -> &mut Trainer<'a,'b> {
        self.halt_condition = halt_condition;
        self
    }

    pub fn update_rule(&mut self, update_rule: UpdateRule) -> &mut Trainer<'a,'b> {
        self.update_rule = update_rule;
        self
    }

    pub fn threads(&mut self, threads: usize) -> &mut Trainer<'a,'b> {
        self.threads = threads;
        self
    }

    pub fn go(&mut self) -> f64 {
        self.nn.train_details(
            self.examples,
            self.rate,
            self.momentum,
            self.log_interval,
            self.halt_condition,
            self.update_rule,
            self.threads
        )
    }

}

#[derive(Debug, Clone)]
pub struct NN {
    layers: Vec<Layer>,
    num_inputs: usize,
}

impl NN {
    pub fn run(&self, inputs: &Vec<f64>) -> Vec<f64> {
        if inputs.len() != self.num_inputs {
            panic!("input has a different length than the network's input layer");
        }
        self.do_run(inputs).pop().unwrap()
    }

    pub fn train<'b>(&'b mut self, examples: &'b [(Vec<f64>, Vec<f64>)]) -> Trainer {
        Trainer {
            examples: examples,
            rate: DEFAULT_LEARNING_RATE,
            momentum: DEFAULT_MOMENTUM,
            log_interval: None,
            halt_condition: Epochs(DEFAULT_EPOCHS),
            update_rule: Stochastic,
            threads: 1,
            nn: self
        }
    }

    fn train_details(&mut self, examples: &[(Vec<f64>, Vec<f64>)], rate: f64, momentum: f64, log_interval: Option<usize>,
                    halt_condition: HaltCondition, update_rule: UpdateRule, threads: usize) -> f64 {

        let mut epochs = 0;
        let mut error_rate = 0f64;

        // check that input and output sizes are correct
        let input_layer_size = self.num_inputs;
        let output_layer_size = self.layers[self.layers.len() - 1].len();
        for &(ref inputs, ref outputs) in examples.iter() {
            if inputs.len() != input_layer_size {
                panic!("input has a different length than the network's input layer");
            }
            if outputs.len() != output_layer_size {
                panic!("output has a different length than the network's output layer");
            }
        }

        let mut prev_deltas = self.make_weights_tracker(0.0f64);

        loop {

            // log error rate if neccessary
            match log_interval {
                Some(interval) if epochs>0 && epochs % interval == 0 => {
                    println!("error rate: {}", error_rate);
                },
                _ => (),
            }

            // check if we've met the halt condition yet
            match halt_condition {
                Epochs(epochs_halt) => {
                    if epochs == epochs_halt { return error_rate }
                },
                MSE(target_error) => {
                    if target_error == error_rate { return error_rate }
                }
            }

            if threads > 1 {
                error_rate = self.train_threaded(examples, rate, momentum, threads, &mut prev_deltas)
            } else if update_rule == Stochastic {
                error_rate = self.train_stochastic(examples, rate, momentum, &mut prev_deltas)
            } else {
                error_rate = self.train_batch(examples, rate, momentum, &mut prev_deltas)
            }

            epochs += 1;
        }
    }

    fn train_threaded(&mut self, examples: &[(Vec<f64>, Vec<f64>)], rate: f64, momentum: f64,
                      threads: usize, prev_deltas: &mut Vec<Vec<Vec<f64>>>) -> f64 {

        let mut error_rate = 0.0f64;

        // for &(ref inputs, ref targets) in examples.iter() {
        //     let results = self.do_run(&inputs);
        //     let weight_updates = self.calculate_weight_updates(&results, &targets);
        //     error_rate += calculate_error(&results, &targets);
        //     self.update_weights(&weight_updates, prev_deltas, rate, momentum)
        // }

        // for i in 0..threads {
        //     let _ = thread::scoped(move || {
        //     });
        // }

        error_rate

    }

    fn train_stochastic(&mut self, examples: &[(Vec<f64>, Vec<f64>)], rate: f64, momentum: f64,
                        prev_deltas: &mut Vec<Vec<Vec<f64>>>) -> f64 {

        let mut error_rate = 0.0f64;

        for &(ref inputs, ref targets) in examples.iter() {
            let results = self.do_run(&inputs);
            let weight_updates = self.calculate_weight_updates(&results, &targets);
            error_rate += calculate_error(&results, &targets);
            self.update_weights(&weight_updates, prev_deltas, rate, momentum)
        }

        error_rate
    }

    fn train_batch(&mut self, examples: &[(Vec<f64>, Vec<f64>)], rate: f64, momentum: f64,
                   prev_deltas: &mut Vec<Vec<Vec<f64>>>) -> f64 {

        let mut error_rate = 0.0f64;

        let mut batch_data = self.make_weights_tracker(0.0f64);

        for &(ref inputs, ref targets) in examples.iter() {
            let results = self.do_run(&inputs);
            let weight_updates = self.calculate_weight_updates(&results, &targets);
            error_rate += calculate_error(&results, &targets);
            update_batch_data(&mut batch_data, &weight_updates);
        }

        self.update_weights(&batch_data, prev_deltas, rate, momentum);

        error_rate
    }

    fn do_run(&self, inputs: &Vec<f64>) -> Vec<Vec<f64>> {
        let mut results = Vec::new();
        results.push(inputs.clone());
        for (layer_index, layer) in self.layers.iter().enumerate() {
            let mut layer_results = Vec::new();
            for node in layer.iter() {
                layer_results.push( sigmoid(modified_dotprod(&node, &results[layer_index])) )
            }
            results.push(layer_results);
        }
        results
    }

    // updates all weights in the network
    fn update_weights(&mut self, network_weight_updates: &Vec<Vec<Vec<f64>>>, prev_deltas: &mut Vec<Vec<Vec<f64>>>, rate: f64, momentum: f64) {
        for layer_index in 0..self.layers.len() {
            let mut layer = &mut self.layers[layer_index];
            let layer_weight_updates = &network_weight_updates[layer_index];
            for node_index in 0..layer.len() {
                let mut node = &mut layer[node_index];
                let node_weight_updates = &layer_weight_updates[node_index];
                for weight_index in 0..node.len() {
                    let weight_update = node_weight_updates[weight_index];
                    let prev_delta = prev_deltas[layer_index][node_index][weight_index];
                    let delta = (rate * weight_update) + (momentum * prev_delta);
                    node[weight_index] += delta;
                    prev_deltas[layer_index][node_index][weight_index] = delta;
                }
            }
        }
    }

    // calculates all weight updates by backpropagation
    fn calculate_weight_updates(&self, results: &Vec<Vec<f64>>, targets: &[f64]) -> Vec<Vec<Vec<f64>>> {
        let mut network_errors:Vec<Vec<f64>> = Vec::new();
        let mut network_weight_updates = Vec::new();
        let layers = &self.layers;
        let network_results = &results[1..]; // skip the input layer

        let mut next_layer_nodes: Option<&Layer> = None;

        for (layer_index, (layer_nodes, layer_results)) in iter_zip_enum(layers, network_results).rev() {
            let prev_layer_results = &results[layer_index];
            let mut layer_errors = Vec::new();
            let mut layer_weight_updates = Vec::new();

            for (node_index, (node, &result)) in iter_zip_enum(layer_nodes, layer_results) {
                let mut node_weight_updates = Vec::new();
                let mut node_error;

                // calculate error for this node
                if layer_index == layers.len() - 1 {
                    node_error = result * (1f64 - result) * (targets[node_index] - result);
                } else {
                    let mut sum = 0f64;
                    for (next_node, &next_node_error_data) in next_layer_nodes.unwrap().iter().zip((&network_errors[layer_index]).iter()) {
                        sum += next_node[node_index+1] * next_node_error_data; // +1 because the 0th weight is the threshold
                    }
                    node_error = result * (1f64 - result) * sum;
                }

                // calculate weight updates for this node
                for weight_index in 0..node.len() {
                    let mut prev_layer_result;
                    if weight_index == 0 {
                        prev_layer_result = 1f64; // theshold
                    } else {
                        prev_layer_result = prev_layer_results[weight_index-1];
                    }
                    let weight_update = node_error * prev_layer_result;
                    node_weight_updates.push(weight_update);
                }

                layer_errors.push(node_error);
                layer_weight_updates.push(node_weight_updates);
            }

            network_errors.push(layer_errors);
            network_weight_updates.push(layer_weight_updates);
            next_layer_nodes = Some(&layer_nodes);
        }

        // updates were built by backpropagation so reverse them
        network_weight_updates.reverse();

        network_weight_updates
    }

    fn make_weights_tracker<T: Clone>(&self, place_holder: T) -> Vec<Vec<Vec<T>>> {
        let mut network_level = Vec::new();
        for layer in self.layers.iter() {
            let mut layer_level = Vec::new();
            for node in layer.iter() {
                let mut node_level = Vec::new();
                for _ in node.iter() {
                    node_level.push(place_holder.clone());
                }
                layer_level.push(node_level);
            }
            network_level.push(layer_level);
        }

        network_level
    }
}

fn modified_dotprod(node: &Node, values: &Vec<f64>) -> f64 {
    let mut it = node.iter();
    let mut total = *it.next().unwrap(); // for the threshold weight
    for (weight, value) in it.zip(values.iter()) {
        total += weight * value;
    }
    total
}

fn sigmoid(y: f64) -> f64 {
    1f64 / (1f64 + Float::exp(-y))
}

// adds new network weight updates into the update updates already collected
fn update_batch_data(batch_data: &mut Vec<Vec<Vec<f64>>> , network_weight_updates: &Vec<Vec<Vec<f64>>>) {
    for layer_index in 0..batch_data.len() {
        let mut batch_layer = &mut batch_data[layer_index];
        let layer_weight_updates = &network_weight_updates[layer_index];
        for node_index in 0..batch_layer.len() {
            let mut batch_node = &mut batch_layer[node_index];
            let node_weight_updates = &layer_weight_updates[node_index];
            for weight_index in 0..batch_node.len() {
                batch_node[weight_index] += node_weight_updates[weight_index];
            }
        }
    }
}

// takes two arrays and enumerates the iterator produced by zipping each of
// their iterators together
fn iter_zip_enum<'s, 't, S: 's, T: 't>(s: &'s [S], t: &'t [T]) ->
    Enumerate<Zip<slice::Iter<'s, S>, slice::Iter<'t, T>>>  {
    s.iter().zip(t.iter()).enumerate()
}

fn calculate_error(results: &Vec<Vec<f64>>, targets: &[f64]) -> f64 {
    let ref last_resutls = results[results.len()-1];
    let mut total:f64 = 0f64;
    for (&result, &target) in last_resutls.iter().zip(targets.iter()) {
        total += (target - result).powi(2);
    }
    0.5 * total
}

pub fn new(layers_sizes: &[usize]) -> NN {
    if layers_sizes.len() < 2 {
        panic!("must have at least two layers");
    }
    let mut layers = Vec::new();
    let mut it = layers_sizes.iter();
    // get the first layer size
    let first_layer_size = *it.next().unwrap();

    // setup the rest of the layers
    let mut prev_layer_size = first_layer_size;
    for &layer_size in it {
        let mut layer: Layer = Vec::new();
        for _ in 0..layer_size {
            let mut node: Node = Vec::new();
            for _ in 0..prev_layer_size+1 {
                let random_weight: f64 = rand::random();
                node.push(random_weight);
            }
            node.shrink_to_fit();
            layer.push(node)
        }
        layer.shrink_to_fit();
        layers.push(layer);
        prev_layer_size = layer_size;
    }
    layers.shrink_to_fit();
    NN { layers: layers, num_inputs: first_layer_size }
}<|endoftext|>


<commit_before>use std::ops::{Mul, Add};

/// Structure for computing the B-spline with the given control points
/// and knots.
pub struct BSpline<T: Mul<f32, Output = T> + Add<Output = T> + Copy> {
    /// Degree of the polynomial that we use to make the curve segments
    degree: usize,
    /// Control points for the curve
    control_points: Vec<T>,
    /// TODO: What is a good description for the knots?
    knots: Vec<f32>,
}

impl<T: Mul<f32, Output = T> + Add<Output = T> + Copy> BSpline<T> {
    /// Create a new B-spline curve of the desired degree that will blend between
    /// the passed control points using the knots. The knots should be sorted in ascending
    /// order, otherwise they will be sorted for you which may lead to undesired knots
    /// for control points
    pub fn new(degree: usize, control_points: Vec<T>, mut knots: Vec<f32>) -> BSpline<T> {
        // TODO: Maybe a ctor for cardinal curves that will check we have the right number of
        // knots? Is this check correct?
        if control_points.len() < degree {
            panic!("Too few control points for curve");
        }
        knots.sort_by(|a, b| a.partial_cmp(b).unwrap());
        BSpline { degree: degree, control_points: control_points, knots: knots }
    }
    /// Compute a point on the curve at `t`
    /// TODO: Handling of out of bounds t values? Are t values not in the domain considered
    /// out of range? The extra `degree` values are just for when we're going down the tree
    /// to find the interpolated values there right?
    pub fn point(&self, t: f32) -> T {
        // Find the first index with a knot value greater than the t we're searching for. We want
        // to find i such that: knot[i] <= t < knot[i + 1]
        let (mut i, _) = self.knots.iter().take_while(|&x| !(*x > t)).enumerate().last().unwrap();
        i = i + 1;
        if i == self.knots.len() {
            i = self.knots.len() - self.degree - 1;
        } else if i == 0 {
            i = self.degree;
        }
        /*
        let i = match upper_bounds(&self.knots[self.degree - 1..self.knots.len() - self.degree], t) {
            Some(x) => x,
            None => self.knots.len() - self.degree - 1,
        };
        */
        //println!("Found i = {} for t = {}\n\tknots = {:?}", i, t, self.knots);
        //println!("degree = {}", self.degree);
        self.de_boors(t, self.degree, i)
    }
    /// Recursively compute de Boor's B-spline algorithm. TODO: This is terrible,
    /// compute it iteratively! Recursive version is just for a simple formualation
    /// of the initial implementation.
    fn de_boors(&self, t: f32, k: usize, i: usize) -> T {
        if k == 0 {
            //println!("Returning control point {}", i);
            self.control_points[i - 1]
        } else {
            //println!("Looking at k = {}, i = {}, t = {}", k, i, t);
            //println!("\tknots[i + self.degree - k] = {}, self.knots[i - 1] = {}",
            //         self.knots[i + self.degree - k], self.knots[i - 1]);
            // TODO: This is still broken
            let alpha = (t - self.knots[i - 1]) / (self.knots[i + self.degree - k] - self.knots[i - 1]);
            self.de_boors(t, k - 1, i - 1) * (1.0 - alpha) + self.de_boors(t, k - 1, i) * alpha
        }
    }
}

/// Return the index of the first element greater than the value passed.
/// The data **must** be sorted.
/// If no element greater than the value passed is found the function returns None.
fn upper_bounds(data: &[f32], value: f32) -> Option<usize> {
    let mut first = 0usize;
    let mut step;
    let mut count = data.len() as isize;
    while count > 0 {
        step = count / 2;
        let it = first + step as usize;
        if !value.lt(&data[it]) {
            first = it + 1;
            count -= step + 1;
        } else {
            count = step;
        }
    }
    // If we didn't find an element greater than value
    if first == data.len() {
        None
    } else {
        Some(first)
    }
}

#[cfg(test)]
mod test {
    use std::ops::{Mul, Add};
    use std::iter;

    use super::BSpline;

    #[derive(Copy, Clone, Debug)]
    struct Point {
        x: f32,
        y: f32,
    }
    impl Point {
        fn new(x: f32, y: f32) -> Point {
            Point { x: x, y: y }
        }
    }
    impl Mul<f32> for Point {
        type Output = Point;
        fn mul(self, rhs: f32) -> Point {
            Point { x: self.x * rhs, y: self.y * rhs }
        }
    }
    impl Add for Point {
        type Output = Point;
        fn add(self, rhs: Point) -> Point {
            Point { x: self.x + rhs.x, y: self.y + rhs.y }
        }
    }

    #[derive(Copy, Clone, Debug)]
    struct Pointi {
        x: i32,
        y: i32,
    }
    impl Pointi {
        fn new(x: i32, y: i32) -> Pointi {
            Pointi { x: x, y: y }
        }
    }
    impl Mul<f32> for Pointi {
        type Output = Pointi;
        fn mul(self, rhs: f32) -> Pointi {
            Pointi { x: (self.x as f32 * rhs) as i32,
                    y: (self.y as f32 * rhs) as i32 }
        }
    }
    impl Add for Pointi {
        type Output = Pointi;
        fn add(self, rhs: Pointi) -> Pointi {
            Pointi { x: self.x + rhs.x, y: self.y + rhs.y }
        }
    }

    //#[test]
    fn linear_bspline() {
        let points = vec![Point::new(-1.0, 0.0), Point::new(0.0, 1.0),
                          Point::new(1.0, 1.0), Point::new(1.0, 2.0)];
        let knots = vec![0.0, 0.0, 1.0, 2.0, 3.0, 3.0];
        let spline = BSpline::new(1, points, knots);
        let x = spline.point(1.5);
        println!("spline(1.5) = {:?}", x);
        assert!(x.x == 0.5 && x.y == 1.0);
    }
    //#[test]
    fn quadratic_bspline() {
        let points = vec![Point::new(-2.0, 0.0), Point::new(0.0, 2.0),
                          Point::new(2.0, 0.0), Point::new(0.0, -2.0)];
        let knots = vec![0.0, 0.0, 0.0, 1.0, 2.0, 2.0, 2.0];
        let spline = BSpline::new(3, points, knots);
        let x = spline.point(1.5);
        println!("spline(1.5) = {:?}", x);
        assert!(x.x == 1.25 && x.y == -0.25);
    }
    #[test]
    fn bspline_plot() {
        let points = vec![Pointi::new(0, 5), Pointi::new(9, 20),
                          Pointi::new(29, 20), Pointi::new(39, 5)];
        let knots = vec![0.0, 0.0, 0.0, 1.0, 2.0, 2.0, 2.0];

        // TODO: This doesn't compute or plot the correct curve
        let plot_w = 80;
        let plot_h = 50;
        let mut plot: Vec<_> = iter::repeat(' ').take(plot_w * plot_h).collect();

        let t_start = knots[0];
        let t_end = knots[knots.len() - 1];
        println!("Starting at {}, ending at {}", t_start, t_end);
        let spline = BSpline::new(2, points.clone(), knots);

        let steps = 20;
        let step_size = (t_end - t_start) / steps as f32;
        for s in 0..steps {
            let t = step_size * s as f32 + t_start;
            println!("t = {}", t);
            let x = spline.point(t);
            println!("x = {:?}", x);
            if x.x > -1 && x.x < plot_w as i32 && x.y > -1 && x.y < plot_h as i32 {
                plot[(plot_h - 1 - x.y as usize) * plot_w + x.x as usize] = 'X';
            }
        }
        for i in 0..points.len() {
            let symbol = match i {
                x if x == 0 => 'S',
                x if x == points.len() - 1 => 'E',
                _ => 'C',
            };
            plot[(plot_h - 1 - points[i].y as usize) * plot_w + points[i].x as usize] = symbol;
        }

        for y in 0..plot_h {
            for x in 0..plot_w {
                print!("{}", plot[y * plot_w + x]);
            }
            println!("");
        }
    }
    //#[test]
    fn quadratic_bspline_plot1d() {
        let points = vec![0.0, 0.0, 1.0, 0.0, 0.0];
        let knots = vec![0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 3.0];
        let t_start = knots[0];
        let t_end = knots[knots.len() - 1];
        println!("Starting at {}, ending at {}", t_start, t_end);
        let spline = BSpline::new(2, points, knots);
        let t = 0.5;
        println!("spline({}) = {}", t, spline.point(t));
    }
    //#[test]
    fn cubic_bspline_plot1d() {
        let points = vec![0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0];
        let knots = vec![-2.0, -2.0, -2.0, -2.0, -1.0, 0.0, 1.0, 2.0, 2.0, 2.0, 2.0];
        let t_start = knots[0];
        let t_end = knots[knots.len() - 1];
        println!("Starting at {}, ending at {}", t_start, t_end);
        let spline = BSpline::new(3, points, knots);
        let t = 0.5;
        println!("spline({}) = {}", t, spline.point(t));
    }
    //#[test]
    fn quartic_bspline_plot1d() {
        let points = vec![0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0];
        let knots = vec![0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0];
        let t_start = knots[0];
        let t_end = knots[knots.len() - 1];
        println!("Starting at {}, ending at {}", t_start, t_end);
        let spline = BSpline::new(4, points, knots);
        let t = 3.5;
        println!("spline({}) = {}", t, spline.point(t));
    }
}

<commit_msg>Use Interpolate trait instead to support non-lerping types<commit_after>use std::ops::{Mul, Add};

pub trait Interpolate {
    fn interpolate(&self, other: &Self, t: f32) -> Self;
}

impl<T: Mul<f32, Output = T> + Add<Output = T> + Copy> Interpolate for T {
    fn interpolate(&self, other: &Self, t: f32) -> Self {
        *self * (1.0 - t) + *other * t
    }
}

/// Structure for computing the B-spline with the given control points
/// and knots.
pub struct BSpline<T: Interpolate + Copy> {
    /// Degree of the polynomial that we use to make the curve segments
    degree: usize,
    /// Control points for the curve
    control_points: Vec<T>,
    /// TODO: What is a good description for the knots?
    knots: Vec<f32>,
}

impl<T: Interpolate + Copy> BSpline<T> {
    /// Create a new B-spline curve of the desired degree that will blend between
    /// the passed control points using the knots. The knots should be sorted in ascending
    /// order, otherwise they will be sorted for you which may lead to undesired knots
    /// for control points
    pub fn new(degree: usize, control_points: Vec<T>, mut knots: Vec<f32>) -> BSpline<T> {
        // TODO: Maybe a ctor for cardinal curves that will check we have the right number of
        // knots? Is this check correct?
        if control_points.len() < degree {
            panic!("Too few control points for curve");
        }
        knots.sort_by(|a, b| a.partial_cmp(b).unwrap());
        BSpline { degree: degree, control_points: control_points, knots: knots }
    }
    /// Compute a point on the curve at `t`
    /// TODO: Handling of out of bounds t values? Are t values not in the domain considered
    /// out of range? The extra `degree` values are just for when we're going down the tree
    /// to find the interpolated values there right?
    pub fn point(&self, t: f32) -> T {
        // Find the first index with a knot value greater than the t we're searching for. We want
        // to find i such that: knot[i] <= t < knot[i + 1]
        let (mut i, _) = self.knots.iter().take_while(|&x| !(*x > t)).enumerate().last().unwrap();
        i = i + 1;
        if i == self.knots.len() {
            i = self.knots.len() - self.degree - 1;
        } else if i == 0 {
            i = self.degree;
        }
        /*
        let i = match upper_bounds(&self.knots[self.degree - 1..self.knots.len() - self.degree], t) {
            Some(x) => x,
            None => self.knots.len() - self.degree - 1,
        };
        */
        //println!("Found i = {} for t = {}\n\tknots = {:?}", i, t, self.knots);
        //println!("degree = {}", self.degree);
        self.de_boors(t, self.degree, i)
    }
    /// Recursively compute de Boor's B-spline algorithm. TODO: This is terrible,
    /// compute it iteratively! Recursive version is just for a simple formualation
    /// of the initial implementation.
    fn de_boors(&self, t: f32, k: usize, i: usize) -> T {
        if k == 0 {
            //println!("Returning control point {}", i);
            self.control_points[i - 1]
        } else {
            //println!("Looking at k = {}, i = {}, t = {}", k, i, t);
            //println!("\tknots[i + self.degree - k] = {}, self.knots[i - 1] = {}",
            //         self.knots[i + self.degree - k], self.knots[i - 1]);
            // TODO: This is still broken
            let alpha = (t - self.knots[i - 1]) / (self.knots[i + self.degree - k] - self.knots[i - 1]);
            self.de_boors(t, k - 1, i - 1).interpolate(&self.de_boors(t, k - 1, i), alpha)
        }
    }
}

/// Return the index of the first element greater than the value passed.
/// The data **must** be sorted.
/// If no element greater than the value passed is found the function returns None.
fn upper_bounds(data: &[f32], value: f32) -> Option<usize> {
    let mut first = 0usize;
    let mut step;
    let mut count = data.len() as isize;
    while count > 0 {
        step = count / 2;
        let it = first + step as usize;
        if !value.lt(&data[it]) {
            first = it + 1;
            count -= step + 1;
        } else {
            count = step;
        }
    }
    // If we didn't find an element greater than value
    if first == data.len() {
        None
    } else {
        Some(first)
    }
}

#[cfg(test)]
mod test {
    use std::ops::{Mul, Add};
    use std::iter;

    use super::BSpline;

    #[derive(Copy, Clone, Debug)]
    struct Point {
        x: f32,
        y: f32,
    }
    impl Point {
        fn new(x: f32, y: f32) -> Point {
            Point { x: x, y: y }
        }
    }
    impl Mul<f32> for Point {
        type Output = Point;
        fn mul(self, rhs: f32) -> Point {
            Point { x: self.x * rhs, y: self.y * rhs }
        }
    }
    impl Add for Point {
        type Output = Point;
        fn add(self, rhs: Point) -> Point {
            Point { x: self.x + rhs.x, y: self.y + rhs.y }
        }
    }

    #[derive(Copy, Clone, Debug)]
    struct Pointi {
        x: i32,
        y: i32,
    }
    impl Pointi {
        fn new(x: i32, y: i32) -> Pointi {
            Pointi { x: x, y: y }
        }
    }
    impl Mul<f32> for Pointi {
        type Output = Pointi;
        fn mul(self, rhs: f32) -> Pointi {
            Pointi { x: (self.x as f32 * rhs) as i32,
                    y: (self.y as f32 * rhs) as i32 }
        }
    }
    impl Add for Pointi {
        type Output = Pointi;
        fn add(self, rhs: Pointi) -> Pointi {
            Pointi { x: self.x + rhs.x, y: self.y + rhs.y }
        }
    }

    // TODO: Test on 1D functions?
    #[test]
    fn linear_bspline() {
        let points = vec![Point::new(-1.0, 0.0), Point::new(0.0, 1.0),
                          Point::new(1.0, 1.0), Point::new(1.0, 2.0)];
        let knots = vec![0.0, 0.0, 1.0, 2.0, 3.0, 3.0];
        let spline = BSpline::new(1, points, knots);
        let x = spline.point(1.5);
        println!("spline(1.5) = {:?}", x);
        assert!(x.x == 0.5 && x.y == 1.0);
    }
    //#[test]
    fn quadratic_bspline_plot1d() {
        let points = vec![0.0, 0.0, 1.0, 0.0, 0.0];
        let knots = vec![0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 3.0];
        let t_start = knots[0];
        let t_end = knots[knots.len() - 1];
        println!("Starting at {}, ending at {}", t_start, t_end);
        let spline = BSpline::new(2, points, knots);
        let t = 0.5;
        println!("spline({}) = {}", t, spline.point(t));
    }
    //#[test]
    fn cubic_bspline_plot1d() {
        let points = vec![0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0];
        let knots = vec![-2.0, -2.0, -2.0, -2.0, -1.0, 0.0, 1.0, 2.0, 2.0, 2.0, 2.0];
        let t_start = knots[0];
        let t_end = knots[knots.len() - 1];
        println!("Starting at {}, ending at {}", t_start, t_end);
        let spline = BSpline::new(3, points, knots);
        let t = 0.5;
        println!("spline({}) = {}", t, spline.point(t));
    }
    //#[test]
    fn quartic_bspline_plot1d() {
        let points = vec![0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0];
        let knots = vec![0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0];
        let t_start = knots[0];
        let t_end = knots[knots.len() - 1];
        println!("Starting at {}, ending at {}", t_start, t_end);
        let spline = BSpline::new(4, points, knots);
        let t = 3.5;
        println!("spline({}) = {}", t, spline.point(t));
    }
}

<|endoftext|>


<commit_before>// (c) 2015 Joost Yervante Damad <joost@productize.be>

// loosely based on https://github.com/cgaebel/sexp
// latest version can be found at https://github.com/andete/rust_sexp

use std::fmt;
use std::str::FromStr;
use std::f64;

use std::fs::File;
use std::io::prelude::*;

pub enum Atom {
  S(String),
  Q(String),
  I(i64),
  F(f64),
}

impl Atom {
    pub fn f(&self) -> Result<f64,String> {
        match *self {
            Atom::F(f) => Ok(f),
            Atom::I(i) => Ok(i as f64),
            ref x => Err(format!("not a float: {}", x))
        }
    }
    pub fn i(&self) -> Result<i64,String> {
        match *self {
            Atom::I(i) => Ok(i),
            ref x => Err(format!("not an int: {}", x))
        }
    }
    pub fn string(&self) -> Result<String,String> {
        match *self {
            Atom::S(ref s) => Ok(s.clone()),
            Atom::Q(ref s) => Ok(s.clone()),
            ref x => Err(format!("not a string: {}", x))
        }
    }
    pub fn as_string(&self) -> Result<String,String> {
        match *self {
            Atom::S(ref s) => Ok(s.clone()),
            Atom::Q(ref s) => Ok(s.clone()),
            Atom::F(ref s) => Ok(format!("{}", s)),
            Atom::I(ref s) => Ok(format!("{}", s)),
        }
    }
}

pub enum Sexp {
  Atom(Atom),
  Empty,
  List(Vec<Sexp>),
}

impl Sexp {
    pub fn atom(&self) -> Result<&Atom,String> {
        match *self {
            Sexp::Atom(ref f) => Ok(f),
            ref x => Err(format!("not an atom: {}", x))
        }
    }
    pub fn list(&self) -> Result<&Vec<Sexp>,String> {
        match *self {
            Sexp::List(ref v) => Ok(v),
            ref x => Err(format!("not a list: {}", x))
        }
    }
}

pub struct ParseError {
    msg: &'static str,
    line: usize,
    lpos: usize,
}

pub enum Error {
    ParseError(ParseError),
    IOError(std::io::Error),
}

pub type ERes<T> = Result<T, Error>;

fn err_parse<T>(msg: &'static str, state: &ParseState) -> ERes<T> {
    Err(Error::ParseError(ParseError { msg: msg, line: state.line, lpos: state.lpos}))
}

fn err_io<T>(err: std::io::Error) -> ERes<T> {
    Err(Error::IOError(err))
}

struct ParseState {
    pos: usize,
    line: usize,
    lpos: usize,
    vec: Vec<char>,
    len: usize,
    store_pos: usize,
    store_line: usize,
    store_lpos: usize,
}

impl ParseState {
    fn peek(&self) -> ERes<char> {
        if self.pos >= self.len {
            return err_parse("end of document reached", self)
        }
        Ok(self.vec[self.pos])
    }
    fn peek_option(&self) -> Option<char> {
        if self.pos >= self.len {
            return None
        }
        Some(self.vec[self.pos])
    }
    fn next(&mut self) -> ERes<()> {
        if self.pos >= self.len {
            return err_parse("end of document reached", self)
        }
        let c = self.vec[self.pos];
        self.pos += 1;
        match c {
            '\r' | '\n' => {
                self.lpos = 0;
                self.line += 1;
            }
            _ => {
                self.lpos += 1;
            }
        }
        Ok(())
    }

    fn store_pos(&mut self) {
        self.store_pos = self.pos;
        self.store_line = self.line;
        self.store_lpos = self.lpos;

    }

    fn restore_pos(&mut self) {
        self.pos = self.store_pos;
        self.line = self.store_line;
        self.lpos = self.store_lpos;
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::ParseError(ref p) =>
                write!(f, "Parse Error {}:{}: {}", p.line, p.lpos, p.msg),
            Error::IOError(ref i) =>
                write!(f, "{}", i)
        }
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::ParseError(ref p) =>
                write!(f, "Parse Error {}:{}: {}", p.line, p.lpos, p.msg),
            Error::IOError(ref i) =>
                write!(f, "{}", i)
        }
    }
}

impl fmt::Display for Atom {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
        Atom::S(ref s) => write!(f, "{}", s),
        Atom::Q(ref s) => write!(f, "\"{}\"", s),
        Atom::I(i)     => write!(f, "{}", i),
        Atom::F(d)     => {
            let z = d.floor();
            if d - z < f64::EPSILON {
                write!(f, "{}.0", z)
            } else {
                write!(f, "{}", d)
            }
        }
    }
  }
}

impl fmt::Display for Sexp {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
      Sexp::Atom(ref a) => write!(f, "{}", a),
      Sexp::List(ref xs) => {
        try!(write!(f, "("));
        for (i, x) in xs.iter().enumerate() {
          let s = if i == 0 { "" } else { " " };
          try!(write!(f, "{}{}", s, x));
        }
        write!(f, ")")
      },
      Sexp::Empty => write!(f, ""),
    }
  }
}

fn parse_list(state: &mut ParseState) -> ERes<Sexp> {
    //println!("list");
    try!(state.next()); // skip (
    let mut first = true;
    let mut l: Vec<Sexp> = Vec::new();
    loop {
        match try!(state.peek()) {
            ')' => {
                try!(state.next());
                break;
            }
            ' ' | '\t' | '\r' | '\n' => {
                try!(state.next());
            }
            _ => {
                let res = try!(parse_sexp(state));
                if first {
                    //println!("List: {}", &res);
                    first = false;
                }
                l.push(res)
            }
        }
    }
    let l = Sexp::List(l);
    //println!("Found list {}", &l);
    Ok(l)
}

fn parse_quoted_string(state: &mut ParseState) -> ERes<Atom> {
    //println!("qstring");
    try!(state.next()); // skip "
    let mut s = String::new();
    loop {
        match try!(state.peek()) {
            '"' => {
                try!(state.next());
                break
            }
            x @ '\r' | x @ '\n' => {
                s.push(x);
                try!(state.next());
                }
            x => {
                s.push(x);
                try!(state.next());
            }
        }
    }
    //println!("Found quoted string {}", s);
    Ok(Atom::Q(s))
}

fn parse_string(state: &mut ParseState) -> ERes<Atom> {
    //println!("string");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\t' | '\r' | '\n' | ')' => break,
                    '"' => return err_parse("unexpected \" in string", state),
                    x => s.push(x),
                }
            }
            None => {
                break;
            }
        }
        try!(state.next())
    }
    //println!("Found string {}", s);
    Ok(Atom::S(s))
}

fn parse_number(state: &mut ParseState) -> ERes<Atom> {
    //println!("number");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\r' | '\n' | '\t' | ')' => {
                        break
                    },
                    '0' ... '9' | '.' | '-' => {
                        s.push(state.vec[state.pos])
                    },
                    _ => {
                        return err_parse("unexpected char in number", &state)
                    },
                }
            }
            None => {
                break
            }
        }
        try!(state.next())
    }
    //println!("Found number {}", s);
    let s2: &str = &s[..];
    if s.contains('.') {
        Ok(Atom::F(f64::from_str(s2).unwrap()))
    } else {
        Ok(Atom::I(i64::from_str(s2).unwrap()))
    }
}

fn parse_atom(state: &mut ParseState) -> ERes<Sexp> {
    //println!("atom");
    let a = match try!(state.peek()) {
        '"' => {
            try!(parse_quoted_string(state))
        },
        '0' ... '9' | '.' | '-' => {
            state.store_pos();
            match parse_number(state) {
                Ok(a) => {
                    a
                },
                Err(_) => {
                    state.restore_pos();
                    try!(parse_string(state))
                },
            }
        }
        _ => {
            try!(parse_string(state))
        }
    };
    Ok(Sexp::Atom(a))
}

fn parse_sexp(state: &mut ParseState) -> ERes<Sexp> {
    loop {
        match try!(state.peek()) {
            '(' => {
                return parse_list(state)
            }
            ' ' | '\t' | '\r' | '\n' => {
                try!(state.next());
            }
            ')' => {
                return err_parse("unmatched )", state)
            }
            _ => {
                return parse_atom(state)
            }
        }
    }
}

fn parse(data: &str) -> ERes<Sexp> {
    if data.len() == 0 {
        Ok(Sexp::Empty)
    } else {
        let vec: Vec<char> = data.chars().collect();
        let len = vec.len();
        let state = &mut ParseState { pos: 0, line: 1, lpos: 0, vec: vec, len: len, store_pos: 0, store_lpos: 0, store_line: 0, };
        parse_sexp(state)
    }
}

fn read_file(name: &str) -> Result<String, std::io::Error> {
    let mut f = try!(File::open(name));
    let mut s = String::new();
    try!(f.read_to_string(&mut s));
    Ok(s)
}

pub fn parse_str(s: &str) -> ERes<Sexp> {
    parse(s)
}

pub fn parse_file(name: &str) -> ERes<Sexp> {
    let s = try!(match read_file(name) {
        Ok(s) => Ok(s),
        Err(x) => err_io(x),
    });
    parse(&s[..])
}

#[cfg(test)]
mod tests {
    use super::*;

    #[allow(dead_code)]
    fn check_parse(s: &str) {
        let e = parse_str(s).unwrap();
        let t = format!("{}", e);
        assert_eq!(s, t);
    }

    #[allow(dead_code)]
    fn parse_fail(s: &str) {
        parse_str(s).unwrap();
    }

    #[test]
    fn test_empty() { check_parse("") }

    #[test]
    fn test_minimal() { check_parse("()") }

    #[test]
    fn test_string() { check_parse("hello") }

    #[test]
    fn test_qstring() { check_parse("\"hello\"") }

    #[test]
    fn test_number() { check_parse("1.3") }

    #[test]
    fn test_float_vs_int() { check_parse("2.0") }

    #[test]
    fn test_double() { check_parse("(())") }

    #[test]
    fn test_br_string() { check_parse("(world)") }

    #[test]
    fn test_br_qstring() { check_parse("(\"world\")") }

    #[test]
    fn test_br_int() { check_parse("(42)") }

    #[test]
    fn test_br_float() { check_parse("(12.7)") }

    #[test]
    fn test_br_qbrstring() { check_parse("(\"(()\")") }

    #[test]
    fn test_number_string() { check_parse("567A_WZ") }

    #[test]
    #[should_panic(expected="Parse Error 1:1: end of document reached")]
    fn test_invalid1() { parse_fail("(") }

    #[test]
    #[should_panic(expected="Parse Error 1:0: unmatched )")]
    fn test_invalid2() { parse_fail(")") }

    #[test]
    #[should_panic(expected="Parse Error 1:6: end of document reached")]
    fn test_invalid3() { parse_fail("\"hello") }

    #[test]
    fn test_complex() { check_parse("(module SWITCH_3W_SIDE_MMP221-R (layer F.Cu) (descr \"\") (pad 1 thru_hole rect (size 1.2 1.2) (at -2.5 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 2 thru_hole rect (size 1.2 1.2) (at 0.0 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 3 thru_hole rect (size 1.2 1.2) (at 2.5 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 5 thru_hole rect (size 1.2 1.2) (at 0.0 1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 6 thru_hole rect (size 1.2 1.2) (at -2.5 1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 4 thru_hole rect (size 1.2 1.2) (at 2.5 1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (fp_line (start -4.5 -1.75) (end 4.5 -1.75) (layer F.SilkS) (width 0.127)) (fp_line (start 4.5 -1.75) (end 4.5 1.75) (layer F.SilkS) (width 0.127)) (fp_line (start 4.5 1.75) (end -4.5 1.75) (layer F.SilkS) (width 0.127)) (fp_line (start -4.5 1.75) (end -4.5 -1.75) (layer F.SilkS) (width 0.127)))") }

    /*
    #[test]
    fn test_temp() {
        let s = parse_file("/tmp/usbser.kicad_pcb").unwrap();
        println!("{}", s);
    }
    */
}

<commit_msg>list_atom check<commit_after>// (c) 2015 Joost Yervante Damad <joost@productize.be>

// loosely based on https://github.com/cgaebel/sexp
// latest version can be found at https://github.com/andete/rust_sexp

use std::fmt;
use std::str::FromStr;
use std::f64;

use std::fs::File;
use std::io::prelude::*;

pub enum Atom {
  S(String),
  Q(String),
  I(i64),
  F(f64),
}

impl Atom {
    pub fn f(&self) -> Result<f64,String> {
        match *self {
            Atom::F(f) => Ok(f),
            Atom::I(i) => Ok(i as f64),
            ref x => Err(format!("not a float: {}", x))
        }
    }
    pub fn i(&self) -> Result<i64,String> {
        match *self {
            Atom::I(i) => Ok(i),
            ref x => Err(format!("not an int: {}", x))
        }
    }
    pub fn string(&self) -> Result<String,String> {
        match *self {
            Atom::S(ref s) => Ok(s.clone()),
            Atom::Q(ref s) => Ok(s.clone()),
            ref x => Err(format!("not a string: {}", x))
        }
    }
    pub fn as_string(&self) -> Result<String,String> {
        match *self {
            Atom::S(ref s) => Ok(s.clone()),
            Atom::Q(ref s) => Ok(s.clone()),
            Atom::F(ref s) => Ok(format!("{}", s)),
            Atom::I(ref s) => Ok(format!("{}", s)),
        }
    }
}

pub enum Sexp {
  Atom(Atom),
  Empty,
  List(Vec<Sexp>),
}

impl Sexp {
    pub fn atom(&self) -> Result<&Atom,String> {
        match *self {
            Sexp::Atom(ref f) => Ok(f),
            ref x => Err(format!("not an atom: {}", x))
        }
    }
    pub fn list(&self) -> Result<&Vec<Sexp>,String> {
        match *self {
            Sexp::List(ref v) => Ok(v),
            ref x => Err(format!("not a list: {}", x))
        }
    }

    pub fn list_atom(&self, s:&str) -> Result<&Vec<Sexp>,String> {
        let v = match *self {
            Sexp::List(ref v) => v,
            ref x => return Err(format!("not a list: {}", x))
        };
        let v2 =&v[..];
        let st = try!(try!(v2[0].atom()).string());
        if st != s {
            return Err(format!("list doesn't start with {}", s))
        };
        Ok(v)
    }
}

pub struct ParseError {
    msg: &'static str,
    line: usize,
    lpos: usize,
}

pub enum Error {
    ParseError(ParseError),
    IOError(std::io::Error),
}

pub type ERes<T> = Result<T, Error>;

fn err_parse<T>(msg: &'static str, state: &ParseState) -> ERes<T> {
    Err(Error::ParseError(ParseError { msg: msg, line: state.line, lpos: state.lpos}))
}

fn err_io<T>(err: std::io::Error) -> ERes<T> {
    Err(Error::IOError(err))
}

struct ParseState {
    pos: usize,
    line: usize,
    lpos: usize,
    vec: Vec<char>,
    len: usize,
    store_pos: usize,
    store_line: usize,
    store_lpos: usize,
}

impl ParseState {
    fn peek(&self) -> ERes<char> {
        if self.pos >= self.len {
            return err_parse("end of document reached", self)
        }
        Ok(self.vec[self.pos])
    }
    fn peek_option(&self) -> Option<char> {
        if self.pos >= self.len {
            return None
        }
        Some(self.vec[self.pos])
    }
    fn next(&mut self) -> ERes<()> {
        if self.pos >= self.len {
            return err_parse("end of document reached", self)
        }
        let c = self.vec[self.pos];
        self.pos += 1;
        match c {
            '\r' | '\n' => {
                self.lpos = 0;
                self.line += 1;
            }
            _ => {
                self.lpos += 1;
            }
        }
        Ok(())
    }

    fn store_pos(&mut self) {
        self.store_pos = self.pos;
        self.store_line = self.line;
        self.store_lpos = self.lpos;

    }

    fn restore_pos(&mut self) {
        self.pos = self.store_pos;
        self.line = self.store_line;
        self.lpos = self.store_lpos;
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::ParseError(ref p) =>
                write!(f, "Parse Error {}:{}: {}", p.line, p.lpos, p.msg),
            Error::IOError(ref i) =>
                write!(f, "{}", i)
        }
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::ParseError(ref p) =>
                write!(f, "Parse Error {}:{}: {}", p.line, p.lpos, p.msg),
            Error::IOError(ref i) =>
                write!(f, "{}", i)
        }
    }
}

impl fmt::Display for Atom {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
        Atom::S(ref s) => write!(f, "{}", s),
        Atom::Q(ref s) => write!(f, "\"{}\"", s),
        Atom::I(i)     => write!(f, "{}", i),
        Atom::F(d)     => {
            let z = d.floor();
            if d - z < f64::EPSILON {
                write!(f, "{}.0", z)
            } else {
                write!(f, "{}", d)
            }
        }
    }
  }
}

impl fmt::Display for Sexp {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
      Sexp::Atom(ref a) => write!(f, "{}", a),
      Sexp::List(ref xs) => {
        try!(write!(f, "("));
        for (i, x) in xs.iter().enumerate() {
          let s = if i == 0 { "" } else { " " };
          try!(write!(f, "{}{}", s, x));
        }
        write!(f, ")")
      },
      Sexp::Empty => write!(f, ""),
    }
  }
}

fn parse_list(state: &mut ParseState) -> ERes<Sexp> {
    //println!("list");
    try!(state.next()); // skip (
    let mut first = true;
    let mut l: Vec<Sexp> = Vec::new();
    loop {
        match try!(state.peek()) {
            ')' => {
                try!(state.next());
                break;
            }
            ' ' | '\t' | '\r' | '\n' => {
                try!(state.next());
            }
            _ => {
                let res = try!(parse_sexp(state));
                if first {
                    //println!("List: {}", &res);
                    first = false;
                }
                l.push(res)
            }
        }
    }
    let l = Sexp::List(l);
    //println!("Found list {}", &l);
    Ok(l)
}

fn parse_quoted_string(state: &mut ParseState) -> ERes<Atom> {
    //println!("qstring");
    try!(state.next()); // skip "
    let mut s = String::new();
    loop {
        match try!(state.peek()) {
            '"' => {
                try!(state.next());
                break
            }
            x @ '\r' | x @ '\n' => {
                s.push(x);
                try!(state.next());
                }
            x => {
                s.push(x);
                try!(state.next());
            }
        }
    }
    //println!("Found quoted string {}", s);
    Ok(Atom::Q(s))
}

fn parse_string(state: &mut ParseState) -> ERes<Atom> {
    //println!("string");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\t' | '\r' | '\n' | ')' => break,
                    '"' => return err_parse("unexpected \" in string", state),
                    x => s.push(x),
                }
            }
            None => {
                break;
            }
        }
        try!(state.next())
    }
    //println!("Found string {}", s);
    Ok(Atom::S(s))
}

fn parse_number(state: &mut ParseState) -> ERes<Atom> {
    //println!("number");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\r' | '\n' | '\t' | ')' => {
                        break
                    },
                    '0' ... '9' | '.' | '-' => {
                        s.push(state.vec[state.pos])
                    },
                    _ => {
                        return err_parse("unexpected char in number", &state)
                    },
                }
            }
            None => {
                break
            }
        }
        try!(state.next())
    }
    //println!("Found number {}", s);
    let s2: &str = &s[..];
    if s.contains('.') {
        Ok(Atom::F(f64::from_str(s2).unwrap()))
    } else {
        Ok(Atom::I(i64::from_str(s2).unwrap()))
    }
}

fn parse_atom(state: &mut ParseState) -> ERes<Sexp> {
    //println!("atom");
    let a = match try!(state.peek()) {
        '"' => {
            try!(parse_quoted_string(state))
        },
        '0' ... '9' | '.' | '-' => {
            state.store_pos();
            match parse_number(state) {
                Ok(a) => {
                    a
                },
                Err(_) => {
                    state.restore_pos();
                    try!(parse_string(state))
                },
            }
        }
        _ => {
            try!(parse_string(state))
        }
    };
    Ok(Sexp::Atom(a))
}

fn parse_sexp(state: &mut ParseState) -> ERes<Sexp> {
    loop {
        match try!(state.peek()) {
            '(' => {
                return parse_list(state)
            }
            ' ' | '\t' | '\r' | '\n' => {
                try!(state.next());
            }
            ')' => {
                return err_parse("unmatched )", state)
            }
            _ => {
                return parse_atom(state)
            }
        }
    }
}

fn parse(data: &str) -> ERes<Sexp> {
    if data.len() == 0 {
        Ok(Sexp::Empty)
    } else {
        let vec: Vec<char> = data.chars().collect();
        let len = vec.len();
        let state = &mut ParseState { pos: 0, line: 1, lpos: 0, vec: vec, len: len, store_pos: 0, store_lpos: 0, store_line: 0, };
        parse_sexp(state)
    }
}

fn read_file(name: &str) -> Result<String, std::io::Error> {
    let mut f = try!(File::open(name));
    let mut s = String::new();
    try!(f.read_to_string(&mut s));
    Ok(s)
}

pub fn parse_str(s: &str) -> ERes<Sexp> {
    parse(s)
}

pub fn parse_file(name: &str) -> ERes<Sexp> {
    let s = try!(match read_file(name) {
        Ok(s) => Ok(s),
        Err(x) => err_io(x),
    });
    parse(&s[..])
}

#[cfg(test)]
mod tests {
    use super::*;

    #[allow(dead_code)]
    fn check_parse(s: &str) {
        let e = parse_str(s).unwrap();
        let t = format!("{}", e);
        assert_eq!(s, t);
    }

    #[allow(dead_code)]
    fn parse_fail(s: &str) {
        parse_str(s).unwrap();
    }

    #[test]
    fn test_empty() { check_parse("") }

    #[test]
    fn test_minimal() { check_parse("()") }

    #[test]
    fn test_string() { check_parse("hello") }

    #[test]
    fn test_qstring() { check_parse("\"hello\"") }

    #[test]
    fn test_number() { check_parse("1.3") }

    #[test]
    fn test_float_vs_int() { check_parse("2.0") }

    #[test]
    fn test_double() { check_parse("(())") }

    #[test]
    fn test_br_string() { check_parse("(world)") }

    #[test]
    fn test_br_qstring() { check_parse("(\"world\")") }

    #[test]
    fn test_br_int() { check_parse("(42)") }

    #[test]
    fn test_br_float() { check_parse("(12.7)") }

    #[test]
    fn test_br_qbrstring() { check_parse("(\"(()\")") }

    #[test]
    fn test_number_string() { check_parse("567A_WZ") }

    #[test]
    #[should_panic(expected="Parse Error 1:1: end of document reached")]
    fn test_invalid1() { parse_fail("(") }

    #[test]
    #[should_panic(expected="Parse Error 1:0: unmatched )")]
    fn test_invalid2() { parse_fail(")") }

    #[test]
    #[should_panic(expected="Parse Error 1:6: end of document reached")]
    fn test_invalid3() { parse_fail("\"hello") }

    #[test]
    fn test_complex() { check_parse("(module SWITCH_3W_SIDE_MMP221-R (layer F.Cu) (descr \"\") (pad 1 thru_hole rect (size 1.2 1.2) (at -2.5 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 2 thru_hole rect (size 1.2 1.2) (at 0.0 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 3 thru_hole rect (size 1.2 1.2) (at 2.5 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 5 thru_hole rect (size 1.2 1.2) (at 0.0 1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 6 thru_hole rect (size 1.2 1.2) (at -2.5 1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 4 thru_hole rect (size 1.2 1.2) (at 2.5 1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (fp_line (start -4.5 -1.75) (end 4.5 -1.75) (layer F.SilkS) (width 0.127)) (fp_line (start 4.5 -1.75) (end 4.5 1.75) (layer F.SilkS) (width 0.127)) (fp_line (start 4.5 1.75) (end -4.5 1.75) (layer F.SilkS) (width 0.127)) (fp_line (start -4.5 1.75) (end -4.5 -1.75) (layer F.SilkS) (width 0.127)))") }

    /*
    #[test]
    fn test_temp() {
        let s = parse_file("/tmp/usbser.kicad_pcb").unwrap();
        println!("{}", s);
    }
    */
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;

pub mod builders;
mod parser;
mod types;

pub use parser::{parse_response, ParseResult};
pub use types::*;
<commit_msg>Expose types module for use in downstream libraries<commit_after>#[macro_use]
extern crate nom;

pub mod builders;
mod parser;
pub mod types;

pub use parser::{parse_response, ParseResult};
pub use types::*;
<|endoftext|>