Учитывая n
на n
matrix M
, в строке i
и столбце j
, я хотел бы перебрать все соседние значения в круговой спирали.
Целью этого является проверка некоторой функции f
, которая зависит от M, чтобы найти радиус от (i, j)
, в котором f
возвращает True
. Итак, f
выглядит следующим образом:
def f(x, y):
"""do stuff with x and y, and return a bool"""
и будет вызываться вот так:
R = numpy.zeros(M.shape, dtype=numpy.int)
# for (i, j) in M
for (radius, (cx, cy)) in circle_around(i, j):
if not f(M[i][j], M[cx][cy]):
R[cx][cy] = radius - 1
break
Где circle_around
- это функция, которая возвращает (итератор к) индексы в круговой спирали. Поэтому для каждой точки в M
этот код будет вычислять и сохранять радиус из той точки, в которой f
возвращает True
.
Если есть более эффективный способ вычисления R
, я тоже буду открыт.
Update:
Спасибо всем, кто представил ответы. Я написал короткую функцию для построения вывода из ваших итераторов circle_around
, чтобы показать, что они делают. Если вы обновите свой ответ или опубликуете новый, вы можете использовать этот код для проверки своего решения.
from matplotlib import pyplot as plt
def plot(g, name):
plt.axis([-10, 10, -10, 10])
ax = plt.gca()
ax.yaxis.grid(color='gray')
ax.xaxis.grid(color='gray')
X, Y = [], []
for i in xrange(100):
(r, (x, y)) = g.next()
X.append(x)
Y.append(y)
print "%d: radius %d" % (i, r)
plt.plot(X, Y, 'r-', linewidth=2.0)
plt.title(name)
plt.savefig(name + ".png")
Вот результаты:
plot(circle_around(0, 0), "F.J")
:
plot(circle_around(0, 0, 10), "WolframH")
:
Я закодировал предложение магния следующим образом:
def circle_around_magnesium(x, y):
import math
theta = 0
dtheta = math.pi / 32.0
a, b = (0, 1) # are there better params to use here?
spiral = lambda theta : a + b*theta
lastX, lastY = (x, y)
while True:
r = spiral(theta)
X = r * math.cos(theta)
Y = r * math.sin(theta)
if round(X) != lastX or round(Y) != lastY:
lastX, lastY = round(X), round(Y)
yield (r, (lastX, lastY))
theta += dtheta
plot(circle_around(0, 0, 10), "magnesium")
:
Как вы можете видеть, ни один из результатов, которые удовлетворяют интерфейсу, который я ищу, создал круговую спираль, которая охватывает все индексы вокруг 0, 0. FJ является самым близким, хотя WolframH попадает в правильные точки, просто не в спиральном порядке.