use nalgebra::DMatrix;
pub fn linear_regression_qr(x: &DMatrix<f64>, y: &DMatrix<f64>) -> DMatrix<f64> {
let x_r = x.clone().qr().r();
x_r.clone().pseudo_inverse(f64::EPSILON).unwrap()
* x_r.transpose().pseudo_inverse(f64::EPSILON).unwrap()
* x.transpose()
* y
}
pub fn linear_regression_sqrt_weighted(
x: &DMatrix<f64>,
y: &DMatrix<f64>,
w: &DMatrix<f64>,
) -> DMatrix<f64> {
let mut x = x.to_owned();
let mut y = y.to_owned();
let mut w = w.to_owned();
if w.iter().any(|&w_i| w_i == 0.0) {
let w_0_rows = w
.iter()
.enumerate()
.filter(|(_, &w_i)| w_i == 0.0)
.map(|(i, _)| i)
.collect::<Vec<_>>();
x = x.remove_rows_at(&w_0_rows);
y = y.remove_rows_at(&w_0_rows);
w = w.remove_rows_at(&w_0_rows);
}
let wts = DMatrix::from_iterator(w.shape().0, 1, w.iter().map(|w_i| w_i.sqrt()));
let mut weighted_x = x.insert_column(0, 1.0);
weighted_x
.column_iter_mut()
.for_each(|mut row| row.component_mul_assign(&wts));
let weighted_y = y.component_mul(&wts);
linear_regression_qr(&weighted_x, &weighted_y)
}
pub fn linear_regression_sqrt_weighted_no_intercept(
x: &DMatrix<f64>,
y: &DMatrix<f64>,
w: &DMatrix<f64>,
) -> DMatrix<f64> {
let mut x = x.to_owned();
let mut y = y.to_owned();
let mut w = w.to_owned();
if w.iter().any(|&w_i| w_i == 0.0) {
let w_0_rows = w
.iter()
.enumerate()
.filter(|(_, &w_i)| w_i == 0.0)
.map(|(i, _)| i)
.collect::<Vec<_>>();
x = x.remove_rows_at(&w_0_rows);
y = y.remove_rows_at(&w_0_rows);
w = w.remove_rows_at(&w_0_rows);
}
let wts = DMatrix::from_iterator(w.shape().0, 1, w.iter().map(|w_i| w_i.sqrt()));
let mut weighted_x = x;
weighted_x
.column_iter_mut()
.for_each(|mut row| row.component_mul_assign(&wts));
let weighted_y = y.component_mul(&wts);
linear_regression_qr(&weighted_x, &weighted_y)
}
pub fn linear_regression_weighted_no_intercept(
x: &DMatrix<f64>,
y: &DMatrix<f64>,
w: &DMatrix<f64>,
) -> DMatrix<f64> {
let mut x = x.to_owned();
let mut y = y.to_owned();
let mut w = w.to_owned();
if w.iter().any(|&w_i| w_i == 0.0) {
let w_0_rows = w
.iter()
.enumerate()
.filter(|(_, &w_i)| w_i == 0.0)
.map(|(i, _)| i)
.collect::<Vec<_>>();
x = x.remove_rows_at(&w_0_rows);
y = y.remove_rows_at(&w_0_rows);
w = w.remove_rows_at(&w_0_rows);
}
let mut weighted_x = x;
weighted_x
.column_iter_mut()
.for_each(|mut row| row.component_mul_assign(&w));
let weighted_y = y.component_mul(&w);
linear_regression_qr(&weighted_x, &weighted_y)
}