Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support no_std mode #10

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ description = "Tools for convenient comparison of matrices"
readme = "README.md"

[features]
default = ["std"]
std = []
proptest-support = [ "proptest"]

[dependencies]
num-traits = { version = "0.2", default-features = false }
matrixcompare-core = { path = "matrixcompare-core", version="0.1"}
proptest = { version = "1.0", optional = true }
proptest = { version = "1.0", optional = true, default-features = false }
hashbrown = "0.14.3"

[dev-dependencies]
quickcheck = "0.9"
Expand Down
18 changes: 11 additions & 7 deletions matrixcompare-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#![no_std]
extern crate alloc;
use alloc::vec::Vec;

/// Defines how the elements of a matrix may be accessed.
pub enum Access<'a, T> {
Dense(&'a dyn DenseAccess<T>),
Expand Down Expand Up @@ -28,8 +32,8 @@ pub trait SparseAccess<T>: Matrix<T> {
}

impl<T, X> Matrix<T> for &X
where
X: Matrix<T>,
where
X: Matrix<T>,
{
fn rows(&self) -> usize {
X::rows(*self)
Expand All @@ -45,17 +49,17 @@ impl<T, X> Matrix<T> for &X
}

impl<T, X> DenseAccess<T> for &X
where
X: DenseAccess<T>,
where
X: DenseAccess<T>,
{
fn fetch_single(&self, row: usize, col: usize) -> T {
X::fetch_single(*self, row, col)
}
}

impl<T, X> SparseAccess<T> for &X
where
X: SparseAccess<T>,
where
X: SparseAccess<T>,
{
fn nnz(&self) -> usize {
X::nnz(*self)
Expand All @@ -64,4 +68,4 @@ impl<T, X> SparseAccess<T> for &X
fn fetch_triplets(&self) -> Vec<(usize, usize, T)> {
X::fetch_triplets(&self)
}
}
}
32 changes: 25 additions & 7 deletions src/comparators.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
//! Comparators used for element-wise comparison of matrix entries.

use crate::alloc::string::ToString;
use crate::ulp::{Ulp, UlpComparisonResult};
use core::fmt::Write;

use num_traits::{float::FloatCore, Num};

use std::fmt;
use std::fmt::{Display, Formatter};
use alloc::string::String;
use core::fmt;
use core::fmt::{Display, Formatter};

/// Trait that describes elementwise comparators for [assert_matrix_eq!](../macro.assert_matrix_eq!.html).
///
Expand Down Expand Up @@ -72,7 +75,14 @@ where
}

fn description(&self) -> String {
format!("absolute difference, |x - y| <= {tol}.", tol = self.tol)
let mut out = String::new();
write!(
out,
"absolute difference, |x - y| <= {tol}.",
tol = self.tol
)
.unwrap();
out
}
}

Expand Down Expand Up @@ -147,10 +157,14 @@ where
}

fn description(&self) -> String {
format!(
let mut out = String::new();
write!(
out,
"ULP difference less than or equal to {tol}. See documentation for details.",
tol = self.tol
)
.unwrap();
out
}
}

Expand Down Expand Up @@ -208,14 +222,18 @@ where
}

fn description(&self) -> String {
format!(
let mut out = String::new();
write!(
out,
"Epsilon-sized absolute comparison, followed by an ULP-based comparison.
Please see the documentation for details.
Epsilon: {eps}
ULP tolerance: {ulp}",
eps = self.abs.tol,
ulp = self.ulp.tol
)
.unwrap();
out
}
}

Expand All @@ -227,12 +245,12 @@ mod tests {
UlpElementwiseComparator, UlpError,
};
use crate::ulp::{Ulp, UlpComparisonResult};
use core::f64;
use quickcheck::TestResult;
use std::f64;

/// Returns the next adjacent floating point number (in the direction of positive infinity)
fn next_f64(x: f64) -> f64 {
use std::mem;
use core::mem;
let as_int = unsafe { mem::transmute::<f64, i64>(x) };
unsafe { mem::transmute::<i64, f64>(as_int + 1) }
}
Expand Down
17 changes: 13 additions & 4 deletions src/comparison_failure.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use crate::alloc::string::ToString;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
use std::fmt::{Display, Formatter};
use core::fmt::Write;
use core::fmt::{Display, Formatter};

const MAX_MISMATCH_REPORTS: usize = 12;

Expand Down Expand Up @@ -29,7 +33,8 @@ where

// Write the error into a string first, so that we can add a space between
// the element output and the error output only if there is something to report.
let error = format!("{}", self.error);
let mut error = String::new();
write!(error, "{}", self.error)?;
if !error.is_empty() {
write!(f, " {}", self.error)?;
}
Expand Down Expand Up @@ -96,10 +101,13 @@ where
// TODO: Write directly to formatter
let overflow_msg = if mismatches_overflow {
let num_hidden_entries = self.mismatches.len() - MAX_MISMATCH_REPORTS;
format!(
let mut msg = String::new();
write!(
msg,
" ... ({} mismatching elements not shown)\n",
num_hidden_entries
)
)?;
msg
} else {
String::new()
};
Expand Down Expand Up @@ -139,6 +147,7 @@ pub enum MatrixComparisonFailure<T, Error> {
DuplicateSparseEntry(Entry),
}

#[cfg(feature = "std")]
impl<T, E> std::error::Error for MatrixComparisonFailure<T, E>
where
T: fmt::Debug + Display,
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ example in the repository.
*/

#![allow(clippy::float_cmp)]
#![no_std]

#[macro_use]
mod matrix_comparison;
Expand All @@ -83,6 +84,7 @@ mod comparison_failure;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
extern crate alloc;

pub mod comparators;
mod macros;
Expand Down
12 changes: 6 additions & 6 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ macro_rules! base_scalar_eq {
{
use $crate::{compare_scalars};
use $crate::comparators::ExactElementwiseComparator;
use std::borrow::Borrow;
use core::borrow::Borrow;
let comp = ExactElementwiseComparator;
let result = compare_scalars($x.borrow(), $y.borrow(), comp);
if let Err(error) = result {
Expand All @@ -287,7 +287,7 @@ Please see the documentation for ways to compare scalars approximately.\n",
{
use $crate::{compare_scalars};
use $crate::comparators::ExactElementwiseComparator;
use std::borrow::Borrow;
use core::borrow::Borrow;
let comp = ExactElementwiseComparator;
let result = compare_scalars($x.borrow(), $y.borrow(), comp);
if let Err(error) = result {
Expand All @@ -300,7 +300,7 @@ Please see the documentation for ways to compare scalars approximately.\n",
{
use $crate::{compare_scalars};
use $crate::comparators::AbsoluteElementwiseComparator;
use std::borrow::Borrow;
use core::borrow::Borrow;
let comp = AbsoluteElementwiseComparator { tol: $tol.clone() };
let result = compare_scalars($x.borrow(), $y.borrow(), comp);
if let Err(error) = result {
Expand All @@ -313,7 +313,7 @@ Please see the documentation for ways to compare scalars approximately.\n",
{
use $crate::{compare_scalars};
use $crate::comparators::UlpElementwiseComparator;
use std::borrow::Borrow;
use core::borrow::Borrow;
let comp = UlpElementwiseComparator { tol: $tol.clone() };
let result = compare_scalars($x.borrow(), $y.borrow(), comp);
if let Err(error) = result {
Expand All @@ -326,7 +326,7 @@ Please see the documentation for ways to compare scalars approximately.\n",
{
use $crate::{compare_scalars};
use $crate::comparators::FloatElementwiseComparator;
use std::borrow::Borrow;
use core::borrow::Borrow;
let comp = FloatElementwiseComparator::default();
let result = compare_scalars($x.borrow(), $y.borrow(), comp);
if let Err(error) = result {
Expand All @@ -341,7 +341,7 @@ Please see the documentation for ways to compare scalars approximately.\n",
{
use $crate::{compare_scalars};
use $crate::comparators::FloatElementwiseComparator;
use std::borrow::Borrow;
use core::borrow::Borrow;
let comp = FloatElementwiseComparator::default()$(.$key($val))+;
let result = compare_scalars($x.borrow(), $y.borrow(), comp);
if let Err(error) = result {
Expand Down
8 changes: 5 additions & 3 deletions src/matrix_comparison.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use crate::{
Access, Coordinate, DenseAccess, DimensionMismatch, ElementsMismatch, Matrix,
MatrixComparisonFailure, MatrixElementComparisonFailure, SparseAccess,
};
use alloc::vec::Vec;
use hashbrown::{HashMap, HashSet};
use num_traits::Zero;
use std::collections::{HashMap, HashSet};

use crate::Entry;

Expand All @@ -26,7 +27,8 @@ where
for (i, j, v) in triplets.iter().cloned() {
if i >= rows || j >= cols {
return Err(HashMapBuildError::OutOfBoundsCoord((i, j)));
} else if matrix.insert((i, j), v).is_some() {
}
if matrix.insert((i, j), v).is_some() {
return Err(HashMapBuildError::DuplicateCoord((i, j)));
}
}
Expand Down Expand Up @@ -71,7 +73,7 @@ where
let right_keys: HashSet<_> = right_hash.keys().collect();
let zero = T::zero();

for coord in left_keys.union(&right_keys) {
for &coord in left_keys.union(&right_keys) {
let a = left_hash.get(coord).unwrap_or(&zero);
let b = right_hash.get(coord).unwrap_or(&zero);
if let Err(error) = comparator.compare(&a, &b) {
Expand Down
3 changes: 2 additions & 1 deletion src/scalar_comparison.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt;
use alloc::string::String;
use core::fmt;

use crate::comparators::ElementwiseComparator;

Expand Down
7 changes: 4 additions & 3 deletions src/ulp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Tools for ULP-based comparison of floating point numbers.
use std::mem;
use crate::alloc::borrow::ToOwned;
use core::mem;

/// Represents the result of an ULP-based comparison between two floating point numbers.
#[derive(Debug, Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -67,9 +68,9 @@ impl_float_ulp!(f64, i64);
mod tests {
use super::Ulp;
use super::UlpComparisonResult;
use core::mem;
use core::{f32, f64};
use quickcheck::TestResult;
use std::mem;
use std::{f32, f64};

#[test]
fn plus_minus_zero_is_exact_match_f32() {
Expand Down