生成两个平方和== 1的随机数

时间:2019-05-08 18:51:02

标签: python numpy random geometry

嗨,我想生成两个随机数,以使它们的平方和等于1。

我已经编写了这段代码。它们的平方和可能不完全等于1,但应该接近0.999。我还使用了if(math.isclose(abs(gene_value_1)**2 + abs(gene_value_2)**2, 1)),但是它不起作用。

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)

我想生成两个随机数,它们的平方和几乎等于1。

5 个答案:

答案 0 :(得分:8)

您的要求实际上不是两个不同的数字。这是用于一对平方和等于1的数字。

如果x**2 + y**2 = 1,则y完全由xy = sqrt(1 - x**2)

确定
gene_value_1 = random.uniform(0, 1)
gene_value_2 = math.sqrt(1.0 - gene_value_1**2)
如问题和答案中的注释所述,以这种方式获得的分布相对于两个数字而言是不均匀的。由于gene_value_1gene_value_2将在统一情况下描述笛卡尔空间中的单位圆,因此您可以这样做

angle = random.uniform(0, 2 * math.pi)
gene_value_1 = math.cos(angle)
gene_value_2 = math.sin(angle)

答案 1 :(得分:2)

我对Mark Dickinson's suggestion功不可没,他使用三角函数生成两个平方和为1的随机数。这是最重要的三角恒等式之一,有时被称为正弦和余弦的勾股定律

  

正弦^ 2(θ)+ cos ^ 2(θ)= 1

因此,我们在间隔theta中随机采样[-pi, pi]并取其sinecosine。这给了我们两个数字,当它们独立地平方然后求和时,将等于1。

因此,该实现将类似于:

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

答案 2 :(得分:1)

  

生成两个随机数,其平方和接近   等于1。

假设几乎相等就意味着一些小的变化量

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

答案 3 :(得分:0)

isclose的默认容差为10 ^ -9;对于您的目的,这可能太紧了。由于您未能指定问题,因此我将尝试使用完全不使用该功能的版本:

import random

tol = 0.01    # Tolerance: how close to 1.0 do we have to be?

# For illustration, try 1000 times; only a few will get close enough.
for _ in range(1000):
    gene_value_1 = random.uniform(0, 1)
    gene_value_2 = random.uniform(0, 1)
    if abs((gene_value_1**2 + gene_value_2**2) - 1.0) < tol:
        print(gene_value_1, gene_value_2)

输出:

0.494788483232363 0.8684265825591323
0.2534457849885592 0.9641226120957478
0.7203139196461331 0.6907040618050416
0.5209764827501758 0.8494629588837268
0.35131722626502326 0.9326863439646066
0.9090058297727053 0.41193607685541955
0.38668550268554913 0.9211652839586227
0.4981396919166827 0.8716609641505723
0.32335194126436084 0.9515174500031403
0.8975054159419422 0.4338981696304519
0.9055370877201422 0.4174842572890476
0.6174536739530609 0.789563981024344
0.8238168460048567 0.564248521210536
0.8086540730748032 0.5877591346132056
0.9483222364877975 0.3290608007951834
0.7610944343401178 0.6448728614809394
0.9909209668202087 0.1333222757510487
0.985161966125415 0.16537725793380365
0.39363133060821665 0.9232464739964449

答案 4 :(得分:0)

如果您想要两个平方之和为1的值,则已经提出的基于几何的建议非常好,即,在[0,2π)上均匀生成角度θ,并使用正弦(θ)和余弦(θ)。但是,如果您想扩展到更大的尺寸,这种方法很快就会令人讨厌。

一个泛化到任意数量维度的不错选择是生成独立的高斯并将其标准化。 N个独立的多元高斯可表示为一个N维向量,该向量同样有可能指向N空间中的任何方向。生成向量,将其长度标准化为1.0,然后求和,即时平方和==1。如果希望平方和接近1但不相等,则可以将标准化比例因子随机化。

from functools import reduce
from math import sqrt
from random import gauss, uniform

def sum_of_squares_is_one(n = 2):
    if ((n < 2) or (int(n) != n)) is True:
        raise Exception("Invalid argument for n")
    l = [gauss(0.0, 1.0) for _ in range(n)]
    norm = sqrt(reduce(lambda sum,x: sum + x*x, l, 0.0)) # / uniform(0.95, 1.05)
    return [x / norm for x in l]

print(sum_of_squares_is_one())
# => [-0.5507487065788466, -0.8346711101995371]
print(sum_of_squares_is_one(5))
# => [-0.5985784458250389, 0.3741123562198886, -0.2600006068118713, -0.5415988718467569, 0.37525209604886034]

n传递一个显式参数以获得N维结果。 如果要获得平方和在[0.95,1.05]中的值,请取消对除以除数的注释,或根据需要调整范围。

相关问题