def des_b(ci0, norb, nelec, ap_id): r'''Construct (N-1)-electron wavefunction by removing a beta electron from N-electron wavefunction. Args: ci0 : 2D array CI coefficients, row for alpha strings and column for beta strings. norb : int Number of orbitals. nelec : int or 2-item list Number of electrons, or 2-item list for (alpha, beta) electrons ap_id : int Orbital index (0-based), for the annihilation operator Returns: 2D array, row for alpha strings and column for beta strings. Note it has different number of columns to the input CI coefficients. ''' if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec des_index = cistring.gen_des_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb-1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (des_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap,2] sign = des_index[entry_has_ap,3] # This sign prefactor accounts for interchange of operators with alpha and beta spins if neleca % 2 == 1: sign *= -1 ci1[:,addr_ci1] = ci0[:,addr_ci0] * sign return ci1
def _make_rdm2_abba(fcivec, norb, nelec): if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec if nelecb == norb or neleca == 0: # no intermediate determinants return numpy.zeros((norb,norb,norb,norb)) acre_index = cistring.gen_cre_str_index(range(norb), neleca-1) bdes_index = cistring.gen_des_str_index(range(norb), nelecb+1) instra = cistring.num_strings(norb, neleca-1) nb = cistring.num_strings(norb, nelecb) dm1 = numpy.empty((norb,norb)) dm2 = numpy.empty((norb,norb,norb,norb)) fn = _ctypes.dlsym(librdm._handle, 'FCIdm2_abba_kern') librdm.FCIspindm12_drv(ctypes.c_void_p(fn), dm1.ctypes.data_as(ctypes.c_void_p), dm2.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(instra), ctypes.c_int(nb), ctypes.c_int(neleca), ctypes.c_int(nelecb), acre_index.ctypes.data_as(ctypes.c_void_p), bdes_index.ctypes.data_as(ctypes.c_void_p)) return dm2
def test_gen_des_str_index(self): idx = cistring.gen_des_str_index(range(4), 2) idx0 = [[[ 0, 0, 1,-1], [ 0, 1, 0, 1]], [[ 0, 0, 2,-1], [ 0, 2, 0, 1]], [[ 0, 1, 2,-1], [ 0, 2, 1, 1]], [[ 0, 0, 3,-1], [ 0, 3, 0, 1]], [[ 0, 1, 3,-1], [ 0, 3, 1, 1]], [[ 0, 2, 3,-1], [ 0, 3, 2, 1]]], self.assertTrue(numpy.allclose(idx, idx0))
def des_b(ci0, norb, nelec, ap_id): if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec des_index = cistring.gen_des_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb-1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (des_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap,2] sign = des_index[entry_has_ap,3] ci1[:,addr_ci1] = ci0[:,addr_ci0] * sign return ci1
def des_a(ci0, norb, nelec, ap_id): if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec des_index = cistring.gen_des_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca-1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = (des_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap,2] sign = des_index[entry_has_ap,3] #print(addr_ci0) #print(addr_ci1) ci1[addr_ci1] = sign.reshape(-1,1) * ci0[addr_ci0] return ci1
def des_a(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N-1)-electron wavefunction by removing an alpha electron from the N-electron wavefunction. ... math:: |N-1\rangle = \hat{a}_p |N\rangle Args: ci0 : 2D array CI coefficients, row for alpha strings and column for beta strings. norb : int Number of orbitals. (neleca,nelecb) : (int,int) Number of (alpha, beta) electrons of the input CI function ap_id : int Orbital index (0-based), for the annihilation operator Returns: 2D array, row for alpha strings and column for beta strings. Note it has different number of rows to the input CI coefficients ''' neleca, nelecb = neleca_nelecb if ci0.ndim == 1: ci0 = ci0.reshape(cistring.num_strings(norb, neleca), cistring.num_strings(norb, nelecb)) if neleca <= 0: return numpy.zeros((0, ci0.shape[1])) des_index = cistring.gen_des_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca-1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = (des_index[:,:,1] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap,2] sign = des_index[entry_has_ap,3] #print(addr_ci0) #print(addr_ci1) ci1[addr_ci1] = sign.reshape(-1,1) * ci0[addr_ci0] return ci1
def des_a(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N-1)-electron wavefunction by removing an alpha electron from the N-electron wavefunction. ... math:: |N-1\rangle = \hat{a}_p |N\rangle Args: ci0 : 2D array CI coefficients, row for alpha strings and column for beta strings. norb : int Number of orbitals. (neleca,nelecb) : (int,int) Number of (alpha, beta) electrons of the input CI function ap_id : int Orbital index (0-based), for the annihilation operator Returns: 2D array, row for alpha strings and column for beta strings. Note it has different number of rows to the input CI coefficients ''' neleca, nelecb = neleca_nelecb if ci0.ndim == 1: ci0 = ci0.reshape(cistring.num_strings(norb, neleca), cistring.num_strings(norb, nelecb)) if neleca <= 0: return numpy.zeros((0, ci0.shape[1])) des_index = cistring.gen_des_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca - 1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = (des_index[:, :, 1] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap, 2] sign = des_index[entry_has_ap, 3] #print(addr_ci0) #print(addr_ci1) ci1[addr_ci1] = sign.reshape(-1, 1) * ci0[addr_ci0] return ci1
def des_a(ci0, norb, nelec, ap_id): r'''Construct (N-1)-electron wavefunction by removing an alpha electron from the N-electron wavefunction. ... math:: |N-1\rangle = \hat{a}_p |N\rangle Args: ci0 : 2D array CI coefficients, row for alpha strings and column for beta strings. norb : int Number of orbitals. nelec : int or 2-item list Number of electrons, or 2-item list for (alpha, beta) electrons ap_id : int Orbital index (0-based), for the annihilation operator Returns: 2D array, row for alpha strings and column for beta strings. Note it has different number of rows to the input CI coefficients ''' if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec des_index = cistring.gen_des_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca-1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = (des_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap,2] sign = des_index[entry_has_ap,3] #print(addr_ci0) #print(addr_ci1) ci1[addr_ci1] = sign.reshape(-1,1) * ci0[addr_ci0] return ci1
def _make_rdm2_abba(fcivec, norb, nelec): fcivec = numpy.asarray(fcivec, order='C') neleca, nelecb = _unpack_nelec(nelec) if nelecb == norb or neleca == 0: # no intermediate determinants return numpy.zeros((norb, norb, norb, norb)) acre_index = cistring.gen_cre_str_index(range(norb), neleca - 1) bdes_index = cistring.gen_des_str_index(range(norb), nelecb + 1) instra = cistring.num_strings(norb, neleca - 1) nb = cistring.num_strings(norb, nelecb) dm1 = numpy.empty((norb, norb)) dm2 = numpy.empty((norb, norb, norb, norb)) librdm.FCIspindm12_drv(librdm.FCIdm2_abba_kern, dm1.ctypes.data_as(ctypes.c_void_p), dm2.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(instra), ctypes.c_int(nb), ctypes.c_int(neleca), ctypes.c_int(nelecb), acre_index.ctypes.data_as(ctypes.c_void_p), bdes_index.ctypes.data_as(ctypes.c_void_p)) return dm2
def _make_rdm2_abba(fcivec, norb, nelec): fcivec = numpy.asarray(fcivec, order='C') neleca, nelecb = _unpack_nelec(nelec) if nelecb == norb or neleca == 0: # no intermediate determinants return numpy.zeros((norb,norb,norb,norb)) acre_index = cistring.gen_cre_str_index(range(norb), neleca-1) bdes_index = cistring.gen_des_str_index(range(norb), nelecb+1) instra = cistring.num_strings(norb, neleca-1) nb = cistring.num_strings(norb, nelecb) dm1 = numpy.empty((norb,norb)) dm2 = numpy.empty((norb,norb,norb,norb)) librdm.FCIspindm12_drv(librdm.FCIdm2_abba_kern, dm1.ctypes.data_as(ctypes.c_void_p), dm2.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(instra), ctypes.c_int(nb), ctypes.c_int(neleca), ctypes.c_int(nelecb), acre_index.ctypes.data_as(ctypes.c_void_p), bdes_index.ctypes.data_as(ctypes.c_void_p)) return dm2
def _make_rdm2_baab(fcivec, norb, nelec): fcivec = numpy.asarray(fcivec, order='C') neleca, nelecb = _unpack(nelec) if neleca == norb or nelecb == 0: # no intermediate determinants return numpy.zeros((norb,norb,norb,norb)) ades_index = cistring.gen_des_str_index(range(norb), neleca+1) bcre_index = cistring.gen_cre_str_index(range(norb), nelecb-1) instra = cistring.num_strings(norb, neleca+1) nb = cistring.num_strings(norb, nelecb) dm1 = numpy.empty((norb,norb)) dm2 = numpy.empty((norb,norb,norb,norb)) fn = _ctypes.dlsym(librdm._handle, 'FCIdm2_baab_kern') librdm.FCIspindm12_drv(ctypes.c_void_p(fn), dm1.ctypes.data_as(ctypes.c_void_p), dm2.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(instra), ctypes.c_int(nb), ctypes.c_int(neleca), ctypes.c_int(nelecb), ades_index.ctypes.data_as(ctypes.c_void_p), bcre_index.ctypes.data_as(ctypes.c_void_p)) return dm2
def des_b(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N-1)-electron wavefunction by removing a beta electron from N-electron wavefunction. Args: ci0 : 2D array CI coefficients, row for alpha strings and column for beta strings. norb : int Number of orbitals. (neleca,nelecb) : (int,int) Number of (alpha, beta) electrons of the input CI function ap_id : int Orbital index (0-based), for the annihilation operator Returns: 2D array, row for alpha strings and column for beta strings. Note it has different number of columns to the input CI coefficients. ''' neleca, nelecb = neleca_nelecb if ci0.ndim == 1: ci0 = ci0.reshape(cistring.num_strings(norb, neleca), cistring.num_strings(norb, nelecb)) if nelecb <= 0: return numpy.zeros((ci0.shape[0], 0)) des_index = cistring.gen_des_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb-1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (des_index[:,:,1] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap,2] sign = des_index[entry_has_ap,3] # This sign prefactor accounts for interchange of operators with alpha and beta spins if neleca % 2 == 1: sign *= -1 ci1[:,addr_ci1] = ci0[:,addr_ci0] * sign return ci1
def des_b(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N-1)-electron wavefunction by removing a beta electron from N-electron wavefunction. Args: ci0 : 2D array CI coefficients, row for alpha strings and column for beta strings. norb : int Number of orbitals. (neleca,nelecb) : (int,int) Number of (alpha, beta) electrons of the input CI function ap_id : int Orbital index (0-based), for the annihilation operator Returns: 2D array, row for alpha strings and column for beta strings. Note it has different number of columns to the input CI coefficients. ''' neleca, nelecb = neleca_nelecb if ci0.ndim == 1: ci0 = ci0.reshape(cistring.num_strings(norb, neleca), cistring.num_strings(norb, nelecb)) if nelecb <= 0: return numpy.zeros((ci0.shape[0], 0)) des_index = cistring.gen_des_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb - 1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (des_index[:, :, 1] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = des_index[entry_has_ap, 2] sign = des_index[entry_has_ap, 3] # This sign prefactor accounts for interchange of operators with alpha and beta spins if neleca % 2 == 1: sign *= -1 ci1[:, addr_ci1] = ci0[:, addr_ci0] * sign return ci1