use nalgebra::{DVector, RealField, Scalar};
use num_traits::Float;
use crate::distrib::Regression;
use crate::prelude::tools::Report;
use crate::regression::ols;
use crate::{tools, Error};
pub fn adf_test<F: RealField + Scalar + Float>(
y: &DVector<F>,
lag: usize,
regression: Regression,
) -> Result<Report<F>, Error> {
let (delta_y, x, size) = tools::prepare(y, lag, regression)?;
let (_betas, t_stats) = ols(&delta_y, &x)?;
Ok(Report {
test_statistic: t_stats[0],
size,
})
}
#[cfg(test)]
mod tests {
use approx::assert_relative_eq;
use nalgebra::DVector;
use crate::distrib::Regression;
use crate::prelude::tools::{adf_test, dickeyfuller_test};
const Y: [f64; 11] = [
-1.06714348,
-1.14700339,
0.79204106,
-0.05845247,
-0.67476754,
-0.10396661,
1.82059282,
-0.51169443,
2.07712365,
1.85668086,
2.56363688,
];
#[test]
fn test_t_statistics_n() {
let lag = 1;
let y = DVector::from_row_slice(&Y[..]);
let report = adf_test(&y, lag, Regression::NoConstantNoTrend).unwrap();
assert_eq!(report.size, 9);
assert_relative_eq!(report.test_statistic, -0.417100483298f64, epsilon = 1e-9);
}
#[test]
fn test_t_statistics_c() {
let lag = 2;
let y = DVector::from_row_slice(&Y[..]);
let report = adf_test(&y, lag, Regression::Constant).unwrap();
assert_eq!(report.size, 8);
assert_relative_eq!(report.test_statistic, 0.486121422662f64, epsilon = 1e-9);
}
#[test]
fn test_t_statistics_ct() {
let lag = 0;
let y = DVector::from_row_slice(&Y[..]);
let report = adf_test(&y, lag, Regression::ConstantAndTrend).unwrap();
assert_eq!(report.size, 10);
assert_relative_eq!(report.test_statistic, -4.20337098854f64, epsilon = 1e-9);
}
#[test]
fn test_adf_lag_0_is_dickeyfuller_test() {
let lag = 0;
let y = vec![1_f32, 3., 6., 10., 15., 21., 28., 36., 45., 55.];
let y = DVector::from(y);
let regression = Regression::Constant;
let report = adf_test(&y, lag, regression).unwrap();
let df_report = dickeyfuller_test(&y, regression).unwrap();
assert_eq!(report.test_statistic, df_report.test_statistic);
assert_eq!(report.size, df_report.size);
}
}