| 396 | } |
| 397 | |
| 398 | pub fn covariance(returns: &DMatrix<f64>) -> DMatrix<f64> { |
| 399 | let rows = returns.nrows(); |
| 400 | let cols = returns.ncols(); |
| 401 | if rows < 2 { |
| 402 | return DMatrix::<f64>::zeros(cols, cols); |
| 403 | } |
| 404 | let means: Vec<f64> = (0..cols).map(|c| returns.column(c).sum() / rows as f64).collect(); |
| 405 | let mut cov = DMatrix::<f64>::zeros(cols, cols); |
| 406 | for i in 0..cols { |
| 407 | for j in i..cols { |
| 408 | let mut s = 0.0; |
| 409 | for r in 0..rows { |
| 410 | let di = returns[(r, i)] - means[i]; |
| 411 | let dj = returns[(r, j)] - means[j]; |
| 412 | s += di * dj; |
| 413 | } |
| 414 | s /= (rows - 1) as f64; |
| 415 | cov[(i, j)] = s; |
| 416 | cov[(j, i)] = s; |
| 417 | } |
| 418 | } |
| 419 | cov |
| 420 | } |
| 421 | |
| 422 | fn normalize_expected_returns(exp: &DMatrix<f64>) -> Result<DMatrix<f64>, ClaError> { |
| 423 | let n = exp.nrows().max(exp.ncols()); |