Skip to content

Commit

Permalink
Improved various function signatures, added macro
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchmindtree committed Oct 10, 2015
1 parent 88376f5 commit 2b135c9
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 19 deletions.
14 changes: 14 additions & 0 deletions src/chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@


/// A macro used to simplify chaining together multiple `IntoIter` types.
///
/// Returns a single iterator yielding all of the chained elements.
#[macro_export]
macro_rules! chain {
() => { ::std::iter::empty() };
($first: expr) => { $first.into_iter() };
($first: expr, $($iter:expr),*) => { $first.into_iter()$(.chain($iter))* };
}



1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub use vec::{
TakeOnly,
};

mod chain;
pub mod epsilon;
pub mod factorisation;
pub mod fps;
Expand Down
46 changes: 27 additions & 19 deletions src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
///
///
use num::{Float, FromPrimitive, ToPrimitive};
use num::{Float, NumCast};
use num::PrimInt as Int;
use std::mem;

Expand All @@ -30,36 +30,36 @@ pub fn in_range<T: Ord>(val: T, min: T, max: T) -> bool {

/// Interpolate from start to stop 'amt' amount.
#[inline]
pub fn lerp(start: f32, stop: f32, amt: f32) -> f32 {
pub fn lerp<F: Float>(start: F, stop: F, amt: F) -> F {
start + (stop - start) * amt
}

/// Map a value from a given range to a new given range.
#[inline]
pub fn map_range<X: Copy + FromPrimitive + ToPrimitive,
Y: Copy + FromPrimitive + ToPrimitive>
(val: X, in_min: X, in_max: X, out_min: Y, out_max: Y) -> Y {
pub fn map_range<X, Y>(val: X, in_min: X, in_max: X, out_min: Y, out_max: Y) -> Y where
X: NumCast,
Y: NumCast + Copy,
{
use epsilon::epsilon;
let (val_f, in_min_f, in_max_f, out_min_f, out_max_f) = (
val.to_f64().unwrap(),
in_min.to_f64().unwrap(),
in_max.to_f64().unwrap(),
out_min.to_f64().unwrap(),
out_max.to_f64().unwrap(),
);

let val_f: f64 = NumCast::from(val).unwrap();
let in_min_f: f64 = NumCast::from(in_min).unwrap();
let in_max_f: f64 = NumCast::from(in_max).unwrap();
let out_min_f: f64 = NumCast::from(out_min).unwrap();
let out_max_f: f64 = NumCast::from(out_max).unwrap();

if (in_min_f - in_max_f).abs() < epsilon() {
println!("jmath Warning: map(): avoiding possible divide by zero, \
println!("utils::math::map_range warning: avoiding possible divide by zero, \
in_min ({}) and in_max({})", in_min_f, in_max_f);
return out_min;
}
FromPrimitive::from_f64(
(val_f - in_min_f) / (in_max_f - in_min_f) * (out_max_f - out_min_f) + out_min_f
).unwrap()
Y::from((val_f - in_min_f) / (in_max_f - in_min_f) * (out_max_f - out_min_f) + out_min_f)
.unwrap()
}

/// Models the CPP remainder function.
#[inline]
pub fn remainder<F: Float + FromPrimitive + ToPrimitive>(numer: F, denom: F) -> F {
pub fn remainder<F: Float>(numer: F, denom: F) -> F {
let rquot: F = (numer / denom).round();
numer - rquot * denom
}
Expand All @@ -76,10 +76,18 @@ pub fn modulo<I: Int>(a: I, b: I) -> I {

/// Wrap value to a range.
#[inline]
pub fn wrap(val: f32, mut from: f32, mut to: f32) -> f32 {
pub fn wrap<F: Float>(val: F, mut from: F, mut to: F) -> F {
if from > to { mem::swap(&mut from, &mut to); }
let cycle = to - from;
if cycle == 0.0 { return to; }
if cycle == F::zero() { return to; }
val - cycle * ((val - from) / cycle).floor()
}

/// The logistic aka sigmoid function.
#[inline]
pub fn sigmoid<F: Float>(f: F) -> F {
use std::f64::consts::E;
let e = F::from(E).unwrap();
F::one() / (F::one() + e.powf(-f))
}

18 changes: 18 additions & 0 deletions tests/chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

#[macro_use] extern crate utils;

#[test]
fn chain() {

let empty: ::std::iter::Empty<i32> = chain![];
let empty_vec: Vec<i32> = vec![];
assert_eq!(empty.collect::<Vec<_>>(), empty_vec);

let one = chain![Some("G'day")];
assert_eq!(one.collect::<Vec<_>>(), vec!["G'day"]);

let nums = chain![Some(0), vec![1, 2, 3, 4], Some(5).into_iter().chain(Some(6))];
assert_eq!(nums.collect::<Vec<_>>(), vec![0, 1, 2, 3, 4, 5, 6]);

}

0 comments on commit 2b135c9

Please sign in to comment.