aboutsummaryrefslogtreecommitdiff
path: root/src/stats/bivariate/bootstrap.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stats/bivariate/bootstrap.rs')
-rwxr-xr-xsrc/stats/bivariate/bootstrap.rs83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/stats/bivariate/bootstrap.rs b/src/stats/bivariate/bootstrap.rs
new file mode 100755
index 0000000..8fe8ede
--- /dev/null
+++ b/src/stats/bivariate/bootstrap.rs
@@ -0,0 +1,83 @@
+#[cfg(test)]
+macro_rules! test {
+ ($ty:ident) => {
+ mod $ty {
+ use quickcheck::TestResult;
+ use quickcheck::quickcheck;
+ use approx::relative_eq;
+
+ use crate::stats::bivariate::regression::Slope;
+ use crate::stats::bivariate::Data;
+
+ quickcheck! {
+ fn means(size: usize, start: usize,
+ offset: usize, nresamples: usize) -> TestResult {
+ if let Some(x) = crate::stats::test::vec::<$ty>(size, start) {
+ let y = crate::stats::test::vec::<$ty>(size + offset, start + offset).unwrap();
+ let data = Data::new(&x[start..], &y[start+offset..]);
+
+ let (x_means, y_means) = if nresamples > 0 {
+ data.bootstrap(nresamples, |d| (d.x().mean(), d.y().mean()))
+ } else {
+ return TestResult::discard();
+ };
+
+ let x_min = data.x().min();
+ let x_max = data.x().max();
+ let y_min = data.y().min();
+ let y_max = data.y().max();
+
+ TestResult::from_bool(
+ // Computed the correct number of resamples
+ x_means.len() == nresamples &&
+ y_means.len() == nresamples &&
+ // No uninitialized values
+ x_means.iter().all(|&x| {
+ (x > x_min || relative_eq!(x, x_min)) &&
+ (x < x_max || relative_eq!(x, x_max))
+ }) &&
+ y_means.iter().all(|&y| {
+ (y > y_min || relative_eq!(y, y_min)) &&
+ (y < y_max || relative_eq!(y, y_max))
+ })
+ )
+ } else {
+ TestResult::discard()
+ }
+ }
+ }
+
+ quickcheck! {
+ fn slope(size: usize, start: usize,
+ offset: usize, nresamples: usize) -> TestResult {
+ if let Some(x) = crate::stats::test::vec::<$ty>(size, start) {
+ let y = crate::stats::test::vec::<$ty>(size + offset, start + offset).unwrap();
+ let data = Data::new(&x[start..], &y[start+offset..]);
+
+ let slopes = if nresamples > 0 {
+ data.bootstrap(nresamples, |d| (Slope::fit(&d),)).0
+ } else {
+ return TestResult::discard();
+ };
+
+ TestResult::from_bool(
+ // Computed the correct number of resamples
+ slopes.len() == nresamples &&
+ // No uninitialized values
+ slopes.iter().all(|s| s.0 > 0.)
+ )
+ } else {
+ TestResult::discard()
+ }
+ }
+ }
+
+ }
+ };
+}
+
+#[cfg(test)]
+mod test {
+ test!(f32);
+ test!(f64);
+}