diff --git a/src/correlation.rs b/src/correlation.rs index 200bbc45..254d7b9d 100644 --- a/src/correlation.rs +++ b/src/correlation.rs @@ -119,6 +119,8 @@ where fn pearson_correlation(&self) -> Array2 where A: Float + FromPrimitive; + + private_decl! {} } impl CorrelationExt for ArrayBase @@ -164,6 +166,8 @@ where // element-wise division cov / std_matrix } + + private_impl! {} } #[cfg(test)] diff --git a/src/entropy.rs b/src/entropy.rs index 3841cb02..e32d3d43 100644 --- a/src/entropy.rs +++ b/src/entropy.rs @@ -120,6 +120,8 @@ where where S2: Data, A: Float; + + private_decl! {} } impl EntropyExt for ArrayBase @@ -212,6 +214,8 @@ where let cross_entropy = -temp.sum(); Ok(cross_entropy) } + + private_impl! {} } #[cfg(test)] diff --git a/src/histogram/histograms.rs b/src/histogram/histograms.rs index 4eaeaad4..2cd367ce 100644 --- a/src/histogram/histograms.rs +++ b/src/histogram/histograms.rs @@ -147,6 +147,8 @@ where fn histogram(&self, grid: Grid) -> Histogram where A: Ord; + + private_decl! {} } impl HistogramExt for ArrayBase @@ -161,4 +163,6 @@ where } histogram } + + private_impl! {} } diff --git a/src/lib.rs b/src/lib.rs index 6a7cdf38..09ade038 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,6 +48,39 @@ pub use quantile::{interpolate, Quantile1dExt, QuantileExt}; pub use sort::Sort1dExt; pub use summary_statistics::SummaryStatisticsExt; +#[macro_use] +mod private { + /// This is a public type in a private module, so it can be included in + /// public APIs, but other crates can't access it. + pub struct PrivateMarker; + + /// Defines an associated function for a trait that is impossible for other + /// crates to implement. This makes it possible to add new associated + /// types/functions/consts/etc. to the trait without breaking changes. + macro_rules! private_decl { + () => { + /// This method makes this trait impossible to implement outside of + /// `ndarray-stats` so that we can freely add new methods, etc., to + /// this trait without breaking changes. + /// + /// We don't anticipate any other crates needing to implement this + /// trait, but if you do have such a use-case, please let us know. + /// + /// **Warning** This method is not considered part of the public + /// API, and client code should not rely on it being present. It + /// may be removed in a non-breaking release. + fn __private__(&self, _: crate::private::PrivateMarker); + }; + } + + /// Implements the associated function defined by `private_decl!`. + macro_rules! private_impl { + () => { + fn __private__(&self, _: crate::private::PrivateMarker) {} + }; + } +} + mod correlation; mod entropy; pub mod errors; diff --git a/src/maybe_nan/mod.rs b/src/maybe_nan/mod.rs index 15adbafd..eba3b2f5 100644 --- a/src/maybe_nan/mod.rs +++ b/src/maybe_nan/mod.rs @@ -289,6 +289,8 @@ where S: DataMut, D: RemoveAxis, F: FnMut(ArrayViewMut1<'a, A::NotNan>) -> B; + + private_decl! {} } impl MaybeNanExt for ArrayBase @@ -365,6 +367,8 @@ where { self.map_axis_mut(axis, |lane| mapping(A::remove_nan_mut(lane))) } + + private_impl! {} } #[cfg(test)] diff --git a/src/quantile/interpolate.rs b/src/quantile/interpolate.rs index a0fe64d4..0b7871d9 100644 --- a/src/quantile/interpolate.rs +++ b/src/quantile/interpolate.rs @@ -44,6 +44,8 @@ pub trait Interpolate { /// or if `None` is provided for the higher value when it's needed. #[doc(hidden)] fn interpolate(lower: Option, higher: Option, q: N64, len: usize) -> T; + + private_decl! {} } /// Select the higher value. @@ -69,6 +71,7 @@ impl Interpolate for Higher { fn interpolate(_lower: Option, higher: Option, _q: N64, _len: usize) -> T { higher.unwrap() } + private_impl! {} } impl Interpolate for Lower { @@ -81,6 +84,7 @@ impl Interpolate for Lower { fn interpolate(lower: Option, _higher: Option, _q: N64, _len: usize) -> T { lower.unwrap() } + private_impl! {} } impl Interpolate for Nearest { @@ -97,6 +101,7 @@ impl Interpolate for Nearest { higher.unwrap() } } + private_impl! {} } impl Interpolate for Midpoint @@ -115,6 +120,7 @@ where let higher = higher.unwrap(); lower.clone() + (higher.clone() - lower.clone()) / denom.clone() } + private_impl! {} } impl Interpolate for Linear @@ -135,4 +141,5 @@ where let higher_f64 = higher.to_f64().unwrap(); lower.clone() + T::from_f64(fraction * (higher_f64 - lower_f64)).unwrap() } + private_impl! {} } diff --git a/src/quantile/mod.rs b/src/quantile/mod.rs index 3926e24f..d718d1fa 100644 --- a/src/quantile/mod.rs +++ b/src/quantile/mod.rs @@ -295,6 +295,8 @@ where A::NotNan: Clone + Ord, S: DataMut, I: Interpolate; + + private_decl! {} } impl QuantileExt for ArrayBase @@ -568,6 +570,8 @@ where }); Ok(quantile) } + + private_impl! {} } /// Quantile methods for 1-D arrays. @@ -635,6 +639,8 @@ where S: DataMut, S2: Data, I: Interpolate; + + private_decl! {} } impl Quantile1dExt for ArrayBase @@ -665,6 +671,8 @@ where { self.quantiles_axis_mut(Axis(0), qs, interpolate) } + + private_impl! {} } pub mod interpolate; diff --git a/src/sort.rs b/src/sort.rs index 5a0b5d3b..4f4bfc41 100644 --- a/src/sort.rs +++ b/src/sort.rs @@ -103,6 +103,8 @@ where where A: Ord + Clone, S: DataMut; + + private_decl! {} } impl Sort1dExt for ArrayBase @@ -183,6 +185,8 @@ where self.swap(0, i - 1); i - 1 } + + private_impl! {} } /// To retrieve multiple indexes from the sorted array in an optimized fashion, diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs index de65a801..89d4df9d 100644 --- a/src/summary_statistics/means.rs +++ b/src/summary_statistics/means.rs @@ -105,6 +105,8 @@ where } } } + + private_impl! {} } /// Returns a vector containing all moments of the array elements up to diff --git a/src/summary_statistics/mod.rs b/src/summary_statistics/mod.rs index e0a71399..8351ff82 100644 --- a/src/summary_statistics/mod.rs +++ b/src/summary_statistics/mod.rs @@ -140,6 +140,8 @@ where fn central_moments(&self, order: u16) -> Result, EmptyInput> where A: Float + FromPrimitive; + + private_decl! {} } mod means;