예제 #1
0
 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")
예제 #2
0
    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