Home > Blockchain >  Generate specific Toeplitz covariance matrix
Generate specific Toeplitz covariance matrix

Time:01-15

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.

  • Related