<commit_before>use utils::RingBuffer;

#[allow(dead_code)]
enum InsertionResult {
    Inserted { length: usize },
    OutOfMemory,
}

#[allow(dead_code)]
enum State {
    Closed,
    Connected { seq: usize },
}

#[allow(dead_code)]
#[derive(Default)]
struct Segment {
    pub valid: bool,
    pub begin: usize,
    pub length: usize,
}

impl Segment {
    pub fn new(begin: usize, length: usize) -> Segment {
        Segment { valid: false, begin: begin, length: length}
    }

    #[inline]
    pub fn is_valid(&self) -> bool {
        self.valid
    }

    #[inline]
    pub fn reset(&mut self, length: usize) {
        self.valid = false;
        self.length = length;
    }
}

#[allow(dead_code)]
struct ReorderedData {
    pub data: RingBuffer,
    pub buffer_size: usize,
    pub window_size: usize,
    pub state: State,
    pub head_seq: usize,
    pub tail_seq: usize,
    pub segments: Vec<Segment>,
}

const PAGE_SIZE: usize = 4096; // Page size in bytes, not using huge pages here.

#[allow(dead_code)]
impl ReorderedData {
    #[inline]
    fn round_to_pages(buffer_size: usize) -> usize {
        (buffer_size + (PAGE_SIZE - 1)) & PAGE_SIZE
    }

    #[inline]
    fn round_to_power_of_2(mut size: usize) -> usize {
        size -= 1;
        size |= size >> 1;
        size |= size >> 2;
        size |= size >> 4;
        size |= size >> 8;
        size |= size >> 16;
        size |= size >> 32;
        size += 1;
        size
    }

    pub fn new(buffer_size: usize, window_size: usize) -> Option<ReorderedData> {
        if window_size >= buffer_size {
            None
        } else {
            let page_aligned_size = ReorderedData::round_to_pages(buffer_size);
            let pages = ReorderedData::round_to_power_of_2(page_aligned_size / PAGE_SIZE);
            Some(ReorderedData {
                data: RingBuffer::new(pages).unwrap(),
                buffer_size: page_aligned_size,
                window_size: window_size,
                state: State::Closed,
                head_seq: 0,
                tail_seq: 0,
                // Use less space than this if possible.
                segments: (0..page_aligned_size).map(|b| Segment::new(b, 1)).collect(),
            })
        }
    }

    fn fast_path_insert(&mut self, data: &[u8]) -> InsertionResult {
        let mut written = 0;
        while written < data.len() {
            written += self.data.write_at_tail(data);
            while self.data.available() >= self.window_size {
                // Notify (thus potentially draining the buffer
            }
        }
        self.tail_seq += written;
        InsertionResult::Inserted { length: self.data.available() }
    }

    fn slow_path_insert(&mut self, seq: usize, data: &[u8]) -> InsertionResult {
        if self.tail_seq > seq { // Received an old segment, discard for now.
            InsertionResult::Inserted { length: self.data.available() }
        } else {
            let offset = seq - self.tail_seq;
            let inserted = self.data.write_at_offset_from_tail(offset, data);
            if inserted < data.len() {
                InsertionResult::OutOfMemory
            } else {
                InsertionResult::Inserted { length: self.data.available() }
            }
        }

    }

    pub fn seq(&mut self, seq: usize, data: &[u8]) -> InsertionResult {
        self.state = State::Connected {seq: seq};
        self.head_seq = seq;
        self.tail_seq = seq;
        self.fast_path_insert(data)
    }

    pub fn add_data(&mut self, seq: usize, data: &[u8]) -> InsertionResult {
        if seq == self.tail_seq { // Fast path
            self.fast_path_insert(data)
        } else { // Slow path
            self.slow_path_insert(seq, data)
        }
    }
}
<commit_msg>Create a list of segments that have been completed<commit_after>use utils::RingBuffer;
use std::cmp::max;

#[allow(dead_code)]
enum InsertionResult {
    Inserted { length: usize },
    OutOfMemory,
}

#[allow(dead_code)]
enum State {
    Closed,
    Connected { seq: usize },
}

#[allow(dead_code)]
#[derive(Default)]
struct Segment {
    pub prev: isize,
    pub valid: bool,
    pub begin: usize,
    pub length: usize,
    pub next: isize,
}

impl Segment {
    pub fn new(begin: usize, length: usize) -> Segment {
        Segment { prev: -1, next: -1, valid: false, begin: begin, length: length}
    }

    #[inline]
    pub fn is_valid(&self) -> bool {
        self.valid
    }

    #[inline]
    pub fn reset(&mut self, length: usize) {
        self.valid = false;
        self.length = length;
        self.prev = -1;
        self.next = -1;
    }
}

#[allow(dead_code)]
struct SegmentList {
    storage: Vec<Segment>,
    available: Vec<isize>,
    head: isize,
    tail: isize,
}

impl SegmentList {
    pub fn new(length: usize) -> SegmentList {
        SegmentList {
            storage: (0..(length as isize)).map(|_| Segment::new(0, 0)).collect(),
            available: (0..(length as isize)).collect(),
            head: -1,
            tail: -1,
        }
    }

    #[inline]
    pub fn head<'a>(&'a self) -> Option<&'a Segment> {
        if self.head == -1 {
            None
        } else {
            Some(&self.storage[self.head as usize])
        }
    }

    #[inline]
    pub fn tail<'a>(&'a self) -> Option<&'a Segment> {
        if self.tail == -1 {
            None
        } else {
            Some(&self.storage[self.tail as usize])
        }
    }

    #[inline]
    pub fn remove_head(&mut self) {
        if self.head != -1 {
            self.head = self.storage[self.head as usize].next;
        }
    }

    #[inline]
    pub fn remove_tail(&mut self) {
        if self.tail != -1 {
            self.tail = self.storage[self.tail as usize].prev;
        }
    }

    #[inline]
    fn insert_before_node(&mut self, next: isize, begin: usize, len: usize) -> isize {
        let idx = if let Some(nidx) = self.available.pop() {
            nidx
        } else {
            self.storage.push(Segment::new(0, 0));
            self.storage.len() as isize
        };
        self.storage[idx as usize].begin = begin;
        self.storage[idx as usize].length = len;
        self.storage[idx as usize].valid = true;
        self.storage[idx as usize].next = next;
        if next != -1 {
            let prev = self.storage[next as usize].prev;
            self.storage[idx as usize].prev = prev;
            self.storage[next as usize].prev = idx;
            if prev != -1 {
                self.storage[prev as usize].next = idx;
            }
        } else {
            self.storage[idx as usize].prev = -1;
        }
        idx
    }

    #[inline]
    pub fn insert_segment<'a>(&'a mut self, begin: usize, len: usize) -> Option<&'a Segment>{
        let mut idx = self.head;
        if idx == -1 { // Special case the first insertion.
            idx = self.insert_before_node(-1, begin, len);
            self.head = idx;
            self.tail = idx;
            return Some(&self.storage[idx as usize])
        } else {
            let end = begin + len;
            while idx != -1 {
                let segment_end = self.storage[idx as usize].begin + self.storage[idx as usize].length;
                if segment_end == begin { // We can just add to the current segment.
                    self.storage[idx as usize].length += len;
                    return Some(&self.storage[idx as usize])
                } else if self.storage[idx as usize].begin > end { // We are on to segments that are further down, insert
                    let idx = self.insert_before_node(idx, begin, len);
                    return Some(&self.storage[idx as usize])
                } else if self.storage[idx as usize].begin <= begin { // Overlapping segment
                    let new_end = max(segment_end, end);
                    self.storage[idx as usize].length = new_end - self.storage[idx as usize].begin;
                    return Some(&self.storage[idx as usize]);
                }
            }
            // Nothing matched, so let us insert at the tail.
            None

        }
    }
}

#[allow(dead_code)]
struct ReorderedData {
    pub data: RingBuffer,
    pub buffer_size: usize,
    pub window_size: usize,
    pub state: State,
    pub head_seq: usize,
    pub tail_seq: usize,
}

const PAGE_SIZE: usize = 4096; // Page size in bytes, not using huge pages here.

#[allow(dead_code)]
impl ReorderedData {
    #[inline]
    fn round_to_pages(buffer_size: usize) -> usize {
        (buffer_size + (PAGE_SIZE - 1)) & PAGE_SIZE
    }

    #[inline]
    fn round_to_power_of_2(mut size: usize) -> usize {
        size -= 1;
        size |= size >> 1;
        size |= size >> 2;
        size |= size >> 4;
        size |= size >> 8;
        size |= size >> 16;
        size |= size >> 32;
        size += 1;
        size
    }

    pub fn new(buffer_size: usize, window_size: usize) -> Option<ReorderedData> {
        if window_size >= buffer_size {
            None
        } else {
            let page_aligned_size = ReorderedData::round_to_pages(buffer_size);
            let pages = ReorderedData::round_to_power_of_2(page_aligned_size / PAGE_SIZE);
            Some(ReorderedData {
                data: RingBuffer::new(pages).unwrap(),
                buffer_size: page_aligned_size,
                window_size: window_size,
                state: State::Closed,
                head_seq: 0,
                tail_seq: 0,
                // Use less space than this if possible.
            })
        }
    }

    fn fast_path_insert(&mut self, data: &[u8]) -> InsertionResult {
        let mut written = 0;
        while written < data.len() {
            written += self.data.write_at_tail(data);
            while self.data.available() >= self.window_size {
                // Notify (thus potentially draining the buffer
            }
        }
        self.tail_seq += written;
        InsertionResult::Inserted { length: self.data.available() }
    }

    fn slow_path_insert(&mut self, seq: usize, data: &[u8]) -> InsertionResult {
        if self.tail_seq > seq { // Received an old segment, discard for now.
            InsertionResult::Inserted { length: self.data.available() }
        } else {
            let offset = seq - self.tail_seq;
            let inserted = self.data.write_at_offset_from_tail(offset, data);
            if inserted < data.len() {
                InsertionResult::OutOfMemory
            } else {
                InsertionResult::Inserted { length: self.data.available() }
            }
        }

    }

    pub fn seq(&mut self, seq: usize, data: &[u8]) -> InsertionResult {
        self.state = State::Connected {seq: seq};
        self.head_seq = seq;
        self.tail_seq = seq;
        self.fast_path_insert(data)
    }

    pub fn add_data(&mut self, seq: usize, data: &[u8]) -> InsertionResult {
        if seq == self.tail_seq { // Fast path
            self.fast_path_insert(data)
        } else { // Slow path
            self.slow_path_insert(seq, data)
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt;

/// An error encountered while working with structured data.
#[derive(Clone, Debug)]
pub struct Error {
    msg: &'static str,
}

impl Error {
    /// Create an error from the given message.
    pub fn msg(msg: &'static str) -> Self {
        Error {
            msg: msg,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.msg.fmt(f)
    }
}

impl From<fmt::Error> for Error {
    fn from(_: fmt::Error) -> Self {
        Error::msg("formatting failed")
    }
}

impl From<Error> for fmt::Error {
    fn from(_: Error) -> Self {
        fmt::Error
    }
}

#[cfg(feature = "std")]
mod std_support {
    use super::*;
    use std::error;

    impl error::Error for Error {
        fn description(&self) -> &str {
            "key values error"
        }
    }
}
<commit_msg>Add conversion to/from io::Error for kv::Error<commit_after>use std::fmt;

/// An error encountered while working with structured data.
#[derive(Debug)]
pub struct Error {
    inner: Inner
}

#[derive(Debug)]
enum Inner {
    #[cfg(feature = "std")]
    Io(std::io::Error),
    Msg(&'static str),
    Fmt,
}

impl Error {
    /// Create an error from the given message.
    pub fn msg(msg: &'static str) -> Self {
        Error {
            inner: Inner::Msg(msg),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::Inner::*;
        match &self.inner {
            #[cfg(feature = "std")]
            Io(err) => err.fmt(f),
            Msg(msg) => msg.fmt(f),
            Fmt => fmt::Error.fmt(f),
        }
    }
}

impl From<fmt::Error> for Error {
    fn from(_: fmt::Error) -> Self {
        Error {
            inner: Inner::Fmt,
        }
    }
}

impl From<Error> for fmt::Error {
    fn from(_: Error) -> Self {
        fmt::Error
    }
}

#[cfg(feature = "std")]
mod std_support {
    use super::*;
    use std::{error, io};

    impl error::Error for Error {
        fn description(&self) -> &str {
            "key values error"
        }
    }

    impl From<io::Error> for Error {
        fn from(err: io::Error) -> Self {
            Error {
                inner: Inner::Io(err)
            }
        }
    }

    impl From<Error> for io::Error {
        fn from(err: Error) -> Self {
            if let Inner::Io(err) = err.inner {
                err
            } else {
                io::Error::new(io::ErrorKind::Other, err)
            }
        }
    }
}
<|endoftext|>


<commit_before>use ndarray::*;
use ndarray_linalg::*;
use num_traits::Float;

use traits::*;
use jacobian::*;
use adaptor::time_series;

/// Calculate all Lyapunov exponents
pub fn exponents<A, S, TEO>(
    mut teo: TEO,
    x0: ArrayBase<S, Ix1>,
    alpha: A::Real,
    duration: usize,
) -> Array1<A>
where
    A: RealScalar,
    S: DataMut<Elem = A> + DataClone,
    TEO: TimeEvolution<Scalar = A, Dim = Ix1> + TimeStep<Time = A>,
{
    let n = x0.len();
    let dur = teo.get_dt() * into_scalar(duration as f64);
    let mut teo2 = teo.clone();
    let ts = time_series(x0, &mut teo);
    ts.scan(Array::eye(n), |q, x| {
        teo2.lin_approx(x.to_owned(), alpha).apply_multi_inplace(q);
        let (q_next, r) = q.qr().unwrap();
        *q = q_next;
        let d: Array1<A> = r.diag().map(|x| AssociatedReal::inject(x.abs().ln()));
        Some(d)
    }).skip(duration / 10)
        .take(duration)
        .fold(ArrayBase::zeros(n), |mut x, y| {
            azip!(mut x, y in { *x = *x + y/dur } );
            x
        })
}
<commit_msg>Simplify Lyapunov implement<commit_after>use ndarray::*;
use ndarray_linalg::*;
use num_traits::Float;

use traits::*;
use jacobian::*;

/// Calculate all Lyapunov exponents
pub fn exponents<A, TEO>(teo: TEO, x: Array1<A>, alpha: A::Real, duration: usize) -> Array1<A::Real>
where
    A: Scalar,
    TEO: TimeEvolution<Scalar = A, Dim = Ix1> + TimeStep<Time = A::Real>,
{
    let n = teo.model_size();
    let dur = teo.get_dt() * into_scalar(duration as f64);
    Series::new(teo, x, alpha)
        .map(|(_q, r)| r.diag().map(|x| x.abs().ln()))
        .skip(duration / 10)
        .take(duration)
        .fold(ArrayBase::zeros(n), |mut x, y| {
            azip!(mut x, y in { *x = *x + y/dur } );
            x
        })
}

pub struct Series<A, TEO>
where
    A: Scalar,
    TEO: TimeEvolution<Scalar = A, Dim = Ix1>,
{
    teo: TEO,
    x: Array1<A>,
    q: Array2<A>,
    alpha: A::Real,
}

impl<A, TEO> Series<A, TEO>
where
    A: Scalar,
    TEO: TimeEvolution<Scalar = A, Dim = Ix1>,
{
    pub fn new(teo: TEO, x: Array1<A>, alpha: A::Real) -> Self {
        let q = Array::eye(teo.model_size());
        Series { teo, x, q, alpha }
    }
}

impl<A, TEO> Iterator for Series<A, TEO>
where
    A: Scalar,
    TEO: TimeEvolution<Scalar = A, Dim = Ix1>,
{
    type Item = (Array2<A>, Array2<A>);

    fn next(&mut self) -> Option<Self::Item> {
        let q = self.teo
            .lin_approx(self.x.to_owned(), self.alpha)
            .apply_multi_inplace(&mut self.q);
        let (q, r) = q.qr_square_inplace().unwrap();
        self.teo.iterate(&mut self.x);
        Some((q.to_owned(), r))
    }
}
<|endoftext|>


<commit_before>use error::Error;
use json;
use std::default::Default;

#[derive(Debug, Default)]
pub struct Manifest {
    pub edition: Edition,
    pub targets: Vec<Target>,
}

impl Manifest {
    fn from_str(src: &str) -> Result<Self, Error> {
        let mut j = json::parse(src).map_err(Error::InvalidManifestJson)?;

        let edition: Edition = match j["edition"].as_str() {
            Some("2015") => Edition::E2015,
            Some("2018") => Edition::E2018,
            Some(unknown) => panic!("Unrecognized value for edition \"{}\"", unknown),
            None => Edition::default(),
        };

        let targets: Vec<Target> = j["targets"].members_mut().map(Target::from_json).collect();

        Result::Ok(Manifest { edition, targets })
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Edition {
    E2015,
    E2018,
}

impl Default for Edition {
    fn default() -> Self {
        Edition::E2015
    }
}

#[derive(Debug, PartialEq)]
pub struct Target {
    kind: Vec<String>,
    crate_types: Vec<String>,
    name: String,
    src_path: String,
    edition: Option<String>,
}

impl Target {
    const LIB_KINDS: [&'static str; 4] = ["lib", "rlib", "dylib", "staticlib"];

    fn from_json(j: &mut json::JsonValue) -> Target {
        let kind: Vec<String> = {
            assert!(j["kind"].is_array());
            j["kind"]
                .members_mut()
                .map(|k| k.take_string().unwrap())
                .collect()
        };
        let crate_types: Vec<String> = {
            assert!(j["crate_types"].is_array());
            j["crate_types"]
                .members_mut()
                .map(|k| k.take_string().unwrap())
                .collect()
        };
        let name: String = j["name"].take_string().expect("name is missing");
        let src_path: String = j["src_path"].take_string().expect("src_path is missing");
        let edition: Option<String> = j["edition"].take_string();
        // lib | rlib | staticlib | dylib
        Target {
            kind,
            crate_types,
            name,
            src_path,
            edition,
        }
    }

    fn is_bin(&self) -> bool {
        self.kind.contains(&String::from("bin"))
    }

    fn is_lib(&self) -> bool {
        self.kind
            .iter()
            .find(|k| Self::LIB_KINDS.contains(&&k[..]))
            .is_some()
    }
}

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

    fn read_manifest(filename: &str) -> Manifest {
        let manifest_str: String =
            fs::read_to_string(filename).expect("manifest file cannot be read");
        Manifest::from_str(&manifest_str).expect("manifest cannot be read")
    }

    #[test]
    fn manifest_with_edition2018_can_be_parsed() {
        let manifest = read_manifest("test-resources/example-edition-2018.json");
        assert_eq!(Edition::E2018, manifest.edition);
    }

    #[test]
    fn manifest_with_edition2015_can_be_parsed() {
        let manifest = read_manifest("test-resources/example-edition-2015.json");
        assert_eq!(Edition::E2015, manifest.edition);
    }

    #[test]
    fn manifest_without_edition_can_be_parsed() {
        let manifest = read_manifest("test-resources/example-no-edition.json");
        assert_eq!(Edition::E2015, manifest.edition);
    }

    #[test]
    fn manifest_for_simple_lib() {
        let manifest = read_manifest("test-resources/example-lib.json");
        assert_eq!(
            Target {
                kind: vec!(String::from("lib")),
                crate_types: vec!(String::from("lib")),
                name: String::from("example-lib"),
                src_path: String::from("/home/muhuk/Documents/code/example-lib/src/lib.rs"),
                edition: Some(String::from("2018"))
            },
            manifest.targets[0]
        );
        assert!(manifest.targets[0].is_lib());
        assert!(!manifest.targets[0].is_bin());
    }

    #[test]
    fn manifest_for_simple_bin() {
        let manifest = read_manifest("test-resources/example-bin.json");
        assert_eq!(
            Target {
                kind: vec!(String::from("bin")),
                crate_types: vec!(String::from("bin")),
                name: String::from("example-bin"),
                src_path: String::from("/home/muhuk/Documents/code/example-bin/src/main.rs"),
                edition: Some(String::from("2018"))
            },
            manifest.targets[0]
        );
        assert!(manifest.targets[0].is_bin());
        assert!(!manifest.targets[0].is_lib());
    }
}
<commit_msg>Cleanup<commit_after>use error::Error;
use json;
use std::default::Default;

#[derive(Debug, Default)]
pub struct Manifest {
    pub edition: Edition,
    pub targets: Vec<Target>,
}

impl Manifest {
    fn from_str(src: &str) -> Result<Self, Error> {
        let mut j = json::parse(src).map_err(Error::InvalidManifestJson)?;

        let edition: Edition = match j["edition"].as_str() {
            Some("2015") => Edition::E2015,
            Some("2018") => Edition::E2018,
            Some(unknown) => panic!("Unrecognized value for edition \"{}\"", unknown),
            None => Edition::default(),
        };

        let targets: Vec<Target> = j["targets"].members_mut().map(Target::from_json).collect();

        Result::Ok(Manifest { edition, targets })
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Edition {
    E2015,
    E2018,
}

impl Default for Edition {
    fn default() -> Self {
        Edition::E2015
    }
}

#[derive(Debug, PartialEq)]
pub struct Target {
    kind: Vec<String>,
    crate_types: Vec<String>,
    name: String,
    src_path: String,
    edition: Option<String>,
}

impl Target {
    const LIB_KINDS: [&'static str; 4] = ["lib", "rlib", "dylib", "staticlib"];

    fn from_json(j: &mut json::JsonValue) -> Target {
        let kind: Vec<String> = {
            assert!(j["kind"].is_array());
            j["kind"]
                .members_mut()
                .map(|k| k.take_string().unwrap())
                .collect()
        };
        let crate_types: Vec<String> = {
            assert!(j["crate_types"].is_array());
            j["crate_types"]
                .members_mut()
                .map(|k| k.take_string().unwrap())
                .collect()
        };
        let name: String = j["name"].take_string().expect("name is missing");
        let src_path: String = j["src_path"].take_string().expect("src_path is missing");
        let edition: Option<String> = j["edition"].take_string();
        Target {
            kind,
            crate_types,
            name,
            src_path,
            edition,
        }
    }

    fn is_bin(&self) -> bool {
        self.kind.contains(&String::from("bin"))
    }

    fn is_lib(&self) -> bool {
        self.kind
            .iter()
            .find(|k| Self::LIB_KINDS.contains(&&k[..]))
            .is_some()
    }
}

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

    fn read_manifest(filename: &str) -> Manifest {
        let manifest_str: String =
            fs::read_to_string(filename).expect("manifest file cannot be read");
        Manifest::from_str(&manifest_str).expect("manifest cannot be read")
    }

    #[test]
    fn manifest_with_edition2018_can_be_parsed() {
        let manifest = read_manifest("test-resources/example-edition-2018.json");
        assert_eq!(Edition::E2018, manifest.edition);
    }

    #[test]
    fn manifest_with_edition2015_can_be_parsed() {
        let manifest = read_manifest("test-resources/example-edition-2015.json");
        assert_eq!(Edition::E2015, manifest.edition);
    }

    #[test]
    fn manifest_without_edition_can_be_parsed() {
        let manifest = read_manifest("test-resources/example-no-edition.json");
        assert_eq!(Edition::E2015, manifest.edition);
    }

    #[test]
    fn manifest_for_simple_lib() {
        let manifest = read_manifest("test-resources/example-lib.json");
        assert_eq!(
            Target {
                kind: vec!(String::from("lib")),
                crate_types: vec!(String::from("lib")),
                name: String::from("example-lib"),
                src_path: String::from("/home/muhuk/Documents/code/example-lib/src/lib.rs"),
                edition: Some(String::from("2018"))
            },
            manifest.targets[0]
        );
        assert!(manifest.targets[0].is_lib());
        assert!(!manifest.targets[0].is_bin());
    }

    #[test]
    fn manifest_for_simple_bin() {
        let manifest = read_manifest("test-resources/example-bin.json");
        assert_eq!(
            Target {
                kind: vec!(String::from("bin")),
                crate_types: vec!(String::from("bin")),
                name: String::from("example-bin"),
                src_path: String::from("/home/muhuk/Documents/code/example-bin/src/main.rs"),
                edition: Some(String::from("2018"))
            },
            manifest.targets[0]
        );
        assert!(manifest.targets[0].is_bin());
        assert!(!manifest.targets[0].is_lib());
    }
}
<|endoftext|>


<commit_before>//#![crate_name = "mesh"]
#![feature(old_io)]
//mod mesh;

use std::cmp::*;
use std::collections::HashMap;
use std::f32::NAN;
use std::fmt;
use std::old_io::{BufferedReader,Reader};
use std::hash::{Hash, Hasher};
use std::mem::{transmute};
use std::vec::Vec;

#[derive(PartialEq, PartialOrd, Copy)] //Show,
pub struct Vector3D {
    x: f32,
    y: f32,
    z: f32,
}

// PartialEq is derived above, but we need to impl Eq since floats don't get
// it by default. This function is just a
impl Eq for Vector3D {
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

impl fmt::Debug for Vector3D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{},{})", self.x, self.y, self.z)
    }
}

impl Vector3D {
    fn read(r: &mut Reader) -> Vector3D {
        let xr = r.read_le_f32();
        let yr = r.read_le_f32();
        let zr = r.read_le_f32();
        if xr.is_ok() && yr.is_ok() && zr.is_ok() {
            let v = Vector3D { x: xr.ok().unwrap(), y: yr.ok().unwrap(), z: zr.ok().unwrap() };
            return v
        }
        return Vector3D { x: NAN, y: NAN, z: NAN };
    }
}

// Implement Hash since there is no default for f32. We'll just hash the bits
// since we know the f32s will all be canonical from reading.
impl Hash for Vector3D {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        //println!("V3D hash {:p}", self);
        let x: u32 = unsafe { transmute(self.x) };
        x.hash(state);
        let y: u32 = unsafe { transmute(self.y) };
        y.hash(state);
        let z: u32 = unsafe { transmute(self.z) };
        z.hash(state);
        //println!("V3D hash done {:p}", self);
    }
}

#[derive(PartialEq, Eq, Hash, Copy)]
pub struct StlFacet {
    n : Vector3D,
    v1: Vector3D,
    v2: Vector3D,
    v3: Vector3D,
    abc: u16,
}

impl fmt::Debug for StlFacet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{:?}]({:?}-{:?}-{:?})[{:X}]",
            &self.n, &self.v1, &self.v2, &self.v3, self.abc)
    }
}

impl StlFacet {
    fn read(r: &mut Reader) -> StlFacet {
        let n = Vector3D::read(r);
        let v1 = Vector3D::read(r);
        let v2 = Vector3D::read(r);
        let v3 = Vector3D::read(r);
        let abc = r.read_le_u16().unwrap();
        StlFacet { n:n, v1:v1, v2:v2, v3:v3, abc:abc }
    }
}

pub struct VertexMap {
    vertices: HashMap<Vector3D,usize>,
}

impl VertexMap {
    pub fn new() -> VertexMap {
        VertexMap {
            vertices: HashMap::new(),
        }
    }

    pub fn len(&self) -> usize {
        self.vertices.len()
    }

    pub fn get(&self, v3d: &Vector3D) -> usize {
        *self.vertices.get(v3d).unwrap()
    }

    pub fn add(&mut self, vertex: Vector3D) -> usize {
        if self.vertices.contains_key(&vertex) {
            //println!("add existing {}", vector3d_str(&vertex));
            *self.vertices.get(&vertex).unwrap()
        } else {
            //println!("add new {}", vector3d_str(&vertex));
            let idx = self.vertices.len();
            self.vertices.insert(vertex, idx);
            idx
        }
    }

    pub fn vector(&self) -> Vec<Vector3D> {
        let mut v: Vec<Vector3D> = Vec::with_capacity(self.vertices.len());
        for (v3d, idx) in self.vertices.iter() {
            v.push(*v3d);  // Funkiness just to get v expanded. Below writes the real values.
        }
        for (v3d, idx) in self.vertices.iter() {
            //println!("v3d:{:?} idx:{}", v3d, idx);
            v[*idx] = *v3d;
        }
        //for i in 0..v.len() {
        //    println!("v3d[{}]: {:?}", i, v[i]);
        //}
        v
    }
}

#[derive(PartialEq, Debug, Eq, Hash, Copy)]
pub struct Facet {
    v1: usize,
    v2: usize,
    v3: usize,
}

pub struct Mesh {
    vertices: Vec<Vector3D>,
    facets: Vec<Facet>,
}

impl Mesh {
    pub fn new() -> Mesh {
        Mesh {
            vertices: Vec::new(),
            facets: Vec::new(),
        }
    }

    fn indexed_vertices(fv: &Vec<StlFacet>, vm: &VertexMap) -> Vec<Facet> {
        let mut v: Vec<Facet> = Vec::with_capacity(fv.len());
        for f in fv.iter() {
            let v1 = vm.get(&f.v1);
            let v2 = vm.get(&f.v2);
            let v3 = vm.get(&f.v3);
            v.push(Facet{
                v1: v1,
                v2: v2,
                v3: v3,
            })
        }
        v
    }

    pub fn new_from_stl(fv: &Vec<StlFacet>, vm: &VertexMap) -> Mesh {
        let vs = vm.vector();
        let fs = Mesh::indexed_vertices(fv, vm);
        Mesh {
            vertices: vs,
            facets: fs,
        }
    }

    pub fn read(r: &mut Reader) -> Mesh {

        /*
        let buf = [0; 80];
        let header = match r.read(&buf) {
            Ok(nread) => {
                let hdr = String::from_utf8(&buf).unwrap();
                println!("Header: \"{}\"", hdr);
                hdr
            }
            Err(e) => {
                println!("Truncated file: {}", e);
                return Mesh{vertices: Vec::new(), facets: Vec::new()};
            }
        };

        return if header.starts_with("solid ") {
            println!("Is ASCII STL");
            Mesh::read_ascii(r)
        }
        else {
            println!("Is binary STL");
            Mesh::read_binary(r)
        }
        */
        Mesh::read_binary(r)
    }

    /*
    fn read_ascii(r: &mut Reader) -> Mesh {
        //solid vcg
        //  facet normal 7.733874e-001 -3.151335e-002 6.331499e-001
        //    outer loop
        //      vertex  2.137833e+001 5.385936e+001 1.350253e+001
        //      vertex  2.341920e+001 4.700068e+001 1.066826e+001
        //      vertex  2.859041e+001 5.985682e+001 4.991545e+000
        //    endloop
        //  endfacet
        //endsolid vcg
        for line in r.lines() {
            print!("{}", line.unwrap());
        }
        Mesh::new() // TODO
    }
    */

    fn read_binary(r: &mut Reader) -> Mesh {
        let facet_count = match r.read_le_u32() {
            Ok(c) => { println!("Facets: {}", c); c},
            Err(e) => { println!("Truncated file: {}", e); 0},
        };

        let mut facets: Vec<StlFacet> = Vec::with_capacity(facet_count as usize);
        let mut vertices = VertexMap::new();
        println!("Collections ready");

        for fi in range(0, facet_count) {
            let f = StlFacet::read(r);
            let v1i = vertices.add(f.v1);
            let v2i = vertices.add(f.v2);
            let v3i = vertices.add(f.v3);
            println!("  Facet[{}]: {:?} => {}-{}-{}", fi, f, v1i, v2i, v3i);
            facets.push(f);
        }
        println!("Vertices: {}", vertices.len());

        Mesh::new_from_stl(&facets, &vertices)
    }
}
<commit_msg>read is better<commit_after>//#![crate_name = "mesh"]
#![feature(old_io)]
//mod mesh;

use std::cmp::*;
use std::collections::HashMap;
use std::f32::NAN;
use std::fmt;
use std::old_io::{BufferedReader,IoResult,Reader};
use std::hash::{Hash, Hasher};
use std::mem::{transmute};
use std::vec::Vec;

#[derive(PartialEq, PartialOrd, Copy)] //Show,
pub struct Vector3D {
    x: f32,
    y: f32,
    z: f32,
}

// PartialEq is derived above, but we need to impl Eq since floats don't get
// it by default. This function is just a
impl Eq for Vector3D {
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

impl fmt::Debug for Vector3D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{},{})", self.x, self.y, self.z)
    }
}

impl Vector3D {
    fn read(r: &mut Reader) -> Vector3D {
        let xr = r.read_le_f32();
        let yr = r.read_le_f32();
        let zr = r.read_le_f32();
        if xr.is_ok() && yr.is_ok() && zr.is_ok() {
            let v = Vector3D { x: xr.ok().unwrap(), y: yr.ok().unwrap(), z: zr.ok().unwrap() };
            return v
        }
        return Vector3D { x: NAN, y: NAN, z: NAN };
    }
}

// Implement Hash since there is no default for f32. We'll just hash the bits
// since we know the f32s will all be canonical from reading.
impl Hash for Vector3D {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        //println!("V3D hash {:p}", self);
        let x: u32 = unsafe { transmute(self.x) };
        x.hash(state);
        let y: u32 = unsafe { transmute(self.y) };
        y.hash(state);
        let z: u32 = unsafe { transmute(self.z) };
        z.hash(state);
        //println!("V3D hash done {:p}", self);
    }
}

pub struct StlHeader {
    header: [u8; 80],
}

#[derive(PartialEq, Eq, Hash, Copy)]
pub struct StlFacet {
    n : Vector3D,
    v1: Vector3D,
    v2: Vector3D,
    v3: Vector3D,
    abc: u16,
}

impl fmt::Debug for StlFacet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{:?}]({:?}-{:?}-{:?})[{:X}]",
            &self.n, &self.v1, &self.v2, &self.v3, self.abc)
    }
}

impl StlFacet {
    fn read(r: &mut Reader) -> StlFacet {
        let n = Vector3D::read(r);
        let v1 = Vector3D::read(r);
        let v2 = Vector3D::read(r);
        let v3 = Vector3D::read(r);
        let abc = r.read_le_u16().unwrap();
        StlFacet { n:n, v1:v1, v2:v2, v3:v3, abc:abc }
    }
}

pub struct VertexMap {
    vertices: HashMap<Vector3D,usize>,
}

impl VertexMap {
    pub fn new() -> VertexMap {
        VertexMap {
            vertices: HashMap::new(),
        }
    }

    pub fn len(&self) -> usize {
        self.vertices.len()
    }

    pub fn get(&self, v3d: &Vector3D) -> usize {
        *self.vertices.get(v3d).unwrap()
    }

    pub fn add(&mut self, vertex: Vector3D) -> usize {
        if self.vertices.contains_key(&vertex) {
            //println!("add existing {}", vector3d_str(&vertex));
            *self.vertices.get(&vertex).unwrap()
        } else {
            //println!("add new {}", vector3d_str(&vertex));
            let idx = self.vertices.len();
            self.vertices.insert(vertex, idx);
            idx
        }
    }

    pub fn vector(&self) -> Vec<Vector3D> {
        let mut v: Vec<Vector3D> = Vec::with_capacity(self.vertices.len());
        for (v3d, idx) in self.vertices.iter() {
            v.push(*v3d);  // Funkiness just to get v expanded. Below writes the real values.
        }
        for (v3d, idx) in self.vertices.iter() {
            //println!("v3d:{:?} idx:{}", v3d, idx);
            v[*idx] = *v3d;
        }
        //for i in 0..v.len() {
        //    println!("v3d[{}]: {:?}", i, v[i]);
        //}
        v
    }
}

#[derive(PartialEq, Debug, Eq, Hash, Copy)]
pub struct Facet {
    v1: usize,
    v2: usize,
    v3: usize,
}

pub struct Mesh {
    vertices: Vec<Vector3D>,
    facets: Vec<Facet>,
}

impl Mesh {
    pub fn new() -> Mesh {
        Mesh {
            vertices: Vec::new(),
            facets: Vec::new(),
        }
    }

    fn indexed_vertices(fv: &Vec<StlFacet>, vm: &VertexMap) -> Vec<Facet> {
        let mut v: Vec<Facet> = Vec::with_capacity(fv.len());
        for f in fv.iter() {
            let v1 = vm.get(&f.v1);
            let v2 = vm.get(&f.v2);
            let v3 = vm.get(&f.v3);
            v.push(Facet{
                v1: v1,
                v2: v2,
                v3: v3,
            })
        }
        v
    }

    pub fn new_from_stl(fv: &Vec<StlFacet>, vm: &VertexMap) -> Mesh {
        let vs = vm.vector();
        let fs = Mesh::indexed_vertices(fv, vm);
        Mesh {
            vertices: vs,
            facets: fs,
        }
    }

    pub fn read<R: Reader>(r: &mut R) -> IoResult<Mesh> {

        let mut header = StlHeader { header: [0u8; 80] };
        try!(r.read_at_least(header.header.len(), &mut header.header));

        let hs = String::from_utf8_lossy(&header.header);
        if hs.starts_with("solid ") {
            println!("Is ASCII STL");
        } else {
            println!("Is binary STL");
        }

        Mesh::read_binary(r)
    }

    /*
    fn read_ascii(r: &mut Reader) -> Mesh {
        //solid vcg
        //  facet normal 7.733874e-001 -3.151335e-002 6.331499e-001
        //    outer loop
        //      vertex  2.137833e+001 5.385936e+001 1.350253e+001
        //      vertex  2.341920e+001 4.700068e+001 1.066826e+001
        //      vertex  2.859041e+001 5.985682e+001 4.991545e+000
        //    endloop
        //  endfacet
        //endsolid vcg
        for line in r.lines() {
            print!("{}", line.unwrap());
        }
        Mesh::new() // TODO
    }
    */

    fn read_binary(r: &mut Reader) -> IoResult<Mesh> {
        let facet_count = match r.read_le_u32() {
            Ok(c) => { println!("Facets: {}", c); c},
            Err(e) => { println!("Truncated file: {}", e); 0},
        };

        let mut facets: Vec<StlFacet> = Vec::with_capacity(facet_count as usize);
        let mut vertices = VertexMap::new();
        println!("Collections ready");

        for fi in range(0, facet_count) {
            let f = StlFacet::read(r);
            let v1i = vertices.add(f.v1);
            let v2i = vertices.add(f.v2);
            let v3i = vertices.add(f.v3);
            println!("  Facet[{}]: {:?} => {}-{}-{}", fi, f, v1i, v2i, v3i);
            facets.push(f);
        }
        println!("Vertices: {}", vertices.len());

        Ok(Mesh::new_from_stl(&facets, &vertices))
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use model;

pub type CV = f64;
pub type CDF = model::dist::CDF<CV>;

/// Calculate CDF for differential expression.
pub fn cdf(cdfs: &[model::expressionset::CDF]) -> CDF {
    model::meanvar::cdf(cdfs, |mean, var| var.sqrt() / mean).reduce().sample(100)
}

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

    use model;
    use io;

    const GENE: &'static str = "COL5A1";

    fn setup() -> Box<model::readout::Model> {
        model::readout::new_model(16, 4, 0.04, 0.1, 4, io::codebook::Reader::from_file("test/codebook/140genesData.1.txt", 4).unwrap().codebook())
    }

    fn setup_mhd2() -> Box<model::readout::Model> {
        model::readout::new_model(14, 4, 0.04, 0.1, 2, io::codebook::Reader::from_file("test/codebook/1001genesData.txt", 2).unwrap().codebook())
    }

    #[test]
    fn test_cdf() {
        let readout = setup();
        let cdfs1 = [
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            model::expression::cdf(GENE, 5, 5, &readout, 100)
        ];
        let cdfs2 = [
            model::expression::cdf(GENE, 50, 50, &readout, 100),
            model::expression::cdf(GENE, 50, 50, &readout, 100),
            model::expression::cdf(GENE, 50, 50, &readout, 100),
            model::expression::cdf(GENE, 50, 50, &readout, 100)
        ];
        let cdf1 = model::expressionset::cdf(&cdfs1, 0.0);
        let cdf2 = model::expressionset::cdf(&cdfs2, 0.0);
        println!("{} {}", cdfs1[0].expected_value(), cdfs2[0].expected_value());

        let cdf = cdf(&[cdf1, cdf2]);

        let total = cdf.total_prob();
        println!("{:?}", cdf);

        assert!(total <= 0.0);
        assert_relative_eq!(total, 0.0, epsilon = 0.0002);
        assert_relative_eq!(cdf.expected_value(), 1.14, epsilon = 0.02);
    }

    #[test]
    fn test_zero_cv() {
        let readout = setup();
        let cdfs1 = [
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100)
        ];
        let cdfs2 = [
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100)
        ];
        let cdf1 = model::expressionset::cdf(&cdfs1, 0.0);
        let cdf2 = model::expressionset::cdf(&cdfs2, 0.0);
        println!("{} {}", cdfs1[0].expected_value(), cdfs2[0].expected_value());
        println!("{:?}", cdf1.iter_pmf().collect_vec());

        let cdf = cdf(&[cdf1, cdf2]);

        assert_relative_eq!(*cdf.map(), 0.0);
    }

    #[test]
    fn test_ahnak2() {
        let gene = "AHNAK2";
        let readout = setup_mhd2();
        // let mut cdfs1 = vec![
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100),
        //     model::expression::cdf(gene, 3, 3, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 6, 6, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100),
        //     model::expression::cdf(gene, 4, 4, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        // ];
        // cdfs1.
        // let mut cdfs2 = vec![
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100)
        // ];
        let cdfs1 = io::cdf::expression::Reader::from_file("test/expression_cdf/1.txt").unwrap().cdfs();
        let cdfs2 = io::cdf::expression::Reader::from_file("test/expression_cdf/2.txt").unwrap().cdfs();
        let cdfs3 = io::cdf::expression::Reader::from_file("test/expression_cdf/3.txt").unwrap().cdfs();

        let cdfs1 = cdfs1.get("AHNAK2").unwrap();
        let cdfs2 = cdfs2.get("AHNAK2").unwrap();
        let cdfs3 = cdfs3.get("AHNAK2").unwrap();

        let cdf1 = model::expressionset::cdf(&cdfs1, 1.0);
        let cdf2 = model::expressionset::cdf(&cdfs2, 1.0);
        let cdf3 = model::expressionset::cdf(&cdfs3, 1.0);
        println!("{} {} {}", cdf1.map(), cdf2.map(), cdf3.map());
        println!("{} {} {}", cdf1.expected_value(), cdf2.expected_value(), cdf3.expected_value());

        let cdf = cdf(&[cdf1, cdf2]);
        println!("{}", cdf.map());
        println!("{}", cdf.expected_value());

        println!("{:?}", cdf.estimate(0.5));

        assert!(false);
    }
}
<commit_msg>Cleanup.<commit_after>// Copyright 2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use model;

pub type CV = f64;
pub type CDF = model::dist::CDF<CV>;

/// Calculate CDF for differential expression.
pub fn cdf(cdfs: &[model::expressionset::CDF]) -> CDF {
    model::meanvar::cdf(cdfs, |mean, var| var.sqrt() / mean).reduce().sample(100)
}

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

    use model;
    use io;

    const GENE: &'static str = "COL5A1";

    fn setup() -> Box<model::readout::Model> {
        model::readout::new_model(16, 4, 0.04, 0.1, 4, io::codebook::Reader::from_file("test/codebook/140genesData.1.txt", 4).unwrap().codebook())
    }

    #[test]
    fn test_cdf() {
        let readout = setup();
        let cdfs1 = [
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            model::expression::cdf(GENE, 5, 5, &readout, 100)
        ];
        let cdfs2 = [
            model::expression::cdf(GENE, 50, 50, &readout, 100),
            model::expression::cdf(GENE, 50, 50, &readout, 100),
            model::expression::cdf(GENE, 50, 50, &readout, 100),
            model::expression::cdf(GENE, 50, 50, &readout, 100)
        ];
        let cdf1 = model::expressionset::cdf(&cdfs1, 0.0);
        let cdf2 = model::expressionset::cdf(&cdfs2, 0.0);
        println!("{} {}", cdfs1[0].expected_value(), cdfs2[0].expected_value());

        let cdf = cdf(&[cdf1, cdf2]);

        let total = cdf.total_prob();
        println!("{:?}", cdf);

        assert!(total <= 0.0);
        assert_relative_eq!(total, 0.0, epsilon = 0.0002);
        assert_relative_eq!(cdf.expected_value(), 1.14, epsilon = 0.02);
    }

    #[test]
    fn test_zero_cv() {
        let readout = setup();
        let cdfs1 = [
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100)
        ];
        let cdfs2 = [
            model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100),
            //model::expression::cdf(GENE, 5, 5, &readout, 100)
        ];
        let cdf1 = model::expressionset::cdf(&cdfs1, 0.0);
        let cdf2 = model::expressionset::cdf(&cdfs2, 0.0);
        println!("{} {}", cdfs1[0].expected_value(), cdfs2[0].expected_value());
        println!("{:?}", cdf1.iter_pmf().collect_vec());

        let cdf = cdf(&[cdf1, cdf2]);

        assert_relative_eq!(*cdf.map(), 0.0);
    }

    #[test]
    fn test_ahnak2() {
        // let mut cdfs1 = vec![
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100),
        //     model::expression::cdf(gene, 3, 3, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 6, 6, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100),
        //     model::expression::cdf(gene, 4, 4, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        // ];
        // cdfs1.
        // let mut cdfs2 = vec![
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 1, 1, &readout, 100),
        //     model::expression::cdf(gene, 2, 2, &readout, 100)
        // ];
        let cdfs1 = io::cdf::expression::Reader::from_file("test/expression_cdf/1.txt").unwrap().cdfs();
        let cdfs2 = io::cdf::expression::Reader::from_file("test/expression_cdf/2.txt").unwrap().cdfs();
        let cdfs3 = io::cdf::expression::Reader::from_file("test/expression_cdf/3.txt").unwrap().cdfs();

        let cdfs1 = cdfs1.get("AHNAK2").unwrap();
        let cdfs2 = cdfs2.get("AHNAK2").unwrap();
        let cdfs3 = cdfs3.get("AHNAK2").unwrap();

        let cdf1 = model::expressionset::cdf(&cdfs1, 1.0);
        let cdf2 = model::expressionset::cdf(&cdfs2, 1.0);
        let cdf3 = model::expressionset::cdf(&cdfs3, 1.0);
        println!("{} {} {}", cdf1.map(), cdf2.map(), cdf3.map());
        println!("{} {} {}", cdf1.expected_value(), cdf2.expected_value(), cdf3.expected_value());

        let cdf = cdf(&[cdf1, cdf2]);
        println!("{}", cdf.map());
        println!("{}", cdf.expected_value());

        println!("{:?}", cdf.estimate(0.5));

        assert!(false);
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]
#![feature(globs)]
#![crate_name = "cube"]

extern crate shader_version;
extern crate vecmath;
extern crate event;
extern crate input;
extern crate cam;
extern crate gfx;
extern crate render;
// extern crate glfw_window;
extern crate sdl2;
extern crate sdl2_window;
#[phase(plugin)]
extern crate gfx_macros;
extern crate native;
extern crate time;

use std::cell::RefCell;
// use glfw_window::GlfwWindow;
use sdl2_window::Sdl2Window;
use gfx::{ Device, DeviceHelper, ToSlice };
use event::{ Events, Window, WindowSettings };

//----------------------------------------
// Cube associated data

#[vertex_format]
struct Vertex {
    #[as_float]
    a_pos: [i8, ..3],
    #[as_float]
    a_tex_coord: [u8, ..2],
}

impl Vertex {
    fn new(pos: [i8, ..3], tc: [u8, ..2]) -> Vertex {
        Vertex {
            a_pos: pos,
            a_tex_coord: tc,
        }
    }
}

#[shader_param(CubeBatch)]
struct Params {
    u_model_view_proj: [[f32, ..4], ..4],
    t_color: gfx::shade::TextureParam,
}

static VERTEX_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    attribute vec3 a_pos;
    attribute vec2 a_tex_coord;
    varying vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec3 a_pos;
    in vec2 a_tex_coord;
    out vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    varying vec2 v_TexCoord;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture2D(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec2 v_TexCoord;
    out vec4 o_Color;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
};

//----------------------------------------

// We need to run on the main thread, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        shader_version::opengl::OpenGL_3_2,
        WindowSettings {
            title: "cube".to_string(),
            size: [win_width, win_height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    window.capture_cursor(true);

    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let frame = gfx::Frame::new(win_width as u16, win_height as u16);
    let state = gfx::DrawState::new().depth(gfx::state::LessEqual, true);

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = device.create_mesh(vertex_data.as_slice());

    let index_data: &[u8] = [
         0,  1,  2,  2,  3,  0, // top
         4,  5,  6,  6,  7,  4, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 13, 14, 14, 16, 12, // left
        16, 17, 18, 18, 19, 16, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device
        .create_buffer_static::<u8>(index_data)
        .to_slice(gfx::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = device.create_texture(tinfo).unwrap();
    device.update_texture(
            &texture,
            &img_info,
            vec![0x20u8, 0xA0u8, 0xC0u8, 0x00u8].as_slice()
        ).unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(
            gfx::tex::Bilinear,
            gfx::tex::Clamp
        )
    );

    let program = device.link_program(
            VERTEX_SRC.clone(),
            FRAGMENT_SRC.clone()
        ).unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: CubeBatch = graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
    };

    let model = vecmath::mat4_id();
    let projection = cam::CameraPerspective {
            fov: 90.0f32,
            near_clip: 0.1,
            far_clip: 1000.0,
            aspect_ratio: (win_width as f32) / (win_height as f32)
        }.projection();
    let mut first_person = cam::FirstPerson::new(
        [0.5f32, 0.5, 4.0],
        cam::FirstPersonSettings::keyboard_wasd()
    );

    let window = RefCell::new(window);
    for e in Events::new(&window) {
        use event::RenderEvent;

        first_person.event(&e);
        e.render(|args| {
            graphics.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &frame
            );
            data.u_model_view_proj = cam::model_view_projection(
                    model,
                    first_person.camera(args.ext_dt).orthogonal(),
                    projection
                );
            graphics.draw(&batch, &data, &frame);
            graphics.end_frame();
        });
    }
}

<commit_msg>Removed unused crate render<commit_after>#![feature(phase)]
#![feature(globs)]
#![crate_name = "cube"]

extern crate shader_version;
extern crate vecmath;
extern crate event;
extern crate input;
extern crate cam;
extern crate gfx;
// extern crate glfw_window;
extern crate sdl2;
extern crate sdl2_window;
#[phase(plugin)]
extern crate gfx_macros;
extern crate native;
extern crate time;

use std::cell::RefCell;
// use glfw_window::GlfwWindow;
use sdl2_window::Sdl2Window;
use gfx::{ Device, DeviceHelper, ToSlice };
use event::{ Events, Window, WindowSettings };

//----------------------------------------
// Cube associated data

#[vertex_format]
struct Vertex {
    #[as_float]
    a_pos: [i8, ..3],
    #[as_float]
    a_tex_coord: [u8, ..2],
}

impl Vertex {
    fn new(pos: [i8, ..3], tc: [u8, ..2]) -> Vertex {
        Vertex {
            a_pos: pos,
            a_tex_coord: tc,
        }
    }
}

#[shader_param(CubeBatch)]
struct Params {
    u_model_view_proj: [[f32, ..4], ..4],
    t_color: gfx::shade::TextureParam,
}

static VERTEX_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    attribute vec3 a_pos;
    attribute vec2 a_tex_coord;
    varying vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec3 a_pos;
    in vec2 a_tex_coord;
    out vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120
    varying vec2 v_TexCoord;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture2D(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec2 v_TexCoord;
    out vec4 o_Color;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
};

//----------------------------------------

// We need to run on the main thread, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        shader_version::opengl::OpenGL_3_2,
        WindowSettings {
            title: "cube".to_string(),
            size: [win_width, win_height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    window.capture_cursor(true);

    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let frame = gfx::Frame::new(win_width as u16, win_height as u16);
    let state = gfx::DrawState::new().depth(gfx::state::LessEqual, true);

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = device.create_mesh(vertex_data.as_slice());

    let index_data: &[u8] = [
         0,  1,  2,  2,  3,  0, // top
         4,  5,  6,  6,  7,  4, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 13, 14, 14, 16, 12, // left
        16, 17, 18, 18, 19, 16, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device
        .create_buffer_static::<u8>(index_data)
        .to_slice(gfx::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = device.create_texture(tinfo).unwrap();
    device.update_texture(
            &texture,
            &img_info,
            vec![0x20u8, 0xA0u8, 0xC0u8, 0x00u8].as_slice()
        ).unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(
            gfx::tex::Bilinear,
            gfx::tex::Clamp
        )
    );

    let program = device.link_program(
            VERTEX_SRC.clone(),
            FRAGMENT_SRC.clone()
        ).unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: CubeBatch = graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
    };

    let model = vecmath::mat4_id();
    let projection = cam::CameraPerspective {
            fov: 90.0f32,
            near_clip: 0.1,
            far_clip: 1000.0,
            aspect_ratio: (win_width as f32) / (win_height as f32)
        }.projection();
    let mut first_person = cam::FirstPerson::new(
        [0.5f32, 0.5, 4.0],
        cam::FirstPersonSettings::keyboard_wasd()
    );

    let window = RefCell::new(window);
    for e in Events::new(&window) {
        use event::RenderEvent;

        first_person.event(&e);
        e.render(|args| {
            graphics.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &frame
            );
            data.u_model_view_proj = cam::model_view_projection(
                    model,
                    first_person.camera(args.ext_dt).orthogonal(),
                    projection
                );
            graphics.draw(&batch, &data, &frame);
            graphics.end_frame();
        });
    }
}

<|endoftext|>


<commit_before>//! User sessions.

use ruma_identifiers::{DeviceId, DeviceIdBox, UserId};

/// A user session, containing an access token and information about the associated user account.
#[derive(Clone, Debug, serde::Deserialize, Eq, Hash, PartialEq, serde::Serialize)]
pub struct Session {
    /// The access token used for this session.
    pub access_token: String,

    /// Identification information for a user
    pub identification: Option<Identification>,
}

/// The identification information about the associated user account if the session is associated
/// with a single user account.
#[derive(Clone, Debug, serde::Deserialize, Eq, Hash, PartialEq, serde::Serialize)]
pub struct Identification {
    /// The user the access token was issued for.
    pub user_id: UserId,

    /// The ID of the client device
    pub device_id: DeviceIdBox,
}

impl Session {
    /// Create a new user session from an access token and a user ID.
    #[deprecated]
    pub fn new(access_token: String, user_id: UserId, device_id: DeviceIdBox) -> Self {
        Self { access_token, identification: Some(Identification { user_id, device_id }) }
    }
}
<commit_msg>client: Remove unused file<commit_after><|endoftext|>


<commit_before>use std::f32::consts::PI;
use std::sync::{Arc, Mutex,
                mpsc::{Sender, Receiver, TryRecvError},
                atomic::{AtomicUsize, Ordering},
};

use cgmath::{Point3, Vector3, Vector4, prelude::*};

use glium::Rect;

use rand::{self, prelude::*};

use crate::bvh::BVHNode;
use crate::camera::Camera;
use crate::color::Color;
use crate::material::Material;
use crate::pt_renderer::{Intersect, Ray, RenderCoordinator};
use crate::scene::Scene;
use crate::triangle::Hit;

// TODO: tune EPSILON since crytek-sponza has shadow acne
const EPSILON: f32 = 1e-5;
const _EB: f32 = 5.0; // Desired expectation value of bounces
// The matching survival probability from negative binomial distribution
const RR_PROB: f32 = _EB / (_EB + 1.0);

pub struct RenderWorker {
    scene: Arc<Scene>,
    camera: Camera,
    coordinator: Arc<Mutex<RenderCoordinator>>,
    message_rx: Receiver<()>,
    result_tx: Sender<(Rect, Vec<f32>)>,
    ray_count: Arc<AtomicUsize>,
}

impl RenderWorker {
    pub fn new(scene: Arc<Scene>, camera: Camera, coordinator: Arc<Mutex<RenderCoordinator>>,
               message_rx: Receiver<()>, result_tx: Sender<(Rect, Vec<f32>)>,
               ray_count: Arc<AtomicUsize>) -> RenderWorker {
        RenderWorker {
            scene, camera, coordinator,
            message_rx, result_tx,
            ray_count,
        }
    }

    pub fn run(&self) {
        let (width, height) = {
            let coordinator = self.coordinator.lock().unwrap();
            (coordinator.width, coordinator.height)
        };
        let clip_to_world = self.camera.get_world_to_clip().invert().unwrap();
        let mut node_stack: Vec<(&BVHNode, f32)> = Vec::new();
        loop {
            match self.message_rx.try_recv() {
                Err(TryRecvError::Empty) => (),
                Ok(_) => return,
                Err(TryRecvError::Disconnected) => {
                    println!("Threads were not properly stopped before disconnecting channel!");
                    return;
                }
            }
            let block = {
                let mut coordinator = self.coordinator.lock().unwrap();
                coordinator.next_block()
            };
            if let Some(rect) = block {
                let mut block = vec![0.0f32; (3 * rect.width * rect.height) as usize];
                for h in 0..rect.height {
                    for w in 0..rect.width {
                        let samples_per_dir = 2u32;
                        let mut c = Color::black();
                        for j in 0..samples_per_dir {
                            for i in 0..samples_per_dir {
                                let dx = (i as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let dy = (j as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let clip_x = 2.0 * ((rect.left + w) as f32 + dx) / width as f32 - 1.0;
                                let clip_y = 2.0 * ((rect.bottom + h) as f32 + dy) / height as f32 - 1.0;
                                let clip_p = Vector4::new(clip_x, clip_y, 1.0, 1.0);
                                let world_p = clip_to_world * clip_p;
                                let dir = ((world_p / world_p.w).truncate() - self.camera.pos.to_vec())
                                    .normalize();
                                let ray = Ray::new(self.camera.pos, dir, std::f32::INFINITY);
                                c += self.trace_ray(ray, &mut node_stack, 0);
                            }
                        }
                        c /= samples_per_dir.pow(2) as f32;
                        let pixel_i = 3 * (h * rect.width + w) as usize;
                        block[pixel_i]     = c.r;
                        block[pixel_i + 1] = c.g;
                        block[pixel_i + 2] = c.b;
                    }
                }
                self.result_tx.send((rect, block)).expect("Receiver closed!");
            } else {
                return;
            }
        }
    }

    fn trace_ray<'a>(&'a self, mut ray: Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>, bounce: u32) -> Color {
        let mut c = Color::black();
        if let Some(hit) = self.find_hit(&mut ray, node_stack) {
            let material = &self.scene.materials[hit.tri.material_i];
            let mut normal = hit.normal();
            // Flip the normal if its pointing to the opposite side from the hit
            if normal.dot(ray.dir) > 0.0 {
                normal *= -1.0;
            }
            if bounce == 0 {
                if let Some(emissive) = material.emissive {
                    c += normal.dot(-ray.dir).max(0.0) * emissive;
                }
            }
            let (emissive, light_pos, light_normal, light_pdf) = self.sample_light();
            let bump_pos = hit.pos() + EPSILON * normal;
            let hit_to_light = light_pos - bump_pos;
            let light_dir = hit_to_light.normalize();
            let mut shadow_ray = Ray::new(bump_pos, light_dir, hit_to_light.magnitude() - EPSILON);
            if self.find_hit(&mut shadow_ray, node_stack).is_none() {
                let cos_l = light_normal.dot(-light_dir).max(0.0);
                let cos_t = normal.dot(light_dir).max(0.0);
                c += emissive * self.brdf(&hit, &ray, &shadow_ray, material)
                    * cos_l * cos_t / (hit_to_light.magnitude2() * light_pdf);
            }
            let rr: f32 = rand::random();
            if rr < RR_PROB {
                let (new_dir, mut pdf) = self.sample_dir(normal);
                pdf *= RR_PROB;
                let new_ray = Ray::new(bump_pos, new_dir, 10.0 * self.camera.scale);
                c += normal.dot(new_dir) * self.brdf(&hit, &ray, &new_ray, material)
                    * self.trace_ray(new_ray, node_stack, bounce + 1) / pdf;
            }
        }
        c
    }

    fn brdf(&self, hit: &Hit, _in_ray: &Ray, _out_ray: &Ray, material: &Material) -> Color {
        let tex_coords = hit.tex_coords();
        material.diffuse(tex_coords) / PI
    }

    fn sample_dir(&self, normal: Vector3<f32>) -> (Vector3<f32>, f32) {
        let dir = 2.0 * PI * rand::random::<f32>();
        let length: f32 = rand::random();
        let x = length * dir.cos();
        let y = length * dir.sin();
        let z = (1.0 - length.powi(2)).sqrt();
        let nx = if normal.x.abs() > normal.y.abs() {
            Vector3::new(normal.z, 0.0, -normal.x).normalize()
        } else {
            Vector3::new(0.0, -normal.z, normal.y).normalize()
        };
        let ny = normal.cross(nx);
        (x * nx + y * ny + z * normal, z / PI)
    }

    pub fn sample_light(&self) -> (Color, Point3<f32>, Vector3<f32>, f32) {
        if self.scene.lights.is_empty() {
            let light_intensity = 10.0 * self.camera.scale;
            (light_intensity * Color::white(), self.camera.pos, self.camera.dir, 1.0)
        } else {
            let i = rand::thread_rng().gen_range(0, self.scene.lights.len());
            let light = &self.scene.lights[i];
            let pdf = 1.0 / (self.scene.lights.len() as f32 * light.area());
            let (point, normal) = light.random_point();
            let light_material = &self.scene.materials[light.material_i];
            let emissive = light_material.emissive.expect("Light wasn't emissive");
            (emissive, point, normal, pdf)
        }
    }

    fn find_hit<'a>(&'a self, ray: &mut Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>) -> Option<Hit> {
        self.ray_count.fetch_add(1, Ordering::Relaxed);
        let bvh = &self.scene.bvh;
        node_stack.push((bvh.root(), 0.0f32));
        let mut closest_hit = None;
        while let Some((node, t)) = node_stack.pop() {
            // We've already found a closer hit
            if ray.length <= t { continue }
            if node.is_leaf() {
                for tri in &self.scene.triangles[node.start_i..node.end_i] {
                    if let Some(hit) = tri.intersect(&ray) {
                        ray.length = hit.t;
                        closest_hit = Some(hit);
                    }
                }
            } else {
                let (left, right) = bvh.get_children(node)
                    .expect("Non leaf node had no child nodes!");
                // TODO: benchmark this properly on the larger scenes
                // TODO: Could this work without pushing the next node to the stack
                if false { // not sorted
                    if let Some(t_left) = left.intersect(&ray) {
                        node_stack.push((left, t_left));
                    }
                    if let Some(t_right) = right.intersect(&ray) {
                        node_stack.push((right, t_right));
                    }
                } else { // sort nodes
                    let left_intersect = left.intersect(&ray);
                    let right_intersect = right.intersect(&ray);
                    if let Some(t_left) = left_intersect {
                        if let Some(t_right) = right_intersect {
                            // Put the closer hit on top
                            if t_left >= t_right {
                                node_stack.push((left, t_left));
                                node_stack.push((right, t_right));
                            } else {
                                node_stack.push((right, t_right));
                                node_stack.push((left, t_left));
                            }
                        } else {
                            node_stack.push((left, t_left));
                        }
                    } else if let Some(t_right) = right_intersect {
                        node_stack.push((right, t_right));
                    }
                }
            }
        }
        closest_hit
    }
}
<commit_msg>Always sort bvh nodes<commit_after>use std::f32::consts::PI;
use std::sync::{Arc, Mutex,
                mpsc::{Sender, Receiver, TryRecvError},
                atomic::{AtomicUsize, Ordering},
};

use cgmath::{Point3, Vector3, Vector4, prelude::*};

use glium::Rect;

use rand::{self, prelude::*};

use crate::bvh::BVHNode;
use crate::camera::Camera;
use crate::color::Color;
use crate::material::Material;
use crate::pt_renderer::{Intersect, Ray, RenderCoordinator};
use crate::scene::Scene;
use crate::triangle::Hit;

// TODO: tune EPSILON since crytek-sponza has shadow acne
const EPSILON: f32 = 1e-5;
const _EB: f32 = 5.0; // Desired expectation value of bounces
// The matching survival probability from negative binomial distribution
const RR_PROB: f32 = _EB / (_EB + 1.0);

pub struct RenderWorker {
    scene: Arc<Scene>,
    camera: Camera,
    coordinator: Arc<Mutex<RenderCoordinator>>,
    message_rx: Receiver<()>,
    result_tx: Sender<(Rect, Vec<f32>)>,
    ray_count: Arc<AtomicUsize>,
}

impl RenderWorker {
    pub fn new(scene: Arc<Scene>, camera: Camera, coordinator: Arc<Mutex<RenderCoordinator>>,
               message_rx: Receiver<()>, result_tx: Sender<(Rect, Vec<f32>)>,
               ray_count: Arc<AtomicUsize>) -> RenderWorker {
        RenderWorker {
            scene, camera, coordinator,
            message_rx, result_tx,
            ray_count,
        }
    }

    pub fn run(&self) {
        let (width, height) = {
            let coordinator = self.coordinator.lock().unwrap();
            (coordinator.width, coordinator.height)
        };
        let clip_to_world = self.camera.get_world_to_clip().invert().unwrap();
        let mut node_stack: Vec<(&BVHNode, f32)> = Vec::new();
        loop {
            match self.message_rx.try_recv() {
                Err(TryRecvError::Empty) => (),
                Ok(_) => return,
                Err(TryRecvError::Disconnected) => {
                    println!("Threads were not properly stopped before disconnecting channel!");
                    return;
                }
            }
            let block = {
                let mut coordinator = self.coordinator.lock().unwrap();
                coordinator.next_block()
            };
            if let Some(rect) = block {
                let mut block = vec![0.0f32; (3 * rect.width * rect.height) as usize];
                for h in 0..rect.height {
                    for w in 0..rect.width {
                        let samples_per_dir = 2u32;
                        let mut c = Color::black();
                        for j in 0..samples_per_dir {
                            for i in 0..samples_per_dir {
                                let dx = (i as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let dy = (j as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let clip_x = 2.0 * ((rect.left + w) as f32 + dx) / width as f32 - 1.0;
                                let clip_y = 2.0 * ((rect.bottom + h) as f32 + dy) / height as f32 - 1.0;
                                let clip_p = Vector4::new(clip_x, clip_y, 1.0, 1.0);
                                let world_p = clip_to_world * clip_p;
                                let dir = ((world_p / world_p.w).truncate() - self.camera.pos.to_vec())
                                    .normalize();
                                let ray = Ray::new(self.camera.pos, dir, std::f32::INFINITY);
                                c += self.trace_ray(ray, &mut node_stack, 0);
                            }
                        }
                        c /= samples_per_dir.pow(2) as f32;
                        let pixel_i = 3 * (h * rect.width + w) as usize;
                        block[pixel_i]     = c.r;
                        block[pixel_i + 1] = c.g;
                        block[pixel_i + 2] = c.b;
                    }
                }
                self.result_tx.send((rect, block)).expect("Receiver closed!");
            } else {
                return;
            }
        }
    }

    fn trace_ray<'a>(&'a self, mut ray: Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>, bounce: u32) -> Color {
        let mut c = Color::black();
        if let Some(hit) = self.find_hit(&mut ray, node_stack) {
            let material = &self.scene.materials[hit.tri.material_i];
            let mut normal = hit.normal();
            // Flip the normal if its pointing to the opposite side from the hit
            if normal.dot(ray.dir) > 0.0 {
                normal *= -1.0;
            }
            if bounce == 0 {
                if let Some(emissive) = material.emissive {
                    c += normal.dot(-ray.dir).max(0.0) * emissive;
                }
            }
            let (emissive, light_pos, light_normal, light_pdf) = self.sample_light();
            let bump_pos = hit.pos() + EPSILON * normal;
            let hit_to_light = light_pos - bump_pos;
            let light_dir = hit_to_light.normalize();
            let mut shadow_ray = Ray::new(bump_pos, light_dir, hit_to_light.magnitude() - EPSILON);
            if self.find_hit(&mut shadow_ray, node_stack).is_none() {
                let cos_l = light_normal.dot(-light_dir).max(0.0);
                let cos_t = normal.dot(light_dir).max(0.0);
                c += emissive * self.brdf(&hit, &ray, &shadow_ray, material)
                    * cos_l * cos_t / (hit_to_light.magnitude2() * light_pdf);
            }
            let rr: f32 = rand::random();
            if rr < RR_PROB {
                let (new_dir, mut pdf) = self.sample_dir(normal);
                pdf *= RR_PROB;
                let new_ray = Ray::new(bump_pos, new_dir, 10.0 * self.camera.scale);
                c += normal.dot(new_dir) * self.brdf(&hit, &ray, &new_ray, material)
                    * self.trace_ray(new_ray, node_stack, bounce + 1) / pdf;
            }
        }
        c
    }

    fn brdf(&self, hit: &Hit, _in_ray: &Ray, _out_ray: &Ray, material: &Material) -> Color {
        let tex_coords = hit.tex_coords();
        material.diffuse(tex_coords) / PI
    }

    fn sample_dir(&self, normal: Vector3<f32>) -> (Vector3<f32>, f32) {
        let dir = 2.0 * PI * rand::random::<f32>();
        let length: f32 = rand::random();
        let x = length * dir.cos();
        let y = length * dir.sin();
        let z = (1.0 - length.powi(2)).sqrt();
        let nx = if normal.x.abs() > normal.y.abs() {
            Vector3::new(normal.z, 0.0, -normal.x).normalize()
        } else {
            Vector3::new(0.0, -normal.z, normal.y).normalize()
        };
        let ny = normal.cross(nx);
        (x * nx + y * ny + z * normal, z / PI)
    }

    pub fn sample_light(&self) -> (Color, Point3<f32>, Vector3<f32>, f32) {
        if self.scene.lights.is_empty() {
            let light_intensity = 10.0 * self.camera.scale;
            (light_intensity * Color::white(), self.camera.pos, self.camera.dir, 1.0)
        } else {
            let i = rand::thread_rng().gen_range(0, self.scene.lights.len());
            let light = &self.scene.lights[i];
            let pdf = 1.0 / (self.scene.lights.len() as f32 * light.area());
            let (point, normal) = light.random_point();
            let light_material = &self.scene.materials[light.material_i];
            let emissive = light_material.emissive.expect("Light wasn't emissive");
            (emissive, point, normal, pdf)
        }
    }

    fn find_hit<'a>(&'a self, ray: &mut Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>) -> Option<Hit> {
        self.ray_count.fetch_add(1, Ordering::Relaxed);
        let bvh = &self.scene.bvh;
        node_stack.push((bvh.root(), 0.0f32));
        let mut closest_hit = None;
        while let Some((node, t)) = node_stack.pop() {
            // We've already found a closer hit
            if ray.length <= t { continue }
            if node.is_leaf() {
                for tri in &self.scene.triangles[node.start_i..node.end_i] {
                    if let Some(hit) = tri.intersect(&ray) {
                        ray.length = hit.t;
                        closest_hit = Some(hit);
                    }
                }
            } else {
                let (left, right) = bvh.get_children(node)
                    .expect("Non leaf node had no child nodes!");
                // TODO: Could this work without pushing the next node to the stack
                let left_intersect = left.intersect(&ray);
                let right_intersect = right.intersect(&ray);
                if let Some(t_left) = left_intersect {
                    if let Some(t_right) = right_intersect {
                        // Put the closer hit on top
                        if t_left >= t_right {
                            node_stack.push((left, t_left));
                            node_stack.push((right, t_right));
                        } else {
                            node_stack.push((right, t_right));
                            node_stack.push((left, t_left));
                        }
                    } else {
                        node_stack.push((left, t_left));
                    }
                } else if let Some(t_right) = right_intersect {
                    node_stack.push((right, t_right));
                }
            }
        }
        closest_hit
    }
}
<|endoftext|>