Skip to content

Commit

Permalink
auto merge of #18827 : bjz/rust/rfc369-numerics, r=alexcrichton
Browse files Browse the repository at this point in the history
This implements a considerable portion of rust-lang/rfcs#369 (tracked in #18640). Some interpretations had to be made in order to get this to work. The breaking changes are listed below:

[breaking-change]

- `core::num::{Num, Unsigned, Primitive}` have been deprecated and their re-exports removed from the `{std, core}::prelude`.
- `core::num::{Zero, One, Bounded}` have been deprecated. Use the static methods on `core::num::{Float, Int}` instead. There is no equivalent to `Zero::is_zero`. Use `(==)` with `{Float, Int}::zero` instead.
- `Signed::abs_sub` has been moved to `std::num::FloatMath`, and is no longer implemented for signed integers.
- `core::num::Signed` has been removed, and its methods have been moved to `core::num::Float` and a new trait, `core::num::SignedInt`. The methods now take the `self` parameter by value.
- `core::num::{Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}` have been removed, and their methods moved to `core::num::Int`. Their parameters are now taken by value. This means that
- `std::time::Duration` no longer implements `core::num::{Zero, CheckedAdd, CheckedSub}` instead defining the required methods non-polymorphically.
- `core::num::{zero, one, abs, signum}` have been deprecated. Use their respective methods instead.
- The `core::num::{next_power_of_two, is_power_of_two, checked_next_power_of_two}` functions have been deprecated in favor of methods defined a new trait, `core::num::UnsignedInt`
- `core::iter::{AdditiveIterator, MultiplicativeIterator}` are now only implemented for the built-in numeric types.
- `core::iter::{range, range_inclusive, range_step, range_step_inclusive}` now require `core::num::Int` to be implemented for the type they a re parametrized over.
  • Loading branch information
bors committed Nov 14, 2014
2 parents 76b9733 + bddde2b commit 15a2831
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 16 deletions.
2 changes: 1 addition & 1 deletion lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ use std::io::fs::PathExtensions;
use std::io::stdio::StdWriter;
use std::io::{File, ChanReader, ChanWriter};
use std::io;
use std::num::{Float, FloatMath, Int};
use std::os;
use std::string::String;
use std::task::TaskBuilder;
Expand Down Expand Up @@ -105,7 +106,6 @@ enum NamePadding { PadNone, PadOnLeft, PadOnRight }

impl TestDesc {
fn padded_name(&self, column_count: uint, align: NamePadding) -> String {
use std::num::Saturating;
let mut name = String::from_str(self.name.as_slice());
let fill = column_count.saturating_sub(name.len());
let mut pad = " ".repeat(fill);
Expand Down
28 changes: 13 additions & 15 deletions stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use std::fmt::Show;
use std::hash::Hash;
use std::io;
use std::mem;
use std::num::Zero;
use std::num;
use std::num::{Float, FloatMath};

fn local_cmp<T:Float>(x: T, y: T) -> Ordering {
// arbitrarily decide that NaNs are larger than everything.
Expand Down Expand Up @@ -145,7 +144,6 @@ pub struct Summary<T> {
}

impl<T: FloatMath + FromPrimitive> Summary<T> {

/// Construct a new summary of a sample set.
pub fn new(samples: &[T]) -> Summary<T> {
Summary {
Expand All @@ -166,7 +164,6 @@ impl<T: FloatMath + FromPrimitive> Summary<T> {
}

impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {

// FIXME #11059 handle NaN, inf and overflow
fn sum(self) -> T {
let mut partials = vec![];
Expand All @@ -176,15 +173,15 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
// This inner loop applies `hi`/`lo` summation to each
// partial so that the list of partial sums remains exact.
for i in range(0, partials.len()) {
let mut y = partials[i];
if num::abs(x) < num::abs(y) {
let mut y: T = partials[i];
if x.abs() < y.abs() {
mem::swap(&mut x, &mut y);
}
// Rounded `x+y` is stored in `hi` with round-off stored in
// `lo`. Together `hi+lo` are exactly equal to `x+y`.
let hi = x + y;
let lo = y - (hi - x);
if !lo.is_zero() {
if lo != Float::zero() {
partials[j] = lo;
j += 1;
}
Expand All @@ -197,7 +194,7 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
partials.truncate(j+1);
}
}
let zero: T = Zero::zero();
let zero: T = Float::zero();
partials.iter().fold(zero, |p, q| p + *q)
}

Expand All @@ -222,10 +219,10 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {

fn var(self) -> T {
if self.len() < 2 {
Zero::zero()
Float::zero()
} else {
let mean = self.mean();
let mut v: T = Zero::zero();
let mut v: T = Float::zero();
for s in self.iter() {
let x = *s - mean;
v = v + x*x;
Expand All @@ -249,7 +246,7 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {

fn median_abs_dev(self) -> T {
let med = self.median();
let abs_devs: Vec<T> = self.iter().map(|&v| num::abs(med - v)).collect();
let abs_devs: Vec<T> = self.iter().map(|&v| (med - v).abs()).collect();
// This constant is derived by smarter statistics brains than me, but it is
// consistent with how R and other packages treat the MAD.
let number = FromPrimitive::from_f64(1.4826).unwrap();
Expand Down Expand Up @@ -294,7 +291,7 @@ fn percentile_of_sorted<T: Float + FromPrimitive>(sorted_samples: &[T],
if sorted_samples.len() == 1 {
return sorted_samples[0];
}
let zero: T = Zero::zero();
let zero: T = Float::zero();
assert!(zero <= pct);
let hundred = FromPrimitive::from_uint(100).unwrap();
assert!(pct <= hundred);
Expand Down Expand Up @@ -370,14 +367,14 @@ pub fn write_boxplot<T: Float + Show + FromPrimitive>(
let himag = ten.powf(s.max.abs().log10().floor());

// need to consider when the limit is zero
let zero: T = Zero::zero();
let lo = if lomag.is_zero() {
let zero: T = Float::zero();
let lo = if lomag == Float::zero() {
zero
} else {
(s.min / lomag).floor() * lomag
};

let hi = if himag.is_zero() {
let hi = if himag == Float::zero() {
zero
} else {
(s.max / himag).ceil() * himag
Expand Down Expand Up @@ -464,6 +461,7 @@ mod tests {

macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({
use std::num::Float;
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
Expand Down

0 comments on commit 15a2831

Please sign in to comment.