Two predictors x₁, x₂ are drawn with a controllable correlation r, then y is generated from a fixed true model plus noise:
x2 = r·x1 + √(1−r²)·z (so corr(x1,x2) ≈ r)
y = 2.0·x1 − 1.5·x2 + σ·ε
OLS (with intercept): β̂ = (XᵀX)⁻¹Xᵀy
solved by Gauss-Jordan matrix inversion from scratch on the 3×3 XᵀX.
VIF_j = 1 / (1 − R²_j) (R²_j from an auxiliary regression of xⱼ
on the other predictor, solved via a 2×2
matrix inversion the same way)
Bootstrap SE(β̂_j): refit OLS on 200 resamples (with replacement,
same n) of the current dataset; SE = stdev of the resampled β̂_j.
With only two predictors this collapses to VIF = 1/(1−r²): as the correlation slider approaches ±1, VIF explodes and the bootstrap standard-error bars on β̂₁ and β̂₂ visibly widen — the two coefficients trade off against each other from one resample to the next even though the fitted line still predicts y almost as well (R² barely moves). That's the textbook symptom of multicollinearity: the individual coefficients stop being reliably identifiable, only their combination along the collinear direction is.
- corr(x₁,x₂) slider — sets how collinear the two predictors are.
- Noise σ — observation noise added to y; higher noise makes the instability easier to see.
- Resample — draws a fresh n=220 sample at the same r, σ, and reruns the 200-fold bootstrap.