def gradient_optimizer(coro):
class GradientOptimizer(Optimizer):<EOL><INDENT>@wraps(coro)<EOL>def __init__(self, *args, **kwargs):<EOL><INDENT>self.algorithm = coro(*args, **kwargs)<EOL>self.algorithm.send(None)<EOL>self.operators = []<EOL><DEDENT>def set_transform(self, func):<EOL><INDENT>self.transform = compose(destruct, func, self.restruct)<EOL><DEDENT>def minimize(self, f_df, x0, display=sys.stdout, maxiter=<NUM_LIT>):<EOL><INDENT>self.display = display<EOL>self.theta = x0<EOL>xk = self.algorithm.send(destruct(x0).copy())<EOL>store = defaultdict(list)<EOL>runtimes = []<EOL>if len(self.operators) == <NUM_LIT:0>:<EOL><INDENT>self.operators = [proxops.identity()]<EOL><DEDENT>obj, grad = wrap(f_df, x0)<EOL>transform = compose(destruct, *reversed(self.operators), self.restruct)<EOL>self.optional_print(tp.header(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']))<EOL>try:<EOL><INDENT>for k in count():<EOL><INDENT>tstart = perf_counter()<EOL>f = obj(xk)<EOL>df = grad(xk)<EOL>xk = transform(self.algorithm.send(df))<EOL>runtimes.append(perf_counter() - tstart)<EOL>store['<STR_LIT:f>'].append(f)<EOL>self.optional_print(tp.row([k,<EOL>f,<EOL>np.linalg.norm(destruct(df)),<EOL>tp.humantime(runtimes[-<NUM_LIT:1>])]))<EOL>if k >= maxiter:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>except KeyboardInterrupt:<EOL><INDENT>pass<EOL><DEDENT>self.optional_print(tp.bottom(<NUM_LIT:4>))<EOL>self.optional_print(u'<STR_LIT>'.format(store['<STR_LIT:f>'][-<NUM_LIT:1>]))<EOL>self.optional_print(u'<STR_LIT>'.format(tp.humantime(sum(runtimes))))<EOL>self.optional_print(u'<STR_LIT>'.format(<EOL>tp.humantime(np.mean(runtimes)),<EOL>tp.humantime(np.std(runtimes)),<EOL>))<EOL>return OptimizeResult({<EOL>'<STR_LIT:x>': self.restruct(xk),<EOL>'<STR_LIT:f>': f,<EOL>'<STR_LIT>': self.restruct(df),<EOL>'<STR_LIT:k>': k,<EOL>'<STR_LIT>': np.array(store['<STR_LIT:f>']),<EOL>})<EOL><DEDENT><DEDENT>return GradientOptimizer<EOL>
Turns a coroutine into a gradient based optimizer.