| 164 | } |
| 165 | |
| 166 | fn covariance(returns: &DMatrix<f64>) -> Result<DMatrix<f64>, HrpError> { |
| 167 | if returns.nrows() < 2 { |
| 168 | return Err(HrpError::NoData); |
| 169 | } |
| 170 | let rows = returns.nrows(); |
| 171 | let cols = returns.ncols(); |
| 172 | let means: Vec<f64> = (0..cols).map(|c| returns.column(c).sum() / rows as f64).collect(); |
| 173 | let mut cov = DMatrix::zeros(cols, cols); |
| 174 | for i in 0..cols { |
| 175 | for j in i..cols { |
| 176 | let mut s = 0.0; |
| 177 | for r in 0..rows { |
| 178 | s += (returns[(r, i)] - means[i]) * (returns[(r, j)] - means[j]); |
| 179 | } |
| 180 | s /= (rows - 1) as f64; |
| 181 | cov[(i, j)] = s; |
| 182 | cov[(j, i)] = s; |
| 183 | } |
| 184 | } |
| 185 | Ok(cov) |
| 186 | } |
| 187 | |
| 188 | fn shrink_covariance(cov: &DMatrix<f64>, alpha: f64) -> DMatrix<f64> { |
| 189 | let a = alpha.clamp(0.0, 1.0); |