def lbfgs_emulation(O, memory_range=5): assert len(O.xfgc_infos) == 1 for O.i_step in xrange(O.params.iteration_limit): if (O.i_step == 0): dests = -O.grads stp = 1 / O.grads.norm() else: active_infos = O.get_active_infos() assert len(active_infos) > 1 if (memory_range is not None): active_infos = active_infos[-(memory_range+1):] memory = O.build_bfgs_memory(active_infos=active_infos) assert memory is not None k_1 = active_infos[-1] k_2 = active_infos[-2] gamma = bfgs.h0_scaling( sk=k_1.x-k_2.x, yk=k_1.grads-k_2.grads) hk0 = flex.double(O.x.size(), gamma) dests = -bfgs.hg_two_loop_recursion( memory=memory, hk0=hk0, gk=O.grads) stp = 1 stp = O.line_search(dests, stp=stp) assert stp is not None O.update_fgc(is_iterate=True) print "%4d: %s" % (O.i_step+1, O.format_rms_info()) sys.stdout.flush() if (O.grads_mean_sq < O.params.grads_mean_sq_threshold): O.termination_remark = "" break else: O.termination_remark = " (iteration limit reached)"
def check(bk, hk): hl = bfgs.h_update(hk, xl-xk, gl-gk) bl = bfgs.b_update(bk, xl-xk, gl-gk) assert approx_equal(matrix.sqr(hl).inverse(), bl) es = eigensystem.real_symmetric(bl) assert es.values().all_gt(0) assert bfgs.h0_scaling(sk=xl-xk, yk=gl-gk) > 0