def cre_a(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N+1)-electron wavefunction by adding an alpha electron in 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 creation 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 neleca >= norb: return numpy.zeros((0, ci0.shape[1])) cre_index = cistring.gen_cre_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca+1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = (cre_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap,2] sign = cre_index[entry_has_ap,3] ci1[addr_ci1] = sign.reshape(-1,1) * ci0[addr_ci0] return ci1
def cre_b(ci0, norb, nelec, ap_id): r'''Construct (N+1)-electron wavefunction by adding a beta electron in the 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 creation 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 cre_index = cistring.gen_cre_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb+1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (cre_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap,2] sign = cre_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_cre_str_index(self): idx = cistring.gen_cre_str_index(range(4), 2) idx0 = [[[ 2, 0, 0, 1], [ 3, 0, 1, 1]], [[ 1, 0, 0,-1], [ 3, 0, 2, 1]], [[ 0, 0, 0, 1], [ 3, 0, 3, 1]], [[ 1, 0, 1,-1], [ 2, 0, 2,-1]], [[ 0, 0, 1, 1], [ 2, 0, 3,-1]], [[ 0, 0, 2, 1], [ 1, 0, 3, 1]]] self.assertTrue(numpy.allclose(idx, idx0))
def cre_b(ci0, norb, nelec, ap_id): if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec cre_index = cistring.gen_cre_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb-1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (cre_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap,2] sign = cre_index[entry_has_ap,3] ci1[:,addr_ci1] = ci0[:,addr_ci0] * sign return ci1
def cre_a(ci0, norb, nelec, ap_id): if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec cre_index = cistring.gen_cre_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca+1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = (cre_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap,2] sign = cre_index[entry_has_ap,3] 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 cre_a(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N+1)-electron wavefunction by adding an alpha electron in 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 creation 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 >= norb: return numpy.zeros((0, ci0.shape[1])) cre_index = cistring.gen_cre_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca + 1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = (cre_index[:, :, 0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap, 2] sign = cre_index[entry_has_ap, 3] ci1[addr_ci1] = sign.reshape(-1, 1) * ci0[addr_ci0] return ci1
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 cre_b(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N+1)-electron wavefunction by adding a beta electron in the 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 creation 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 >= norb: return numpy.zeros((ci0.shape[0], 0)) cre_index = cistring.gen_cre_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb+1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (cre_index[:,:,0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap,2] sign = cre_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 cre_b(ci0, norb, neleca_nelecb, ap_id): r'''Construct (N+1)-electron wavefunction by adding a beta electron in the 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 creation 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 >= norb: return numpy.zeros((ci0.shape[0], 0)) cre_index = cistring.gen_cre_str_index(range(norb), nelecb) nb_ci1 = cistring.num_strings(norb, nelecb + 1) ci1 = numpy.zeros((ci0.shape[0], nb_ci1)) entry_has_ap = (cre_index[:, :, 0] == ap_id) addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap, 2] sign = cre_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 cre_a(ci0, norb, nelec, ap_id): r"""Construct (N+1)-electron wavefunction by adding an alpha electron in 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 creation 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 cre_index = cistring.gen_cre_str_index(range(norb), neleca) na_ci1 = cistring.num_strings(norb, neleca + 1) ci1 = numpy.zeros((na_ci1, ci0.shape[1])) entry_has_ap = cre_index[:, :, 0] == ap_id addr_ci0 = numpy.any(entry_has_ap, axis=1) addr_ci1 = cre_index[entry_has_ap, 2] sign = cre_index[entry_has_ap, 3] ci1[addr_ci1] = sign.reshape(-1, 1) * ci0[addr_ci0] return ci1