Exemplo n.º 1
0
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"]
Exemplo n.º 2
0
   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=[]
Exemplo n.º 3
0
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"]
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
    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 = []
Exemplo n.º 7
0
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."