def _sollya_annotate(self, center, rad, polys): import sagesollya as sollya logger = logging.getLogger(__name__ + ".sollya") logger.info("calling annotatefunction() on %s derivatives", len(polys)) center = QQ(center) sollya_fun = self._sollya_object # sollya keeps all annotations, let's not bother with selecting # the best one for ord, pol0 in enumerate(polys): pol = ZZ(ord).factorial() * pol0 sollya_pol = sum( [c.center() * sollya.x**k for k, c in enumerate(pol)]) dom = RIF(center - rad, center + rad) # XXX: dangerous when inexact err_pol = pol.map_coefficients(lambda c: c - c.squash()) err = RIF(err_pol(RBF.zero().add_error(rad))) with sollya.settings(display=sollya.dyadic): logger = logging.getLogger(__name__ + ".sollya.annotate") logger.debug("annotatefunction(%s, %s, %s, %s, %s);", sollya_fun, sollya_pol, sollya.SollyaObject(dom), sollya.SollyaObject(err), sollya.SollyaObject(center)) sollya.annotatefunction(sollya_fun, sollya_pol, dom, err, center) sollya_fun = sollya.diff(sollya_fun) logger.info("...done")
def _sollya_(self): r""" EXAMPLES:: sage: import logging; logging.basicConfig(level=logging.INFO) sage: logger = logging.getLogger("ore_algebra.analytic.function.sollya") sage: logger.setLevel(logging.DEBUG) sage: import ore_algebra sage: DiffOps, x, Dx = ore_algebra.DifferentialOperators() sage: from ore_algebra.analytic.function import DFiniteFunction sage: f = DFiniteFunction(Dx - 1, [1]) sage: import sagesollya as sollya # optional - sollya sage: sollya.plot(f, sollya.Interval(0, 1)) # not tested ... """ if self._sollya_object is not None: return self._sollya_object import sagesollya as sollya logger = logging.getLogger(__name__ + ".sollya.eval") Dx = self.dop.parent().gen() def wrapper(pt, ord, prec): if RBF(pt.diameter()) >= self.max_rad / 4: return self._known_bound(RBF(pt), post_transform=Dx**ord) try: val = self.approx(pt, prec, post_transform=Dx**ord) except Exception: logger.info("pt=%s, ord=%s, prec=%s, error", pt, ord, prec, exc_info=(pt.absolute_diameter() < .5)) return RIF('nan') logger.debug("pt=%s, ord=%s, prec=%s, val=%s", pt, ord, prec, val) if not pt.overlaps(self._sollya_domain): backtrace = sollya.getbacktrace() logger.debug("%s not in %s", pt.str(style='brackets'), self._sollya_domain.str(style='brackets')) logger.debug("sollya backtrace: %s", [ sollya.objectname(t.struct.called_proc) for t in backtrace ]) return val wrapper.__name__ = self.name self._sollya_object = sollya.sagefunction(wrapper) for pt, ini in self.ini.iteritems(): pt = RIF(pt) if pt.is_exact(): fun = self._sollya_object for ord, val in enumerate(ini): try: sollya.annotatefunction(fun, val, pt, RIF.zero()) except TypeError: logger.info("annotation failed: D^%s(%s)(%s) = %s", ord, self.name, pt, val) fun = sollya.diff(fun) self._update_approx_hook = self._sollya_annotate return self._sollya_object