def precomputed_integral_1b(l1, l2, idx): """ Return the precomputed value stored at position idx in onebody_funcs with matrix elements l1,l2 """ targ = onebody_funcs[idx] enu = enum(targ["caps"]) n1 = enu.toidx(l1) n2 = enu.toidx(l2) return targ["M"][n1, n2] * targ["factor"]
def __init__(self, bpar,sizes, npart, borders, nint=1000, symmetry=None): """ Initialize a set of N-particle basis functions. IN: bpar = tuple containing the harmonic oscillator basis set parameter (m*w/hbar) for each space direction. sizes = tuple for the number of single-particle states for each dimension npart = number of particles borders = list of integration borders for each direction: [(x0,x1),(y0,y1)...] nint = number of points for numerical integrals symmetry= can be "Bose", "Fermi" or None """ self._sizes = sizes self._enu = enum(sizes) self._sizesing = reduce(lambda i,j : int(i)*int(j),sizes,1) self._npart = int(npart) self._symmetry = symmetry self._bpar = bpar self._borders = borders self._nint = nint self.dim = len(self._sizes) if not symmetry in ("Bose","Fermi","Distinguishable",None): print "Unrecognized symmetry=",symmetry raise ValueError maxcount = int(self._sizesing**self._npart) if self._symmetry is "Fermi": if self._sizesing < npart: raise ValueError maxcount = int(binom(self._sizesing,self._npart)*math.factorial(self._npart)) self._qnumbers=define_quantumnumbers(sizes,maxcount,npart,symmetry) self.size = len(self._qnumbers) self.firstder_matrix=None self.secder_matrix=None self.Umatrix=None self.V2matrix=None # anytime braket is called with a different function # you register and compute the elements for a new # matrix. Elements should be (func,nbodies) self._regmatrices=[]
def precomputed_integral_2b(l1, l2, l3, l4, idx): """ Return the precomputed value stored at position idx in onebody_funcs with matrix elements l1,l2 """ targ = twobody_funcs[idx] enu = enum(targ["caps"]) n1 = enu.toidx(l1) n2 = enu.toidx(l2) n3 = enu.toidx(l3) n4 = enu.toidx(l4) return targ["M"][n1, n2, n3, n4] * targ["factor"]
def ___init___(self): """ Basic structure for a basis set object with all the dummy functions required. """ self.size = 0 self.c = 0 self.borders = 0 self.nint = 0 self.secder_matrix = [] self.firstder_matrix = [] self.v2_matrix = [] self._enu = enum((1, 1, 1)) # dummy object self._symmetry = "Distinguishable" self._qnumbers = [1, 1] # dummy self.dim = 2 self._npart = 1
def fft(func, fftpoints, L): """ Does the integral (1/L**d) \int_{-L/2}^{L/2} dr exp(-ikr)f(r) in d dimensions, where k = (2*pi/L)n. With some algebra one can see that this is equivalent to exp(i * pi * n) \int_0^1 ds exp(-i 2*pi n*s) f(L(s-0.5)). This notation is intended to be vectorial in the obvious way. In this form the numpy fft can be used. Returns a ndarray whose elements are wavenumbers translated by nk[d]/2, so that a[n/2,n/2,..] is the k=0 component. """ dim = len(L) pcaps = [fftpoints] * dim enu = enum(pcaps) fdata = np.zeros(pcaps) for samp in xrange(enu.maxidx): lsamp = enu.tolevels(samp) s = map(lambda i, j: float(i) / j, lsamp, pcaps) xsamp = [(L[d] * float(lsamp[d]) / pcaps[d] - float(L[d]) / 2) for d in xrange(dim)] fdata[lsamp] = func(xsamp) ft = np.fft.fftn(fdata) ft = np.fft.fftshift(ft) for nks in xrange(enu.maxidx): ks = enu.tolevels(nks) nrm = (fftpoints)**dim for ck in ks: ck = ck - fftpoints / 2 if ck % 2 != 0: nrm = -nrm ft[ks] = ft[ks] / nrm return ft
def __init__(self, Lbox, ksizes, npart, symmetry=None, fftpoints=128): """ Initialize a set of N-particle basis functions made of planewaves. IN: Lbox = tuple containing the size of the box for each direction ksizes = tuple for the number of single-particle wavevectors for each dimension. Should be an even quantity. npart = number of particles symmetry = can be "Bose", "Fermi" or None fftpoints = points for each direction of the fourier transforms. Single particle in pbc wavefunction phi_n (r) = exp(-i k_n * r)/sqrt(V). For n=-ksize/2,...,ksize/2: this is considered in the definition of wavefunctions, where the levels are translated accordingly. Box is considered symmetric and centered so that the edges are at +/- L/2 for each direction. """ # if ksizes not even translate accordingly. ksizes = map(lambda i: i + i % 2, ksizes) self._ksizes = ksizes self._enu = enum(self._ksizes) self._sizesing = reduce(lambda i, j: int(i) * int(j), self._ksizes, 1) self._kbase = map(lambda i: 2 * math.pi / i, Lbox) self.Lbox = Lbox self.Vbox = 1 for L in Lbox: self.Vbox = self.Vbox * L self._npart = int(npart) self._symmetry = symmetry self.dim = len(self._ksizes) if fftpoints % 2 != 0: print "++++ ODD fftpoints given. Making it even" fftpoints = fftpoints + 1 if fftpoints / 2 < 2 * max(ksizes): print "++++ WARNING: fftpoints is too small, making it the minimum allowed size." fftpoints = 4 * max(ksizes) self.fftpoints = fftpoints if not symmetry in ("Bose", "Fermi", "Distinguishable", None): print "Unrecognized symmetry=", symmetry raise ValueError maxcount = int(self._sizesing**self._npart) if self._symmetry is "Fermi": if self._sizesing < npart: raise ValueError maxcount = int( binom(self._sizesing, self._npart) * math.factorial(self._npart)) self._qnumbers = define_quantumnumbers(self._ksizes, maxcount, npart, symmetry) self.size = len(self._qnumbers) self.firstder_matrix = None self.secder_matrix = None self.Umatrix = None self.V2matrix = None # anytime braket is called with a different function # you register and compute the elements for a new # matrix. Elements should be (func,nbodies) self._regmatrices = [] # integrator functions will register fourier transforms the first time # <func> is asked for. The elements of these arrays are tuples (func, ndarray) self._regft1b = [] self._regft2b = []
def writeFunc(idfunc, fassoc, bpars, caps, mcpoints, fdir, integrator, iszero=lambda i: False, analytical=lambda i: None, symm=True): """ Compute and write the integrals to the corresponding file. IN: idfunc = the ID of the entry fassoc = the function to be used caps = a tuple defining the caps for each quantum number mcpoints = the number of MC steps of integration iszero = a given function that can tell from the levels whether the integral will be null or not. This function takes a tuple as argument, structured as (t1,t2,...tx) where tx are tuples containing the levels. Note that for 1 body the arg is (t1,t2) and for 2 bodies (t1,t2,t3,t4) analytical = a function that given the same arguments as iszero computes the integral analytically. symm = it's a fully symmetric tensor, that means i<=j for 1-body and i<=j<=k<=l for 2-body """ dim = len(caps) arf = nargs(fassoc) body = int(len(arf.args)) if body == 1: fpath = fdir + "/onebody.dat" else: fpath = fdir + "/twobody.dat" # check if it already exists try: f = open(fpath, "r") for ln in f: ln = ln[:-1] if ln.find("ID=") != -1: (n, val) = ln.split("=") if val == idfunc: print idfunc, " already present in file." raise ValueError f.close() except IOError: pass f = open(fpath, "a") enu = enum(caps) maxsize = enu.maxidx f.write("ID=" + idfunc + "\n") f.write("DIM=" + str(dim) + "\n") bpline = "BPAR=" for bp in bpars: bpline = bpline + "{0:14.10f},".format(float(bp)) bpline = list(bpline) bpline = "".join(bpline[:-1]) + "\n" f.write(bpline) capsline = "CAPS=" for cp in caps: capsline = capsline + "{0:3d},".format(int(cp)) capsline = list(capsline) capsline = "".join(capsline[:-1]) + "\n" f.write(capsline) fcaps = [maxsize] * (2 * body) fenu = enum(fcaps) print "Header done. \n Writing datablock \n [ ", sys.stdout.flush() percblock = fenu.maxidx / 10 for i in xrange(fenu.maxidx): flev = fenu.tolevels(i) llist = [] for l in flev: ltadd = enu.tolevels(l) llist.append(ltadd) isord = True if symm is True: if body == 1: if flev[0] > flev[1]: isord = False else: if flev[0] > flev[1] or flev[0] > flev[2] or flev[2] > flev[3]: isord = False val = 0 if not iszero(llist) and isord: val = analytical(llist) if val is None: val = integrator(bpars, *llist, func=fassoc, borders=None, nint=mcpoints) if abs(val) > 1E-4: ln = "" for l in flev: ln = ln + "{0:3d},".format(int(l)) ln = ln + "{0:20.10f}\n".format(float(val)) f.write(ln) if (i + 1) % percblock == 0: print "*", sys.stdout.flush() print "] \n Done."