I want to generate a statistical sample from a multidimensional normal distribution. For this I need to generate one specific kind of covariance matrix:
1 0.99 0.98 0.97 ...
0.99 1 0.99 0.98 ...
0.98 0.99 1 0.99 ...
0.97 0.98 0.99 1 ...
... ... ... ...
Is there a way to generate this kind of matrix for multiple dimensions easily, without writing it by hand? (I need to have matrices with 50-100 dimensions, so doing it by hand is very tedious.)
CodePudding user response:
You can use the scipy.linalg.toeplitz
function, as it is made for exactly this kind of matrix:
>>> import numpy as np
>>> from scipy import linalg
>>> linalg.toeplitz(np.arange(1,0,-0.1), np.arange(1,0,-0.1))
array([[1. , 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1],
[0.9, 1. , 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2],
[0.8, 0.9, 1. , 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3],
[0.7, 0.8, 0.9, 1. , 0.9, 0.8, 0.7, 0.6, 0.5, 0.4],
[0.6, 0.7, 0.8, 0.9, 1. , 0.9, 0.8, 0.7, 0.6, 0.5],
[0.5, 0.6, 0.7, 0.8, 0.9, 1. , 0.9, 0.8, 0.7, 0.6],
[0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 0.9, 0.8, 0.7],
[0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 0.9, 0.8],
[0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 0.9],
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]])
CodePudding user response:
If I've understood you correctly and all you want is to create a matrix with the properties you mentioned - use linspace() and then use the shift operation in a for loop.
e.g.,
x = np.linspace(1, 0, num=10)
Output:
array([1. , 0.88888889, 0.77777778, 0.66666667, 0.55555556, 0.44444444, 0.33333333, 0.22222222, 0.11111111, 0. ])
And then you can shift the array by the amount you like.
np.roll(x, shift=1, axis=0)
Output:
array([0. , 1. , 0.88888889, 0.77777778, 0.66666667, 0.55555556, 0.44444444, 0.33333333, 0.22222222, 0.11111111])
Now you can make the amount you would like to shift into a variable and put it into a for loop like so:
import numpy as np
cov = []
x = np.linspace(1, 0, num=10)
for i, value in enumerate(x):
cov.append(np.roll(x, shift=i, axis=0))
print(cov)
This should give you a list of lists cov containing all the lines of your matrix.