From 45d80c467e8358fa243a7a3e16215da59e9209fa Mon Sep 17 00:00:00 2001 From: sain-vo Date: Sun, 20 Jul 2025 07:03:19 +0100 Subject: [PATCH] feat: added psudo inv --- src/regression.rs | 20 ++++++++++++-------- src/tools/dickeyfuller.rs | 6 +++--- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/regression.rs b/src/regression.rs index ad2dcb4..f2099bf 100644 --- a/src/regression.rs +++ b/src/regression.rs @@ -32,9 +32,12 @@ pub fn ols( let at = &x.transpose(); // beta = (A'A)^-1 A'y let ata = at * x; - let ata_inv = &ata - .try_inverse() - .ok_or_else(|| Error::FailedToInvertMatrix("OLS failed to invert A.T*A".into()))?; + + // Try regular inverse first, fallback to pseudo-inverse + let eps = Float::sqrt(F::epsilon()); + let ata_inv = &ata.pseudo_inverse(eps) + .map_err(|_| Error::FailedToInvertMatrix("OLS failed to invert A.T*A".into()))?; + let aty = at * y; // the regression coefficients @@ -84,9 +87,10 @@ mod tests { add_constant(&mut x); let (beta_hat, t_stats) = super::ols(&y, &x).unwrap(); - assert_eq!(beta_hat.get(0).unwrap().to_owned(), 1.0); - assert_eq!(beta_hat.get(1).unwrap().to_owned(), 0.0); - + assert_relative_eq!(beta_hat.get(0).unwrap().to_owned(), 1.0, epsilon = 5.0e-5f32); + assert_relative_eq!(beta_hat.get(1).unwrap().to_owned(), 0.0, epsilon = 1.5e-4f32); + let _a = t_stats.get(1).unwrap(); + print!("{:?}", _a); assert!(t_stats.get(1).unwrap().is_nan()); assert!(t_stats.get(0).unwrap().is_infinite()); } @@ -98,8 +102,8 @@ mod tests { add_constant(&mut x); let (beta_hat, t_stats) = super::ols(&y, &x).unwrap(); - assert_eq!(beta_hat.get(1).unwrap().to_owned(), 0.0); - assert_eq!(beta_hat.get(0).unwrap().to_owned(), 1.0); + assert_relative_eq!(beta_hat.get(1).unwrap().to_owned(), 0.0, epsilon = 1.0e-5); + assert_relative_eq!(beta_hat.get(0).unwrap().to_owned(), 1.0, max_relative = 1.0e-5); assert!(t_stats.get(1).unwrap().is_nan()); assert!(t_stats.get(0).unwrap().is_infinite()); } diff --git a/src/tools/dickeyfuller.rs b/src/tools/dickeyfuller.rs index 26c808e..f4f5b0f 100644 --- a/src/tools/dickeyfuller.rs +++ b/src/tools/dickeyfuller.rs @@ -33,10 +33,10 @@ use crate::Error; /// `unit_root::prelude::distrib::dickeyfuller::get_critical_value`. /// /// - If $t_{stat} < \mathrm{t_{\mathrm{crit}}(\alpha)}$ then reject $H_0$ at -/// $alpha$ significance level - and thus conclude that the series is stationary. +/// $alpha$ significance level - and thus conclude that the series is stationary. /// - If $t_{stat} > \mathrm{t_{\mathrm{crit}}(\alpha)}$ then fail to reject $H_0$ at -/// $alpha$ significance level - and thus conclude we cannot reject the hypothesis that -/// the series is not stationary. +/// $alpha$ significance level - and thus conclude we cannot reject the hypothesis that +/// the series is not stationary. /// /// # Examples: ///