Exemplo n.º 1
0
def cre_des_linkstr(strs, norb, nelec):
    addrs = dict(zip(strs, range(len(strs))))
    nvir = norb - nelec
    link_index = numpy.zeros((len(addrs), nelec + nelec * nvir, 4), dtype=int)
    link_index[:, :, 0] = -1
    for i0, str1 in enumerate(strs):
        occ = []
        vir = []
        for i in range(norb):
            if str1 & (1 << i):
                occ.append(i)
            else:
                vir.append(i)
        k = 0
        for i in occ:
            link_index[i0, k] = (i, i, i0, 1)
            k += 1
        for a in vir:
            for i in occ:
                str0 = str1 ^ (1 << i) | (1 << a)
                if str0 in addrs:
                    # [cre, des, targetddress, parity]
                    link_index[i0, k] = (a, i, addrs[str0], cistring.cre_des_sign(a, i, str1))
                    k += 1
    return link_index
Exemplo n.º 2
0
def cre_des_linkstr(strs, norb, nelec):
    addrs = dict(zip(strs, range(len(strs))))
    nvir = norb - nelec
    link_index = numpy.zeros((len(addrs), nelec + nelec * nvir, 4),
                             dtype=numpy.int32)
    for i0, str1 in enumerate(strs):
        occ = []
        vir = []
        for i in range(norb):
            if str1 & (1 << i):
                occ.append(i)
            else:
                vir.append(i)
        k = 0
        for i in occ:
            link_index[i0, k] = (i, i, i0, 1)
            k += 1
        for a in vir:
            for i in occ:
                str0 = str1 ^ (1 << i) | (1 << a)
                if str0 in addrs:
                    # [cre, des, targetddress, parity]
                    link_index[i0, k] = (a, i, addrs[str0],
                                         cistring.cre_des_sign(a, i, str1))
                    k += 1
    return link_index
Exemplo n.º 3
0
def t2strs(norb, nelec):
    nocc = nelec
    hf_str = int('1'*nocc, 2)
    addrs = []
    signs = []
    for a in range(nocc+1, norb):
        for b in range(nocc, a):
            for i in reversed(range(1,nocc)):
                for j in reversed(range(i)):
                    str1 = hf_str ^ (1 << j) | (1 << b)
                    sign = cistring.cre_des_sign(b, j, hf_str)
                    sign*= cistring.cre_des_sign(a, i, str1)
                    str1^= (1 << i) | (1 << a)
                    addrs.append(cistring.str2addr(norb, nelec, str1))
                    signs.append(sign)
    return numpy.asarray(addrs), numpy.asarray(signs)
Exemplo n.º 4
0
def t2strs(norb, nelec):
    nocc = nelec
    hf_str = int('1'*nocc, 2)
    addrs = []
    signs = []
    for a in range(nocc+1, norb):
        for b in range(nocc, a):
            for i in reversed(range(1,nocc)):
                for j in reversed(range(i)):
                    str1 = hf_str ^ (1 << j) | (1 << b)
                    sign = cistring.cre_des_sign(b, j, hf_str)
                    sign*= cistring.cre_des_sign(a, i, str1)
                    str1^= (1 << i) | (1 << a)
                    addrs.append(cistring.str2addr(norb, nelec, str1))
                    signs.append(sign)
    return numpy.asarray(addrs), numpy.asarray(signs)
Exemplo n.º 5
0
def t1strs(norb, nelec):
    nocc = nelec
    hf_str = int('1' * nocc, 2)
    addrs = []
    signs = []
    for a in range(nocc, norb):
        for i in reversed(range(nocc)):
            str1 = hf_str ^ (1 << i) | (1 << a)
            addrs.append(cistring.str2addr(norb, nelec, str1))
            signs.append(cistring.cre_des_sign(a, i, hf_str))
    return numpy.asarray(addrs), numpy.asarray(signs)
Exemplo n.º 6
0
Arquivo: cisd.py Projeto: eronca/pyscf
def t1strs(norb, nelec):
    nocc = nelec
    hf_str = int('1'*nocc, 2)
    addrs = []
    signs = []
    for a in range(nocc, norb):
        for i in reversed(range(nocc)):
            str1 = hf_str ^ (1 << i) | (1 << a)
            addrs.append(cistring.str2addr(norb, nelec, str1))
            signs.append(cistring.cre_des_sign(a, i, hf_str))
    return numpy.asarray(addrs), numpy.asarray(signs)
Exemplo n.º 7
0
def t1strs(norb, nelec):
    '''FCI strings (address) for CIS single-excitation amplitues'''
    nocc = nelec
    hf_str = int('1' * nocc, 2)
    addrs = []
    signs = []
    for a in range(nocc, norb):
        for i in reversed(range(nocc)):
            str1 = hf_str ^ (1 << i) | (1 << a)
            addrs.append(cistring.str2addr(norb, nelec, str1))
            signs.append(cistring.cre_des_sign(a, i, hf_str))
    return numpy.asarray(addrs), numpy.asarray(signs)
Exemplo n.º 8
0
def to_fci(cisdvec, norb, nelec):
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    nocc = neleca
    nvir = norb - nocc
    c0 = cisdvec[0]
    c1 = cisdvec[1:nocc * nvir + 1].reshape(nocc, nvir)
    c2 = cisdvec[nocc * nvir + 1:].reshape(nocc, nocc, nvir, nvir)
    t1addr, t1sign = t1strs(norb, nocc)

    na = cistring.num_strings(norb, nocc)
    fcivec = numpy.zeros((na, na))
    fcivec[0, 0] = c0
    c1 = c1[::-1].T.ravel()
    fcivec[0, t1addr] = fcivec[t1addr, 0] = c1 * t1sign
    c2ab = c2[::-1, ::-1].transpose(2, 0, 3, 1).reshape(nocc * nvir, -1)
    c2ab = numpy.einsum('i,j,ij->ij', t1sign, t1sign, c2ab)
    lib.takebak_2d(fcivec, c2ab, t1addr, t1addr)

    if nocc > 1 and nvir > 1:
        hf_str = int('1' * nocc, 2)
        for a in range(nocc, norb):
            for b in range(nocc, a):
                for i in reversed(range(1, nocc)):
                    for j in reversed(range(i)):
                        c2aa = c2[i, j, a - nocc,
                                  b - nocc] - c2[j, i, a - nocc, b - nocc]
                        str1 = hf_str ^ (1 << j) | (1 << b)
                        c2aa *= cistring.cre_des_sign(b, j, hf_str)
                        c2aa *= cistring.cre_des_sign(a, i, str1)
                        str1 ^= (1 << i) | (1 << a)
                        addr = cistring.str2addr(norb, nocc, str1)
                        fcivec[0, addr] = fcivec[addr, 0] = c2aa
    return fcivec
Exemplo n.º 9
0
Arquivo: cisd.py Projeto: eronca/pyscf
def to_fci(cisdvec, norb, nelec):
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    nocc = neleca
    nvir = norb - nocc
    c0 = cisdvec[0]
    c1 = cisdvec[1:nocc*nvir+1].reshape(nocc,nvir)
    c2 = cisdvec[nocc*nvir+1:].reshape(nocc,nocc,nvir,nvir)
    t1addr, t1sign = t1strs(norb, nocc)

    na = cistring.num_strings(norb, nocc)
    fcivec = numpy.zeros((na,na))
    fcivec[0,0] = c0
    c1 = c1[::-1].T.ravel()
    fcivec[0,t1addr] = fcivec[t1addr,0] = c1 * t1sign
    c2ab = c2[::-1,::-1].transpose(2,0,3,1).reshape(nocc*nvir,-1)
    c2ab = numpy.einsum('i,j,ij->ij', t1sign, t1sign, c2ab)
    lib.takebak_2d(fcivec, c2ab, t1addr, t1addr)

    if nocc > 1 and nvir > 1:
        hf_str = int('1'*nocc, 2)
        for a in range(nocc, norb):
            for b in range(nocc, a):
                for i in reversed(range(1, nocc)):
                    for j in reversed(range(i)):
                        c2aa = c2[i,j,a-nocc,b-nocc] - c2[j,i,a-nocc,b-nocc]
                        str1 = hf_str ^ (1 << j) | (1 << b)
                        c2aa*= cistring.cre_des_sign(b, j, hf_str)
                        c2aa*= cistring.cre_des_sign(a, i, str1)
                        str1^= (1 << i) | (1 << a)
                        addr = cistring.str2addr(norb, nocc, str1)
                        fcivec[0,addr] = fcivec[addr,0] = c2aa
    return fcivec
Exemplo n.º 10
0
def to_fcivec(cisdvec, norb, nelec, frozen=0):
    '''Convert CISD coefficients to FCI coefficients'''
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
        assert (neleca == nelecb)

    frozen_mask = numpy.zeros(norb, dtype=bool)
    if isinstance(frozen, (int, numpy.integer)):
        nfroz = frozen
        frozen_mask[:frozen] = True
    else:
        nfroz = len(frozen)
        frozen_mask[frozen] = True

    nocc = numpy.count_nonzero(~frozen_mask[:neleca])
    nmo = norb - nfroz
    nvir = nmo - nocc
    c0, c1, c2 = cisdvec_to_amplitudes(cisdvec, nmo, nocc)
    t1addr, t1sign = t1strs(nmo, nocc)

    na = cistring.num_strings(nmo, nocc)
    fcivec = numpy.zeros((na, na))
    fcivec[0, 0] = c0
    c1 = c1[::-1].T.ravel()
    fcivec[0, t1addr] = fcivec[t1addr, 0] = c1 * t1sign
    c2ab = c2[::-1, ::-1].transpose(2, 0, 3, 1).reshape(nocc * nvir, -1)
    c2ab = numpy.einsum('i,j,ij->ij', t1sign, t1sign, c2ab)
    lib.takebak_2d(fcivec, c2ab, t1addr, t1addr)

    if nocc > 1 and nvir > 1:
        hf_str = int('1' * nocc, 2)
        for a in range(nocc, nmo):
            for b in range(nocc, a):
                for i in reversed(range(1, nocc)):
                    for j in reversed(range(i)):
                        c2aa = c2[i, j, a - nocc,
                                  b - nocc] - c2[j, i, a - nocc, b - nocc]
                        str1 = hf_str ^ (1 << j) | (1 << b)
                        c2aa *= cistring.cre_des_sign(b, j, hf_str)
                        c2aa *= cistring.cre_des_sign(a, i, str1)
                        str1 ^= (1 << i) | (1 << a)
                        addr = cistring.str2addr(nmo, nocc, str1)
                        fcivec[0, addr] = fcivec[addr, 0] = c2aa

    if nfroz == 0:
        return fcivec

    assert (norb < 63)

    strs = cistring.gen_strings4orblist(range(norb), neleca)
    na = len(strs)
    count = numpy.zeros(na, dtype=int)
    parity = numpy.zeros(na, dtype=bool)
    core_mask = numpy.ones(na, dtype=bool)
    # During the loop, count saves the number of occupied orbitals that
    # lower (with small orbital ID) than the present orbital i.
    # Moving all the frozen orbitals to the beginning of the orbital list
    # (before the occupied orbitals) leads to parity odd (= True, with
    # negative sign) or even (= False, with positive sign).
    for i in range(norb):
        if frozen_mask[i]:
            if i < neleca:
                # frozen occupied orbital should be occupied
                core_mask &= (strs & (1 << i)) != 0
                parity ^= (count & 1) == 1
            else:
                # frozen virtual orbital should not be occupied.
                # parity is not needed since it's unoccupied
                core_mask &= (strs & (1 << i)) == 0
        else:
            count += (strs & (1 << i)) != 0
    sub_strs = strs[core_mask & (count == nocc)]
    addrs = cistring.strs2addr(norb, neleca, sub_strs)
    fcivec1 = numpy.zeros((na, na))
    fcivec1[addrs[:, None], addrs] = fcivec
    fcivec1[parity, :] *= -1
    fcivec1[:, parity] *= -1
    return fcivec1