I am working with generators in Python, and I am getting odd behavior. I am not entirely how to phrase the question...
My code performs a pattern search over an objective function. The issue I see shows up when I zip
the results of my patternSearch
generator with an xrange
to get only the first 12 results. It seems as though the xmin
component of the tuple returned by my generator is repeated over the length of the zip. What is especially weird, the ymin
component of the same tuple is not repeated. When I initialize a generator object ps
and call ps.next()
repeatedly, the results are correct.
What could be the issue?? Thanks!
Code
#!/usr/bin/env python2.7
def obj(x):
x1,x2 = x
return 100*(x2 - x1**2)**2 + (1 - x1)**2
# fobj: objective function of vector x
# x0: initial point
# h: initial step size
# r: reduction parameter
def patternSearch(fobj,x0,h,r):
n = len(x0) # get dimensionality
dims = range(0,n)
# initialize given x0
xmin = list(x0)
ymin = fobj(xmin)
yield (xmin,ymin) # send back the initial condition first
while True:
focus = True
for i in dims:
x = xmin # start from the last best point
x[i] += h
y = fobj(x) # eval
if y < ymin:
ymin = y
xmin = x
focus = False
continue
# else, y > ymin
x[i] -= 2*h # go in the opposite direction
y = fobj(x) # eval
if y < ymin:
ymin = y
xmin = x
focus = False
continue
# else, no update to this dim
if focus:
h *= r
yield (xmin,ymin)
def main():
x0 = (3,5)
imax = 12
print 'Initial condition: ', x0
print 'Stop condition: i == ', imax
print 'Iteration | x1 | x2 | y '
for (x,y), i in zip(patternSearch(obj,x0,h=0.5,r=0.5), xrange(imax)):
print "{:>9} | {:<10} | {:<10} | {:<11}".format(i,x[0],x[1],y)
print 'Generator output test:'
g = patternSearch(obj,x0,0.5,0.5)
for i in xrange(imax):
g.next()
Output
Initial condition: (3, 5)
Stop condition: i == 12
Iteration | x1 | x2 | y
0 | 2.0 | 4.03125 | 1604
1 | 2.0 | 4.03125 | 58.5
2 | 2.0 | 4.03125 | 58.5
3 | 2.0 | 4.03125 | 1.953125
4 | 2.0 | 4.03125 | 1.953125
5 | 2.0 | 4.03125 | 1.2900390625
6 | 2.0 | 4.03125 | 1.2900390625
7 | 2.0 | 4.03125 | 1.13043212891
8 | 2.0 | 4.03125 | 1.13043212891
9 | 2.0 | 4.03125 | 1.06357192993
10 | 2.0 | 4.03125 | 1.06357192993
11 | 2.0 | 4.03125 | 1.03150010109
Generator output test:
([3, 5], 1604)
([2.5, 5.5], 58.5)
([2.0, 5.0], 58.5)
([2.25, 4.75], 1.953125)
([2.0, 4.5], 1.953125)
([2.125, 4.375], 1.2900390625)
([2.0, 4.25], 1.2900390625)
([2.0625, 4.1875], 1.13043212890625)
([2.0, 4.125], 1.13043212890625)
([2.03125, 4.09375], 1.0635719299316406)
([2.0, 4.0625], 1.0635719299316406)
([2.015625, 4.046875], 1.0315001010894775)