def update_orb_ci(casscf, mo, ci0, eris, x0_guess=None, conv_tol_grad=1e-4, max_stepsize=None, verbose=None): log = logger.new_logger(casscf, verbose) if max_stepsize is None: max_stepsize = casscf.max_stepsize nmo = mo.shape[1] # MRH, 04/08/2019: enable multiple roots if casscf.fcisolver.nroots == 1: ci0 = ci0.ravel () else: ci0 = [c.ravel () for c in ci0] g_all, g_update, h_op, h_diag = gen_g_hop(casscf, mo, ci0, eris) ngorb = numpy.count_nonzero (casscf.uniq_var_indices (nmo, casscf.ncore, casscf.ncas, casscf.frozen)) norm_gkf = norm_gall = numpy.linalg.norm(g_all) log.debug(' |g|=%5.3g (%4.3g %4.3g) (keyframe)', norm_gall, numpy.linalg.norm(g_all[:ngorb]), numpy.linalg.norm(g_all[ngorb:])) def precond(x, e): if callable(h_diag): x = h_diag(x, e-casscf.ah_level_shift) else: hdiagd = h_diag-(e-casscf.ah_level_shift) hdiagd[abs(hdiagd)<1e-8] = 1e-8 x = x/hdiagd x *= 1/numpy.linalg.norm(x) return x def scale_down_step(dxi, hdxi): dxmax = abs(dxi).max() if dxmax > casscf.max_stepsize: scale = casscf.max_stepsize / dxmax log.debug1('Scale rotation by %g', scale) dxi *= scale hdxi *= scale return dxi, hdxi class Statistic: def __init__(self): self.imic = 0 self.tot_hop = 0 self.tot_kf = 1 # The call to gen_g_hop if x0_guess is None: x0_guess = g_all g_op = lambda: g_all stat = Statistic() dr = 0 ikf = 0 u = numpy.eye(nmo) ci_kf = ci0 if norm_gall < conv_tol_grad*.3: return u, ci_kf, norm_gall, stat, x0_guess for ah_conv, ihop, w, dxi, hdxi, residual, seig \ in ciah.davidson_cc(h_op, g_op, precond, x0_guess, tol=casscf.ah_conv_tol, max_cycle=casscf.ah_max_cycle, lindep=casscf.ah_lindep, verbose=log): stat.tot_hop = ihop norm_residual = numpy.linalg.norm(residual) if (ah_conv or ihop == casscf.ah_max_cycle or # make sure to use the last step ((norm_residual < casscf.ah_start_tol) and (ihop >= casscf.ah_start_cycle)) or (seig < casscf.ah_lindep)): stat.imic += 1 dxmax = abs(dxi).max() dxi, hdxi = scale_down_step(dxi, hdxi) dr += dxi g_all = g_all + hdxi norm_dr = numpy.linalg.norm(dr) norm_gall = numpy.linalg.norm(g_all) norm_gorb = numpy.linalg.norm(g_all[:ngorb]) norm_gci = numpy.linalg.norm(g_all[ngorb:]) log.debug(' imic %d(%d) |g|=%3.2e (%2.1e %2.1e) |dxi|=%3.2e ' 'max(x)=%3.2e |dr|=%3.2e eig=%2.1e seig=%2.1e', stat.imic, ihop, norm_gall, norm_gorb, norm_gci, numpy.linalg.norm(dxi), dxmax, norm_dr, w, seig) max_cycle = max(casscf.max_cycle_micro, casscf.max_cycle_micro-int(numpy.log(norm_gkf+1e-7)*2)) log.debug1('Set max_cycle %d', max_cycle) ikf += 1 if stat.imic > 3 and norm_gall > norm_gkf*casscf.ah_grad_trust_region: g_all = g_all - hdxi dr -= dxi norm_gall = numpy.linalg.norm(g_all) log.debug('|g| >> keyframe, Restore previouse step') break elif (stat.imic >= max_cycle or norm_gall < conv_tol_grad*.3): break elif ((ikf >= max(casscf.kf_interval, casscf.kf_interval-numpy.log(norm_dr+1e-7)) or # Insert keyframe if the keyframe and the esitimated grad are too different norm_gall < norm_gkf/casscf.kf_trust_region)): ikf = 0 u, ci_kf = extract_rotation(casscf, dr, u, ci_kf) dr[:] = 0 g_kf1 = g_update(u, ci_kf) stat.tot_kf += 1 norm_gkf1 = numpy.linalg.norm(g_kf1) norm_gorb = numpy.linalg.norm(g_kf1[:ngorb]) norm_gci = numpy.linalg.norm(g_kf1[ngorb:]) norm_dg = numpy.linalg.norm(g_kf1-g_all) log.debug('Adjust keyframe to |g|= %4.3g (%4.3g %4.3g) ' '|g-correction|= %4.3g', norm_gkf1, norm_gorb, norm_gci, norm_dg) if (norm_dg < norm_gall*casscf.ah_grad_trust_region # kf not too diff #or norm_gkf1 < norm_gkf # grad is decaying # close to solution or norm_gkf1 < conv_tol_grad*casscf.ah_grad_trust_region): g_all = g_kf1 g_kf1 = None norm_gall = norm_gkf = norm_gkf1 else: g_all = g_all - hdxi dr -= dxi norm_gall = norm_gkf = numpy.linalg.norm(g_all) log.debug('Out of trust region. Restore previouse step') break u, ci_kf = extract_rotation(casscf, dr, u, ci_kf) if casscf.fcisolver.nroots == 1: dci_kf = ci_kf - ci0 else: dci_kf = numpy.concatenate ([(x-y).ravel () for x, y in zip (ci_kf, ci0)]) log.debug(' tot inner=%d |g|= %4.3g (%4.3g %4.3g) |u-1|= %4.3g |dci|= %4.3g', stat.imic, norm_gall, norm_gorb, norm_gci, numpy.linalg.norm(u-numpy.eye(nmo)), numpy.linalg.norm(dci_kf)) return u, ci_kf, norm_gkf, stat, dxi
def update_orb_ci(casscf, mo, ci0, eris, x0_guess=None, conv_tol_grad=1e-4, max_stepsize=None, verbose=None): log = logger.new_logger(casscf, verbose) if max_stepsize is None: max_stepsize = casscf.max_stepsize nmo = mo.shape[1] ci0 = ci0.ravel() g_all, g_update, h_op, h_diag = gen_g_hop(casscf, mo, ci0, eris) ngorb = g_all.size - ci0.size g_kf = g_all norm_gkf = norm_gall = numpy.linalg.norm(g_all) log.debug(' |g|=%5.3g (%4.3g %4.3g) (keyframe)', norm_gall, numpy.linalg.norm(g_all[:ngorb]), numpy.linalg.norm(g_all[ngorb:])) def precond(x, e): if callable(h_diag): x = h_diag(x, e-casscf.ah_level_shift) else: hdiagd = h_diag-(e-casscf.ah_level_shift) hdiagd[abs(hdiagd)<1e-8] = 1e-8 x = x/hdiagd x *= 1/numpy.linalg.norm(x) return x def scale_down_step(dxi, hdxi): dxmax = abs(dxi).max() if dxmax > casscf.max_stepsize: scale = casscf.max_stepsize / dxmax log.debug1('Scale rotation by %g', scale) dxi *= scale hdxi *= scale return dxi, hdxi class Statistic: def __init__(self): self.imic = 0 self.tot_hop = 0 self.tot_kf = 1 # The call to gen_g_hop if x0_guess is None: x0_guess = g_all g_op = lambda: g_all stat = Statistic() dr = 0 ikf = 0 u = numpy.eye(nmo) ci_kf = ci0 if norm_gall < conv_tol_grad*.3: return u, ci_kf, norm_gall, stat, x0_guess for ah_conv, ihop, w, dxi, hdxi, residual, seig \ in ciah.davidson_cc(h_op, g_op, precond, x0_guess, tol=casscf.ah_conv_tol, max_cycle=casscf.ah_max_cycle, lindep=casscf.ah_lindep, verbose=log): stat.tot_hop = ihop norm_residual = numpy.linalg.norm(residual) if (ah_conv or ihop == casscf.ah_max_cycle or # make sure to use the last step ((norm_residual < casscf.ah_start_tol) and (ihop >= casscf.ah_start_cycle)) or (seig < casscf.ah_lindep)): stat.imic += 1 dxmax = abs(dxi).max() dxi, hdxi = scale_down_step(dxi, hdxi) dr += dxi g_all = g_all + hdxi norm_dr = numpy.linalg.norm(dr) norm_gall = numpy.linalg.norm(g_all) norm_gorb = numpy.linalg.norm(g_all[:ngorb]) norm_gci = numpy.linalg.norm(g_all[ngorb:]) log.debug(' imic %d(%d) |g|=%3.2e (%2.1e %2.1e) |dxi|=%3.2e ' 'max(x)=%3.2e |dr|=%3.2e eig=%2.1e seig=%2.1e', stat.imic, ihop, norm_gall, norm_gorb, norm_gci, numpy.linalg.norm(dxi), dxmax, norm_dr, w, seig) max_cycle = max(casscf.max_cycle_micro, casscf.max_cycle_micro-int(numpy.log(norm_gkf+1e-7)*2)) log.debug1('Set max_cycle %d', max_cycle) ikf += 1 if stat.imic > 3 and norm_gall > norm_gkf*casscf.ah_grad_trust_region: g_all = g_all - hdxi dr -= dxi norm_gall = numpy.linalg.norm(g_all) log.debug('|g| >> keyframe, Restore previouse step') break elif (stat.imic >= max_cycle or norm_gall < conv_tol_grad*.3): break elif ((ikf >= max(casscf.kf_interval, casscf.kf_interval-numpy.log(norm_dr+1e-7)) or # Insert keyframe if the keyframe and the esitimated grad are too different norm_gall < norm_gkf/casscf.kf_trust_region)): ikf = 0 u, ci_kf = extract_rotation(casscf, dr, u, ci_kf) dr[:] = 0 g_kf1 = g_update(u, ci_kf) stat.tot_kf += 1 norm_gkf1 = numpy.linalg.norm(g_kf1) norm_gorb = numpy.linalg.norm(g_kf1[:ngorb]) norm_gci = numpy.linalg.norm(g_kf1[ngorb:]) norm_dg = numpy.linalg.norm(g_kf1-g_all) log.debug('Adjust keyframe to |g|= %4.3g (%4.3g %4.3g) ' '|g-correction|= %4.3g', norm_gkf1, norm_gorb, norm_gci, norm_dg) if (norm_dg < norm_gall*casscf.ah_grad_trust_region # kf not too diff #or norm_gkf1 < norm_gkf # grad is decaying # close to solution or norm_gkf1 < conv_tol_grad*casscf.ah_grad_trust_region): g_all = g_kf = g_kf1 g_kf1 = None norm_gall = norm_gkf = norm_gkf1 else: g_all = g_all - hdxi dr -= dxi norm_gall = norm_gkf = numpy.linalg.norm(g_all) log.debug('Out of trust region. Restore previouse step') break u, ci_kf = extract_rotation(casscf, dr, u, ci_kf) log.debug(' tot inner=%d |g|= %4.3g (%4.3g %4.3g) |u-1|= %4.3g |dci|= %4.3g', stat.imic, norm_gall, norm_gorb, norm_gci, numpy.linalg.norm(u-numpy.eye(nmo)), numpy.linalg.norm(ci_kf-ci0)) return u, ci_kf, norm_gkf, stat, dxi
def _rotate_orb_cc(mf, h1e, s1e, conv_tol_grad=None, verbose=None): log = logger.new_logger(mf, verbose) if conv_tol_grad is None: conv_tol_grad = numpy.sqrt(mf.conv_tol * .1) #TODO: dynamically adjust max_stepsize, as done in mc1step.py def precond(x, e): hdiagd = h_diag - (e - mf.ah_level_shift) hdiagd[abs(hdiagd) < 1e-8] = 1e-8 x = x / hdiagd ## Because of DFT, donot norm to 1 which leads 1st DM too large. # norm_x = numpy.linalg.norm(x) # if norm_x < 1e-2: # x *= 1e-2/norm_x return x t3m = (time.clock(), time.time()) u = g_kf = g_orb = kfcount = jkcount = None dm0 = vhf0 = None g_op = lambda: g_orb while True: mo_coeff, mo_occ, dm0, vhf0, e_tot = (yield u, g_kf, kfcount, jkcount, dm0, vhf0) fock_ao = mf.get_fock(h1e, s1e, vhf0, dm0) g_kf, h_op, h_diag = mf.gen_g_hop(mo_coeff, mo_occ, fock_ao) norm_gkf = numpy.linalg.norm(g_kf) if g_orb is None: log.debug(' |g|= %4.3g (keyframe)', norm_gkf) kf_trust_region = mf.kf_trust_region x0_guess = g_kf else: norm_dg = numpy.linalg.norm(g_kf - g_orb) log.debug(' |g|= %4.3g (keyframe), |g-correction|= %4.3g', norm_gkf, norm_dg) kf_trust_region = min( max(norm_gorb / (norm_dg + 1e-9), mf.kf_trust_region), 10) log.debug1('Set kf_trust_region = %g', kf_trust_region) x0_guess = dxi g_orb = g_kf norm_gorb = norm_gkf ah_conv_tol = min(norm_gorb**2, mf.ah_conv_tol) # increase the AH accuracy when approach convergence #ah_start_cycle = max(mf.ah_start_cycle, int(-numpy.log10(norm_gorb))) ah_start_cycle = mf.ah_start_cycle imic = 0 dr = 0 ukf = None jkcount = 0 kfcount = 0 ikf = 0 for ah_end, ihop, w, dxi, hdxi, residual, seig \ in ciah.davidson_cc(h_op, g_op, precond, x0_guess, tol=ah_conv_tol, max_cycle=mf.ah_max_cycle, lindep=mf.ah_lindep, verbose=log): norm_residual = numpy.linalg.norm(residual) ah_start_tol = min(norm_gorb * 5, mf.ah_start_tol) if (ah_end or ihop == mf.ah_max_cycle or # make sure to use the last step ((norm_residual < ah_start_tol) and (ihop >= ah_start_cycle)) or (seig < mf.ah_lindep)): imic += 1 dxmax = numpy.max(abs(dxi)) if dxmax > mf.max_stepsize: scale = mf.max_stepsize / dxmax log.debug1('... scale rotation size %g', scale) dxi *= scale hdxi *= scale else: scale = None dr = dr + dxi g_orb = g_orb + hdxi norm_dr = numpy.linalg.norm(dr) norm_gorb = numpy.linalg.norm(g_orb) norm_dxi = numpy.linalg.norm(dxi) log.debug( ' imic %d(%d) |g|= %4.3g |dxi|= %4.3g ' 'max(|x|)= %4.3g |dr|= %4.3g eig= %4.3g seig= %4.3g', imic, ihop, norm_gorb, norm_dxi, dxmax, norm_dr, w, seig) max_cycle = max( mf.max_cycle_inner, mf.max_cycle_inner - int(numpy.log(norm_gkf + 1e-9) * 2)) log.debug1( 'Set ah_start_tol %g, ah_start_cycle %d, max_cycle %d', ah_start_tol, ah_start_cycle, max_cycle) ikf += 1 if imic > 3 and norm_gorb > norm_gkf * mf.ah_grad_trust_region: g_orb = g_orb - hdxi dr -= dxi norm_gorb = numpy.linalg.norm(g_orb) log.debug('|g| >> keyframe, Restore previouse step') break elif (imic >= max_cycle or norm_gorb < conv_tol_grad / mf.ah_grad_trust_region): break elif ( ikf > 2 and # avoid frequent keyframe #TODO: replace it with keyframe_scheduler ( ikf >= max(mf.kf_interval, mf.kf_interval - numpy.log(norm_dr + 1e-9)) or # Insert keyframe if the keyframe and the esitimated g_orb are too different norm_gorb < norm_gkf / kf_trust_region)): ikf = 0 u = mf.update_rotate_matrix(dr, mo_occ, mo_coeff=mo_coeff) if ukf is not None: u = mf.rotate_mo(ukf, u) ukf = u dr[:] = 0 mo1 = mf.rotate_mo(mo_coeff, u) dm = mf.make_rdm1(mo1, mo_occ) # use mf._scf.get_veff to avoid density-fit mf polluting get_veff vhf0 = mf._scf.get_veff(mf._scf.mol, dm, dm_last=dm0, vhf_last=vhf0) dm0 = dm # Use API to compute fock instead of "fock=h1e+vhf0". This is because get_fock # is the hook being overloaded in many places. fock_ao = mf.get_fock(h1e, s1e, vhf0, dm0) g_kf1 = mf.get_grad(mo1, mo_occ, fock_ao) norm_gkf1 = numpy.linalg.norm(g_kf1) norm_dg = numpy.linalg.norm(g_kf1 - g_orb) jkcount += 1 kfcount += 1 if log.verbose >= logger.DEBUG: e_tot, e_last = mf._scf.energy_tot(dm, h1e, vhf0), e_tot log.debug( 'Adjust keyframe g_orb to |g|= %4.3g ' '|g-correction|=%4.3g E=%.12g dE=%.5g', norm_gkf1, norm_dg, e_tot, e_tot - e_last) if (norm_dg < norm_gorb * mf.ah_grad_trust_region # kf not too diff #or norm_gkf1 < norm_gkf # grad is decaying # close to solution or norm_gkf1 < conv_tol_grad * mf.ah_grad_trust_region): kf_trust_region = min( max(norm_gorb / (norm_dg + 1e-9), mf.kf_trust_region), 10) log.debug1('Set kf_trust_region = %g', kf_trust_region) g_orb = g_kf = g_kf1 norm_gorb = norm_gkf = norm_gkf1 else: g_orb = g_orb - hdxi dr -= dxi norm_gorb = numpy.linalg.norm(g_orb) log.debug( 'Out of trust region. Restore previouse step') break u = mf.update_rotate_matrix(dr, mo_occ, mo_coeff=mo_coeff) if ukf is not None: u = mf.rotate_mo(ukf, u) jkcount += ihop + 1 log.debug(' tot inner=%d %d JK |g|= %4.3g |u-1|= %4.3g', imic, jkcount, norm_gorb, numpy.linalg.norm(dr)) h_op = h_diag = None t3m = log.timer('aug_hess in %d inner iters' % imic, *t3m)
def rotate_orb_cc(mf, mo_coeff, mo_occ, fock_ao, h1e, conv_tol_grad=None, max_stepsize=None, verbose=None): log = logger.new_logger(mf, verbose) if conv_tol_grad is None: conv_tol_grad = numpy.sqrt(mf.conv_tol*.1) #TODO: dynamically adjust max_stepsize, as done in mc1step.py t2m = (time.clock(), time.time()) g_orb, h_op, h_diag = mf.gen_g_hop(mo_coeff, mo_occ, fock_ao) g_kf = g_orb norm_gkf = norm_gorb = numpy.linalg.norm(g_orb) log.debug(' |g|= %4.3g (keyframe)', norm_gorb) t3m = log.timer('gen h_op', *t2m) def precond(x, e): hdiagd = h_diag-(e-mf.ah_level_shift) hdiagd[abs(hdiagd)<1e-8] = 1e-8 x = x/hdiagd ## Because of DFT, donot norm to 1 which leads 1st DM too large. # norm_x = numpy.linalg.norm(x) # if norm_x < 1e-2: # x *= 1e-2/norm_x return x g_op = lambda: g_orb x0_guess = g_orb kf_trust_region = mf.kf_trust_region while True: ah_conv_tol = min(norm_gorb**2, mf.ah_conv_tol) # increase the AH accuracy when approach convergence #ah_start_cycle = max(mf.ah_start_cycle, int(-numpy.log10(norm_gorb))) ah_start_cycle = mf.ah_start_cycle imic = 0 dr = 0 ukf = None jkcount = 0 kfcount = 0 ikf = 0 dm0 = mf.make_rdm1(mo_coeff, mo_occ) # NOTE: vhf0 cannot be computed as (fock_ao - h1e) because mf.get_fock # may be overloaded and fock_ao != h1e + vhf0 vhf0 = mf._scf.get_veff(mf._scf.mol, dm0) for ah_end, ihop, w, dxi, hdxi, residual, seig \ in ciah.davidson_cc(h_op, g_op, precond, x0_guess, tol=ah_conv_tol, max_cycle=mf.ah_max_cycle, lindep=mf.ah_lindep, verbose=log): norm_residual = numpy.linalg.norm(residual) ah_start_tol = min(norm_gorb*5, mf.ah_start_tol) if (ah_end or ihop == mf.ah_max_cycle or # make sure to use the last step ((norm_residual < ah_start_tol) and (ihop >= ah_start_cycle)) or (seig < mf.ah_lindep)): imic += 1 dxmax = numpy.max(abs(dxi)) if dxmax > mf.max_stepsize: scale = mf.max_stepsize / dxmax log.debug1('... scale rotation size %g', scale) dxi *= scale hdxi *= scale else: scale = None dr = dr + dxi g_orb = g_orb + hdxi norm_dr = numpy.linalg.norm(dr) norm_gorb = numpy.linalg.norm(g_orb) norm_dxi = numpy.linalg.norm(dxi) log.debug(' imic %d(%d) |g|= %4.3g |dxi|= %4.3g ' 'max(|x|)= %4.3g |dr|= %4.3g eig= %4.3g seig= %4.3g', imic, ihop, norm_gorb, norm_dxi, dxmax, norm_dr, w, seig) max_cycle = max(mf.max_cycle_inner, mf.max_cycle_inner-int(numpy.log(norm_gkf+1e-9)*2)) log.debug1('Set ah_start_tol %g, ah_start_cycle %d, max_cycle %d', ah_start_tol, ah_start_cycle, max_cycle) ikf += 1 if imic > 3 and norm_gorb > norm_gkf*mf.ah_grad_trust_region: g_orb = g_orb - hdxi dr -= dxi norm_gorb = numpy.linalg.norm(g_orb) log.debug('|g| >> keyframe, Restore previouse step') break elif (imic >= max_cycle or norm_gorb < conv_tol_grad*.5): break elif (ikf > 2 and # avoid frequent keyframe #TODO: replace it with keyframe_scheduler (ikf >= max(mf.kf_interval, mf.kf_interval-numpy.log(norm_dr+1e-9)) or # Insert keyframe if the keyframe and the esitimated g_orb are too different norm_gorb < norm_gkf/kf_trust_region)): ikf = 0 u = mf.update_rotate_matrix(dr, mo_occ, mo_coeff=mo_coeff) if ukf is not None: u = mf.rotate_mo(ukf, u) ukf = u dr[:] = 0 mo1 = mf.rotate_mo(mo_coeff, u) dm = mf.make_rdm1(mo1, mo_occ) # use mf._scf.get_veff to avoid density-fit mf polluting get_veff vhf0 = mf._scf.get_veff(mf._scf.mol, dm, dm_last=dm0, vhf_last=vhf0) kfcount += 1 dm0 = dm # Use API to compute fock instead of "fock=h1e+vhf0". This is because get_fock # is the hook being overloaded in many places. fock = mf.get_fock(h1e, vhf=vhf0) g_kf1 = mf.get_grad(mo1, mo_occ, fock) norm_gkf1 = numpy.linalg.norm(g_kf1) norm_dg = numpy.linalg.norm(g_kf1-g_orb) jkcount += 1 log.debug('Adjust keyframe g_orb to |g|= %4.3g ' '|g-correction|= %4.3g', norm_gkf1, norm_dg) if (norm_dg < norm_gorb*mf.ah_grad_trust_region # kf not too diff #or norm_gkf1 < norm_gkf # grad is decaying # close to solution or norm_gkf1 < conv_tol_grad*mf.ah_grad_trust_region): kf_trust_region = min(max(norm_gorb/(norm_dg+1e-9), mf.kf_trust_region), 10) log.debug1('Set kf_trust_region = %g', kf_trust_region) g_orb = g_kf = g_kf1 norm_gorb = norm_gkf = norm_gkf1 else: g_orb = g_orb - hdxi dr -= dxi norm_gorb = numpy.linalg.norm(g_orb) log.debug('Out of trust region. Restore previouse step') break u = mf.update_rotate_matrix(dr, mo_occ, mo_coeff=mo_coeff) if ukf is not None: u = mf.rotate_mo(ukf, u) jkcount += ihop + 1 log.debug(' tot inner=%d %d JK |g|= %4.3g |u-1|= %4.3g', imic, jkcount, norm_gorb, numpy.linalg.norm(dr)) h_op = h_diag = None t3m = log.timer('aug_hess in %d inner iters' % imic, *t3m) mo_coeff, mo_occ, fock_ao = (yield u, g_kf, kfcount, jkcount) g_kf, h_op, h_diag = mf.gen_g_hop(mo_coeff, mo_occ, fock_ao) norm_gkf = numpy.linalg.norm(g_kf) norm_dg = numpy.linalg.norm(g_kf-g_orb) log.debug(' |g|= %4.3g (keyframe), |g-correction|= %4.3g', norm_gkf, norm_dg) kf_trust_region = min(max(norm_gorb/(norm_dg+1e-9), mf.kf_trust_region), 10) log.debug1('Set kf_trust_region = %g', kf_trust_region) g_orb = g_kf norm_gorb = norm_gkf if norm_dxi != 0: x0_guess = dxi else: x0_guess = g_kf