Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate two random numbers whose square sum ==1

Hi I would like to generate two random numbers so that the sum of their squares is equal to 1.

I have written this code. The sum of their square may not be perfectly equal to 1 but it should be near like 0.999. I also used if(math.isclose(abs(gene_value_1)**2 + abs(gene_value_2)**2, 1)) but it doesn't work.

gene_value_1 = random.uniform(0, 1)
gene_value_2 = random.uniform(0, 1)
if(abs(gene_value_1)**2 + abs(gene_value_2)**2) == 1:
    print(added)

I want to generate two random numbers where the sum of their squares is nearly equal to 1.

like image 397
shahid hamdam Avatar asked Dec 13 '22 11:12

shahid hamdam


2 Answers

Your requirement is not really for two distinct numbers. It's for a single pair of numbers whose squared sum equals one.

If x**2 + y**2 = 1, then y is determined entirely by x: y = sqrt(1 - x**2):

gene_value_1 = random.uniform(0, 1)
gene_value_2 = math.sqrt(1.0 - gene_value_1**2)

As mentioned in the comments both to the question and this answer, the distribution obtained in this manner is non-uniform with respect to the two numbers. Since gene_value_1 and gene_value_2 would describe a unit circle in Cartesian space in the uniform case, you can do

angle = random.uniform(0, 2 * math.pi)
gene_value_1 = math.cos(angle)
gene_value_2 = math.sin(angle)
like image 185
Mad Physicist Avatar answered Jan 01 '23 18:01

Mad Physicist


I give full credit to Mark Dickinson's suggestion of using trigonometry for generating two random numbers whose squares sum to 1. This is one of the most important trigonometric identities and is sometimes termed as Pythagorean formula for sines and cosines

sine^2 (theta) + cos^2(theta) = 1

Thus, we sample theta randomly in the interval [-pi, pi] and take the sine and cosine of it. This gives us two numbers which when squared independently and then summed would be equal to 1.

So, the implementation would look something like:

def squared_unity():
    r = np.random.uniform(-np.pi, np.pi)
    r1, r2 = np.cos(r), np.sin(r)
    # sanity check
    sq_sum = np.sum(np.square([r1, r2]))
    print("the two random numbers are: {}, {}".format(round(r1, 4), round(r2, 4)))
    print("sum of the squares of them is: {}".format(round(sq_sum, 4)))

In [172]: for i in range(10): 
     ...:     squared_unity() 

the two random numbers are: -0.4232, 0.906
sum of the squares of them is: 1.0
the two random numbers are: -0.6432, 0.7657
sum of the squares of them is: 1.0
the two random numbers are: -0.9854, 0.1701
sum of the squares of them is: 1.0
the two random numbers are: 0.6192, -0.7852
sum of the squares of them is: 1.0
the two random numbers are: 0.613, 0.7901
sum of the squares of them is: 1.0
the two random numbers are: 0.3289, -0.9444
sum of the squares of them is: 1.0
the two random numbers are: -0.6289, -0.7775
sum of the squares of them is: 1.0
the two random numbers are: 0.5851, 0.811
sum of the squares of them is: 1.0
the two random numbers are: -0.9515, 0.3076
sum of the squares of them is: 1.0
the two random numbers are: 0.992, -0.1258
sum of the squares of them is: 1.0
like image 20
kmario23 Avatar answered Jan 01 '23 16:01

kmario23