2016-02-28 33 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

相關問題