Exemple #1
0
    def get_H(self,mvals=None,customdir=None):
        """Computes the objective function contribution and its gradient / Hessian.

        First the low-level 'get' method is called with the analytic gradient
        and Hessian both turned on.  Then we loop through the fd1_pids and compute
        the corresponding elements of the gradient by finite difference,
        if the 'fdgrad' switch is turned on.

        This is followed by looping through the fd2_pids and computing the corresponding
        Hessian elements by finite difference.  Forward finite difference is used
        throughout for the sake of speed.
        """
        Ans = self.meta_get(mvals,1,1,customdir=customdir)
        if self.fdhess:
            for i in self.pgrad:
                if any([j in self.FF.plist[i] for j in self.fd1_pids]) or 'ALL' in self.fd1_pids:
                    Ans['G'][i] = f1d2p(fdwrap_G(self,mvals,i),self.h,f0 = Ans['X'])
            for i in self.pgrad:
                if any([j in self.FF.plist[i] for j in self.fd2_pids]) or 'ALL' in self.fd2_pids:
                    FDSlice = f1d2p(fdwrap_H(self,mvals,i),self.h,f0 = Ans['G'])
                    Ans['H'][i,:] = FDSlice
                    Ans['H'][:,i] = FDSlice
        elif self.fdhessdiag:
            for i in self.pgrad:
                if any([j in self.FF.plist[i] for j in self.fd2_pids]) or 'ALL' in self.fd2_pids:
                    Ans['G'][i], Ans['H'][i,i] = f12d3p(fdwrap_G(self,mvals,i),self.h, f0 = Ans['X'])
        if Counter() == self.zerograd and self.zerograd >= 0: 
            self.write_0grads(Ans)
        self.hct += 1
        return Ans
Exemple #2
0
    def get_H(self,mvals=None):
        """Computes the objective function contribution and its gradient / Hessian.

        First the low-level 'get' method is called with the analytic gradient
        and Hessian both turned on.  Then we loop through the fd1_pids and compute
        the corresponding elements of the gradient by finite difference,
        if the 'fdgrad' switch is turned on.

        This is followed by looping through the fd2_pids and computing the corresponding
        Hessian elements by finite difference.  Forward finite difference is used
        throughout for the sake of speed.
        """
        Ans = self.meta_get(mvals,1,1)
        if self.fdhess:
            for i in self.pgrad:
                if any([j in self.FF.plist[i] for j in self.fd1_pids]) or 'ALL' in self.fd1_pids:
                    Ans['G'][i] = f1d2p(fdwrap_G(self,mvals,i),self.h,f0 = Ans['X'])
            for i in self.pgrad:
                if any([j in self.FF.plist[i] for j in self.fd2_pids]) or 'ALL' in self.fd2_pids:
                    FDSlice = f1d2p(fdwrap_H(self,mvals,i),self.h,f0 = Ans['G'])
                    Ans['H'][i,:] = FDSlice
                    Ans['H'][:,i] = FDSlice
        elif self.fdhessdiag:
            for i in self.pgrad:
                if any([j in self.FF.plist[i] for j in self.fd2_pids]) or 'ALL' in self.fd2_pids:
                    Ans['G'][i], Ans['H'][i,i] = f12d3p(fdwrap_G(self,mvals,i),self.h, f0 = Ans['X'])
        self.write_0grads(Ans)
        self.hct += 1
        return Ans
Exemple #3
0
    def get_G(self,mvals=None):
        """Computes the objective function contribution and its gradient.

        First the low-level 'get' method is called with the analytic gradient
        switch turned on.  Then we loop through the fd1_pids and compute
        the corresponding elements of the gradient by finite difference,
        if the 'fdgrad' switch is turned on.  Alternately we can compute
        the gradient elements and diagonal Hessian elements at the same time
        using central difference if 'fdhessdiag' is turned on.

        In this function we also record which parameters cause a
        nonzero change in the objective function contribution.
        Parameters which do not change the objective function will
        not be differentiated in subsequent calculations.  This is
        recorded in a text file in the targets directory.

        """
        Ans = self.meta_get(mvals,1,0)
        for i in self.pgrad:
            if any([j in self.FF.plist[i] for j in self.fd1_pids]) or 'ALL' in self.fd1_pids:
                if self.fdhessdiag:
                    Ans['G'][i], Ans['H'][i,i] = f12d3p(fdwrap_G(self,mvals,i),self.h,f0 = Ans['X'])
                elif self.fdgrad:
                    Ans['G'][i] = f1d2p(fdwrap_G(self,mvals,i),self.h,f0 = Ans['X'])
        self.gct += 1
        self.write_0grads(Ans)
        return Ans
Exemple #4
0
    def get_G(self,mvals=None):
        """Computes the objective function contribution and its gradient.

        First the low-level 'get' method is called with the analytic gradient
        switch turned on.  Then we loop through the fd1_pids and compute
        the corresponding elements of the gradient by finite difference,
        if the 'fdgrad' switch is turned on.  Alternately we can compute
        the gradient elements and diagonal Hessian elements at the same time
        using central difference if 'fdhessdiag' is turned on.
        """
        Ans = self.sget(mvals,1,0)
        for i in range(self.FF.np):
            if any([j in self.FF.plist[i] for j in self.fd1_pids]) or 'ALL' in self.fd1_pids:
                if self.fdhessdiag:
                    Ans['G'][i], Ans['H'][i,i] = f12d3p(fdwrap_G(self,mvals,i),self.h,f0 = Ans['X'])
                elif self.fdgrad:
                    Ans['G'][i] = f1d2p(fdwrap_G(self,mvals,i),self.h,f0 = Ans['X'])
        self.gct += 1
        return Ans
Exemple #5
0
    def get(self, mvals, AGrad=False, AHess=False):
        """
        LPW 05-30-2012
        
        This subroutine builds the objective function (and optionally
        its derivatives) from a general software.  

        This subroutine interfaces with simulation software 'drivers'.
        The driver is expected to give exact values, fitting values, and weights.

        @param[in] mvals Mathematical parameter values
        @param[in] AGrad Switch to turn on analytic gradient
        @param[in] AHess Switch to turn on analytic Hessian
        @return Answer Contribution to the objective function
        """
        global LAST_MVALS, CHECK_BASIS
        # print mvals
        # print LAST_MVALS
        # print mvals == LAST_MVALS
        if LAST_MVALS is None or not (mvals == LAST_MVALS).all():
            CHECK_BASIS = False
        else:
            CHECK_BASIS = False
        Answer = {}
        Fac = 1000000
        ## Dictionary for derivative terms
        dM = {}
        # Create the new force field!!
        NP = len(mvals)
        G = np.zeros(NP)
        H = np.zeros((NP, NP))
        pvals = self.FF.make(mvals)
        if float('Inf') in pvals:
            return {'X': 1e10, 'G': G, 'H': H}
        Ans = self.driver()
        W = Ans[:, 2]
        M = Ans[:, 1]
        Q = Ans[:, 0]
        D = M - Q

        self.MAQ = np.mean(np.abs(Q))

        ns = len(M)

        # Wrapper to the driver, which returns just the part that changes.
        def callM(mvals_):
            self.FF.make(mvals_)
            Ans2 = self.driver()
            M_ = Ans2[:, 1]
            D_ = M_ - Q
            return Ans2[:, 1]

        if AGrad:
            # Leaving comment here if we want to reintroduce second deriv someday.
            #     dM[p,:], ddM[p,:] = f12d3p(fdwrap(callM, mvals, p), h = self.h, f0 = M)
            xgrad = []
            for p in self.pgrad:
                dM_arr = f1d2p(fdwrap(callM, mvals, p), h=self.h, f0=M)
                if np.max(np.abs(dM_arr)) == 0.0 and (not self.evaluated):
                    logger.info(
                        "\r Simulation %s will skip over parameter %i in subsequent steps\n"
                        % (self.name, p))
                    xgrad.append(p)
                else:
                    dM[p] = dM_arr.copy()
            for p in xgrad:
                self.pgrad.remove(p)
        Objective = np.dot(W, D**2) * Fac
        if AGrad:
            for p in self.pgrad:
                G[p] = 2 * np.dot(W, D * dM[p])
                if not AHess: continue
                H[p, p] = 2 * np.dot(W, dM[p]**2)
                for q in range(p):
                    if q not in self.pgrad: continue
                    GNP = 2 * np.dot(W, dM[p] * dM[q])
                    H[q, p] = GNP
                    H[p, q] = GNP
        G *= Fac
        H *= Fac
        Answer = {'X': Objective, 'G': G, 'H': H}
        if not in_fd():
            self.D = D
            self.objective = Answer['X']
            LAST_MVALS = mvals.copy()
        return Answer
Exemple #6
0
    def get(self, mvals, AGrad=False, AHess=False):
	"""
        LPW 05-30-2012
        
        This subroutine builds the objective function (and optionally
        its derivatives) from a general software.  

        This subroutine interfaces with simulation software 'drivers'.
        The driver is expected to give exact values, fitting values, and weights.

        @param[in] mvals Mathematical parameter values
        @param[in] AGrad Switch to turn on analytic gradient
        @param[in] AHess Switch to turn on analytic Hessian
        @return Answer Contribution to the objective function
        """
        global LAST_MVALS, CHECK_BASIS
        # print mvals
        # print LAST_MVALS
        # print mvals == LAST_MVALS
        if LAST_MVALS is None or not (mvals == LAST_MVALS).all():
            CHECK_BASIS = False
        else:
            CHECK_BASIS = False
        Answer = {}
        Fac = 1000000
        ## Dictionary for derivative terms
        dM = {}
        # Create the new force field!!
        NP = len(mvals)
        G = np.zeros(NP)
        H = np.zeros((NP,NP))
        pvals = self.FF.make(mvals)
        if float('Inf') in pvals:
            return {'X' : 1e10, 'G' : G, 'H' : H}
        Ans = self.driver()
        W = Ans[:,2]
        M = Ans[:,1]
        Q = Ans[:,0]
        D = M - Q

        self.MAQ = np.mean(np.abs(Q))

        ns = len(M)
        # Wrapper to the driver, which returns just the part that changes.
        def callM(mvals_):
            self.FF.make(mvals_)
            Ans2 = self.driver()
            M_ = Ans2[:,1]
            D_ = M_ - Q
	    return Ans2[:,1]
        if AGrad:
            # Leaving comment here if we want to reintroduce second deriv someday.
            #     dM[p,:], ddM[p,:] = f12d3p(fdwrap(callM, mvals, p), h = self.h, f0 = M)
            xgrad = []
            for p in self.pgrad:
                dM_arr = f1d2p(fdwrap(callM, mvals, p), h = self.h, f0 = M)
                if np.max(np.abs(dM_arr)) == 0.0 and (not self.evaluated):
                    logger.info("\r Simulation %s will skip over parameter %i in subsequent steps\n" % (self.name, p))
                    xgrad.append(p)
                else:
                    dM[p] = dM_arr.copy()
            for p in xgrad:
                self.pgrad.remove(p)
	Objective = np.dot(W, D**2) * Fac
        if AGrad:
            for p in self.pgrad:
                G[p] = 2 * np.dot(W, D*dM[p])
                if not AHess: continue
                H[p, p] = 2 * np.dot(W, dM[p]**2)
                for q in range(p):
                    if q not in self.pgrad: continue
                    GNP = 2 * np.dot(W, dM[p] * dM[q])
                    H[q,p] = GNP
                    H[p,q] = GNP
        G *= Fac
        H *= Fac
        Answer = {'X':Objective, 'G':G, 'H':H}
        if not in_fd():
            self.D = D
            self.objective = Answer['X']
            LAST_MVALS = mvals.copy()
        return Answer
Exemple #7
0
    def get(self, mvals, AGrad=False, AHess=False):
	"""
        LPW 04-17-2013
        
        This subroutine builds the objective function from Psi4.

        @param[in] mvals Mathematical parameter values
        @param[in] AGrad Switch to turn on analytic gradient
        @param[in] AHess Switch to turn on analytic Hessian
        @return Answer Contribution to the objective function
        """
        Answer = {}
        Fac = 1000000
        n = len(mvals)
        X = 0.0
        G = np.zeros(n)
        H = np.zeros((n,n))
        pvals = self.FF.make(mvals)
        self.tdir = os.getcwd()
        self.objd = OrderedDict()
        self.gradd = OrderedDict()
        self.hdiagd = OrderedDict()
        wq = getWorkQueue()

        def fdwrap2(func,mvals0,pidx,qidx,key=None,**kwargs):
            def func2(arg1,arg2):
                mvals = list(mvals0)
                mvals[pidx] += arg1
                mvals[qidx] += arg2
                logger.info("\rfdwrap2:" + func.__name__ + "[%i] = % .1e , [%i] = % .1e" % (pidx, arg1, qidx, arg2) + ' '*50)
                if key != None:
                    return func(mvals,**kwargs)[key]
                else:
                    return func(mvals,**kwargs)
            return func2

        def f2d5p(f, h):
            fpp, fpm, fmp, fmm = [f(i*h,j*h) for i,j in [(1,1),(1,-1),(-1,1),(-1,-1)]]
            fpp = (fpp-fpm-fmp+fmm)/(4*h*h)
            return fpp

        def f2d4p(f, h, f0 = None):
            if f0 == None:
                fpp, fp0, f0p, f0 = [f(i*h,j*h) for i,j in [(1,1),(1,0),(0,1),(0,0)]]
            else:
                fpp, fp0, f0p = [f(i*h,j*h) for i,j in [(1,1),(1,0),(0,1)]]
            fpp = (fpp-fp0-f0p+f0)/(h*h)
            return fpp

        for d in self.objfiles:
            logger.info("\rNow working on" + str(d) + 50*' ' + '\r')
            if wq == None:
                x = self.driver(mvals, d)
            grad  = np.zeros(n)
            hdiag = np.zeros(n)
            hess  = np.zeros((n,n))
            apath = os.path.join(self.tdir, d, "current")
            x = float(open(os.path.join(apath,'objective.out')).readlines()[0].split()[1])*self.factor
            for p in range(self.FF.np):
                if self.callderivs[d][p]:
                    def reader(mvals_,h):
                        apath = os.path.join(self.tdir, d, str(p), str(h))
                        answer = float(open(os.path.join(apath,'objective.out')).readlines()[0].split()[1])*self.factor
                        return answer
                    if AHess:
                        if wq != None:
                            apath = os.path.join(self.tdir, d, "current")
                            x = float(open(os.path.join(apath,'objective.out')).readlines()[0].split()[1])*self.factor
                            grad[p], hdiag[p] = f12d3p(fdwrap(reader, mvals, p, h=self.h), h = self.h, f0 = x)
                        else:
                            grad[p], hdiag[p] = f12d3p(fdwrap(self.driver, mvals, p, d=d), h = self.h, f0 = x)
                        hess[p,p] = hdiag[p]
                    elif AGrad:
                        if self.bidirect:
                            if wq != None:
                                apath = os.path.join(self.tdir, d, "current")
                                x = float(open(os.path.join(apath,'objective.out')).readlines()[0].split()[1])*self.factor
                                grad[p], _ = f12d3p(fdwrap(reader, mvals, p, h=self.h), h = self.h, f0 = x)
                            else:
                                grad[p], _ = f12d3p(fdwrap(self.driver, mvals, p, d=d), h = self.h, f0 = x)
                        else:
                            if wq != None:
                                # Since the calculations are submitted as 3-point finite difference, this part of the code
                                # actually only reads from half of the completed calculations.
                                grad[p] = f1d2p(fdwrap(reader, mvals, p, h=self.h), h = self.h, f0 = x)
                            else:
                                grad[p] = f1d2p(fdwrap(self.driver, mvals, p, d=d), h = self.h, f0 = x)
                            
            self.objd[d] = x
            self.gradd[d] = grad
            self.hdiagd[d] = hdiag
            X += x
            G += grad
            #H += np.diag(hdiag)
            H += hess
        if not in_fd():
            self.objective = X
            self.objvals = self.objd
        # print self.objd
        # print self.gradd
        # print self.hdiagd
                    
        if float('Inf') in pvals:
            return {'X' : 1e10, 'G' : G, 'H' : H}
        return {'X' : X, 'G' : G, 'H' : H}
Exemple #8
0
    def submit_jobs(self, mvals, AGrad=True, AHess=True):
        # This routine is called by Objective.stage() will run before "get".
        # It submits the jobs to the Work Queue and the stage() function will wait for jobs to complete.
        #
        self.tdir = os.getcwd()
        wq = getWorkQueue()
        if wq == None:
            return

        def submit_psi(this_apath, mname, these_mvals):
            """ Create a grid file and a psi4 input file in the absolute path and submit it to the work queue. """
            cwd = os.getcwd()
            if not os.path.exists(this_apath) : os.makedirs(this_apath)
            os.chdir(this_apath)
            self.FF.make(these_mvals)
            o = wopen('objective.dat')
            for line in self.objfiles[d]:
                s = line.split()
                if len(s) > 2 and s[0] == 'path' and s[1] == '=':
                    print >> o, "path = '%s'" % os.getcwd()
                elif len(s) > 2 and s[0] == 'set' and s[1] == 'objective_path':
                    print >> o, "opath = '%s'" % os.getcwd()
                    print >> o, "set objective_path $opath"
                else:
                    print >> o, line,
            o.close()
            os.system("rm -f objective.out")
            if wq == None:
                logger.info("There is no Work Queue!!!\n")
                sys.exit()
            else:
                input_files = [(os.path.join(this_apath, i), i) for i in glob.glob("*")]
                # input_files += [(os.path.join(self.tgtdir,d,"build.dat"), "build.dat")]
                input_files += [(os.path.join(os.path.split(__file__)[0],"data","run_psi_rdvr3_objective.sh"), "run_psi_rdvr3_objective.sh")]
                logger.info("\r")
                queue_up_src_dest(wq,"sh run_psi_rdvr3_objective.sh %s &> run_psi_rdvr3_objective.log" % mname,
                                  input_files=input_files,
                                  output_files=[(os.path.join(this_apath, i),i) for i in ["run_psi_rdvr3_objective.log", "output.dat"]], verbose=False)
            os.chdir(cwd)

        for d in self.objfiles:
            logger.info("\rNow working on" + str(d) + 50*' ' + '\r')
            odir = os.path.join(os.getcwd(),d)
            #if os.path.exists(odir):
            #    shutil.rmtree(odir)
            if not os.path.exists(odir): os.makedirs(odir)
            apath = os.path.join(odir, "current")
            submit_psi(apath, d, mvals)
            for p in range(self.FF.np):
                def subjob(mvals_,h):
                    apath = os.path.join(odir, str(p), str(h))
                    submit_psi(apath, d, mvals_)
                    #logger.info("Will set up a job for %s, parameter %i\n" % (d, p))
                    return 0.0
                if self.callderivs[d][p]:
                    if AHess:
                        f12d3p(fdwrap(subjob, mvals, p, h=self.h), h = self.h, f0 = 0.0)
                    elif AGrad:
                        if self.bidirect:
                            f12d3p(fdwrap(subjob, mvals, p, h=self.h), h = self.h, f0 = 0.0)
                        else:
                            f1d2p(fdwrap(subjob, mvals, p, h=self.h), h = self.h, f0 = 0.0)
Exemple #9
0
    def get(self, mvals, AGrad=False, AHess=False):
        """
        LPW 04-17-2013
        
        This subroutine builds the objective function from Psi4.

        @param[in] mvals Mathematical parameter values
        @param[in] AGrad Switch to turn on analytic gradient
        @param[in] AHess Switch to turn on analytic Hessian
        @return Answer Contribution to the objective function
        """
        Answer = {}
        Fac = 1000000
        n = len(mvals)
        X = 0.0
        G = np.zeros(n)
        H = np.zeros((n, n))
        pvals = self.FF.make(mvals)
        self.tdir = os.getcwd()
        self.objd = OrderedDict()
        self.gradd = OrderedDict()
        self.hdiagd = OrderedDict()
        wq = getWorkQueue()

        def fdwrap2(func, mvals0, pidx, qidx, key=None, **kwargs):
            def func2(arg1, arg2):
                mvals = list(mvals0)
                mvals[pidx] += arg1
                mvals[qidx] += arg2
                logger.info("\rfdwrap2:" + func.__name__ +
                            "[%i] = % .1e , [%i] = % .1e" %
                            (pidx, arg1, qidx, arg2) + ' ' * 50)
                if key is not None:
                    return func(mvals, **kwargs)[key]
                else:
                    return func(mvals, **kwargs)

            return func2

        def f2d5p(f, h):
            fpp, fpm, fmp, fmm = [
                f(i * h, j * h)
                for i, j in [(1, 1), (1, -1), (-1, 1), (-1, -1)]
            ]
            fpp = (fpp - fpm - fmp + fmm) / (4 * h * h)
            return fpp

        def f2d4p(f, h, f0=None):
            if f0 is None:
                fpp, fp0, f0p, f0 = [
                    f(i * h, j * h)
                    for i, j in [(1, 1), (1, 0), (0, 1), (0, 0)]
                ]
            else:
                fpp, fp0, f0p = [
                    f(i * h, j * h) for i, j in [(1, 1), (1, 0), (0, 1)]
                ]
            fpp = (fpp - fp0 - f0p + f0) / (h * h)
            return fpp

        for d in self.objfiles:
            logger.info("\rNow working on" + str(d) + 50 * ' ' + '\r')
            if wq is None:
                x = self.driver(mvals, d)
            grad = np.zeros(n)
            hdiag = np.zeros(n)
            hess = np.zeros((n, n))
            apath = os.path.join(self.tdir, d, "current")
            x = float(
                open(os.path.join(
                    apath,
                    'objective.out')).readlines()[0].split()[1]) * self.factor
            for p in range(self.FF.np):
                if self.callderivs[d][p]:

                    def reader(mvals_, h):
                        apath = os.path.join(self.tdir, d, str(p), str(h))
                        answer = float(
                            open(os.path.join(apath, 'objective.out')).
                            readlines()[0].split()[1]) * self.factor
                        return answer

                    if AHess:
                        if wq is not None:
                            apath = os.path.join(self.tdir, d, "current")
                            x = float(
                                open(os.path.join(apath, 'objective.out')).
                                readlines()[0].split()[1]) * self.factor
                            grad[p], hdiag[p] = f12d3p(fdwrap(reader,
                                                              mvals,
                                                              p,
                                                              h=self.h),
                                                       h=self.h,
                                                       f0=x)
                        else:
                            grad[p], hdiag[p] = f12d3p(fdwrap(self.driver,
                                                              mvals,
                                                              p,
                                                              d=d),
                                                       h=self.h,
                                                       f0=x)
                        hess[p, p] = hdiag[p]
                    elif AGrad:
                        if self.bidirect:
                            if wq is not None:
                                apath = os.path.join(self.tdir, d, "current")
                                x = float(
                                    open(os.path.join(apath, 'objective.out')).
                                    readlines()[0].split()[1]) * self.factor
                                grad[p], _ = f12d3p(fdwrap(reader,
                                                           mvals,
                                                           p,
                                                           h=self.h),
                                                    h=self.h,
                                                    f0=x)
                            else:
                                grad[p], _ = f12d3p(fdwrap(self.driver,
                                                           mvals,
                                                           p,
                                                           d=d),
                                                    h=self.h,
                                                    f0=x)
                        else:
                            if wq is not None:
                                # Since the calculations are submitted as 3-point finite difference, this part of the code
                                # actually only reads from half of the completed calculations.
                                grad[p] = f1d2p(fdwrap(reader,
                                                       mvals,
                                                       p,
                                                       h=self.h),
                                                h=self.h,
                                                f0=x)
                            else:
                                grad[p] = f1d2p(fdwrap(self.driver,
                                                       mvals,
                                                       p,
                                                       d=d),
                                                h=self.h,
                                                f0=x)

            self.objd[d] = x
            self.gradd[d] = grad
            self.hdiagd[d] = hdiag
            X += x
            G += grad
            #H += np.diag(hdiag)
            H += hess
        if not in_fd():
            self.objective = X
            self.objvals = self.objd
        # print self.objd
        # print self.gradd
        # print self.hdiagd

        if float('Inf') in pvals:
            return {'X': 1e10, 'G': G, 'H': H}
        return {'X': X, 'G': G, 'H': H}
Exemple #10
0
    def submit_jobs(self, mvals, AGrad=True, AHess=True):
        # This routine is called by Objective.stage() will run before "get".
        # It submits the jobs to the Work Queue and the stage() function will wait for jobs to complete.
        #
        self.tdir = os.getcwd()
        wq = getWorkQueue()
        if wq is None:
            return

        def submit_psi(this_apath, dname, these_mvals):
            """ Create a grid file and a psi4 input file in the absolute path and submit it to the work queue. """
            cwd = os.getcwd()
            if not os.path.exists(this_apath): os.makedirs(this_apath)
            os.chdir(this_apath)
            self.FF.make(these_mvals)
            o = wopen('objective.dat')
            for line in self.objfiles[d]:
                s = line.split()
                if len(s) > 2 and s[0] == 'path' and s[1] == '=':
                    print("path = '%s'" % os.getcwd(), file=o)
                elif len(s) > 2 and s[0] == 'set' and s[1] == 'objective_path':
                    print("opath = '%s'" % os.getcwd(), file=o)
                    print("set objective_path $opath", file=o)
                else:
                    print(line, end=' ', file=o)
            o.close()
            os.system("rm -f objective.out")
            if wq is None:
                logger.info("There is no Work Queue!!!\n")
                sys.exit()
            else:
                input_files = [(os.path.join(this_apath, i), i)
                               for i in glob.glob("*")]
                input_files += [(os.path.join(self.root, self.tgtdir, dname,
                                              "build.dat"), "build.dat")]
                input_files += [(os.path.join(
                    os.path.split(__file__)[0], "data",
                    "run_psi_rdvr3_objective.sh"),
                                 "run_psi_rdvr3_objective.sh")]
                logger.info("\r")
                queue_up_src_dest(
                    wq,
                    "sh run_psi_rdvr3_objective.sh -c %s &> run_psi_rdvr3_objective.log"
                    % os.path.join(self.root, self.tgtdir, dname),
                    input_files=input_files,
                    output_files=[
                        (os.path.join(this_apath, i), i)
                        for i in ["run_psi_rdvr3_objective.log", "output.dat"]
                    ],
                    verbose=False)
            os.chdir(cwd)

        for d in self.objfiles:
            logger.info("\rNow working on" + str(d) + 50 * ' ' + '\r')
            odir = os.path.join(os.getcwd(), d)
            #if os.path.exists(odir):
            #    shutil.rmtree(odir)
            if not os.path.exists(odir): os.makedirs(odir)
            apath = os.path.join(odir, "current")
            submit_psi(apath, d, mvals)
            for p in range(self.FF.np):

                def subjob(mvals_, h):
                    apath = os.path.join(odir, str(p), str(h))
                    submit_psi(apath, d, mvals_)
                    #logger.info("Will set up a job for %s, parameter %i\n" % (d, p))
                    return 0.0

                if self.callderivs[d][p]:
                    if AHess:
                        f12d3p(fdwrap(subjob, mvals, p, h=self.h),
                               h=self.h,
                               f0=0.0)
                    elif AGrad:
                        if self.bidirect:
                            f12d3p(fdwrap(subjob, mvals, p, h=self.h),
                                   h=self.h,
                                   f0=0.0)
                        else:
                            f1d2p(fdwrap(subjob, mvals, p, h=self.h),
                                  h=self.h,
                                  f0=0.0)
Exemple #11
0
    def get(self, mvals, AGrad=False, AHess=False):
	"""
        LPW 04-17-2013
        
        This subroutine builds the objective function from Psi4.

        @param[in] mvals Mathematical parameter values
        @param[in] AGrad Switch to turn on analytic gradient
        @param[in] AHess Switch to turn on analytic Hessian
        @return Answer Contribution to the objective function
        """
        Answer = {}
        Fac = 1000000
        n = len(mvals)
        X = 0.0
        G = np.zeros(n,dtype=float)
        H = np.zeros((n,n),dtype=float)
        pvals = self.FF.make(mvals)
        self.tdir = os.getcwd()
        self.objd = OrderedDict()
        self.gradd = OrderedDict()
        self.hdiagd = OrderedDict()
        bidirect = False

        def fdwrap2(func,mvals0,pidx,qidx,key=None,**kwargs):
            def func2(arg1,arg2):
                mvals = list(mvals0)
                mvals[pidx] += arg1
                mvals[qidx] += arg2
                print "\rfdwrap2:", func.__name__, "[%i] = % .1e , [%i] = % .1e" % (pidx, arg1, qidx, arg2), ' '*50,
                if key != None:
                    return func(mvals,**kwargs)[key]
                else:
                    return func(mvals,**kwargs)
            return func2

        def f2d5p(f, h):
            fpp, fpm, fmp, fmm = [f(i*h,j*h) for i,j in [(1,1),(1,-1),(-1,1),(-1,-1)]]
            fpp = (fpp-fpm-fmp+fmm)/(4*h*h)
            return fpp

        def f2d4p(f, h, f0 = None):
            if f0 == None:
                fpp, fp0, f0p, f0 = [f(i*h,j*h) for i,j in [(1,1),(1,0),(0,1),(0,0)]]
            else:
                fpp, fp0, f0p = [f(i*h,j*h) for i,j in [(1,1),(1,0),(0,1)]]
            fpp = (fpp-fp0-f0p+f0)/(h*h)
            return fpp

        for d in self.objfiles:
            print "\rNow working on", d, 50*' ','\r',
            x = self.driver(mvals, d)
            grad  = np.zeros(n,dtype=float)
            hdiag = np.zeros(n,dtype=float)
            hess  = np.zeros((n,n),dtype=float)
            for p in range(self.FF.np):
                if self.callderivs[d][p]:
                    if AHess:
                        grad[p], hdiag[p] = f12d3p(fdwrap(self.driver, mvals, p, d=d), h = self.h, f0 = x)
                        hess[p,p] = hdiag[p]
                        # for q in range(p):
                        #     if self.callderivs[d][q]:
                        #         if bidirect:
                        #             hessentry = f2d5p(fdwrap2(self.driver, mvals, p, q, d=d), h = self.h)
                        #         else:
                        #             hessentry = f2d4p(fdwrap2(self.driver, mvals, p, q, d=d), h = self.h, f0 = x)
                        #         hess[p,q] = hessentry
                        #         hess[q,p] = hessentry
                    elif AGrad:
                        if bidirect:
                            grad[p], _ = f12d3p(fdwrap(self.driver, mvals, p, d=d), h = self.h, f0 = x)
                        else:
                            grad[p] = f1d2p(fdwrap(self.driver, mvals, p, d=d), h = self.h, f0 = x)
                            
            self.objd[d] = x
            self.gradd[d] = grad
            self.hdiagd[d] = hdiag
            X += x
            G += grad
            #H += np.diag(hdiag)
            H += hess
        if not in_fd():
            self.objective = X
            self.objvals = self.objd
        # print self.objd
        # print self.gradd
        # print self.hdiagd
                    
        if float('Inf') in pvals:
            return {'X' : 1e10, 'G' : G, 'H' : H}
        return {'X' : X, 'G' : G, 'H' : H}
Exemple #12
0
    def get(self, mvals, AGrad=False, AHess=False):
        """
        LPW 05-30-2012
        
        This subroutine builds the objective function (and optionally
        its derivatives) from a general software.  

        This subroutine interfaces with simulation software 'drivers'.
        The driver is expected to give exact values, fitting values, and weights.

        @param[in] mvals Mathematical parameter values
        @param[in] AGrad Switch to turn on analytic gradient
        @param[in] AHess Switch to turn on analytic Hessian
        @return Answer Contribution to the objective function
        """
        global LAST_MVALS, CHECK_BASIS
        # print mvals
        # print LAST_MVALS
        # print mvals == LAST_MVALS
        if LAST_MVALS == None or not (mvals == LAST_MVALS).all():
            CHECK_BASIS = False
        else:
            CHECK_BASIS = False
        Answer = {}
        Fac = 1000000
        ## Dictionary for derivative terms
        dM = {}
        # Create the new force field!!
        np = len(mvals)
        G = zeros(np, dtype=float)
        H = zeros((np, np), dtype=float)
        pvals = self.FF.make(mvals)
        if float("Inf") in pvals:
            return {"X": 1e10, "G": G, "H": H}
        Ans = self.driver()
        W = Ans[:, 2]
        M = Ans[:, 1]
        Q = Ans[:, 0]
        D = M - Q

        self.MAQ = mean(abs(Q))

        ns = len(M)
        # Wrapper to the driver, which returns just the part that changes.
        def callM(mvals_):
            self.FF.make(mvals_)
            Ans2 = self.driver()
            M_ = Ans2[:, 1]
            D_ = M_ - Q
            return Ans2[:, 1]

        if AGrad:
            # Leaving comment here if we want to reintroduce second deriv someday.
            #     dM[p,:], ddM[p,:] = f12d3p(fdwrap(callM, mvals, p), h = self.h, f0 = M)
            for p in range(np):
                if self.call_derivatives[p] == False:
                    continue
                dM_arr = f1d2p(fdwrap(callM, mvals, p), h=self.h, f0=M)
                if max(abs(dM_arr)) == 0.0 and Counter() == 0:
                    print "\r Simulation %s will skip over parameter %i in subsequent steps" % (self.name, p)
                    self.call_derivatives[p] = False
                else:
                    dM[p] = dM_arr.copy()
        Objective = dot(W, D ** 2) * Fac
        if AGrad:
            for p in range(np):
                if self.call_derivatives[p] == False:
                    continue
                G[p] = 2 * dot(W, D * dM[p])
                if not AHess:
                    continue
                H[p, p] = 2 * dot(W, dM[p] ** 2)
                for q in range(p):
                    if self.call_derivatives[q] == False:
                        continue
                    GNP = 2 * dot(W, dM[p] * dM[q])
                    H[q, p] = GNP
                    H[p, q] = GNP
        G *= Fac
        H *= Fac
        Answer = {"X": Objective, "G": G, "H": H}
        if not in_fd():
            self.D = D
            self.objective = Answer["X"]
            LAST_MVALS = mvals.copy()
        return Answer