Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
    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
Example #6
0
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
Example #7
0
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
Example #8
0
    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
Example #9
0
    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
Example #10
0
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