def _reset(self): self._p0 = sstruct([(k,v) for k,v in self._allitems() if k in self._free]) flat_p0_free = flatten(self._p0, include=self._free) self._np = flat_p0_free.size self._f0 = self.eval() self._scalar = not hasattr(self._f0, '__len__') flat_f0_free = flatten(self._f0) self._nf = flat_f0_free.size try: self.deriv(); raise Exception() except NoSubclassMethod: self._deriv = None except: self._deriv = sstruct() for k,v in self._allitems(): if k in self._free: self._deriv._setfield(k, v * 0.0) try: self.dderiv(); raise Exception() except NoSubclassMethod: self._dderiv = None except: self._dderiv = sstruct() for k,v in self._allitems(): if k in self._free: self._dderiv._setfield(k, v * 0.0) try: self.hessian(); raise Exception() except NoSubclassMethod: self._hessian = None except: siz = [self._np, self._np] self._hessian = numpy.matrix(siz, dtype=numpy.float64) # TODO(HHH): use of Hessians currently assumes scalar zero-order function output self.reset() # call developer's subclass method return flat_p0_free
def _reset(self): self._p0 = sstruct([(k, v) for k, v in self._allitems() if k in self._free]) flat_p0_free = flatten(self._p0, include=self._free) self._np = flat_p0_free.size self._f0 = self.eval() self._scalar = not hasattr(self._f0, '__len__') flat_f0_free = flatten(self._f0) self._nf = flat_f0_free.size try: self.deriv() raise Exception() except NoSubclassMethod: self._deriv = None except: self._deriv = sstruct() for k, v in self._allitems(): if k in self._free: self._deriv._setfield(k, v * 0.0) try: self.dderiv() raise Exception() except NoSubclassMethod: self._dderiv = None except: self._dderiv = sstruct() for k, v in self._allitems(): if k in self._free: self._dderiv._setfield(k, v * 0.0) try: self.hessian() raise Exception() except NoSubclassMethod: self._hessian = None except: siz = [self._np, self._np] self._hessian = numpy.matrix( siz, dtype=numpy.float64 ) # TODO(HHH): use of Hessians currently assumes scalar zero-order function output self.reset() # call developer's subclass method return flat_p0_free
def chgrad(self, plot=False, **kwargs): for k,v in kwargs.items(): self._setfield(k,v) pflat = self._reset() out = sstruct() out.params = self._p0.copy() out._setfield('f.exact', self._f(pflat, force1D=True)) out._setfield('df.exact', self._df(pflat, force2D=True)) out._setfield('df.approx', out.df.exact * numpy.nan) try: out._setfield('ddf.exact', self._ddf(pflat, force2D=True)) except NoSubclassMethod: do_ddf = False else: do_ddf = True; out._setfield('ddf.approx', out.ddf.exact * numpy.nan) try: out._setfield('H.exact', self._H(pflat)) except NoSubclassMethod: do_hessian = False else: do_hessian = True; out._setfield('H.approx', out.H.exact * numpy.nan) fdelta = 1e-4 e = fdelta * abs(pflat) e = numpy.fmax(1e-12, e) keepgoing = (e > 0) # all True to start rpt = 0 while keepgoing.any(): rpt += 1 for iparam in range(self._np): mask = pflat * 0.0 mask.flat[iparam] = 0.5 p_below = pflat - e * mask p_above = pflat + e * mask f_below = self._f(p_below) f_above = self._f(p_above) adfj = (f_above - f_below) / e[iparam] out.df.approx[:, iparam] = adfj # TODO(III): store data from multiple rpts? if do_hessian or do_ddf: df_below = self._df(p_below) df_above = self._df(p_above) addfj = (df_above - df_below) / e[iparam] if do_ddf: out.ddf.approx[:, iparam] = addfj[:, iparam] # TODO(III): store data from multiple rpts? if do_hessian: out.H.approx[:, iparam].flat = addfj.flat # TODO(III): store data from multiple rpts? converged = True # TODO(III): could check for convergence here. currently, only one iteration is performed if converged: keepgoing[iparam] = False e[keepgoing] /= 2 unflatten(self, pflat, include=self._free) self._reset() out.plabels = ['p'+x for x in flatten(self, include=self._free, labels=True)] out.flabels = ['f'+x for x in flatten(self.eval(), include=self._free, labels=True)] fields = ['df', 'ddf', 'H'] for k in fields: v = out._getfield(k, None) if v == None: continue v.abserr = abs(v.exact-v.approx) v.maxabserr = v.abserr.max() v.propabserr = v.abserr / numpy.fmax(abs(v.approx), 1e-13) v.maxpropabserr = v.propabserr.max() if plot: import Plotting pylab = Plotting.load_pylab() fields = ['df', 'ddf', 'H'] labels = {'df':(out.flabels,out.plabels, 'd%s / d%s'), 'ddf':(out.flabels,out.plabels, 'd^2%s / d%s^2'), 'H':(out.plabels,out.plabels, 'df/(d%s)(d%s)'), } got = dict([(k,k in out._fields) for k in fields]) nplots = sum(got.values()) for i,k in enumerate(fields): v = out._getfield(k, None) if v == None: continue if nplots > 1: pylab.subplot(1, nplots, i+1) x = abs(v.approx.flatten()) y = v.abserr.flatten() both0 = numpy.logical_and(x==0.0, y==0.0) x[both0] = numpy.nan y[both0] = numpy.nan x[x==0.0] = 1e-13 y[y==0.0] = 1e-13 x = numpy.log10(x) y = numpy.log10(y) pylab.cla() ax = pylab.gca() ax.indicator, = pylab.plot([numpy.nan,numpy.nan],[numpy.nan,numpy.nan], color=(1,0,1), linewidth=2) v.handles = pylab.plot(numpy.expand_dims(x,0), numpy.expand_dims(y,0), linestyle='None', marker='o', markersize=10, picker=5) lab = labels[k] for j,h in enumerate(v.handles): subs = numpy.unravel_index(j, v.approx.shape) h.txt = (lab[2]+'\nprop. abs. err. = %g') % (lab[0][subs[0]], lab[1][subs[1]], v.propabserr.flat[j]) ax.set_xlabel('log10 of abs approx value') ax.set_ylabel('log10 of abs error') ax.grid(True) def onpick(evt): h = evt.artist x,y = h.get_xdata(), h.get_ydata() ax = h.axes ax.set_title(h.txt) ind = ax.indicator xl,yl = numpy.asarray(ax.get_xlim()),numpy.asarray(ax.get_ylim()) ind.set_xdata([x.mean(), xl.mean()]) ind.set_ydata([y.mean(), yl.max() + numpy.diff(yl) * 0.01]) ind.set_clip_on(False) ind.set_color(h.get_color()) pylab.draw() pylab.gcf().canvas.mpl_connect('pick_event', onpick) pylab.draw() return out
def chgrad(self, plot=False, **kwargs): for k, v in kwargs.items(): self._setfield(k, v) pflat = self._reset() out = sstruct() out.params = self._p0.copy() out._setfield('f.exact', self._f(pflat, force1D=True)) out._setfield('df.exact', self._df(pflat, force2D=True)) out._setfield('df.approx', out.df.exact * numpy.nan) try: out._setfield('ddf.exact', self._ddf(pflat, force2D=True)) except NoSubclassMethod: do_ddf = False else: do_ddf = True out._setfield('ddf.approx', out.ddf.exact * numpy.nan) try: out._setfield('H.exact', self._H(pflat)) except NoSubclassMethod: do_hessian = False else: do_hessian = True out._setfield('H.approx', out.H.exact * numpy.nan) fdelta = 1e-4 e = fdelta * abs(pflat) e = numpy.fmax(1e-12, e) keepgoing = (e > 0) # all True to start rpt = 0 while keepgoing.any(): rpt += 1 for iparam in range(self._np): mask = pflat * 0.0 mask.flat[iparam] = 0.5 p_below = pflat - e * mask p_above = pflat + e * mask f_below = self._f(p_below) f_above = self._f(p_above) adfj = (f_above - f_below) / e[iparam] out.df.approx[:, iparam] = adfj # TODO(III): store data from multiple rpts? if do_hessian or do_ddf: df_below = self._df(p_below) df_above = self._df(p_above) addfj = (df_above - df_below) / e[iparam] if do_ddf: out.ddf.approx[:, iparam] = addfj[:, iparam] # TODO(III): store data from multiple rpts? if do_hessian: out.H.approx[:, iparam].flat = addfj.flat # TODO(III): store data from multiple rpts? converged = True # TODO(III): could check for convergence here. currently, only one iteration is performed if converged: keepgoing[iparam] = False e[keepgoing] /= 2 unflatten(self, pflat, include=self._free) self._reset() out.plabels = [ 'p' + x for x in flatten(self, include=self._free, labels=True) ] out.flabels = [ 'f' + x for x in flatten(self.eval(), include=self._free, labels=True) ] fields = ['df', 'ddf', 'H'] for k in fields: v = out._getfield(k, None) if v == None: continue v.abserr = abs(v.exact - v.approx) v.maxabserr = v.abserr.max() v.propabserr = v.abserr / numpy.fmax(abs(v.approx), 1e-13) v.maxpropabserr = v.propabserr.max() if plot: import Plotting pylab = Plotting.load_pylab() fields = ['df', 'ddf', 'H'] labels = { 'df': (out.flabels, out.plabels, 'd%s / d%s'), 'ddf': (out.flabels, out.plabels, 'd^2%s / d%s^2'), 'H': (out.plabels, out.plabels, 'df/(d%s)(d%s)'), } got = dict([(k, k in out._fields) for k in fields]) nplots = sum(got.values()) for i, k in enumerate(fields): v = out._getfield(k, None) if v == None: continue if nplots > 1: pylab.subplot(1, nplots, i + 1) x = abs(v.approx.flatten()) y = v.abserr.flatten() both0 = numpy.logical_and(x == 0.0, y == 0.0) x[both0] = numpy.nan y[both0] = numpy.nan x[x == 0.0] = 1e-13 y[y == 0.0] = 1e-13 x = numpy.log10(x) y = numpy.log10(y) pylab.cla() ax = pylab.gca() ax.indicator, = pylab.plot([numpy.nan, numpy.nan], [numpy.nan, numpy.nan], color=(1, 0, 1), linewidth=2) v.handles = pylab.plot(numpy.expand_dims(x, 0), numpy.expand_dims(y, 0), linestyle='None', marker='o', markersize=10, picker=5) lab = labels[k] for j, h in enumerate(v.handles): subs = numpy.unravel_index(j, v.approx.shape) h.txt = (lab[2] + '\nprop. abs. err. = %g') % ( lab[0][subs[0]], lab[1][subs[1]], v.propabserr.flat[j]) ax.set_xlabel('log10 of abs approx value') ax.set_ylabel('log10 of abs error') ax.grid(True) def onpick(evt): h = evt.artist x, y = h.get_xdata(), h.get_ydata() ax = h.axes ax.set_title(h.txt) ind = ax.indicator xl, yl = numpy.asarray(ax.get_xlim()), numpy.asarray( ax.get_ylim()) ind.set_xdata([x.mean(), xl.mean()]) ind.set_ydata([y.mean(), yl.max() + numpy.diff(yl) * 0.01]) ind.set_clip_on(False) ind.set_color(h.get_color()) pylab.draw() pylab.gcf().canvas.mpl_connect('pick_event', onpick) pylab.draw() return out