r2rs-stats 0.1.1

Statistics programming for Rust based on R's stats package
Documentation
// "Whatever you do, work at it with all your heart, as working for the Lord,
// not for human masters, since you know that you will receive an inheritance
// from the Lord as a reward. It is the Lord Christ you are serving."
// (Col 3:23-24)

use std::error::Error;

use strafe_trait::{
    Assumption, Concept, Conclusion, InsignificantCoefficient, NoSignificantFeature,
    NormalResiduals, SignificantCoefficient, SomeSignficantFeature, StatisticalTest,
};

use crate::{
    regression::glm::{family::core::Family, link::core::Link, GeneralizedLinearRegression},
    tests::{
        NormalResidualStatistic, NormalResidualTest, SignificanceOfRegressionStatistic,
        SignificanceOfRegressionTest, ZCoefficient, ZCoefficientBuilder,
    },
};

pub struct GeneralizedRegressionTest {
    pub residual_test: NormalResidualStatistic,
    pub significance_test: SignificanceOfRegressionStatistic,
    pub significant_coef_tests: Vec<ZCoefficient>,
}

impl<L: 'static + Link, F: 'static + Family<L> + Clone> StatisticalTest
    for GeneralizedLinearRegression<L, F>
{
    type Input = ();
    type Output = Result<GeneralizedRegressionTest, Box<dyn Error>>;

    fn assumptions() -> Vec<Box<dyn Assumption>> {
        vec![Box::new(NormalResiduals::new())]
    }

    fn null_hypotheses() -> Vec<Box<dyn Conclusion>> {
        vec![
            Box::new(NoSignificantFeature::new()),
            Box::new(InsignificantCoefficient::new()),
        ]
    }

    fn alternate_hypotheses() -> Vec<Box<dyn Conclusion>> {
        vec![
            Box::new(SomeSignficantFeature::new()),
            Box::new(SignificantCoefficient::new()),
        ]
    }

    // TODO: Weights cannot be negative
    // TODO: Cannot be NAN's
    fn test(&mut self, _: &Self::Input) -> Self::Output {
        let residual_test = NormalResidualTest::new()
            .with_alpha(self.alpha)
            .test(&self.model_data)?;

        let significance_test = SignificanceOfRegressionTest::new()
            .with_alpha(self.alpha)
            .test(&self.model_data)?;

        let significant_coef_tests = ZCoefficientBuilder::new()
            .with_alpha(self.alpha)
            .test(&self.model_data)?;

        Ok(GeneralizedRegressionTest {
            residual_test,
            significance_test,
            significant_coef_tests,
        })
    }
}