use super::*;
use crate::primitives::{Matrix, Vector};
#[test]
fn falsify_blr_001_finite_predictions() {
let x = Matrix::from_vec(5, 2, vec![1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 0.5, 0.5, 2.0])
.expect("valid");
let y = Vector::from_slice(&[1.0, 2.0, 3.0, 2.5, 4.5]);
let mut blr = BayesianLinearRegression::new(2);
blr.fit(&x, &y).expect("fit");
let preds = blr.predict(&x).expect("predict");
for i in 0..preds.len() {
assert!(
preds[i].is_finite(),
"FALSIFIED BLR-001: prediction[{i}] = {} is not finite",
preds[i]
);
}
}
#[test]
fn falsify_blr_002_prediction_count() {
let x = Matrix::from_vec(5, 2, vec![1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 0.5, 0.5, 2.0])
.expect("valid");
let y = Vector::from_slice(&[1.0, 2.0, 3.0, 2.5, 4.5]);
let mut blr = BayesianLinearRegression::new(2);
blr.fit(&x, &y).expect("fit");
let preds = blr.predict(&x).expect("predict");
assert_eq!(
preds.len(),
5,
"FALSIFIED BLR-002: {} predictions for 5 inputs",
preds.len()
);
}
#[test]
fn falsify_blr_003_deterministic() {
let x = Matrix::from_vec(4, 1, vec![1.0, 2.0, 3.0, 4.0]).expect("valid");
let y = Vector::from_slice(&[2.5, 4.8, 7.1, 9.5]);
let mut blr = BayesianLinearRegression::new(1);
blr.fit(&x, &y).expect("fit");
let p1 = blr.predict(&x).expect("predict 1");
let p2 = blr.predict(&x).expect("predict 2");
for i in 0..p1.len() {
assert_eq!(
p1[i], p2[i],
"FALSIFIED BLR-003: prediction differs at index {i}"
);
}
}
#[test]
fn falsify_blr_004_posterior_exists() {
let x = Matrix::from_vec(5, 1, vec![1.0, 2.0, 3.0, 4.0, 5.0]).expect("valid");
let y = Vector::from_slice(&[2.0, 4.0, 6.0, 8.0, 10.0]);
let mut blr = BayesianLinearRegression::new(1);
blr.fit(&x, &y).expect("fit");
let posterior = blr.posterior_mean();
assert!(
posterior.is_some(),
"FALSIFIED BLR-004: posterior_mean is None after fit"
);
let mean = posterior.expect("checked above");
for (i, &v) in mean.iter().enumerate() {
assert!(
v.is_finite(),
"FALSIFIED BLR-004: posterior_mean[{i}] = {v} is not finite"
);
}
}
mod blr_proptest_falsify {
use super::*;
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(10))]
#[test]
fn falsify_blr_002_prop_prediction_count(
n in 5..=12usize,
seed in 0..200u32,
) {
let x_data: Vec<f32> = (0..n)
.map(|i| ((i as f32 + seed as f32) * 0.37).sin() * 5.0)
.collect();
let x = Matrix::from_vec(n, 1, x_data).expect("valid");
let y_data: Vec<f32> = (0..n)
.map(|i| 2.0 + 0.5 * i as f32 + (seed as f32 * 0.01))
.collect();
let y = Vector::from_vec(y_data);
let mut blr = BayesianLinearRegression::new(1);
blr.fit(&x, &y).expect("fit");
let preds = blr.predict(&x).expect("predict");
prop_assert_eq!(
preds.len(),
n,
"FALSIFIED BLR-002-prop: {} predictions for {} inputs",
preds.len(), n
);
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(10))]
#[test]
fn falsify_blr_001_prop_finite_predictions(
seed in 0..200u32,
) {
let n = 6;
let x_data: Vec<f32> = (0..n)
.map(|i| ((i as f32 + seed as f32) * 0.37).sin() * 5.0)
.collect();
let x = Matrix::from_vec(n, 1, x_data).expect("valid");
let y_data: Vec<f32> = (0..n)
.map(|i| 2.0 + 0.5 * i as f32 + (seed as f32 * 0.01))
.collect();
let y = Vector::from_vec(y_data);
let mut blr = BayesianLinearRegression::new(1);
blr.fit(&x, &y).expect("fit");
let preds = blr.predict(&x).expect("predict");
for i in 0..preds.len() {
prop_assert!(
preds[i].is_finite(),
"FALSIFIED BLR-001-prop: prediction[{}]={} not finite",
i, preds[i]
);
}
}
}
}