Tek*_*lia 1 python geometry numpy
我正在寻找一个生成器函数,在给定最小距离的情况下返回沿直线的点k。这很简单,可以使用 numpy 完成,如下所示:
points = np.linspace(start, end, k)
Run Code Online (Sandbox Code Playgroud)
然而,我想生成点作为一种“增加分辨率”,这样在从 0 到 1 的线上,生成器将产生:
1/2, 1/4, 3/4, 1/8, 3/8, 5/8, ...
Run Code Online (Sandbox Code Playgroud)
同样,这很容易递归地完成(只需接受端点并在每一半上调用 self ),但我想要一个生成器,它可以实现相同的事情,而不必从一开始就用所有内容填充数组,并且没有重复点。
最好的方法是什么?
实现此目的的一种方法是使用:
def infinite_linspace():
den = 2
while True:
for i in range(1,den,2):
yield i/den
den <<= 1
Run Code Online (Sandbox Code Playgroud)
因此,在这里我们将分子从 1迭代到den-1(含),然后将分母翻倍。
前 15 个数字是:
>>> list(islice(infinite_linspace(), 15))
[0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 0.0625, 0.1875, 0.3125, 0.4375, 0.5625, 0.6875, 0.8125, 0.9375]
>>> [1/2,1/4,3/4,1/8,3/8,5/8,7/8,1/16,3/16,5/16,7/16,9/16,11/16,13/16,15/16]
[0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 0.0625, 0.1875, 0.3125, 0.4375, 0.5625, 0.6875, 0.8125, 0.9375]
Run Code Online (Sandbox Code Playgroud)
我们甚至可以投入更多的智能来相对快速地获取第 i个元素:
class Linspace:
def __iter__(self):
den = 2
while True:
for i in range(1,den,2):
yield i/den
den <<= 1
def __getitem__(self, idx):
if not isinstance(idx, int):
raise TypeError('idx should be an integer')
if idx < 0:
raise ValueError('idx should be positive')
den = denn = idx+1
denn |= den >> 1
while den != denn:
den = denn
denn |= denn >> 1
denn += 1
return (2*idx+3-denn)/denn
Run Code Online (Sandbox Code Playgroud)
现在我们可以在对数时间内访问第 10 个、第 15 个和第 123'456 个元素:
>>> l = Linspace()
>>> l[9]
0.3125
>>> l[14]
0.9375
>>> l[123455]
0.8837966918945312
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
341 次 |
| 最近记录: |