Constructing Positive Definite Covariance Matrices with Chosen Variances
Summary
The discussion presents ways to generate covariance matrices while controlling variance levels. One standard construction separates scale from dependence: place desired standard deviations on a diagonal matrix and combine it with a valid correlation matrix on both sides. A constant off-diagonal correlation gives a simple example, while sampling correlations offers more variety but can produce a matrix that is not positive semidefinite.
For sampled matrices that fail this condition, the answers mention repairing the correlation matrix, including nearest positive definite methods. Another approach starts with a chosen eigenvalue spectrum and rotates the diagonal eigenvalue matrix with a randomly sampled orthogonal matrix. These constructions address different specifications: setting the covariance diagonal, prescribing eigenvalues, or generating draws from a covariance model are not the same task. The discussion does not provide a single universal sampling distribution, and arbitrary sampled correlations require validation or repair before the result can be used as a covariance matrix.
Key ideas
- A covariance matrix can be formed by scaling a valid correlation matrix with the desired standard deviations.
- A constant correlation provides a simple positive semidefinite construction.
- Randomly sampled correlations may need repair to ensure positive semidefiniteness.
- Orthogonal rotations can generate matrices with a specified eigenvalue spectrum.
Tags
Full text
# Generating a random covariance matrix with variances in range
# Generating a random covariance matrix with variances in range
I would like to generate a random covariance matrix with variances in certain range.
How can it be done? (In R if possible)
I tried to generate a lower triangular matrix $L$ where the diagonal $D = \sqrt{V}$, where $V$ is the vector of variances. The problem lies with the rest of the values that do not lie on the diagonal. I do not know how to generate them in order to get at the end a meaningful covariance matrix. Finally, I would just do $C = LL^T$ (Cholesky) in order to get a positive definite matrix with the diagonal being $V$.
## Answer by Enrico Schumann (score 3)
https://quant.stackexchange.com/a/31851
A useful decomposition is, in R's matrix notation, `V = S %*% C %*% S`, in which `S` is a matrix with the standard deviations on the main diagonal and zeros elsewhere, and `C` is the correlation matrix. (See this note on Matrix Multiplication with Diagonal Indices.)
To get a meaningful `V`, you need to have `C` positive (semi)-definit. A simple way to achieve this is to make the correlation a positive constant.
```
n <- 5 ## number of assets
C <- array(0.5, dim = c(n, n))
diag(C) <- 1
```
For more variation, an approach that I have used is to sample correlations from a reasonable range. Then, of course, there is no guarantee that `C` is positive semi-definit, but you can repair it. See, for instance, the function `repairMatrix` in package `NMOF`.
## Answer by Jan Sila (score 2)
https://quant.stackexchange.com/a/31850
I haven't heard of a method to do it your way. Usually, you start with covariance matrix and do Cholesky in order to be able to generate random draws from the multinomial normal distribution with given covariance matrix. Maybe that is what you want?
In any case, if you need precisely specify the variances, see:
`Hirschberger, M., Y. Qi, & R. E. Steuer (2007): “Randomly generating portfolio-selection covariance matrices with specified distributional charac- teristics.” European Journal of Operational Research 177(3): pp. 1610–1625.`
But they have to be quite specific and I wasn't able to get their algorithm working.
But more suitable I reckon is Higham's Nearest PD (implemented in R in `Matrix` package, function `nearPD`.
`Higham, N. J. (2002): “Computing the nearest correlation matrix—a problem from finance.” IMA journal of Numerical Analysis 22(3): pp. 329–343.`
## Answer by g g (score 1)
https://quant.stackexchange.com/a/31856
It is not entirely clear to me what you really want but the following approach might help.
I assume you can generate (samples of) "variances in a certain range". So let $\sigma_1^2,\ldots,\sigma_n^2$ be an (instance of) such variances.
Your problem then is to find a way to generate random symmetric matrices with eigenvalues $\sigma_1^2,\ldots,\sigma_n^2$. According to the spectral theorem a real n-by-n matrix $C$ is positive definite with such eigenvalues if and only if it allows orthogonal diagonalisation, i.e. the factorisation
$$ C = Q D Q^T$$
where $D=\text{diag}(\sigma_1^2,\ldots,\sigma_n^2)$ is a diagonal and $Q$ a n-by-n orthogonal matrix.
Since you know $D$ the only thing you need to do is sample orthogonal matrices. This can be done in R using `rortho` from the package `pracma`.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.