def _regular_step(heff, ovlp, xs, lindep, log): try: e, c = scipy.linalg.eigh(heff[1:, 1:], ovlp[1:, 1:]) except scipy.linalg.LinAlgError: e, c = lib.safe_eigh(heff[1:, 1:], ovlp[1:, 1:], lindep)[:2] if numpy.any(e < -1e-5): log.debug('Negative hessians found %s', e[e < 0]) w, v, seig = lib.safe_eigh(heff, ovlp, lindep) if log.verbose >= logger.DEBUG3: numpy.set_printoptions(3, linewidth=1000) log.debug3('v[0] %s', v[0]) log.debug3('AH eigs %s', w) numpy.set_printoptions(8, linewidth=75) #if e[0] < -.1: # sel = 0 #else: # There exists systems that the first eigenvalue of AH is -inf. # Dynamically choosing the eigenvectors may be better. idx = numpy.where(abs(v[0]) > 0.1)[0] sel = idx[0] log.debug1('CIAH eigen-sel %s', sel) w_t = w[sel] xtrial = _dgemv(v[1:, sel] / v[0, sel], xs) return xtrial, w_t, v[:, sel], sel, seig
def _regular_step(heff, ovlp, xs, lindep, log): try: e, c = scipy.linalg.eigh(heff[1:, 1:], ovlp[1:, 1:]) except scipy.linalg.LinAlgError: e, c = lib.safe_eigh(heff[1:, 1:], ovlp[1:, 1:], lindep)[:2] if e[0] < -1e-5: log.debug('Negative hessians found %s', e[e < 0]) log.debug('AH is shifted to avoid negative hessians') heff = heff.copy() sc = numpy.dot(ovlp[1:, 1:], c) e[(-0.1 < e) & (e < 0)] = .1 e = abs(e) heff[1:, 1:] = numpy.dot(sc * e, sc.T.conj()) w, v, seig = lib.safe_eigh(heff, ovlp, lindep) if log.verbose >= logger.DEBUG3: numpy.set_printoptions(3, linewidth=1000) log.debug3('v[0] %s', v[0]) log.debug3('AH eigs %s', w) numpy.set_printoptions(8, linewidth=75) idx = numpy.where(abs(v[0]) > 0.1)[0] sel = idx[0] #sel = 0 w_t = w[sel] xtrial = _dgemv(v[1:, sel] / v[0, sel], xs) return xtrial, w_t, v[:, sel], sel, seig
def _regular_step(heff, ovlp, xs, lindep, log): try: e, c = scipy.linalg.eigh(heff[1:,1:], ovlp[1:,1:]) except scipy.linalg.LinAlgError: e, c = lib.safe_eigh(heff[1:,1:], ovlp[1:,1:], lindep)[:2] if numpy.any(e < -1e-5): log.debug('Negative hessians found %s', e[e<0]) w, v, seig = lib.safe_eigh(heff, ovlp, lindep) if log.verbose >= logger.DEBUG3: numpy.set_printoptions(3, linewidth=1000) log.debug3('v[0] %s', v[0]) log.debug3('AH eigs %s', w) numpy.set_printoptions(8, linewidth=75) #if e[0] < -.1: # sel = 0 #else: # There exists systems that the first eigenvalue of AH is -inf. # Dynamically choosing the eigenvectors may be better. idx = numpy.where(abs(v[0]) > 0.1)[0] sel = idx[0] log.debug1('CIAH eigen-sel %s', sel) w_t = w[sel] xtrial = _dgemv(v[1:,sel]/v[0,sel], xs) return xtrial, w_t, v[:,sel], sel, seig
def _regular_step(heff, ovlp, xs, lindep, log): try: e, c = scipy.linalg.eigh(heff[1:,1:], ovlp[1:,1:]) except scipy.linalg.LinAlgError: e, c = lib.safe_eigh(heff[1:,1:], ovlp[1:,1:], lindep)[:2] if e[0] < -1e-5: log.debug('Negative hessians found %s', e[e<0]) w, v, seig = lib.safe_eigh(heff, ovlp, lindep) if log.verbose >= logger.DEBUG3: numpy.set_printoptions(3, linewidth=1000) log.debug3('v[0] %s', v[0]) log.debug3('AH eigs %s', w) numpy.set_printoptions(8, linewidth=75) if e[0] < -.1: sel = 0 else: idx = numpy.where(abs(v[0]) > 0.1)[0] sel = idx[0] w_t = w[sel] xtrial = _dgemv(v[1:,sel]/v[0,sel], xs) return xtrial, w_t, v[:,sel], sel, seig
def solve_approx_ci(self, h1, h2, ci0, ecore, e_ci, envs): ''' Solve CI eigenvalue/response problem approximately ''' ncas = self.ncas nelecas = self.nelecas ncore = self.ncore nocc = ncore + ncas if 'norm_gorb' in envs: tol = max(self.conv_tol, envs['norm_gorb']**2*.1) else: tol = None if hasattr(self.fcisolver, 'approx_kernel'): ci1 = self.fcisolver.approx_kernel(h1, h2, ncas, nelecas, ci0=ci0, tol=tol, max_memory=self.max_memory)[1] return ci1, None h2eff = self.fcisolver.absorb_h1e(h1, h2, ncas, nelecas, .5) hc = self.fcisolver.contract_2e(h2eff, ci0, ncas, nelecas).ravel() g = hc - (e_ci-ecore) * ci0.ravel() if self.ci_response_space > 7: logger.debug(self, 'CI step by full response') # full response max_memory = max(400, self.max_memory-lib.current_memory()[0]) e, ci1 = self.fcisolver.kernel(h1, h2, ncas, nelecas, ci0=ci0, tol=tol, max_memory=max_memory) else: nd = min(max(self.ci_response_space, 2), ci0.size) logger.debug(self, 'CI step by %dD subspace response', nd) xs = [ci0.ravel()] ax = [hc] heff = numpy.empty((nd,nd)) seff = numpy.empty((nd,nd)) heff[0,0] = numpy.dot(xs[0], ax[0]) seff[0,0] = 1 for i in range(1, nd): xs.append(ax[i-1] - xs[i-1] * e_ci) ax.append(self.fcisolver.contract_2e(h2eff, xs[i], ncas, nelecas).ravel()) for j in range(i+1): heff[i,j] = heff[j,i] = numpy.dot(xs[i], ax[j]) seff[i,j] = seff[j,i] = numpy.dot(xs[i], xs[j]) e, v = lib.safe_eigh(heff, seff)[:2] ci1 = xs[0] * v[0,0] for i in range(1,nd): ci1 += xs[i] * v[i,0] return ci1, g
def _regular_step(heff, ovlp, xs, lindep, log): w, v, seig = lib.safe_eigh(heff, ovlp, lindep) if log.verbose >= logger.DEBUG3: numpy.set_printoptions(3, linewidth=1000) log.debug3('v[0] %s', v[0]) log.debug3('AH eigs %s', w) log.debug3('H eigs %s', scipy.linalg.eigh(heff[1:, 1:])[0]) numpy.set_printoptions(8, linewidth=75) idx = numpy.where(abs(v[0]) > 0.1)[0] sel = idx[0] if w[sel] < -1e-5: log.debug1('AH might follow negative hessians %s', w[:sel]) w_t = w[sel] xtrial = _dgemv(v[1:, sel] / v[0, sel], xs) return xtrial, w_t, v[:, sel], sel, seig
def _regular_step(heff, ovlp, xs, lindep, log): w, v, seig = lib.safe_eigh(heff, ovlp, lindep) if log.verbose >= logger.DEBUG3: numpy.set_printoptions(3, linewidth=1000) log.debug3('v[0] %s', v[0]) log.debug3('AH eigs %s', w) log.debug3('H eigs %s', scipy.linalg.eigh(heff[1:,1:])[0]) numpy.set_printoptions(8, linewidth=75) idx = numpy.where(abs(v[0]) > 0.1)[0] sel = idx[0] if w[sel] < -1e-5: log.debug1('AH might follow negative hessians %s', w[:sel]) w_t = w[sel] xtrial = _dgemv(v[1:,sel]/v[0,sel], xs) return xtrial, w_t, v[:,sel], sel, seig
def solve_approx_ci(self, h1, h2, ci0, ecore, e_ci): ''' Solve CI eigenvalue/response problem approximately ''' ncas = self.ncas nelecas = self.nelecas ncore = self.ncore nocc = ncore + ncas if hasattr(self.fcisolver, 'approx_kernel'): ci1 = self.fcisolver.approx_kernel(h1, h2, ncas, nelecas, ci0=ci0)[1] return ci1, None h2eff = self.fcisolver.absorb_h1e(h1, h2, ncas, nelecas, .5) hc = self.fcisolver.contract_2e(h2eff, ci0, ncas, nelecas).ravel() g = hc - (e_ci - ecore) * ci0.ravel() if self.ci_response_space > 7: logger.debug(self, 'CI step by full response') # full response e, ci1 = self.fcisolver.kernel(h1, h2, ncas, nelecas, ci0=ci0) else: nd = min(max(self.ci_response_space, 2), ci0.size) logger.debug(self, 'CI step by %dD subspace response', nd) xs = [ci0.ravel()] ax = [hc] heff = numpy.empty((nd, nd)) seff = numpy.empty((nd, nd)) heff[0, 0] = numpy.dot(xs[0], ax[0]) seff[0, 0] = 1 for i in range(1, nd): xs.append(ax[i - 1] - xs[i - 1] * e_ci) ax.append( self.fcisolver.contract_2e(h2eff, xs[i], ncas, nelecas).ravel()) for j in range(i + 1): heff[i, j] = heff[j, i] = numpy.dot(xs[i], ax[j]) seff[i, j] = seff[j, i] = numpy.dot(xs[i], xs[j]) e, v = lib.safe_eigh(heff, seff)[:2] ci1 = xs[0] * v[0, 0] for i in range(1, nd): ci1 += xs[i] * v[i, 0] return ci1, g
def solve_approx_ci(self, h1, h2, ci0, ecore, e_ci, envs): ''' Solve CI eigenvalue/response problem approximately ''' ncas = self.ncas nelecas = self.nelecas ncore = self.ncore nocc = ncore + ncas if 'norm_gorb' in envs: tol = max(self.conv_tol, envs['norm_gorb']**2 * .1) else: tol = None if hasattr(self.fcisolver, 'approx_kernel'): fn = self.fcisolver.approx_kernel ci1 = fn(h1, h2, ncas, nelecas, ci0=ci0, tol=tol, max_memory=self.max_memory)[1] return ci1, None elif not (hasattr(self.fcisolver, 'contract_2e') and hasattr(self.fcisolver, 'absorb_h1e')): fn = self.fcisolver.kernel ci1 = fn(h1, h2, ncas, nelecas, ci0=ci0, tol=tol, max_memory=self.max_memory, max_cycle=self.ci_response_space)[1] return ci1, None h2eff = self.fcisolver.absorb_h1e(h1, h2, ncas, nelecas, .5) hc = self.fcisolver.contract_2e(h2eff, ci0, ncas, nelecas).ravel() g = hc - (e_ci - ecore) * ci0.ravel() if self.ci_response_space > 7: logger.debug(self, 'CI step by full response') # full response max_memory = max(400, self.max_memory - lib.current_memory()[0]) e, ci1 = self.fcisolver.kernel(h1, h2, ncas, nelecas, ci0=ci0, tol=tol, max_memory=max_memory) else: nd = min(max(self.ci_response_space, 2), ci0.size) logger.debug(self, 'CI step by %dD subspace response', nd) xs = [ci0.ravel()] ax = [hc] heff = numpy.empty((nd, nd)) seff = numpy.empty((nd, nd)) heff[0, 0] = numpy.dot(xs[0], ax[0]) seff[0, 0] = 1 for i in range(1, nd): xs.append(ax[i - 1] - xs[i - 1] * e_ci) ax.append( self.fcisolver.contract_2e(h2eff, xs[i], ncas, nelecas).ravel()) for j in range(i + 1): heff[i, j] = heff[j, i] = numpy.dot(xs[i], ax[j]) seff[i, j] = seff[j, i] = numpy.dot(xs[i], xs[j]) e, v = lib.safe_eigh(heff, seff)[:2] ci1 = xs[0] * v[0, 0] for i in range(1, nd): ci1 += xs[i] * v[i, 0] return ci1, g
def solve_approx_ci_csf(mc, h1, h2, ci0, ecore, e_cas, envs): ''' This is identical to pyscf.mcscf.mc1step.CASSCF.solve_approx_ci (with %s/self/mc/g) as of 03/24/2019 for the first 48 lines ''' ncas = mc.ncas nelecas = mc.nelecas ncore = mc.ncore nocc = ncore + ncas if 'norm_gorb' in envs: tol = max(mc.conv_tol, envs['norm_gorb']**2 * .1) else: tol = None if getattr(mc.fcisolver, 'approx_kernel', None): fn = mc.fcisolver.approx_kernel e, ci1 = fn(h1, h2, ncas, nelecas, ecore=ecore, ci0=ci0, tol=tol, max_memory=mc.max_memory) return ci1, None elif not (getattr(mc.fcisolver, 'contract_2e', None) and getattr(mc.fcisolver, 'absorb_h1e', None)): fn = mc.fcisolver.kernel e, ci1 = fn(h1, h2, ncas, nelecas, ecore=ecore, ci0=ci0, tol=tol, max_memory=mc.max_memory, max_cycle=mc.ci_response_space) return ci1, None h2eff = mc.fcisolver.absorb_h1e(h1, h2, ncas, nelecas, .5) # Be careful with the symmetry adapted contract_2e function. When the # symmetry adapted FCI solver is used, the symmetry of ci0 may be # different to fcisolver.wfnsym. This function may output 0. if getattr(mc.fcisolver, 'guess_wfnsym', None): wfnsym = mc.fcisolver.guess_wfnsym(mc.ncas, mc.nelecas, ci0) else: wfnsym = None def contract_2e(c): if wfnsym is None: hc = mc.fcisolver.contract_2e(h2eff, c, ncas, nelecas) else: with lib.temporary_env(mc.fcisolver, wfnsym=wfnsym): hc = mc.fcisolver.contract_2e(h2eff, c, ncas, nelecas) return hc.ravel() hc = contract_2e(ci0) g = hc - (e_cas - ecore) * ci0.ravel() if mc.ci_response_space > 7: logger.debug(mc, 'CI step by full response') # full response max_memory = max(400, mc.max_memory - lib.current_memory()[0]) e, ci1 = mc.fcisolver.kernel(h1, h2, ncas, nelecas, ecore=ecore, ci0=ci0, tol=tol, max_memory=max_memory) else: # MRH 03/24/2019: this is where I intervene to enforce CSFs fci = mc.fcisolver smult = fci.smult neleca, nelecb = _unpack_nelec(nelecas) norb = np.asarray(h1).shape[-1] if hasattr(fci, 'wfnsym') and hasattr(fci, 'confsym'): idx_sym = fci.confsym[fci.econf_csf_mask] == fci.wfnsym else: idx_sym = None xs = [ csf.pack_sym_ci( transform_civec_det2csf(ci0, norb, neleca, nelecb, smult, csd_mask=fci.csd_mask, do_normalize=True)[0], idx_sym) ] nd = min(max(mc.ci_response_space, 2), xs[0].size) logger.debug(mc, 'CI step by %dD subspace response', nd) def contract_2e_csf(x): x_det = transform_civec_csf2det(csf.unpack_sym_ci(x, idx_sym), norb, neleca, nelecb, smult, csd_mask=fci.csd_mask)[0] hx = contract_2e(x_det) hx = transform_civec_det2csf(hx, norb, neleca, nelecb, smult, csd_mask=fci.csd_mask, do_normalize=False)[0] return csf.pack_sym_ci(hx, idx_sym).ravel() ax = [contract_2e_csf(xs[0])] heff = np.empty((nd, nd)) seff = np.empty((nd, nd)) heff[0, 0] = np.dot(xs[0], ax[0]) seff[0, 0] = 1 for i in range(1, nd): xs.append(ax[i - 1] - xs[i - 1] * e_cas) ax.append(contract_2e_csf(xs[i])) for j in range(i + 1): heff[i, j] = heff[j, i] = (xs[i] * ax[j]).sum() seff[i, j] = seff[j, i] = (xs[i] * xs[j]).sum() e, v = lib.safe_eigh(heff, seff)[:2] ci1 = xs[0] * v[0, 0] for i in range(1, nd): ci1 += xs[i] * v[i, 0] ci1 = transform_civec_csf2det(csf.unpack_sym_ci(ci1, idx_sym), norb, neleca, nelecb, smult, csd_mask=fci.csd_mask, do_normalize=True)[0] return ci1, g