コード例 #1
0
def uhf_external(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop1, hdiag1, hop2, hdiag2 = _gen_hop_uhf_external(mf, with_symmetry)

    def precond(dx, e, x0):
        hdiagd = hdiag1 - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    x0 = numpy.zeros_like(hdiag1)
    x0[hdiag1 > 1e-5] = 1. / hdiag1[hdiag1 > 1e-5]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag1)] = 1
    e1, v = lib.davidson(hop1, x0, precond, tol=1e-4, verbose=log)
    if e1 < -1e-5:
        log.note('UHF/UKS wavefunction has a real -> complex instablity')
    else:
        log.note(
            'UHF/UKS wavefunction is stable in the real -> complex stability analysis'
        )

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    x0 = numpy.zeros_like(hdiag2)
    x0[hdiag2 > 1e-5] = 1. / hdiag2[hdiag2 > 1e-5]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag2)] = 1
    e3, v = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    log.debug('uhf_external: lowest eigs of H = %s', e3)
    mo = scipy.linalg.block_diag(*mf.mo_coeff)
    if e3 < -1e-5:
        log.note('UHF/UKS wavefunction has an UHF/UKS -> GHF/GKS instablity.')
        occidxa = numpy.where(mf.mo_occ[0] > 0)[0]
        viridxa = numpy.where(mf.mo_occ[0] == 0)[0]
        occidxb = numpy.where(mf.mo_occ[1] > 0)[0]
        viridxb = numpy.where(mf.mo_occ[1] == 0)[0]
        nocca = len(occidxa)
        nvira = len(viridxa)
        noccb = len(occidxb)
        nvirb = len(viridxb)
        nmo = nocca + nvira
        dx = numpy.zeros((nmo * 2, nmo * 2))
        dx[viridxa[:, None],
           nmo + occidxb] = v[:nvira * noccb].reshape(nvira, noccb)
        dx[nmo + viridxb[:, None],
           occidxa] = v[nvira * noccb:].reshape(nvirb, nocca)
        u = newton_ah.expmat(dx - dx.conj().T)
        mo = numpy.dot(mo, u)
        mo = numpy.hstack([
            mo[:, :nocca], mo[:, nmo:nmo + noccb], mo[:, nocca:nmo],
            mo[:, nmo + noccb:]
        ])
    else:
        log.note(
            'UHF/UKS wavefunction is stable in the UHF/UKS -> GHF/GKS stability analysis'
        )
    return mo
コード例 #2
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def rhf_external(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop1, hdiag1, hop2, hdiag2 = _gen_hop_rhf_external(mf, with_symmetry)

    def precond(dx, e, x0):
        hdiagd = hdiag1 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = numpy.zeros_like(hdiag1)
    x0[hdiag1>1e-5] = 1. / hdiag1[hdiag1>1e-5]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag1)] = 1
    e1, v1 = lib.davidson(hop1, x0, precond, tol=1e-4, verbose=log)
    if e1 < -1e-5:
        log.note('RHF/RKS wavefunction has a real -> complex instablity')
    else:
        log.note('RHF/RKS wavefunction is stable in the real -> complex stability analysis')

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = v1
    e3, v3 = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    if e3 < -1e-5:
        log.note('RHF/RKS wavefunction has a RHF/RKS -> UHF/UKS instablity.')
        mo = (_rotate_mo(mf.mo_coeff, mf.mo_occ, v3), mf.mo_coeff)
    else:
        log.note('RHF/RKS wavefunction is stable in the RHF/RKS -> UHF/UKS stability analysis')
        mo = (mf.mo_coeff, mf.mo_coeff)
    return mo
コード例 #3
0
ファイル: stability.py プロジェクト: xlzan/pyscf
def rhf_external(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop1, hdiag1, hop2, hdiag2 = _gen_hop_rhf_external(mf, with_symmetry)

    def precond(dx, e, x0):
        hdiagd = hdiag1 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = numpy.zeros_like(hdiag1)
    x0[hdiag1>1e-5] = 1. / hdiag1[hdiag1>1e-5]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag1)] = 1
    e1, v1 = lib.davidson(hop1, x0, precond, tol=1e-4, verbose=log)
    if e1 < -1e-5:
        log.note('RHF/RKS wavefunction has a real -> complex instablity')
    else:
        log.note('RHF/RKS wavefunction is stable in the real -> complex stablity analysis')

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = v1
    e3, v3 = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    if e3 < -1e-5:
        log.note('RHF/RKS wavefunction has a RHF/RKS -> UHF/UKS instablity.')
        mo = (_rotate_mo(mf.mo_coeff, mf.mo_occ, v3), mf.mo_coeff)
    else:
        log.note('RHF/RKS wavefunction is stable in the RHF/RKS -> UHF/UKS stablity analysis')
        mo = (mf.mo_coeff, mf.mo_coeff)
    return mo
コード例 #4
0
ファイル: selected_ci_slow.py プロジェクト: chrinide/pyscf
def kernel(h1e, eri, norb, nelec, ecore=0, verbose=logger.NOTE):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
    namax = cistring.num_strings(norb, neleca)
    nbmax = cistring.num_strings(norb, nelecb)

    myci = SelectedCI()

    strsa = [int('1'*neleca, 2)]
    strsb = [int('1'*nelecb, 2)]
    ci_strs = (strsa, strsb)
    ci0 = numpy.ones((1,1))
    ci0, ci_strs = enlarge_space(myci, (ci0, ci_strs), h2e, norb, nelec)

    def all_linkstr_index(ci_strs):
        cd_indexa = cre_des_linkstr(ci_strs[0], norb, neleca)
        dd_indexa = des_des_linkstr(ci_strs[0], norb, neleca)
        cd_indexb = cre_des_linkstr(ci_strs[1], norb, nelecb)
        dd_indexb = des_des_linkstr(ci_strs[1], norb, nelecb)
        return cd_indexa, dd_indexa, cd_indexb, dd_indexb

    def hop(c):
        hc = contract_2e(h2e, (c, ci_strs), norb, nelec, link_index)
        return hc.reshape(-1)
    precond = lambda x, e, *args: x/(hdiag-e+1e-4)

    e_last = 0
    tol = 1e-2
    conv = False
    for icycle in range(norb):
        tol = max(tol*1e-2, myci.float_tol)
        link_index = all_linkstr_index(ci_strs)
        hdiag = make_hdiag(h1e, eri, ci_strs, norb, nelec)
        e, ci0 = lib.davidson(hop, ci0.reshape(-1), precond, tol=tol,
                              verbose=verbose)
        print('icycle %d  ci.shape %s  E = %.15g' %
              (icycle, (len(ci_strs[0]), len(ci_strs[1])), e))
        if ci0.shape == (namax,nbmax) or abs(e-e_last) < myci.float_tol*10:
            conv = True
            break
        ci1, ci_strs = enlarge_space(myci, (ci0, ci_strs), h2e, norb, nelec)
        if ci1.size < ci0.size*1.02:
            conv = True
            break
        e_last = e
        ci0 = ci1

    link_index = all_linkstr_index(ci_strs)
    hdiag = make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, ci0 = lib.davidson(hop, ci0.reshape(-1), precond, tol=myci.conv_tol,
                          verbose=verbose)

    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    return e+ecore, (ci0.reshape(na,nb), ci_strs)
コード例 #5
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def uhf_external(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop1, hdiag1, hop2, hdiag2 = _gen_hop_uhf_external(mf, with_symmetry)

    def precond(dx, e, x0):
        hdiagd = hdiag1 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = numpy.zeros_like(hdiag1)
    x0[hdiag1>1e-5] = 1. / hdiag1[hdiag1>1e-5]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag1)] = 1
    e1, v = lib.davidson(hop1, x0, precond, tol=1e-4, verbose=log)
    if e1 < -1e-5:
        log.note('UHF/UKS wavefunction has a real -> complex instablity')
    else:
        log.note('UHF/UKS wavefunction is stable in the real -> complex stability analysis')

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = numpy.zeros_like(hdiag2)
    x0[hdiag2>1e-5] = 1. / hdiag2[hdiag2>1e-5]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag2)] = 1
    e3, v = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    log.debug('uhf_external: lowest eigs of H = %s', e3)
    mo = scipy.linalg.block_diag(*mf.mo_coeff)
    if e3 < -1e-5:
        log.note('UHF/UKS wavefunction has an UHF/UKS -> GHF/GKS instablity.')
        occidxa = numpy.where(mf.mo_occ[0]> 0)[0]
        viridxa = numpy.where(mf.mo_occ[0]==0)[0]
        occidxb = numpy.where(mf.mo_occ[1]> 0)[0]
        viridxb = numpy.where(mf.mo_occ[1]==0)[0]
        nocca = len(occidxa)
        nvira = len(viridxa)
        noccb = len(occidxb)
        nvirb = len(viridxb)
        nmo = nocca + nvira
        dx = numpy.zeros((nmo*2,nmo*2))
        dx[viridxa[:,None],nmo+occidxb] = v[:nvira*noccb].reshape(nvira,noccb)
        dx[nmo+viridxb[:,None],occidxa] = v[nvira*noccb:].reshape(nvirb,nocca)
        u = newton_ah.expmat(dx - dx.conj().T)
        mo = numpy.dot(mo, u)
        mo = numpy.hstack([mo[:,:nocca], mo[:,nmo:nmo+noccb],
                           mo[:,nocca:nmo], mo[:,nmo+noccb:]])
    else:
        log.note('UHF/UKS wavefunction is stable in the UHF/UKS -> GHF/GKS stability analysis')
    return mo
コード例 #6
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def uhf_internal(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_uhf(mf, mf.mo_coeff, mf.mo_occ,
                                            with_symmetry=with_symmetry)
    hdiag *= 2
    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    def hessian_x(x): # See comments in function rhf_internal
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g!=0] = 1. / hdiag[g!=0]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag)] = 1
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.note('UHF/UKS wavefunction has an internal instablity.')
        nocca = numpy.count_nonzero(mf.mo_occ[0]> 0)
        nvira = numpy.count_nonzero(mf.mo_occ[0]==0)
        mo = (_rotate_mo(mf.mo_coeff[0], mf.mo_occ[0], v[:nocca*nvira]),
              _rotate_mo(mf.mo_coeff[1], mf.mo_occ[1], v[nocca*nvira:]))
    else:
        log.note('UHF/UKS wavefunction is stable in the intenral stability analysis')
        mo = mf.mo_coeff
    return mo
コード例 #7
0
def rhf_internal(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_rhf(mf,
                                            mf.mo_coeff,
                                            mf.mo_occ,
                                            with_symmetry=with_symmetry)
    hdiag *= 2

    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    # The results of hop(x) corresponds to a displacement that reduces
    # gradients g.  It is the vir-occ block of the matrix vector product
    # (Hessian*x). The occ-vir block equals to x2.T.conj(). The overall
    # Hessian for internal reotation is x2 + x2.T.conj(). This is
    # the reason we apply (.real * 2) below
    def hessian_x(x):
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g != 0] = 1. / hdiag[g != 0]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag)] = 1
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.note('RHF/RKS wavefunction has an internal instablity')
        mo = _rotate_mo(mf.mo_coeff, mf.mo_occ, v)
    else:
        log.note(
            'RHF/RKS wavefunction is stable in the internal stability analysis'
        )
        mo = mf.mo_coeff
    return mo
コード例 #8
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def ghf_stability(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    with_symmetry = True
    g, hop, hdiag = newton_ah.gen_g_hop_ghf(mf, mf.mo_coeff, mf.mo_occ,
                                            with_symmetry=with_symmetry)
    hdiag *= 2
    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    def hessian_x(x): # See comments in function rhf_internal
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g!=0] = 1. / hdiag[g!=0]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag)] = 1
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.note('GHF wavefunction has an internal instablity')
        mo = _rotate_mo(mf.mo_coeff, mf.mo_occ, v)
    else:
        log.note('GHF wavefunction is stable in the intenral stability analysis')
        mo = mf.mo_coeff
    return mo
コード例 #9
0
def uhf_internal(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_uhf(mf,
                                            mf.mo_coeff,
                                            mf.mo_occ,
                                            with_symmetry=with_symmetry)
    hdiag *= 2

    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    def hessian_x(x):  # See comments in function rhf_internal
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g != 0] = 1. / hdiag[g != 0]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag)] = 1
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.note('UHF/UKS wavefunction has an internal instablity.')
        nocca = numpy.count_nonzero(mf.mo_occ[0] > 0)
        nvira = numpy.count_nonzero(mf.mo_occ[0] == 0)
        mo = (_rotate_mo(mf.mo_coeff[0], mf.mo_occ[0], v[:nocca * nvira]),
              _rotate_mo(mf.mo_coeff[1], mf.mo_occ[1], v[nocca * nvira:]))
    else:
        log.note(
            'UHF/UKS wavefunction is stable in the internal stability analysis'
        )
        mo = mf.mo_coeff
    return mo
コード例 #10
0
ファイル: direct_ep.py プロジェクト: MSwenne/BEP
def kernel(t,
           u,
           g,
           hpp,
           nsite,
           nelec,
           nphonon,
           tol=1e-9,
           max_cycle=100,
           verbose=0,
           ecore=0,
           **kwargs):
    cishape = make_shape(nsite, nelec, nphonon)
    ci0 = numpy.zeros(cishape)
    ci0.__setitem__((0, 0) + (0, ) * nsite, 1)
    # Add noise for initial guess, remove it if problematic
    ci0[0, :] += numpy.random.random(ci0[0, :].shape) * 1e-6
    ci0[:, 0] += numpy.random.random(ci0[:, 0].shape) * 1e-6

    def hop(c):
        hc = contract_all(t, u, g, hpp, c, nsite, nelec, nphonon)
        return hc.reshape(-1)

    hdiag = make_hdiag(t, u, g, hpp, nsite, nelec, nphonon)
    precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
    e, c = lib.davidson(hop,
                        ci0.reshape(-1),
                        precond,
                        tol=tol,
                        max_cycle=max_cycle,
                        verbose=verbose,
                        **kwargs)
    return e + ecore, c
コード例 #11
0
ファイル: stability.py プロジェクト: pyscf/pyscf
def rohf_internal(mf, with_symmetry=True, verbose=None, return_status=False):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_rohf(mf,
                                             mf.mo_coeff,
                                             mf.mo_occ,
                                             with_symmetry=with_symmetry)
    hdiag *= 2
    stable = True

    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    def hessian_x(x):  # See comments in function rhf_internal
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g != 0] = 1. / hdiag[g != 0]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag)] = 1
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.note(f'{mf.__class__} wavefunction has an internal instability.')
        mo = _rotate_mo(mf.mo_coeff, mf.mo_occ, v)
        stable = False
    else:
        log.note(f'{mf.__class__} wavefunction is stable in the internal '
                 'stability analysis')
        mo = mf.mo_coeff
    if return_status:
        return mo, stable
    else:
        return mo
コード例 #12
0
def uhf_internal(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_uhf(mf, mf.mo_coeff, mf.mo_occ)

    def precond(dx, e, x0):
        hdiagd = hdiag * 2 - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    def hessian_x(x):  # See comments in function rhf_internal
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g != 0] = 1. / hdiag[g != 0]
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.log('KUHF/KUKS wavefunction has an internal instability.')
        tot_x_a = sum(
            (occ > 0).sum() * (occ == 0).sum() for occ in mf.mo_occ[0])
        mo = (_rotate_mo(mf.mo_coeff[0], mf.mo_occ[0], v[:tot_x_a]),
              _rotate_mo(mf.mo_coeff[1], mf.mo_occ[1], v[tot_x_a:]))
    else:
        log.log(
            'KUHF/KUKS wavefunction is stable in the internal stability analysis'
        )
        mo = mf.mo_coeff
    return mo
コード例 #13
0
ファイル: idmrg.py プロジェクト: klgunst/OGDMRG
    def optimizeUnitCells(self, D, two_site, verbosity, rotate):
        """Optimizes the two unit cells.
        """
        for info in self._sweep(two_site):
            # Create the big site
            AA = self.make_center_site(two_site, info)
            diagonal = self.heff_diagonal(two_site, info)

            w, v = davidson(lambda x: self.Heff(x, two_site, info),
                            x0=AA.ravel(),
                            precond=diagonal)
            self.eigenval = w * self.sign

            print_info = {
                'sites': info['sites'],
                'fidelity': 1 - abs(np.dot(AA.ravel().conj(), v)),
                'energy': self.energy,
            }
            print_info = {
                **print_info,
                **self.update_sites(v, two_site, info, D, rotate)
            }
            if verbosity >= 2:
                print(print_info)
        if verbosity >= 2:
            print()
コード例 #14
0
ファイル: stability.py プロジェクト: pulkin/pyscf
def rhf_internal(mf, with_symmetry=True, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_rhf(mf,
                                            mf.mo_coeff,
                                            mf.mo_occ,
                                            with_symmetry=with_symmetry)

    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    x0 = numpy.zeros_like(g)
    x0[g != 0] = 1. / hdiag[g != 0]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag)] = 1
    e, v = lib.davidson(hop, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.note('RHF/RKS wavefunction has an internal instablity')
        mo = _rotate_mo(mf.mo_coeff, mf.mo_occ, v)
    else:
        log.note(
            'RHF/RKS wavefunction is stable in the intenral stablity analysis')
        mo = mf.mo_coeff
    return mo
コード例 #15
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def rhf_internal(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_rhf(mf, mf.mo_coeff, mf.mo_occ)
    def precond(dx, e, x0):
        hdiagd = hdiag*2 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    # The results of hop(x) corresponds to a displacement that reduces
    # gradients g.  It is the vir-occ block of the matrix vector product
    # (Hessian*x). The occ-vir block equals to x2.T.conj(). The overall
    # Hessian for internal reotation is x2 + x2.T.conj(). This is
    # the reason we apply (.real * 2) below
    def hessian_x(x):
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g!=0] = 1. / hdiag[g!=0]
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.log('KRHF/KRKS wavefunction has an internal instablity')
        mo = _rotate_mo(mf.mo_coeff, mf.mo_occ, v)
    else:
        log.log('KRHF/KRKS wavefunction is stable in the intenral stability analysis')
        mo = mf.mo_coeff
    return mo
コード例 #16
0
def Hmat_diagonalization(Hmat, method="full", nroots=1, diags=None):
    '''
    exact diagonalization 
    '''
    if method == "Arnoldi": 

        print "arpack Arnoldi method"
        e, c = scipy.sparse.linalg.eigsh(Hmat, k=nroots, which="SA")
        print "e=",e

    elif method == "Davidson":
        
        print "pyscf davidson method"
        precond = lambda x, e, *args: x/(diags-e+1e-4)
        nconfigs = Hmat.shape[0]
        def hop(c):
            return Hmat.dot(c)
        initial = np.random.rand(nconfigs)-0.5
        e, c = lib.davidson(hop, initial, precond, nroots=nroots,max_cycle=100)
    
    elif method == "full":

        print "full diagonalization"
        e, c = scipy.linalg.eigh(a=Hmat.todense())

    return e, c
コード例 #17
0
def kernel(myci, eris, ci0=None, max_cycle=50, tol=1e-8,
           verbose=logger.INFO):
    mol = myci.mol
    nmo = myci.nmo
    nocc = myci.nocc
    mo_energy = eris.fock.diagonal()
    diag = make_diagonal(mol, mo_energy, eris, nocc)
    ehf = diag[0]
    diag -= ehf

    if ci0 is None:
# MP2 initial guess
        nvir = nmo - nocc
        e_i = mo_energy[:nocc]
        e_a = mo_energy[nocc:]
        ci0 = numpy.zeros(1+nocc*nvir+(nocc*nvir)**2)
        ci0[0] = 1
        t2 = 2*eris.voov.transpose(1,2,0,3) - eris.voov.transpose(1,2,3,0)
        t2 /= lib.direct_sum('i+j-a-b', e_i, e_i, e_a, e_a)
        ci0[1+nocc*nvir:] = t2.ravel()

    def op(x):
        return contract(myci, x, eris)

    def precond(x, e, *args):
        return x / (diag - e)

    def cisd_dot(x1, x2):
        return dot(x1, x2, nocc, nvir)

    ecisd, ci = lib.davidson(op, ci0, precond, max_cycle=max_cycle, tol=tol,
                             dot=cisd_dot, verbose=verbose)
    conv = True  # It should be checked in lib.davidson function
    return conv, ecisd, ci
コード例 #18
0
ファイル: rte_lanz.py プロジェクト: mariomotta/QITE
def RTE(H_, dT, Tmax, lanczos=False, psi0=None):
    # --- diagonalization ---
    N = H_[0][2].shape[1]
    nbit = int(np.log2(N))
    hdiag = np.zeros(N, dtype=complex)
    ei = np.zeros(N, dtype=complex)
    for i in range(N):
        xi = Int2Bas(i, 2, nbit)
        for (A, h, imp, gmp) in H_:
            nact = len(A)
            for m in np.where(np.abs(h) > 1e-8)[0]:
                sm = Int2Bas(m, 4, nact)
                #print A,sm,[xi[A[i]] for i in range(nact)]
                smx = [
                    sigma_matrices[xi[A[w]], xi[A[w]], sm[w]]
                    for w in range(nact)
                ]
                hdiag[i] += h[m] * np.prod(smx)
        if (i % 1000 == 0): print i, N, hdiag[i]

    precond = lambda x, e, *args: x / (hdiag - e + 1e-4)

    def hop(c_):
        return Hpsi(H_, c_)

    epsm0, Um0 = davidson(hop, psi0, precond)

    fout = open('RTE_davidson.out', 'w')
    fout.write("gs energy %.6f \n" % epsm0)

    # --- initial state ---
    if (psi0 is None):
        i0 = np.argmin(hdiag)
        psi0 = np.zeros(N, dtype=complex)
        psi0[i0] = 1.0

    # --- real-time evolution ---
    bra_RTE = psi0[:]
    braH_RTE = Hpsi(H_, psi0[:])[:]
    ket_RTE = psi0[:]

    nbeta = int(Tmax / dT) + 1
    hvect_LANZ = np.zeros(nbeta + 1, dtype=complex)
    svect_LANZ = np.zeros(nbeta + 1, dtype=complex)

    fout.write("ITE\n")
    for ib in range(nbeta):
        hvect_LANZ[ib] = np.einsum('a,a', np.conj(braH_RTE), ket_RTE)
        svect_LANZ[ib] = np.einsum('a,a', np.conj(bra_RTE), ket_RTE)
        ket_RTE = ExpitH(H_, ket_RTE, dT)[0]
        print ib, hvect_LANZ[ib]

    dump_lanz_rte(hvect_LANZ[:nbeta], svect_LANZ[:nbeta], 'qlanz.vecs')

    fout.close()
コード例 #19
0
def ghf_stability(mf, verbose=None, return_status=False):
    '''
    Stability analysis for GHF/GKS method.

    Args:
        mf : GHF or GKS object

    Kwargs:
        return_status: bool
            Whether to return `stable_i` and `stable_e`

    Returns:
        If return_status is False (default), the return value includes
        a new set of orbitals, which are more close to the stable condition.

        Else, another one boolean variable (indicating current status:
        stable or unstable) is returned.
    '''
    log = logger.new_logger(mf, verbose)
    with_symmetry = True
    g, hop, hdiag = newton_ah.gen_g_hop_ghf(mf,
                                            mf.mo_coeff,
                                            mf.mo_occ,
                                            with_symmetry=with_symmetry)
    hdiag *= 2
    stable = True

    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    def hessian_x(x):  # See comments in function rhf_internal
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g != 0] = 1. / hdiag[g != 0]
    if not with_symmetry:  # allow to break point group symmetry
        x0[numpy.argmin(hdiag)] = 1
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.note('GHF wavefunction has an internal instability')
        mo = _rotate_mo(mf.mo_coeff, mf.mo_occ, v)
        stable = False
    else:
        log.note(
            'GHF wavefunction is stable in the internal stability analysis')
        mo = mf.mo_coeff
    if return_status:
        return mo, stable
    else:
        return mo
コード例 #20
0
ファイル: fci_slow.py プロジェクト: chrinide/pyscf
def kernel(h1e, g2e, norb, nelec, ecore=0):
    h2e = absorb_h1e(h1e, g2e, norb, nelec, .5)

    na = cistring.num_strings(norb, nelec//2)
    ci0 = numpy.zeros((na,na))
    ci0[0,0] = 1

    def hop(c):
        hc = contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)
    hdiag = make_hdiag(h1e, g2e, norb, nelec)
    precond = lambda x, e, *args: x/(hdiag-e+1e-4)
    e, c = lib.davidson(hop, ci0.reshape(-1), precond)
    return e+ecore
コード例 #21
0
def kernel(hobj):
    mol = hobj.mol
    atom_charges = mol.atom_charges()
    atmlst = numpy.where(atom_charges != 0)[0]  # Exclude ghost atoms
    natm = len(atmlst)
    mass = numpy.array([elements.MASSES[atom_charges[i]] for i in atmlst])
    reduced_mass = 1. / (1. / mass).sum()

    if hobj.nroots is None:
        h = hobj.hess(atmlst=atmlst)
        h = numpy.einsum('ijxy,i,j->ijxy', h, mass**-.5, mass**-.5)
        h = h.transpose(0, 2, 1, 3).reshape(natm * 3, natm * 3)
        e, c = numpy.linalg.eigh(h)
        c = c.T
    else:  # Solve some roots
        h_op, hdiag = hobj.gen_hop()
        hdiag = hdiag.reshape(-1, 3)[atmlst].ravel()

        def vib_mode_h_op(x):
            x1 = numpy.zeros((mol.natm, 3))
            x1[atmlst] = numpy.einsum('i,ix->ix', mass**-.5,
                                      x.reshape(natm, 3))
            hx = h_op(x1).reshape(-1, 3)[atmlst]
            hx = numpy.einsum('i,ix->ix', mass**-.5, hx)
            return hx.ravel()

        def precond(x, e, *args):
            hdiagd = hdiag - e
            hdiagd[abs(hdiagd) < 1e-8] = 1e-8
            return x / hdiagd

        e, c = lib.davidson(vib_mode_h_op,
                            hdiag,
                            precond,
                            tol=hobj.conv_tol,
                            nroots=hobj.nroots,
                            verbose=5)
        c = numpy.asarray(c)

    hartree_kj = nist.HARTREE2J * 1e3
    unit2cm = ((hartree_kj * nist.AVOGADRO)**.5 / (nist.BOHR * 1e-10) /
               (2 * numpy.pi * nist.LIGHT_SPEED_SI) * 1e-2)
    hobj.freq = numpy.sign(e) * abs(e)**.5 * unit2cm
    lib.logger.note(hobj, 'Freq %s', hobj.freq)

    # TODO: Remove translation and rotation modes
    hobj.mode = c.reshape(-1, natm, 3)
    # Transform back to cartesian coordinates
    #hobj.mode = numpy.einsum('i,kix->kix', mass**-.5, c.reshape(-1,natm,3))
    return hobj.freq, hobj.mode
コード例 #22
0
def kernel(h1e, eri, norb, nelec, ecore=0):
    h2e = absorb_h1e(h1e, eri, norb, nelec, .5)

    na = cistring.num_strings(norb, nelec // 2)
    ci0 = numpy.zeros((na, na))
    ci0[0, 0] = 1

    def hop(c):
        hc = contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)

    hdiag = make_hdiag(h1e, eri, norb, nelec)
    precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
    e, c = lib.davidson(hop, ci0.reshape(-1), precond)
    return e + ecore
コード例 #23
0
ファイル: direct_ep.py プロジェクト: berquist/pyscf
def kernel(t, u, g, hpp, nsite, nelec, nphonon,
           tol=1e-9, max_cycle=100, verbose=0, **kwargs):
    cishape = make_shape(nsite, nelec, nphonon)
    ci0 = numpy.zeros(cishape)
    ci0.__setitem__((0,0) + (0,)*nsite, 1)
    # Add noise for initial guess, remove it if problematic
    ci0[0,:] += numpy.random.random(ci0[0,:].shape) * 1e-6
    ci0[:,0] += numpy.random.random(ci0[:,0].shape) * 1e-6

    def hop(c):
        hc = contract_all(t, u, g, hpp, c, nsite, nelec, nphonon)
        return hc.reshape(-1)
    hdiag = make_hdiag(t, u, g, hpp, nsite, nelec, nphonon)
    precond = lambda x, e, *args: x/(hdiag-e+1e-4)
    return lib.davidson(hop, ci0.reshape(-1), precond,
                        tol=tol, max_cycle=max_cycle, verbose=verbose,
                        **kwargs)
コード例 #24
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def rhf_external(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop2, hdiag2 = _gen_hop_rhf_external(mf)

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = numpy.zeros_like(hdiag2)
    x0[hdiag2>1e-5] = 1. / hdiag2[hdiag2>1e-5]
    e3, v3 = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    if e3 < -1e-5:
        log.log('KRHF/KRKS wavefunction has an KRHF/KRKS -> KUHF/KUKS instablity.')
        mo = (_rotate_mo(mf.mo_coeff, mf.mo_occ, v3), mf.mo_coeff)
    else:
        log.log('KRHF/KRKS wavefunction is stable in the KRHF/KRKS -> KUHF/KUKS stability analysis')
        mo = (mf.mo_coeff, mf.mo_coeff)
    return mo
コード例 #25
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def uhf_external(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop2, hdiag2 = _gen_hop_uhf_external(mf)

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    x0 = numpy.zeros_like(hdiag2)
    x0[hdiag2>1e-5] = 1. / hdiag2[hdiag2>1e-5]
    e3, v = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    log.debug('uhf_external: lowest eigs of H = %s', e3)
    mo = None
    if e3 < -1e-5:
        log.log('KUHF/KUKS wavefunction has an KUHF/KUKS -> KGHF/KGKS instablity.')
    else:
        log.log('KUHF/KUKS wavefunction is stable in the KUHF/KUKS -> KGHF/KGKS stability analysis')
    return mo
コード例 #26
0
ファイル: rhf.py プロジェクト: chrinide/pyscf
def kernel(hobj):
    mol = hobj.mol
    atom_charges = mol.atom_charges()
    atmlst = numpy.where(atom_charges != 0)[0]  # Exclude ghost atoms
    natm = len(atmlst)
    mass = numpy.array([elements.MASSES[atom_charges[i]] for i in atmlst])
    reduced_mass = 1./(1./mass).sum()

    if hobj.nroots is None:
        h = hobj.hess(atmlst=atmlst)
        h = numpy.einsum('ijxy,i,j->ijxy', h, mass**-.5, mass**-.5)
        h = h.transpose(0,2,1,3).reshape(natm*3,natm*3)
        e, c = numpy.linalg.eigh(h)
        c = c.T
    else: # Solve some roots
        h_op, hdiag = hobj.gen_hop()
        hdiag = hdiag.reshape(-1,3)[atmlst].ravel()
        def vib_mode_h_op(x):
            x1 = numpy.zeros((mol.natm,3))
            x1[atmlst] = numpy.einsum('i,ix->ix', mass**-.5, x.reshape(natm,3))
            hx = h_op(x1).reshape(-1,3)[atmlst]
            hx = numpy.einsum('i,ix->ix', mass**-.5, hx)
            return hx.ravel()

        def precond(x, e, *args):
            hdiagd = hdiag-e
            hdiagd[abs(hdiagd)<1e-8] = 1e-8
            return x/hdiagd
        e, c = lib.davidson(vib_mode_h_op, hdiag, precond, tol=hobj.conv_tol,
                            nroots=hobj.nroots, verbose=5)
        c = numpy.asarray(c)

    hartree_kj = nist.HARTREE2J*1e3
    unit2cm = ((hartree_kj * nist.AVOGADRO)**.5 / (nist.BOHR*1e-10)
               / (2*numpy.pi*nist.LIGHT_SPEED_SI) * 1e-2)
    hobj.freq = numpy.sign(e) * abs(e)**.5 * unit2cm
    lib.logger.note(hobj, 'Freq %s', hobj.freq)

# TODO: Remove translation and rotation modes
    hobj.mode = c.reshape(-1,natm,3)
    # Transform back to cartesian coordinates
    #hobj.mode = numpy.einsum('i,kix->kix', mass**-.5, c.reshape(-1,natm,3))
    return hobj.freq, hobj.mode
コード例 #27
0
ファイル: doci_slow.py プロジェクト: zzy2014/pyscf
    def kernel(self, h1e, eri, norb, nelec, ci0=None, ecore=0, **kwargs):
        if isinstance(nelec, (int, numpy.integer)):
            nelecb = nelec // 2
            neleca = nelec - nelecb
        else:
            neleca, nelecb = nelec
        h2e = self.absorb_h1e(h1e, eri, norb, nelec, .5)
        h2e = ao2mo.restore(1, h2e, norb)

        hdiag = self.make_hdiag(h1e, eri, norb, nelec)
        nroots = 1
        if ci0 is None:
            ci0 = self.get_init_guess(norb, nelec, nroots, hdiag)

        def hop(c):
            return self.contract_2e(h2e, c, norb, nelec)

        precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
        e, c = lib.davidson(hop, ci0, precond, **kwargs)
        return e + ecore, c
コード例 #28
0
ファイル: doci_slow.py プロジェクト: zzy2014/pyscf
    def kernel_ref(h1e, eri, norb, nelec, ecore=0, **kwargs):
        if isinstance(nelec, (int, numpy.integer)):
            nelecb = nelec // 2
            neleca = nelec - nelecb
        else:
            neleca, nelecb = nelec
        h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
        h2e = ao2mo.restore(1, h2e, norb)
        na = cistring.num_strings(norb, neleca)
        ci0 = numpy.zeros(na)
        ci0[0] = 1

        link_index = cistring.gen_linkstr_index(range(norb), neleca)

        def hop(c):
            return contract_2e_ref(h2e, c, norb, nelec, link_index)

        hdiag = make_hdiag(h1e, eri, norb, nelec)
        precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
        e, c = lib.davidson(hop, ci0.reshape(-1), precond, **kwargs)
        return e + ecore
コード例 #29
0
def rhf_internal(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_rhf(mf, mf.mo_coeff, mf.mo_occ)

    def precond(dx, e, x0):
        hdiagd = hdiag - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    x0 = numpy.zeros_like(g)
    x0[g != 0] = 1. / hdiag[g != 0]
    e, v = lib.davidson(hop, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.log('KRHF/KRKS wavefunction has an internal instablity')
        mo = _rotate_mo(mf.mo_coeff, mf.mo_occ, v)
    else:
        log.log(
            'KRHF/KRKS wavefunction is stable in the intenral stablity analysis'
        )
        mo = mf.mo_coeff
    return mo
コード例 #30
0
ファイル: stability.py プロジェクト: chrinide/pyscf
def uhf_internal(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    g, hop, hdiag = newton_ah.gen_g_hop_uhf(mf, mf.mo_coeff, mf.mo_occ)
    def precond(dx, e, x0):
        hdiagd = hdiag*2 - e
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        return dx/hdiagd
    def hessian_x(x): # See comments in function rhf_internal
        return hop(x).real * 2

    x0 = numpy.zeros_like(g)
    x0[g!=0] = 1. / hdiag[g!=0]
    e, v = lib.davidson(hessian_x, x0, precond, tol=1e-4, verbose=log)
    if e < -1e-5:
        log.log('KUHF/KUKS wavefunction has an internal instablity.')
        tot_x_a = sum((occ>0).sum()*(occ==0).sum() for occ in mf.mo_occ[0])
        mo = (_rotate_mo(mf.mo_coeff[0], mf.mo_occ[0], v[:tot_x_a]),
              _rotate_mo(mf.mo_coeff[1], mf.mo_occ[1], v[tot_x_a:]))
    else:
        log.log('KUHF/KUKS wavefunction is stable in the intenral stability analysis')
        mo = mf.mo_coeff
    return mo
コード例 #31
0
def uhf_external(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop2, hdiag2 = _gen_hop_uhf_external(mf)

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    x0 = numpy.zeros_like(hdiag2)
    x0[hdiag2 > 1e-5] = 1. / hdiag2[hdiag2 > 1e-5]
    e3, v = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    log.debug('uhf_external: lowest eigs of H = %s', e3)
    mo = None
    if e3 < -1e-5:
        log.log(
            'KUHF/KUKS wavefunction has an KUHF/KUKS -> KGHF/KGKS instablity.')
    else:
        log.log(
            'KUHF/KUKS wavefunction is stable in the KUHF/KUKS -> KGHF/KGKS stablity analysis'
        )
    return mo
コード例 #32
0
def rhf_external(mf, verbose=None):
    log = logger.new_logger(mf, verbose)
    hop2, hdiag2 = _gen_hop_rhf_external(mf)

    def precond(dx, e, x0):
        hdiagd = hdiag2 - e
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        return dx / hdiagd

    x0 = numpy.zeros_like(hdiag2)
    x0[hdiag2 > 1e-5] = 1. / hdiag2[hdiag2 > 1e-5]
    e3, v3 = lib.davidson(hop2, x0, precond, tol=1e-4, verbose=log)
    if e3 < -1e-5:
        log.log(
            'KRHF/KRKS wavefunction has an KRHF/KRKS -> KUHF/KUKS instablity.')
        mo = (_rotate_mo(mf.mo_coeff, mf.mo_occ, v3), mf.mo_coeff)
    else:
        log.log(
            'KRHF/KRKS wavefunction is stable in the KRHF/KRKS -> KUHF/KUKS stability analysis'
        )
        mo = (mf.mo_coeff, mf.mo_coeff)
    return mo
コード例 #33
0
def rhf_external(mf, with_symmetry=True, show_hessian=True, verbose=None):
        #log = logger.new_logger(mf, verbose)
        hop1, hdiag1, hop2, hdiag2 = _gen_hop_rhf_external(mf, with_symmetry)

        def precond(dx, e, x0):
            hdiagd = hdiag1 - e
            hdiagd[abs(hdiagd)<1e-8] = 1e-8
            return dx/hdiagd
        
        x0 = np.zeros_like(hdiag1)
        x0[hdiag1>1e-5] = 1. / hdiag1[hdiag1>1e-5]
        if not with_symmetry:  # allow to break point group symmetry
            x0[np.argmin(hdiag1)] = 1
        e1, v1 = lib.davidson(hop1, x0, precond, tol=1e-4)
        if e1 < -1e-5:
            print('RHF/RKS wavefunction has a real -> complex instablity at ',x)
        #else:
            #print('RHF/RKS wavefunction is stable in the real -> complex stability analysis')

        def precond(dx, e, x0):
            hdiagd = hdiag2 - e
            hdiagd[abs(hdiagd)<1e-8] = 1e-8
            return dx/hdiagd
        x0 = v1

        #hop2 is a function (so as to work with the davidson algorithm)
        #we get the matrix by applying to each basis vector.
        if show_hessian==True:
            #capital Hop2 is the matrix
            hop2_matrix=np.zeros((len(x0),len(x0)))

            for k in range(len(x0)):
                xk=np.zeros_like(x0)
                xk[k]=1
                yk=hop2(xk)

                hop2_matrix[:,k]=yk

            #better printing to read the hessian
            np.set_printoptions(linewidth=300,suppress=True,precision=3)

            print("Printing Hessian:")
            print(hop2_matrix)
            print("Done")

            #reset parameters
            np.set_printoptions(linewidth=80, suppress=False,precision=5)

        e3, v3 = lib.davidson(hop2, x0, precond, tol=1e-10)
        
        if e3 < -1e-5:
            if verbose:
                print('RHF/RKS wavefunction has a RHF/RKS -> UHF/UKS instablity at ',x)
                print(e3)
                print(v3)
            Ca,Cb = (_rotate_mo(mf.mo_coeff, mf.mo_occ, v3), mf.mo_coeff)

            mo_occ = mf.get_occ(mo_energy=mf.mo_energy, mo_coeff=mf.mo_coeff)

            dm_broken=pyscf.scf.UHF(diatomic).make_rdm1((Ca, Cb), (mo_occ, mo_occ))
            return dm_broken
        else:
            return False;           
コード例 #34
0
def QITE(H_,
         db,
         bmax,
         lanczos=False,
         psi0=None,
         omega=None,
         ncheck=1,
         davidson=True):

    if (davidson):
        N = H_[0][2].shape[1]
        nbit = int(np.log2(N))
        hdiag = np.zeros(N, dtype=complex)
        for i in range(N):
            hdiag[i] = Hii(H_, i)
            print i, hdiag[i]

        precond = lambda x, e, *args: x / (hdiag - e + 1e-4)

        def hop(c_):
            return Hpsi(H_, c_)

        if (psi0 is None):
            i0 = np.argmin(hdiag)
            psi0 = np.zeros(N, dtype=complex)
            psi0[i0] = 1.0

        from pyscf.lib import davidson
        epsm0, Um0 = davidson(hop, psi0, precond)
    else:
        Hm = Hmat(H_)
        N = Hm.shape[0]
        nbit = int(np.log2(N))
        eps, U = SciLA.eigh(Hm)
        m0 = np.argmin(eps)
        epsm0 = eps[m0]
        Um0 = U[:, m0]
        zeta = np.exp(-db * (eps - eps[m0]))
        fide = 1.0

    fout = open('QITE.out', 'w')
    fout.write("FCI gs energy %.6f \n" % epsm0)
    fout.write("FCI gs wfn \n")
    print_state(Um0, nbit, fout)

    psi_QITE = psi0[:]

    nbeta = int(bmax / db) + 1
    hvect_LANZ = np.zeros(nbeta + 1)
    svect_LANZ = np.zeros(nbeta + 1)

    xv = None
    fout.write("QITE\n")
    for ib in range(nbeta):
        ea, ev = Hmoms(H_, psi_QITE)
        hvect_LANZ[ib] = ea

        if (omega is None): fide = fidelity(psi_QITE, Um0)
        else: fide = LA.norm(psi_QITE[omega])**2

        if (lanczos):
            ea_ = Lanczos_QITE(hvect_LANZ[:ib + 1], svect_LANZ[:ib + 1], db)
            fout.write("%.6f %.6f %.6f %.6f %.6f \n" %
                       (ib * db, ea, ev, fide, ea_))
        else:
            fout.write("%.6f %.6f %.6f %.6f \n" % (ib * db, ea, ev, fide))
        fout.flush()

        if (ncheck > 0): check = (ib % ncheck == 0)
        else: check = False
        psi_QITE, dnorm, xv = QITE_step(H_, psi_QITE, db, xv, check)
        svect_LANZ[ib + 1] = svect_LANZ[ib] + np.log(dnorm)

    fout.write("QITE gs wfn \n")
    print_state(psi_QITE, nbit, fout)
    dump_state(psi_QITE, nbit, 'qite.psi')
    dump_lanz_vecs(hvect_LANZ[:nbeta], svect_LANZ[:nbeta], 'qlanz.vecs')

    fout.close()
コード例 #35
0
ファイル: direct_spin1.py プロジェクト: v3op01/pyscf
 def eig(self, op, x0, precond, **kwargs):
     if kwargs['nroots'] == 1 and x0[0].size > 6.5e7:  # 500MB
         lessio = True
     else:
         lessio = False
     return lib.davidson(op, x0, precond, lessio=lessio, **kwargs)
コード例 #36
0
ファイル: MPSsolver.py プロジェクト: jiangtong1000/ephMPS
def optimization(MPS, MPSdim, MPSQN, MPO, MPOdim, ephtable, pbond, nexciton,\
        procedure, method="2site", nroots=1, inverse=1.0):
    '''
    1 or 2 site optimization procedure
    inverse = 1.0 / -1.0 
    -1.0 to get the largest eigenvalue
    '''

    assert method in ["2site", "1site"]
    print "optimization method", method

    # construct the environment matrix
    construct_enviro(MPS, MPS, MPO, "L")

    nMPS = len(MPS)
    # construct each sweep cycle scheme
    if method == "1site":
        loop = [['R', i]
                for i in xrange(nMPS - 1, -1, -1)] + [['L', i]
                                                      for i in xrange(0, nMPS)]
    else:
        loop = [['R', i]
                for i in xrange(nMPS - 1, 0, -1)] + [['L', i]
                                                     for i in xrange(1, nMPS)]

    # initial matrix
    ltensor = np.ones((1, 1, 1))
    rtensor = np.ones((1, 1, 1))

    energy = []
    for isweep in xrange(len(procedure)):
        print "Procedure", procedure[isweep]

        for system, imps in loop:
            if system == "R":
                lmethod, rmethod = "Enviro", "System"
            else:
                lmethod, rmethod = "System", "Enviro"

            if method == "1site":
                lsite = imps - 1
                addlist = [imps]
            else:
                lsite = imps - 2
                addlist = [imps - 1, imps]

            ltensor = GetLR('L',
                            lsite,
                            MPS,
                            MPS,
                            MPO,
                            itensor=ltensor,
                            method=lmethod)
            rtensor = GetLR('R',
                            imps + 1,
                            MPS,
                            MPS,
                            MPO,
                            itensor=rtensor,
                            method=rmethod)

            # get the quantum number pattern
            qnmat, qnbigl, qnbigr = construct_qnmat(MPSQN, ephtable, pbond,
                                                    addlist, method, system)
            cshape = qnmat.shape

            # hdiag
            tmp_ltensor = np.einsum("aba -> ba", ltensor)
            tmp_MPOimps = np.einsum("abbc -> abc", MPO[imps])
            tmp_rtensor = np.einsum("aba -> ba", rtensor)
            if method == "1site":
                #   S-a c f-S
                #   O-b-O-g-O
                #   S-a c f-S
                path = [([0, 1],"ba, bcg -> acg"),\
                        ([1, 0],"acg, gf -> acf")]
                hdiag = tensorlib.multi_tensor_contract(
                    path, tmp_ltensor, tmp_MPOimps,
                    tmp_rtensor)[(qnmat == nexciton)]
                # initial guess   b-S-c
                #                   a
                cguess = MPS[imps][qnmat == nexciton]
            else:
                #   S-a c   d f-S
                #   O-b-O-e-O-g-O
                #   S-a c   d f-S
                tmp_MPOimpsm1 = np.einsum("abbc -> abc", MPO[imps - 1])
                path = [([0, 1],"ba, bce -> ace"),\
                        ([0, 1],"edg, gf -> edf"),\
                        ([0, 1],"ace, edf -> acdf")]
                hdiag = tensorlib.multi_tensor_contract(
                    path, tmp_ltensor, tmp_MPOimpsm1, tmp_MPOimps,
                    tmp_rtensor)[(qnmat == nexciton)]
                # initial guess b-S-c-S-e
                #                 a   d
                cguess = np.tensordot(MPS[imps - 1], MPS[imps],
                                      axes=1)[qnmat == nexciton]

            hdiag *= inverse
            nonzeros = np.sum(qnmat == nexciton)
            print "Hmat dim", nonzeros

            count = [0]

            def hop(c):
                # convert c to initial structure according to qn pattern
                cstruct = c1d2cmat(cshape, c, qnmat, nexciton)
                count[0] += 1

                if method == "1site":
                    #S-a   l-S
                    #    d
                    #O-b-O-f-O
                    #    e
                    #S-c   k-S

                    path = [([0, 1],"abc, adl -> bcdl"),\
                            ([2, 0],"bcdl, bdef -> clef"),\
                            ([1, 0],"clef, lfk -> cek")]
                    cout = tensorlib.multi_tensor_contract(
                        path, ltensor, cstruct, MPO[imps], rtensor)
                else:
                    #S-a       l-S
                    #    d   g
                    #O-b-O-f-O-j-O
                    #    e   h
                    #S-c       k-S
                    path = [([0, 1],"abc, adgl -> bcdgl"),\
                            ([3, 0],"bcdgl, bdef -> cglef"),\
                            ([2, 0],"cglef, fghj -> clehj"),\
                            ([1, 0],"clehj, ljk -> cehk")]
                    cout = tensorlib.multi_tensor_contract(
                        path, ltensor, cstruct, MPO[imps - 1], MPO[imps],
                        rtensor)
                # convert structure c to 1d according to qn
                return inverse * cout[qnmat == nexciton]

            if nroots != 1:
                cguess = [cguess]
                for iroot in xrange(nroots - 1):
                    cguess += [np.random.random([nonzeros]) - 0.5]

            precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
            e, c = lib.davidson(hop, cguess, precond, max_cycle=100,\
                    nroots=nroots)
            # scipy arpack solver : much slower than davidson
            #A = scipy.sparse.linalg.LinearOperator((nonzeros,nonzeros), matvec=hop)
            #e, c = scipy.sparse.linalg.eigsh(A,k=1, which="SA",v0=cguess)
            print "HC loops:", count[0]
            print "isweep, imps, e=", isweep, imps, e

            energy.append(e)

            cstruct = c1d2cmat(cshape, c, qnmat, nexciton, nroots=nroots)

            if nroots == 1:
                # direct svd the coefficient matrix
                mps, mpsdim, mpsqn, compmps = Renormalization_svd(cstruct, qnbigl, qnbigr,\
                        system, nexciton, procedure[isweep][0], percent=procedure[isweep][1])
            else:
                # diagonalize the reduced density matrix
                mps, mpsdim, mpsqn, compmps = Renormalization_ddm(cstruct, qnbigl, qnbigr,\
                        system, nexciton, procedure[isweep][0], percent=procedure[isweep][1])

            if method == "1site":
                MPS[imps] = mps
                if system == "L":
                    if imps != len(MPS) - 1:
                        MPS[imps + 1] = np.tensordot(compmps,
                                                     MPS[imps + 1],
                                                     axes=1)
                        MPSdim[imps + 1] = mpsdim
                        MPSQN[imps + 1] = mpsqn
                    else:
                        MPS[imps] = np.tensordot(MPS[imps], compmps, axes=1)
                        MPSdim[imps + 1] = 1
                        MPSQN[imps + 1] = [0]

                else:
                    if imps != 0:
                        MPS[imps - 1] = np.tensordot(MPS[imps - 1],
                                                     compmps,
                                                     axes=1)
                        MPSdim[imps] = mpsdim
                        MPSQN[imps] = mpsqn
                    else:
                        MPS[imps] = np.tensordot(compmps, MPS[imps], axes=1)
                        MPSdim[imps] = 1
                        MPSQN[imps] = [0]
            else:
                if system == "L":
                    MPS[imps - 1] = mps
                    MPS[imps] = compmps
                else:
                    MPS[imps] = mps
                    MPS[imps - 1] = compmps

                MPSdim[imps] = mpsdim
                MPSQN[imps] = mpsqn

    if nroots == 1:
        lowestenergy = np.min(energy)
        print "lowest energy = ", lowestenergy

    return energy
コード例 #37
0
    def kernel(self, D=16, sites=2, max_iter=100, tol=1e-15, verbosity=2):
        """Executing of the DMRG algorithm.

        Args:
            D: The bond dimension to use for DMRG. The algorithm can choose
            a bond dimension larger than the one specified to avoid truncating
            between renormalized states degenerate in their singular values.

            sites: The number of sites to add each step

            max_iter: The maximal iterations to use in the DMRG algorithm.

            tol: The tolerance on which to abort the calculation

            verbosity: 0: Don't print anything.
                       1: Print results for the optimization.
                       2: Print intermediate result at every even chain length.
        """
        if sites % 2 != 0:
            raise ValueError('Number of sites needs to be even')

        self.nrsites = sites

        AA = None
        for i in range(max_iter):
            # Diagonalize
            size = self.M * self.M * (self.p**self.nrsites)
            if AA is None or AA.size != size:
                AA = rand(size)
                AA /= norm(AA)
            w, v = davidson(self.Heff, x0=AA, precond=self.Heffdiagonal())

            AA = v
            # Renormalize the basis
            E = (w - self.Etot) / self.nrsites
            ΔE, self.E, self.Etot = self.E - E, E, w

            trunc, info = self.renormalize_basis(AA, D)
            if info is not None and verbosity >= 3:
                print(info)

            error = info['ArAl TF'] if info is not None else None

            # Update the effective Hamiltonian
            self.update_Heff()

            # Energy difference between this and the previous even-length chain
            if verbosity >= 2:
                print(
                    f"it {i}:\tM: {self.M},\tE: {self.E:.12f},\t"
                    f"ΔE: {ΔE:.3g},\ttrunc: {trunc:.3g}",
                    end='')
                if error is None:
                    print()
                else:
                    print(f',\tError: {error}')
            try:
                if i > 10 and error < tol:
                    break
            except TypeError:
                # error or tol is None
                pass

        if verbosity >= 1:
            print(f"its: {i},\tM: {self.M},\tE: {self.E:.12f},\t"
                  f"ΔE: {ΔE:.3g},\ttrunc: {trunc:.3g}")
            if i == max_iter:
                print("Convergence not reached.")

        return self.E
コード例 #38
0
def kernel(h1e, eri, norb, nelec, ecore=0, verbose=logger.NOTE):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
    namax = cistring.num_strings(norb, neleca)
    nbmax = cistring.num_strings(norb, nelecb)

    myci = SelectedCI()

    strsa = [int('1' * neleca, 2)]
    strsb = [int('1' * nelecb, 2)]
    ci_strs = (strsa, strsb)
    ci0 = numpy.ones((1, 1))
    ci0, ci_strs = enlarge_space(myci, (ci0, ci_strs), h2e, norb, nelec)

    def all_linkstr_index(ci_strs):
        cd_indexa = cre_des_linkstr(ci_strs[0], norb, neleca)
        dd_indexa = des_des_linkstr(ci_strs[0], norb, neleca)
        cd_indexb = cre_des_linkstr(ci_strs[1], norb, nelecb)
        dd_indexb = des_des_linkstr(ci_strs[1], norb, nelecb)
        return cd_indexa, dd_indexa, cd_indexb, dd_indexb

    def hop(c):
        hc = contract_2e(h2e, (c, ci_strs), norb, nelec, link_index)
        return hc.reshape(-1)

    precond = lambda x, e, *args: x / (hdiag - e + 1e-4)

    e_last = 0
    tol = 1e-2
    conv = False
    for icycle in range(norb):
        tol = max(tol * 1e-2, myci.float_tol)
        link_index = all_linkstr_index(ci_strs)
        hdiag = make_hdiag(h1e, eri, ci_strs, norb, nelec)
        e, ci0 = lib.davidson(hop,
                              ci0.reshape(-1),
                              precond,
                              tol=tol,
                              verbose=verbose)
        print('icycle %d  ci.shape %s  E = %.15g' %
              (icycle, (len(ci_strs[0]), len(ci_strs[1])), e))
        if ci0.shape == (namax,
                         nbmax) or abs(e - e_last) < myci.float_tol * 10:
            conv = True
            break
        ci1, ci_strs = enlarge_space(myci, (ci0, ci_strs), h2e, norb, nelec)
        if ci1.size < ci0.size * 1.02:
            conv = True
            break
        e_last = e
        ci0 = ci1

    link_index = all_linkstr_index(ci_strs)
    hdiag = make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, ci0 = lib.davidson(hop,
                          ci0.reshape(-1),
                          precond,
                          tol=myci.conv_tol,
                          verbose=verbose)

    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    return e + ecore, (ci0.reshape(na, nb), ci_strs)
コード例 #39
0
def calc_eigs_davidson(mpsL,
                       W,
                       F,
                       site,
                       nStates,
                       nStatesCalc=None,
                       preserveState=False,
                       orthonormalize=False,
                       oneSite=True,
                       edgePreserveState=True):
    Hfun, precond = make_ham_func(mpsL[0], W, F, site, oneSite=oneSite)
    (n1, n2, n3) = mpsL[0][site].shape
    if nStatesCalc is None: nStatesCalc = nStates
    nStates, nStatesCalc = min(nStates,
                               n1 * n2 * n3 - 1), min(nStatesCalc,
                                                      n1 * n2 * n3 - 1)
    guess = []
    # PH - Figure out new initial guess here !!!
    for state in range(nStates):
        if oneSite:
            guess.append(np.reshape(mpsL[state][site], -1))
        else:
            guess.append(
                np.reshape(
                    einsum('ijk,lkm->iljm', mpsL[state][site],
                           mpsL[state][site + 1]), -1))
    # PH - Could add some convergence check
    #print(len(guess))
    vals, vecso = davidson(Hfun,
                           guess,
                           precond,
                           nroots=nStatesCalc,
                           pick=pick_eigs,
                           follow_state=False,
                           tol=1e-16,
                           max_cycle=1000)
    #print(len(vecso))
    sort_inds = np.argsort(np.real(vals))
    try:
        vecs = np.zeros((len(vecso[0]), nStates), dtype=np.complex_)
        E = -vals[sort_inds[:nStates]]
        for i in range(min(nStates, len(sort_inds))):
            try:
                vecs[:, i] = vecso[sort_inds[i]]
            except:
                vecs[:, i] = guess[i]
    except:
        vecs = vecso
        E = -vals
        pass
    # Allow orthonormalize to a float indicating a gap size where it should be turned on
    if not isinstance(orthonormalize, bool):
        if nStates == 1: orthonormalize = False
        else:
            gap = np.abs(E[0] - E[1])
            if gap < orthonormalize:
                orthonormalize = True
            else:
                orthonormalize = False
    # Orthonormalize (when gap is too small?) - PH, Why?
    if (nStates > 1) and orthonormalize:
        vecs = sla.orth(vecs)
    # At the ends, we do not want to switch states when preserving state is off
    if ((site == 0) or (site == len(mpsL[0]) - 1)) and edgePreserveState:
        preserveState = True
    E, vecs, ovlp = check_overlap(guess[0],
                                  vecs,
                                  E,
                                  preserveState=preserveState)
    return E, vecs, ovlp
コード例 #40
0
 def eig(self, op, x0, precond, **kwargs):
     if kwargs['nroots'] == 1 and x0[0].size > 6.5e7: # 500MB
         lessio = True
     else:
         lessio = False
     return lib.davidson(op, x0, precond, lessio=lessio, **kwargs)
コード例 #41
0
ファイル: ite.py プロジェクト: mmetcalf14/QITE
def ITE(H_,db,bmax,lanczos=False,psi0=None):

 N     = H_[0][2].shape[1]
 nbit  = int(np.log2(N))
 hdiag = np.zeros(N,dtype=complex)
 for i in range(N):
  hdiag[i] = Hii(H_,i)

 precond = lambda x,e, *args: x/(hdiag-e+1e-4)

 def hop(c_):
  return Hpsi(H_,c_)

 if(psi0 is None):
  i0       = np.argmin(hdiag)
  psi0     = np.zeros(N,dtype=complex)
  psi0[i0] = 1.0
 
 from pyscf.lib import davidson
 epsm0,Um0 = davidson(hop,psi0,precond)
 
 fout = open('ITE.out','w')
 fout.write("FCI gs energy %.6f \n" % epsm0)
 fout.write("FCI gs wfn \n")
 print_state(Um0,nbit,fout)

 if(psi0 is None):
  i0          = np.argmin(hdiag)
  psi_ITE     = np.zeros(N,dtype=complex)
  psi_ITE[i0] = 1.0
 else:
  psi_ITE     = psi0.copy()

 nbeta = int(bmax/db)+1
 hvect_LANZ = np.zeros(nbeta+1)
 svect_LANZ = np.zeros(nbeta+1)

 if(lanczos):
  space_LANZ = np.zeros((N,nbeta),dtype=complex)

 fout.write("ITE\n")
 for ib in range(nbeta):
  ea,ev          = Hmoms(H_,psi_ITE)
  hvect_LANZ[ib] = ea
  fide           = fidelity(psi_ITE,Um0)

  if(lanczos):
   space_LANZ[:,ib] = psi_ITE.copy()
   psi_LANZ         = Lanczos_kernel(UH,space_LANZ[:,:ib+1])
   ea_,ev_          = Hmoms(H_,psi_LANZ)
   fide_            = fidelity(psi_LANZ,Um0)
   fout.write("%.6f %.6f %.6f %.6f %.6f %.6f %.6f \n" % (ib*db,ea,ev,fide,ea_,ev_,fide_))
  else:
   fout.write("%.6f %.6f %.6f %.6f \n" % (ib*db,ea,ev,fide)) 

  psi_ITE,dn = ExpmbH(H_,psi_ITE,db)
  svect_LANZ[ib+1]  = svect_LANZ[ib]+np.log(dn)

 fout.write("ITE gs wfn \n")
 print_state(psi_ITE,nbit,fout)
 dump_state(psi_ITE,nbit,'ite.psi')
 dump_lanz_vecs(hvect_LANZ[:nbeta],svect_LANZ[:nbeta],'qlanz.vecs')

 fout.close()