def get_G(self, mvals=None, customdir=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, customdir=customdir) 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 if Counter() == self.zerograd and self.zerograd >= 0: self.write_0grads(Ans) return Ans
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
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
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
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