Skip to content

Commit

Permalink
Merge 065ea55 into 50c265f
Browse files Browse the repository at this point in the history
  • Loading branch information
chalharu committed Oct 23, 2017
2 parents 50c265f + 065ea55 commit c676ed1
Show file tree
Hide file tree
Showing 9 changed files with 1,112 additions and 558 deletions.
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ before_script:
script:
- cargo build --features="$FEATURES"
- cargo test --no-run --features="$FEATURES"
- cargo build --release --features="$FEATURES"
- cargo test --release --no-run --features="$FEATURES"
- |
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
cargo kcov --coveralls --features="$FEATURES"
Expand Down Expand Up @@ -93,7 +96,7 @@ env:
- RUSTFLAGS="-C debug-assertions=on"
- RUSTFLAGS="-C debug-assertions=off"
global:
secure: qwMSXpdCryGDyfiy1lXEcR/kWhATlQGVNAqV83n9uBKDLP6WsX4C25zMAz1/0wkjiorBMNFGhxMLI956md7V84sLX+6FNfA0tRODtAnJYyjR3AX4RkXB6zFhbTqWg/2BAefJ7Y7Vy0qKLKbqFq6023lKg09Mk80fEReba4PisrMgfj3LCCUarAnxfuFnAB7LmlvWXHNd3w+x6dV8fxO0Zw6QoqB9wQQvQzIiApqWCTyoxQhW+qzo6bXrctPct/OGNhmf4I0l1QJBGPN6qpFrxSjFljbxqIBiagCb6k1WERpok2FiNjhXCowUhTMyaGIlZLaVLjuISu8+aCyHZqK/yQLIDwWm5iY3Ko1gUbhvcg3aQV2ovpN8nxrQaiEkhg8mUPDPG0NencibFItb510L/VK3UkBWgTcKmwMjsqErh/l3a6UvezSAkUHrkMMAGLSrKnveFXeGCTwePLN40NgqJzuKsaSL+gqlTP7dHVtWpsBIvmrK7x4ItwWGRETYQR9HJQbeX+bxQSDJRpkuSTmY1iFL6GF1R0SNRYjXIeZ8Ei8F6O0RqUl7sWjMf9KEWD1LVkWj3X8eM+lTLyNSzP9BGlTP/Q34oJ2LKc4lYj59NE5ai4/rzfz0p8/ANoEJxUJoYgkdl90jw90UltPEjxD7YeCJ8WVhB4tp72qV44RtlDA=
secure: K76k+cWN808HPtLvgnUKQmOBlfjzzQJ0KZAJzffkn1JO2zBpmJwMiIZZKGbLk1N+lP4eGUSx0DBwytyo6owG/6KPtIHWp3WA1p6vpTMRAELwMLH+/AKFPBp43c+Rm3mMI3HKsN6IB2yOfsWwxEdBROLnRO+sT38BnHIuXBSW/UTNqg4lml3OAhui+oa1lR0BIcL1dkEuDjZdDSzWzrQAULgR3C4maaFVQoaVhZNpSlE8D1lHompghxvjFk5vzewERUJMbLe5uozkxdQNwcJMMB775l6p7kAvHIy/mEoDrOqOeSPMdr8bnr/DDS/asU992R5AONd6Ml4h83WJZGLk2NRF9E16LzE939i7imrrg8Zprs7J1S9NzfQIXH83YsJIQ2A+9fAvLwKDvfm0epgw5MZhNP538inrmUT0IXG5aqqlI5ISHzqLRUNmOO/VaxkpKQer0GuOBvReheh+h/6XizzGGsI6yLHiimQ8SQV0o10jBXi+Flo9hwxY3ZhbbNRSTaHGjawx/vkNraBlHCX6otRr2ewTodlsl46uM0J97j/eg2S4UUSiMHyyl4JhJQ5iJxNmZEsdLCzStrdFtGfAc4oA77NJVLjMRHSUxybokKeUBVbXuQ3MpNrdmjlKvg0o2oMFsYLI2AXoVfWxq8JVdDHtads1Lh302HsDDms0eTY=

cache:
cargo: true
Expand Down
16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
[package]
name = "nearly_eq"
version = "0.2.4"
name = "appro-eq"
version = "0.1.0"
authors = ["Mitsuharu Seki <mitsu1986@gmail.com>"]
repository = "https://github.com/chalharu/rust-nearly-eq"
repository = "https://github.com/chalharu/rust-appro-eq"
keywords = ["assert", "array"]
license = "MPL-2.0"
readme = "README.md"
description = "Nearly(Approximately) equal traits and assertion"
documentation = "https://docs.rs/nearly_eq/"
description = "Approximately equal traits and assertion"
documentation = "https://docs.rs/appro-eq/"

[lib]
name = "nearly_eq"
name = "appro_eq"
bench = false
test = true

Expand Down Expand Up @@ -38,10 +38,10 @@ version = ">=0.0.0"
docs = ["complex", "rational", "ndarray", "i128"]
i128 = []
rational = ["num-rational", "num-integer", "num-traits"]
complex = ["num-complex"]
complex = ["num-complex", "num-traits"]

[badges]
travis-ci = { repository = "chalharu/rust-nearly-eq" }
travis-ci = { repository = "chalharu/rust-appro-eq" }

[package.metadata.docs.rs]
features = ["docs"]
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
# rust-nearly-eq
[![crates.io badge](https://img.shields.io/crates/v/nearly-eq.svg)](https://crates.io/crates/nearly-eq)
[![Build Status](https://travis-ci.org/chalharu/rust-nearly-eq.svg?branch=master)](https://travis-ci.org/chalharu/rust-nearly-eq)
[![docs.rs](https://docs.rs/nearly_eq/badge.svg)](https://docs.rs/nearly_eq)
[![Coverage Status](https://coveralls.io/repos/github/chalharu/rust-nearly-eq/badge.svg?branch=master)](https://coveralls.io/github/chalharu/rust-nearly-eq?branch=master)
# rust-appro-eq

Implementing the `NearlyEq` traits, Can asserts that the two expressions are nearly(approximately) equal to each other.
[![crates.io badge](https://img.shields.io/crates/v/appro-eq.svg)](https://crates.io/crates/appro-eq)
[![Build Status](https://travis-ci.org/chalharu/rust-appro-eq.svg?branch=master)](https://travis-ci.org/chalharu/rust-appro-eq)
[![docs.rs](https://docs.rs/appro-eq/badge.svg)](https://docs.rs/appro_eq)
[![Coverage Status](https://coveralls.io/repos/github/chalharu/rust-appro-eq/badge.svg?branch=master)](https://coveralls.io/github/chalharu/rust-appro-eq?branch=master)

Implementing the `ApproEq` traits, Can asserts that the two expressions are approximately equal to each other.

## How-to Use
See the [crate documentation](https://docs.rs/nearly_eq/) for more details.

See the [crate documentation](https://docs.rs/appro-eq/) for more details.

### Examples

```rust
assert_nearly_eq!(1f64, 1.5f64, 0.6f64); // does not panic
assert_nearly_eq!(0f64, 1e-12f64); // does not panic
assert_appro_eq!(1f64, 1.5f64, 0.6f64); // does not panic
assert_appro_eq!(0f64, 1e-12f64); // does not panic
```

```rust:should_panic
assert_nearly_eq!(1f64, 2f64); // panics
assert_appro_eq!(1f64, 2f64); // panics
```

### Optional Features

- **`complex`** - Implement `NearlyEq` traits for `num_complex::Complex`. This adds a dependency on the `num-complex` crate.
- **`complex`** - Implement `ApproEq` traits for `num_complex::Complex`. This adds a dependency on the `num-complex` crate.

- **`rational`** - Implement `NearlyEq` traits for `num_rational::Ratio`. This adds a dependency on the `num-rational` crate.
- **`rational`** - Implement `ApproEq` traits for `num_rational::Ratio`. This adds a dependency on the `num-rational` crate.

- **`ndarray`** - Implement `NearlyEq` traits for `ndarray::ArrayBase`. This adds a dependency on the `ndarray` crate.
- **`ndarray`** - Implement `ApproEq` traits for `ndarray::ArrayBase`. This adds a dependency on the `ndarray` crate.

- **`i128`** - Implement `NearlyEq` traits for `i128` and `u128`. **Available only on Rust nightly channel.**
- **`i128`** - Implement `ApproEq` traits for `i128` and `u128`. **Available only on Rust nightly channel.**
192 changes: 158 additions & 34 deletions src/assert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,76 +3,200 @@
//! version 2.0 (the "License"). You can obtain a copy of the License at
//! http://mozilla.org/MPL/2.0/.

/// Asserts that two expressions are nearly(approximately) equal to each other.
/// Asserts that two expressions are approximately equal to each other.
///
/// You can optionally add an optional diff value. If you don't supply
/// a diff value as an argument, NearlyEq::eps() is the default used.
/// a diff value as an argument, Tolerance::tolerance() is the default used.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate nearly_eq;
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// assert_nearly_eq!(1f64, 1.5f64, 0.6f64); // does not panic
/// assert_nearly_eq!(0f64, 1e-12f64); // does not panic
/// assert_appro_eq!(1f64, 1.5f64, 0.6f64); // does not panic
/// assert_appro_eq!(0f64, 1e-12f64); // does not panic
/// assert_appro_eq!(vec![0f64, 1.0, 0.0], vec![1e-12f64, 1.0, -1e-13f64]); // does not panic
/// # }
/// ```
/// ```should_panic
/// # #[macro_use] extern crate nearly_eq;
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// assert_nearly_eq!(1f64, 2f64); // panics
/// assert_appro_eq!(1f64, 2f64); // panics
/// # }
/// ```
#[macro_export]
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
macro_rules! assert_nearly_eq {
macro_rules! assert_appro_eq {
($a:expr, $b:expr) => ({
let (a, b) = (&$a, &$b);
#[inline(always)]
fn nearly_eq_noeps<A: ?Sized, B, C: $crate::NearlyEq<A, B> + ?Sized>(a: &C, b: &A) -> bool {
a.eq(b, &C::eps())
}
assert!(nearly_eq_noeps(a, b),
assert!($crate::AbsApproEq::abs_appro_eq(&$a, &$b),
"assertion failed: `(left == right)` (left: `{:?}` , right: `{:?}`)",
*a, *b);
$a, $b);
});
($a:expr, $b:expr, $eps:expr) => ({
let (a, b, eps) = (&$a, &$b, &$eps);
#[inline(always)]
fn nearly_eq<A: ?Sized, B, C: $crate::NearlyEq<A, B> + ?Sized>(a: &C, b: &A, c: &B) -> bool {
a.eq(b, c)
}
assert!(nearly_eq(a, b, eps),
assert!($crate::AbsApproEqWithTol::abs_appro_eq_with_tol(&$a, &$b, &$eps),
"assertion failed: `(left == right)` (left: `{:?}` , right: `{:?}`, eps: `{:?}`)",
*a, *b, $eps);
$a, $b, $eps);
})
}

/// Asserts that two expressions are nearly(approximately) equal to each other.
/// Asserts that the absolute error of the two expressions is small enough.
///
/// You can optionally add an optional diff value. If you don't supply
/// a diff value as an argument, NearlyEq::eps() is the default used.
/// a diff value as an argument, Tolerance::tolerance() is the default used.
///
/// Unlike assert_nearly_eq!, debug_assert_nearly_eq! statements are only enabled in non optimized builds by default.
/// An optimized build will omit all debug_assert_nearly_eq! statements unless -C debug-assertions is passed to the compiler.
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// assert_appro_eq_abs!(1f64, 1.5f64, 0.6f64); // does not panic
/// assert_appro_eq_abs!(0f64, 1e-12f64); // does not panic
/// assert_appro_eq_abs!(vec![0f64, 1.0, 0.0], vec![1e-12f64, 1.0, -1e-13f64]); // does not panic
/// # }
/// ```
/// ```should_panic
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// assert_appro_eq_abs!(1f64, 2f64); // panics
/// # }
/// ```
#[macro_export]
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
macro_rules! assert_appro_eq_abs {
($a:expr, $b:expr) => ({
assert!($crate::AbsApproEq::abs_appro_eq(&$a, &$b),
"assertion failed: `(left == right)` (left: `{:?}` , right: `{:?}`)",
$a, $b);
});
($a:expr, $b:expr, $eps:expr) => ({
assert!($crate::AbsApproEqWithTol::abs_appro_eq_with_tol(&$a, &$b, &$eps),
"assertion failed: `(left == right)` (left: `{:?}` , right: `{:?}`, eps: `{:?}`)",
$a, $b, $eps);
})
}

/// Asserts that the relative error of the two expressions is small enough.
///
/// You can optionally add an optional diff value. If you don't supply
/// a diff value as an argument, Tolerance::tolerance() is the default used.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// assert_appro_eq_rel!(1f64, 1.5f64, 0.6f64); // does not panic
/// assert_appro_eq_rel!(1f64, 1.0 + 1e-12f64); // does not panic
/// assert_appro_eq_rel!(vec![1f64, 1.0, 1.0], vec![1.0 + 1e-12f64, 1.0, 1.0 - 1e-13f64]); // does not panic
/// # }
/// ```
/// ```should_panic
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// assert_appro_eq_rel!(1f64, 2f64); // panics
/// # }
/// ```
#[macro_export]
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
macro_rules! assert_appro_eq_rel {
($a:expr, $b:expr) => ({
assert!($crate::RelApproEq::rel_appro_eq(&$a, &$b),
"assertion failed: `(left == right)` (left: `{:?}` , right: `{:?}`)",
$a, $b);
});
($a:expr, $b:expr, $eps:expr) => ({
assert!($crate::RelApproEqWithTol::rel_appro_eq_with_tol(&$a, &$b, &$eps),
"assertion failed: `(left == right)` (left: `{:?}` , right: `{:?}`, eps: `{:?}`)",
$a, $b, $eps);
})
}

/// Asserts that two expressions are approximately equal to each other.
///
/// You can optionally add an optional diff value. If you don't supply
/// a diff value as an argument, Tolerance::tolerance() is the default used.
///
/// Unlike assert_appro_eq!, debug_assert_appro_eq! statements are only enabled in non optimized builds by default.
/// An optimized build will omit all debug_assert_appro_eq! statements unless -C debug-assertions is passed to the compiler.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate nearly_eq;
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// debug_assert_nearly_eq!(1f64, 1.5f64, 0.6f64); // does not panic
/// debug_assert_nearly_eq!(0f64, 1e-12f64); // does not panic
/// debug_assert_appro_eq!(1f64, 1.5f64, 0.6f64); // does not panic
/// debug_assert_appro_eq!(0f64, 1e-12f64); // does not panic
/// debug_assert_appro_eq!(vec![0f64, 1.0, 0.0], vec![1e-12f64, 1.0, -1e-13f64]); // does not panic
/// # }
/// ```
/// ```should_panic
/// # #[macro_use] extern crate nearly_eq;
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// debug_assert_nearly_eq!(1f64, 2f64); // panics
/// debug_assert_appro_eq!(1f64, 2f64); // panics
/// # }
/// ```
#[macro_export]
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.3"))]
macro_rules! debug_assert_nearly_eq {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_nearly_eq!($($arg)*); })
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
macro_rules! debug_assert_appro_eq {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_appro_eq!($($arg)*); })
}

/// Asserts that the absolute error of the two expressions is small enough.
///
/// You can optionally add an optional diff value. If you don't supply
/// a diff value as an argument, Tolerance::tolerance() is the default used.
///
/// Unlike assert_appro_eq_abs!, debug_assert_appro_eq_abs! statements are only enabled in non optimized builds by default.
/// An optimized build will omit all debug_assert_appro_eq_abs! statements unless -C debug-assertions is passed to the compiler.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// debug_assert_appro_eq_abs!(1f64, 1.5f64, 0.6f64); // does not panic
/// debug_assert_appro_eq_abs!(0f64, 1e-12f64); // does not panic
/// debug_assert_appro_eq_abs!(vec![0f64, 1.0, 0.0], vec![1e-12f64, 1.0, -1e-13f64]); // does not panic
/// # }
/// ```
/// ```should_panic
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// debug_assert_appro_eq_abs!(1f64, 2f64); // panics
/// # }
/// ```
#[macro_export]
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
macro_rules! debug_assert_appro_eq_abs {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_appro_eq_abs!($($arg)*); })
}

/// Asserts that the relative error of the two expressions is small enough.
///
/// You can optionally add an optional diff value. If you don't supply
/// a diff value as an argument, Tolerance::tolerance() is the default used.
///
/// Unlike assert_appro_eq_rel!, debug_assert_appro_eq_rel! statements are only enabled in non optimized builds by default.
/// An optimized build will omit all debug_assert_appro_eq_rel! statements unless -C debug-assertions is passed to the compiler.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// debug_assert_appro_eq_rel!(1f64, 1.5f64, 0.6f64); // does not panic
/// debug_assert_appro_eq_rel!(1f64, 1.0 + 1e-12f64); // does not panic
/// debug_assert_appro_eq_rel!(vec![1f64, 1.0, 1.0], vec![1.0 + 1e-12f64, 1.0, 1.0 - 1e-13f64]); // does not panic
/// # }
/// ```
/// ```should_panic
/// # #[macro_use] extern crate appro_eq;
/// # fn main() {
/// debug_assert_appro_eq_rel!(1f64, 2f64); // panics
/// # }
/// ```
#[macro_export]
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
macro_rules! debug_assert_appro_eq_rel {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_appro_eq_rel!($($arg)*); })
}
42 changes: 35 additions & 7 deletions src/complex_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,43 @@
//! http://mozilla.org/MPL/2.0/.

use num_complex::Complex;
use NearlyEq;
use num_traits::Float;
use AbsError;
use RelError;
use ApproEqResult;
use std::ops::{Div, Sub};

#[cfg_attr(feature = "docs", stable(feature = "num-complex", since = "0.1.2"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Complex<A>, B> for Complex<C> {
fn eps() -> B {
C::eps()
#[cfg_attr(feature = "docs", stable(feature = "num-complex", since = "0.1.0"))]
impl<A, D: Float, B: AbsError<A, D>> AbsError<Complex<A>, D> for Complex<B> {
fn abs_error(&self, expected: &Complex<A>) -> ApproEqResult<D> {
let diff_re = self.re.abs_error(&expected.re);
let diff_im = self.im.abs_error(&expected.im);
if match (&diff_re, &diff_im) {
(&Err(_), _) => false,
(_, &Err(_)) => true,
(&Ok(ref diff_re), &Ok(ref diff_im)) => match (diff_re, diff_im) {
(&None, _) => true,
(_, &None) => false,
(&Some(ref diff_re), &Some(ref diff_im)) => {
return Ok(Some(
Float::sqrt((*diff_re * *diff_re) + (*diff_im * *diff_im)),
))
}
},
} {
diff_im
} else {
diff_re
}
}
}

fn eq(&self, other: &Complex<A>, eps: &B) -> bool {
self.re.eq(&other.re, eps) && self.im.eq(&other.im, eps)
#[cfg_attr(feature = "docs", stable(feature = "num-complex", since = "0.1.0"))]
impl<A: Float, D: Float + Div<A, Output = D>, B: Sub<A, Output = D> + Copy> RelError<Complex<A>, D>
for Complex<B> {
fn rel_error(&self, expected: &Complex<A>) -> ApproEqResult<D> {
Ok(Some(
Complex::new(self.re - expected.re, self.im - expected.im).norm() / expected.norm(),
))
}
}
Loading

0 comments on commit c676ed1

Please sign in to comment.