Skip to content
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
16 changes: 16 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ jobs:
- name: Check no_std with rand
run: cargo check --target riscv32imac-unknown-none-elf --no-default-features --features rand --lib

- name: Check no_std with nalgebra
run: cargo check --target riscv32imac-unknown-none-elf --no-default-features --features nalgebra --lib

- name: Check no_std with nalgebra and rand
run: cargo check --target riscv32imac-unknown-none-elf --no-default-features --features nalgebra,rand --lib

features:
needs: [clippy, fmt]
runs-on: ubuntu-latest
Expand All @@ -103,6 +109,16 @@ jobs:
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown, wasm32-wasip1
- name: Install Wasmtime
uses: bytecodealliance/actions/wasmtime/setup@v1
with:
version: "46.0.1"

- name: Build no_std runtime verification
run: cargo build --manifest-path tests/no_std/Cargo.toml --target wasm32-unknown-unknown --locked

- name: Run no_std calculations
run: wasmtime run --invoke verify tests/no_std/target/wasm32-unknown-unknown/debug/statrs_no_std_runtime.wasm

- name: Check WebAssembly without a host RNG
run: cargo check --target wasm32-unknown-unknown --no-default-features --features std,nalgebra,rand --lib
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ tests/*.dat

# Generated by Cargo
/target/
/tests/no_std/target/
*.lock

#editor specific
Expand Down
12 changes: 12 additions & 0 deletions Cargo.lock.MSRV

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,10 @@ required-features = ["rand", "std", "kde"]
[features]
default = ["std", "nalgebra", "rand"]
std = ["approx/std", "num-traits/std", "nalgebra?/std", "rand?/std"]
# at the moment, all nalgebra features needs std
nalgebra = ["dep:nalgebra", "std"]
nalgebra = ["dep:nalgebra", "nalgebra/alloc", "nalgebra/libm"]
rand = ["dep:rand", "nalgebra?/rand-no-std", "rand?/std_rng"]
# kd-tree backed density estimation (src/density), implemented in terms of nalgebra vectors
kde = ["dep:kdtree", "nalgebra"]
kde = ["dep:kdtree", "nalgebra", "std"]

[dependencies]
approx = { version = "0.5.0", default-features = false }
Expand Down
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,36 @@ statrs = "*" # replace * by the latest version of the crate.

For examples, view [the docs](https://docs.rs/statrs/*/statrs/).

### `no_std`

Disable the default features to use `statrs` without `std`:

```toml
[dependencies]
statrs = { version = "*", default-features = false }
```

No separate Cargo feature is required for allocation-backed APIs. To enable
matrix-backed distributions without `std`, enable `nalgebra` directly:

```toml
[dependencies]
statrs = { version = "*", default-features = false, features = ["nalgebra"] }
```

Heap-backed APIs use Rust's `alloc` crate. A `no_std` application that calls
these APIs must provide and initialize a global allocator suitable for its
target:

```rust,ignore
#[global_allocator]
static ALLOCATOR: PlatformAllocator = PlatformAllocator::new(/* heap memory */);
```

The allocator type, heap memory, and initialization are platform-specific.
`statrs` does not provide or select an allocator.
When `std` is enabled, its global allocator is used and no setup is required.

### WebAssembly randomness

On `wasm32-unknown-unknown`, sampling works with an explicitly seeded random
Expand Down
1 change: 1 addition & 0 deletions src/density/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

pub mod kde;
pub mod knn;
use alloc::vec::Vec;
use kdtree::{ErrorKind, KdTree, distance::squared_euclidean};
use thiserror::Error;

Expand Down
3 changes: 3 additions & 0 deletions src/distribution/categorical.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::distribution::{Discrete, DiscreteCDF};
use crate::statistics::*;
use alloc::vec::Vec;
use core::f64;
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Implements the
/// [Categorical](https://en.wikipedia.org/wiki/Categorical_distribution)
Expand Down
3 changes: 3 additions & 0 deletions src/distribution/dirichlet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ use crate::distribution::Continuous;
use crate::function::gamma;
use crate::prec;
use crate::statistics::*;
use alloc::{vec, vec::Vec};
use core::f64;
use nalgebra::{Dim, Dyn, OMatrix, OVector};
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Implements the
/// [Dirichlet](https://en.wikipedia.org/wiki/Dirichlet_distribution)
Expand Down
2 changes: 1 addition & 1 deletion src/distribution/empirical.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::distribution::ContinuousCDF;
use crate::statistics::*;
use alloc::collections::btree_map::{BTreeMap, Entry};
use core::convert::Infallible;
use core::ops::Bound;
use non_nan::NonNan;
use std::collections::btree_map::{BTreeMap, Entry};

mod non_nan {
use core::cmp::Ordering;
Expand Down
4 changes: 0 additions & 4 deletions src/distribution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use num_traits::NumAssignOps;
pub use self::bernoulli::Bernoulli;
pub use self::beta::{Beta, BetaError};
pub use self::binomial::{Binomial, BinomialError};
#[cfg(feature = "std")]
pub use self::categorical::{Categorical, CategoricalError};
pub use self::cauchy::{Cauchy, CauchyError};
pub use self::chi::{Chi, ChiError};
Expand All @@ -17,7 +16,6 @@ pub use self::dirac::{Dirac, DiracError};
#[cfg(feature = "nalgebra")]
pub use self::dirichlet::{Dirichlet, DirichletError};
pub use self::discrete_uniform::{DiscreteUniform, DiscreteUniformError};
#[cfg(feature = "std")]
pub use self::empirical::Empirical;
pub use self::erlang::Erlang;
pub use self::exponential::{Exp, ExpError};
Expand Down Expand Up @@ -48,7 +46,6 @@ pub use self::weibull::{Weibull, WeibullError};
mod bernoulli;
mod beta;
mod binomial;
#[cfg(feature = "std")]
mod categorical;
mod cauchy;
mod chi;
Expand All @@ -58,7 +55,6 @@ mod dirac;
#[cfg_attr(docsrs, doc(cfg(feature = "nalgebra")))]
mod dirichlet;
mod discrete_uniform;
#[cfg(feature = "std")]
mod empirical;
mod erlang;
mod exponential;
Expand Down
3 changes: 3 additions & 0 deletions src/distribution/multinomial.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::distribution::Discrete;
use crate::function::factorial;
use crate::statistics::*;
use alloc::vec::Vec;
use nalgebra::{Dim, Dyn, OMatrix, OVector};
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Implements the
/// [Multinomial](https://en.wikipedia.org/wiki/Multinomial_distribution)
Expand Down
3 changes: 3 additions & 0 deletions src/distribution/multivariate_normal.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use crate::distribution::Continuous;
use crate::statistics::{Max, MeanN, Min, Mode, VarianceN};
use alloc::vec::Vec;
use core::f64;
use core::f64::consts::{E, PI};
use nalgebra::{Cholesky, Const, DMatrix, DVector, Dim, DimMin, Dyn, OMatrix, OVector};
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Computes both the normalization and exponential argument in the normal
/// distribution, returning `None` on dimension mismatch.
Expand Down
3 changes: 3 additions & 0 deletions src/distribution/multivariate_students_t.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use crate::distribution::Continuous;
use crate::function::gamma;
use crate::statistics::{Max, MeanN, Min, Mode, VarianceN};
use alloc::vec::Vec;
use core::f64::consts::PI;
use nalgebra::{Cholesky, Const, DMatrix, Dim, DimMin, Dyn, OMatrix, OVector};
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Implements the [Multivariate Student's t-distribution](https://en.wikipedia.org/wiki/Multivariate_t-distribution)
/// distribution using the "nalgebra" crate for matrix operations.
Expand Down
2 changes: 1 addition & 1 deletion src/generate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Provides utility functions for generating data sequences

use crate::euclid::Modulus;
use alloc::{vec, vec::Vec};
use core::f64::consts;
#[cfg(not(feature = "std"))]
use num_traits::Float as _;
Expand All @@ -15,7 +16,6 @@ use num_traits::Float as _;
/// let x = generate::log_spaced(5, 0.0, 4.0);
/// assert_eq!(x, [1.0, 10.0, 100.0, 1000.0, 10000.0]);
/// ```
#[cfg(feature = "std")]
pub fn log_spaced(length: usize, start_exp: f64, stop_exp: f64) -> Vec<f64> {
match length {
0 => Vec::new(),
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

pub mod consts;
#[cfg(feature = "kde")]
#[cfg_attr(docsrs, doc(cfg(feature = "kde")))]
Expand Down
3 changes: 1 addition & 2 deletions src/statistics/order_statistics.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[cfg(feature = "std")]
use super::RankTieBreaker;
use alloc::vec::Vec;

/// The `OrderStatistics` trait provides statistical utilities
/// having to do with ordering. All the algorithms are in-place thus requiring
Expand Down Expand Up @@ -213,6 +213,5 @@ pub trait OrderStatistics<T> {
/// assert_eq!(y.clone().ranks(RankTieBreaker::Min), [1.0, 4.0, 2.0,
/// 2.0]);
/// ```
#[cfg(feature = "std")]
fn ranks(&mut self, tie_breaker: RankTieBreaker) -> Vec<T>;
}
3 changes: 1 addition & 2 deletions src/statistics/slice_statistics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::statistics::*;
use alloc::{vec, vec::Vec};
use core::ops::{Index, IndexMut};

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
Expand Down Expand Up @@ -197,7 +198,6 @@ impl<D: AsMut<[f64]> + AsRef<[f64]>> OrderStatistics<f64> for Data<D> {
self.upper_quartile() - self.lower_quartile()
}

#[cfg(feature = "std")]
fn ranks(&mut self, tie_breaker: RankTieBreaker) -> Vec<f64> {
let n = self.len();
let mut ranks: Vec<f64> = vec![0.0; n];
Expand Down Expand Up @@ -392,7 +392,6 @@ impl<D: AsMut<[f64]> + AsRef<[f64]> + Clone> Median<f64> for Data<D> {
}
}

#[cfg(feature = "std")]
fn handle_rank_ties(
ranks: &mut [f64],
index: &[(usize, &f64)],
Expand Down
5 changes: 4 additions & 1 deletion src/stats_tests/anderson_darling.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::distribution::ContinuousCDF;
use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
#[non_exhaustive]
Expand Down Expand Up @@ -27,7 +30,7 @@ pub fn anderson_darling<T: ContinuousCDF<f64, f64>>(
if n == 0 {
return Err(AndersonDarlingError::SampleSizeInvalid);
}
let mut f_obs = f_obs.to_vec();
let mut f_obs = Vec::from(f_obs);
f_obs.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());

let n_float = n as f64;
Expand Down
2 changes: 2 additions & 0 deletions src/stats_tests/chisquare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use crate::distribution::{ChiSquared, ContinuousCDF};
use crate::prec;
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Represents the errors that can occur when computing the chisquare function
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
Expand Down
3 changes: 3 additions & 0 deletions src/stats_tests/f_oneway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

use crate::distribution::{ContinuousCDF, FisherSnedecor};
use crate::stats_tests::NaNPolicy;
use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Represents the errors that occur when computing the f_oneway function
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
Expand Down
3 changes: 3 additions & 0 deletions src/stats_tests/ks_test.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//! Provides the [Kolmogorov-Smirnov (KS) test](https://en.wikipedia.org/wiki/Kolmogorov–Smirnov_test) and related
//! functions

use alloc::{vec, vec::Vec};
use core::f64;
use core::iter::zip;

#[cfg(not(feature = "std"))]
use num_traits::Float as _;
use num_traits::clamp;

use crate::distribution::ContinuousCDF;
Expand Down
3 changes: 3 additions & 0 deletions src/stats_tests/mannwhitneyu.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Provides the [Mann-Whitney U test](https://en.wikipedia.org/wiki/Mann–Whitney_U_test#) and related
//! functions

use alloc::{vec, vec::Vec};
#[cfg(not(feature = "std"))]
use num_traits::Float as _;
use num_traits::clamp;

use crate::distribution::{ContinuousCDF, Normal};
Expand Down
7 changes: 0 additions & 7 deletions src/stats_tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
#[cfg(feature = "std")]
pub mod anderson_darling;
#[cfg(feature = "std")]
pub mod chisquare;
#[cfg(feature = "std")]
pub mod f_oneway;
pub mod fisher;
#[cfg(feature = "std")]
pub mod ks_test;
#[cfg(feature = "std")]
pub mod mannwhitneyu;
#[cfg(feature = "std")]
pub mod skewtest;
#[cfg(feature = "std")]
pub mod ttest_onesample;

/// Specifies an [alternative hypothesis](https://en.wikipedia.org/wiki/Alternative_hypothesis)
Expand Down
3 changes: 3 additions & 0 deletions src/stats_tests/skewtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

use crate::distribution::{ContinuousCDF, Normal};
use crate::stats_tests::{Alternative, NaNPolicy};
use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Represents the errors that can occur when computing the skewtest function
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
Expand Down
3 changes: 3 additions & 0 deletions src/stats_tests/ttest_onesample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

use crate::distribution::{ContinuousCDF, StudentsT};
use crate::stats_tests::{Alternative, NaNPolicy};
use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use num_traits::Float as _;

/// Represents the errors that can occur when computing the ttest_onesample function
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
Expand Down
Loading