Skip to content

Commit

Permalink
Fix model fitting failure for a standard error equal to zero
Browse files Browse the repository at this point in the history
This would result in a t-value of Nan, which gets rejected by
students_t_cdf. The previous implementation silently forwarded the NaN.
This fixed version produces a p-value of 1.0 instead.
  • Loading branch information
n1m3 committed Feb 4, 2023
1 parent ed67986 commit aebcda6
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,10 @@ impl LowLevelRegressionModel {
let centered_tss = centered_input_matrix.dot(&centered_input_matrix);
let rsquared = 1. - (ssr / centered_tss);
let rsquared_adj = 1. - ((n - 1) as f64 / df_resid as f64 * (1. - rsquared));
let tvalues = parameters.iter().zip(se.iter()).map(|(x, y)| x / y);
let tvalues = parameters
.iter()
.zip(se.iter())
.map(|(&x, &y)| x / y.max(std::f64::EPSILON));
let pvalues: Vec<f64> = tvalues
.map(|x| students_t_cdf(x.abs().neg(), df_resid as i64).map(|i| i * 2.))
.collect::<Option<_>>()
Expand Down
76 changes: 76 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,82 @@ fn test_pinv_with_data_columns() {
assert_almost_eq!(regression.scale(), scale);
}

#[test]
fn test_standard_error_equal_to_zero_does_not_prevent_fitting() {
// Regression test for underlying issue of https://github.com/n1m3/linregress/issues/9

// The following input does not conform to our API (we expect that all intercepts == 1, not 0),
// but Hyrum's law...
let data = vec![
0.0,
0.0,
0.0,
34059798.0,
0.0,
1.0,
66771421.0,
0.0,
2.0,
100206133.0,
0.0,
3.0,
133435943.0,
0.0,
4.0,
166028256.0,
0.0,
5.0,
199723152.0,
0.0,
6.0,
233754352.0,
0.0,
7.0,
267284084.0,
0.0,
8.0,
301756656.0,
0.0,
9.0,
331420366.0,
0.0,
10.0,
367961084.0,
0.0,
11.0,
401288216.0,
0.0,
12.0,
434555574.0,
0.0,
13.0,
469093436.0,
0.0,
14.0,
501541551.0,
0.0,
15.0,
523986797.0,
0.0,
16.0,
558792615.0,
0.0,
17.0,
631494010.0,
0.0,
18.0,
669229109.0,
0.0,
19.0,
704321427.0,
0.0,
20.0,
];
let rows = 21;
let columns = 3;
fit_low_level_regression_model(&data, rows, columns).unwrap();
}

#[test]
fn test_low_level_model_fitting() {
let inputs = vec![1., 3., 4., 5., 2., 3., 4.];
Expand Down

0 comments on commit aebcda6

Please sign in to comment.