2016-02-28 131 views
0

我试图在R^n,其中n未知的情况下实现网格搜索(在Python中,如果它很重要)。在R^n中的立方体/球体网格搜索

输入包括球体的半径和中心,以及控制网格分辨率的超参数theta。我想根据这三个参数来表示这个球体中的每个点。

我也愿意考虑立方体搜索,只迭代立方体的面。 (即,迭代L_inf sphere

如果我知道,N = 2,我会做的是:

import numpy as np 

def enumerate_2d_sphere(R,theta,center=(0,0)): 
    for n in xrange(int(2*np.pi/theta)+1): 
     degree = n*theta 
     point =(center[0]+R*np.cos(degree),center[1]+R*np.sin(degree)) 
     yield point 

for p in enumerate_2d_sphere(1,0.1): 
    print p 

由于n可以任意大,我正在寻找一种方式来遍历球\立方体有效。

任何想法?

++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++

最后我用的是什么strubbly建议修改后的版本:

import itertools 
import numpy as np 
import matplotlib.pyplot as plt 

def f(d, center, scale=1): 
    dim = len(center) 
    print d/-2.0 
    diff = scale * np.array([d/-2.0 for _ in xrange(dim)]) 
    bias = diff + center 
    for i in range(dim): 
     l = ([ xrange(1,d) for _ in xrange(i)] + 
      [[0,d]] + 
      [ xrange(d+1) for _ in xrange(dim-i-1)] 
      ) 
     for r in itertools.product(*l): 
      yield scale*np.array(r)+bias 
#example for R^2: 
center = (1,1.5) 
data = np.array([x for x in f(20,center,scale = 0.1)]) 


plt.scatter(data[:,0], data[:,1],color='r',s=100,alpha=0.5) 
plt.scatter(center[0], center[1],color='b',s=300,alpha=0.5) 
plt.show() 

输出数字:

enter image description here

另外一个选项是生成 uniformly distributed samples on the sphere。需要注意的是样本的数目控制点的“密度”(或预期密度):

import numpy as np 
def generate_random_points(R,center,quantity=1000): 
    """ 
    :param R: float 
    :param center: np.array 
    :param quantity: int 
    """ 
    dim = len(center) 
    for n in xrange(quantity): 
     s = np.random.normal(0, 1,dim) 
     r = np.sqrt(np.dot(s,s)) 
     s = (R/r) * s 
     yield s+center 

最坏方法(在简单和效率的方面)。将生成上使用enumeration of n-1 angles球体点。由于需要计算产品sincos(虽然也可能会被黑客攻击),所以效率不高。

+1

你能多解释一下你想要的吗?例如,假设R = 10,n = 2,c =(0,0),θ= 1。作为R,c和theta的函数,代表这个磁盘中的所有点是什么意思? –

+0

我添加了一个例子 – omerbp

回答

1

您可以在n维中使用球坐标。 wikipedia),或者只需将最后一个坐标设置为获得正确半径(加号或减号)所需的任何值即可使用欧几里德坐标。这两个都是很好的参数化,并会给你所有的球上点 - 与正确数量的参数迭代。

但是,它们不会自然地导致恒定的面积(体积)元素 - 这很容易通过考虑3个球体来看到。这个问题没有简单的解决方案。

我认为一种可能的方法是使用n-1维网格参数化,但是根据体积将第n个分量细分为可变数量的值。

n立方体的面更容易:只需生成第n个坐标为最小或最大坐标的n对面。因此,例如,考虑从原点开始的大小为1的正方体:

将第一个坐标设置为零,并在余数上枚举网格。然后将其设置为一个,然后再次执行。然后重复第二个坐标。等等。

下面是使用itertools.product来做到这一点的一种简单方法。为了简单和高效,我已将该框缩放为整数坐标:您需要重新调整并移动中心。所以n是维数和d沿每个轴的细分数。

import itertools 

def f(n,d): 

    for i in range(n): 
     l = ([ range(1,d-1) for _ in range(i)] + 
      [[0,d-1]] + 
      [ range(d) for _ in range(n-i-1)] 
      ) 
     for r in itertools.product(*l): 
      yield r 

print(list(f(4,3))) 
+0

“我的意思是”用表面缩放而不是体积“ - 考虑一种算法,可以生成一个球内的所有点,并抛出所有位于球内部的点。你的解决方案只能使用递归来实现,对吗? – omerbp

+0

嗯,我认为这将是简单的递归,但没有,不需要。例如,您可以使用'itertools.product'或编写自己的等效代码。 – strubbly

+0

我将添加简单版本的代码 – strubbly

0

我不认为sklearn网格搜索功能有这个选项,但手动实现这个应该不难

  • 叠代的每个N N
  • 的值,迭代n个不同的角度参数与THETA步幅从0到360
  • 如果wan't球体体积,也迭代半径 - 如果你只需要表面,保持半径不变
+0

尺寸'n'在运行前是未知的,所以可以有更多的角度比两个... – omerbp

+1

没有注意到这个... 它是否必须是网格搜索,或者是手动代码还好吗? –

+0

请注意,在3D中,一个角度从0到360步进,而另一个从0到180,而我不确定在'n'尺寸中会发生什么...... – omerbp