I would like to create a 2 dimensional numpy array M
of size n,n
(a square matrix M
that is) with the following constraints:
- The sum of each row equals to one
- The elements of each row are all between 0 and 1
- The value of row
i
that dominates is located at entryM[i,i]
.
For example, for a square matrix it would be something like
M = np.array([[0.88,0.12],[0.13,0.87]])
- (Bonus) Ideally I want the entries of each row to follow some Gaussian like distribution whose peak, for row
i
, is located at elementM[i,i]
.
In this SO thread a similar question is asked. However, playing with the responses there I was not able to find a way to do it. This is a search problem, and I do understand it might be formulated as an optimization problem. However, I am wondering if these constraints can satisfied without the need of some specialized solver.
CodePudding user response:
For 1) and 2):
M = np.random.rand(n,n)
x = M / M.sum(1, keepdims=True)
CodePudding user response:
I subtract the number of columns from the number of rows per coordinate, and then use them to calculate the value of the Gaussian function, and finally multiply it by a random array and normalize it.
It may not be so random, but it has a high probability of meeting your requirements:
>>> size = 4
>>> ii, jj = np.indices((size, size))
>>> gaussian = np.exp(-((ii - jj) ** 2) / 2)
>>> result = np.random.normal(1, .1, (size, size)) * gaussian
>>> result /= result.sum(1, keepdims=True)
>>> result
array([[0.47556382, 0.38041462, 0.11953135, 0.02449021],
[0.24805318, 0.4126681 , 0.26168636, 0.07759236],
[0.10350016, 0.26245839, 0.37168771, 0.26235374],
[0.02027633, 0.11892695, 0.31971733, 0.54107939]])