I'm currently writing a simple program in python to simulate 1 + 1 dimensional SU(2) yang mills theory. For the case of SU(2) there exists a particular heatbath algorithm for updating the Link variables. In order to implement this algorithm however I need to generate a random real number X such that X is distributed according to P(x) = sqrt(1-X^2)*e^(k*X)
, where k is a real number from negative infinity to infinity.
Fortunately there exists an algorithm to generate X's according to said distribution. Using my limited skills in python I implemented such an algorithm. Here is the code. I'm only using numpy here.
def algorithm(k):
count = 0
while 1 != 0:
r1,r2,r3,r4 = np.random.uniform(low=0,high=1),np.random.uniform(low=0,high=1),np.random.uniform(low=0,high=1),np.random.uniform(low=0,high=1)
L1 = -1/(2*k)*(np.log(r1)+np.log(r3)*np.cos(2*np.pi*r2)**2)
if r4**2 <= 1 - L1:
X = 1 -2*L1
break
else:
count = count + 1
continue
print(count)
return X
Basically, if we take three uniformly distributed random numbers in the intervals 0 to 1 we can generate a random variable l1 which is a function of the three random numbers.
We accept this value L1 if 1 - L1 is greater than or equal to a fourth random number squared (uniformly distributed in the interval 0 to 1). Else we loop back to the beginning and do it all over again. We do this until we accept a value of L1. After we accept L1 we compute X as being 1 - 2*L1. This algorithm ensures that X follows the required distribution.
In my program I'm going to have to generate an two dimensional array of X's. This is quite slow in my current implementation. So here's my question; is there a simpler way to do this using any preset numpy packages? If such a method doesn't exist, is there a way to vectorize this function to generate a two dimensional lattice of random X's without simply iterating it with a for loop?