示例#1
0
    def __call__(self, x, maximum_bits=20000):
        """
        Allows an object of this class to behave like a function. If
        ``ceil`` is an instance of this class, we can do ``ceil(n)`` to get
        the ceiling of ``n``.

        TESTS::

            sage: ceil(SR(10^50 + 10^(-50)))
            100000000000000000000000000000000000000000000000001
            sage: ceil(SR(10^50 - 10^(-50)))
            100000000000000000000000000000000000000000000000000
            sage: ceil(int(10^50))
            100000000000000000000000000000000000000000000000000
        """
        try:
            return x.ceil()
        except AttributeError:
            if isinstance(x, (int, long)):
                return Integer(x)
            elif isinstance(x, (float, complex)):
                return Integer(int(math.ceil(x)))
            elif type(x).__module__ == 'numpy':
                import numpy
                return numpy.ceil(x)

        x_original = x

        from sage.rings.all import RealIntervalField
        # If x can be coerced into a real interval, then we should
        # try increasing the number of bits of precision until
        # we get the ceiling at each of the endpoints is the same.
        # The precision will continue to be increased up to maximum_bits
        # of precision at which point it will raise a value error.
        bits = 53
        try:
            x_interval = RealIntervalField(bits)(x)
            upper_ceil = x_interval.upper().ceil()
            lower_ceil = x_interval.lower().ceil()

            while upper_ceil != lower_ceil and bits < maximum_bits:
                bits += 100
                x_interval = RealIntervalField(bits)(x)
                upper_ceil = x_interval.upper().ceil()
                lower_ceil = x_interval.lower().ceil()

            if bits < maximum_bits:
                return lower_ceil
            else:
                try:
                    return ceil(SR(x).full_simplify())
                except ValueError:
                    pass
                raise ValueError, "x (= %s) requires more than %s bits of precision to compute its ceiling" % (
                    x, maximum_bits)

        except TypeError:
            # If x cannot be coerced into a RealField, then
            # it should be left as a symbolic expression.
            return BuiltinFunction.__call__(self, SR(x_original))
示例#2
0
    def _sage_(self):
        r"""
        Convert a maple expression back to a Sage expression.

        This currently does not implement a parser for the Maple output language,
        therefore only very simple expressions will convert successfully.

        EXAMPLES::

            sage: m = maple('x^2 + 5*y')                            # optional - maple
            sage: m.sage()                                          # optional - maple
            x^2 + 5*y
            sage: m._sage_()                                        # optional - maple
            x^2 + 5*y

        ::

            sage: m = maple('sin(sqrt(1-x^2)) * (1 - cos(1/x))^2')  # optional - maple
            sage: m.sage()                                          # optional - maple
            (cos(1/x) - 1)^2*sin(sqrt(-x^2 + 1))

        """
        result = repr(self)
        # The next few lines are a very crude excuse for a maple "parser".
        result = result.replace("Pi", "pi")

        try:
            from sage.symbolic.all import SR
            return SR(result)
        except Exception:
            raise NotImplementedError("Unable to parse Maple output: %s" %
                                      result)
示例#3
0
    def _sage_(self):
        r"""
        Convert a giac expression back to a Sage expression.

        This currently does not implement a parser for the Giac output language,
        therefore only very simple expressions will convert successfully.
        Warning: List conversion is slow.

        EXAMPLE::

        sage: m = giac('x^2 + 5*y')                            # optional - requires giac
        sage: m.sage()                                          # optional - requires giac
        x^2 + 5*y

        ::

        sage: m = giac('sin(2*sqrt(1-x^2)) * (1 - cos(1/x))^2')  # optional - requires giac
        sage: m.trigexpand().sage()                              # optional - requires giac
        2*(cos(1/x) - 1)^2*sin(sqrt(-x^2 + 1))*cos(sqrt(-x^2 + 1))

        """
        result = repr(self)
        if str(self.type()) != 'DOM_LIST' :
            try:
                from sage.symbolic.all import SR
                return SR(result)
            except:
                raise NotImplementedError, "Unable to parse Giac output: %s" % result
        else:
            return [entry.sage() for entry in self]
示例#4
0
def _do_sqrt(x, prec=None, extend=True, all=False):
    r"""
        Used internally to compute the square root of x.
        
        INPUT:
        
        -  ``x`` - a number
        
        -  ``prec`` - None (default) or a positive integer
           (bits of precision) If not None, then compute the square root
           numerically to prec bits of precision.
        
        -  ``extend`` - bool (default: True); this is a place
           holder, and is always ignored since in the symbolic ring everything
           has a square root.
        
        -  ``extend`` - bool (default: True); whether to extend
           the base ring to find roots. The extend parameter is ignored if
           prec is a positive integer.
        
        -  ``all`` - bool (default: False); whether to return
           a list of all the square roots of x.
        
        
        EXAMPLES::
        
            sage: from sage.functions.other import _do_sqrt
            sage: _do_sqrt(3)
            sqrt(3)
            sage: _do_sqrt(3,prec=10)
            1.7
            sage: _do_sqrt(3,prec=100)
            1.7320508075688772935274463415
            sage: _do_sqrt(3,all=True)
            [sqrt(3), -sqrt(3)]
        
        Note that the extend parameter is ignored in the symbolic ring::
        
            sage: _do_sqrt(3,extend=False)
            sqrt(3)
        """
    from sage.rings.all import RealField, ComplexField
    if prec:
        if x >= 0:
            return RealField(prec)(x).sqrt(all=all)
        else:
            return ComplexField(prec)(x).sqrt(all=all)
    if x == -1:
        from sage.symbolic.pynac import I
        z = I
    else:
        z = SR(x)**one_half

    if all:
        if z:
            return [z, -z]
        else:
            return [z]
    return z
示例#5
0
def adapt_if_symbolic(f):
    """
    If f is symbolic find the variables u, v to substitute into f.
    Otherwise raise a TypeError.
    
    This function is used internally by the plot commands for
    efficiency reasons only.
    """
    from sage.symbolic.all import is_Expression, SR
    if sum([is_Expression(a) for a in f]) > 0:
        g = [SR(a) for a in f]
        vars = list(set(sum([list(a.variables()) for a in g], [])))
        vars.sort()
        if len(vars) > 0:
            u = vars[0]
            if len(vars) > 1:
                v = vars[1]
            else:
                v = None
            return g, u, v
        else:
            g = [lambda x: float(a) for a in g]
            return g, None, None
示例#6
0
    def _sage_(self):
        r"""
        Convert a maple expression back to a Sage expression.

        This currently does not implement a parser for the Maple output language,
        therefore only very simple expressions will convert successfully.

        EXAMPLES::

            sage: m = maple('x^2 + 5*y')                            # optional - maple
            sage: m.sage()                                          # optional - maple
            x^2 + 5*y
            sage: m._sage_()                                        # optional - maple
            x^2 + 5*y

        ::

            sage: m = maple('sin(sqrt(1-x^2)) * (1 - cos(1/x))^2')  # optional - maple
            sage: m.sage()                                          # optional - maple
            (cos(1/x) - 1)^2*sin(sqrt(-x^2 + 1))

        Some matrices can be converted back::

            sage: m = matrix(2, 2, [1, 2, x, 3])    # optional - maple
            sage: mm = maple(m)                     # optional - maple
            sage: mm.sage() == m                    # optional - maple
            True

        Some vectors can be converted back::

            sage: m = vector([1, x, 2, 3])          # optional - maple
            sage: mm = maple(m)                     # optional - maple
            sage: mm.sage() == m                    # optional - maple
            True
        """
        from sage.matrix.constructor import matrix
        from sage.modules.free_module_element import vector
        from sage.rings.integer_ring import ZZ

        result = repr(self)
        # The next few lines are a very crude excuse for a maple "parser".
        result = result.replace("Pi", "pi")

        if result[:6] == "Matrix":
            content = result[7:-1]
            m, n = content.split(',')[:2]
            m = ZZ(m.strip())
            n = ZZ(n.strip())
            coeffs = [self[i + 1, j + 1].sage()
                      for i in range(m) for j in range(n)]
            return matrix(m, n, coeffs)
        elif result[:6] == "Vector":
            start = result.index('(')
            content = result[start + 1:-1]
            m = ZZ(content.split(',')[0].strip())
            return vector([self[i + 1].sage() for i in range(m)])

        try:
            from sage.symbolic.all import SR
            return SR(result)
        except Exception:
            raise NotImplementedError("Unable to parse Maple output: %s" % result)
示例#7
0
     is_ComplexNumber, ComplexField
from sage.misc.latex import latex
import math

import sage.structure.element
coercion_model = sage.structure.element.get_coercion_model()

from sage.structure.coerce import parent
from sage.symbolic.constants import pi
from sage.symbolic.function import is_inexact
from sage.functions.log import exp
from sage.functions.trig import arctan2
from sage.functions.transcendental import Ei
from sage.libs.mpmath import utils as mpmath_utils

one_half = ~SR(2)


class Function_erf(BuiltinFunction):
    _eval_ = BuiltinFunction._eval_default

    def __init__(self):
        r"""
        The error function, defined for real values as
        `\text{erf}(x) = \frac{2}{\sqrt{\pi}} \int_0^x e^{-t^2} dt`.
        This function is also defined for complex values, via analytic
        continuation.

        Sage implements the error function via the ``erfc()`` function in PARI.

        EXAMPLES:
示例#8
0
文件: maple.py 项目: timgates42/sage
    def _sage_(self):
        r"""
        Convert a maple expression back to a Sage expression.

        This currently does not implement a parser for the Maple output language,
        therefore only very simple expressions will convert successfully.

        REFERENCE:

        https://www.asc.tuwien.ac.at/compmath/download/Monagan_Maple_Programming.pdf

        EXAMPLES::

            sage: m = maple('x^2 + 5*y')        # optional - maple
            sage: m.sage()                      # optional - maple
            x^2 + 5*y
            sage: m._sage_()                    # optional - maple
            x^2 + 5*y

            sage: m = maple('sin(sqrt(1-x^2)) * (1 - cos(1/x))^2')  # optional - maple
            sage: m.sage()                                          # optional - maple
            (cos(1/x) - 1)^2*sin(sqrt(-x^2 + 1))

        Some matrices can be converted back::

            sage: m = matrix(2, 2, [1, 2, x, 3])    # optional - maple
            sage: mm = maple(m)                     # optional - maple
            sage: mm.sage() == m                    # optional - maple
            True

        Some vectors can be converted back::

            sage: m = vector([1, x, 2, 3])          # optional - maple
            sage: mm = maple(m)                     # optional - maple
            sage: mm.sage() == m                    # optional - maple
            True

        Integers and rationals are converted as such::

            sage: maple(33).sage().parent()         # optional - maple
            Integer Ring
            sage: maple(191/5).sage().parent()      # optional - maple
            Rational Field

        Sets, lists, sequences::

            sage: maple("[4,5,6]").sage()           # optional - maple
            [4, 5, 6]
            sage: maple({14,33,6}).sage()           # optional - maple
            {6, 14, 33}
            sage: maple("seq(i**2,i=1..5)").sage()  # optional - maple
            (1, 4, 9, 16, 25)

        Strings::

            sage: maple('"banane"').sage()          # optional - maple
            '"banane"'

        Floats::

            sage: Z3 = maple('evalf(Zeta(3))')   # optional - maple
            sage: Z3.sage().parent()             # optional - maple
            Real Field with 53 bits of precision

            sage: sq5 = maple('evalf(sqrt(5),100)')   # optional - maple
            sage: sq5 = sq5.sage(); sq5               # optional - maple
            2.23606797749978969640...
            sage: sq5.parent()                        # optional - maple
            Real Field with 332 bits of precision

        Functions are not yet converted back correctly::

            sage: maple(hypergeometric([3,4],[5],x))  # optional - maple
            hypergeom([3, 4],[5],x)
            sage: _.sage()                # known bug # optional - maple
            hypergeometric((3, 4), (5,), x)
        """
        from sage.matrix.constructor import matrix
        from sage.modules.free_module_element import vector
        from sage.rings.integer_ring import ZZ
        # The next few lines are a very crude excuse for a maple "parser"
        maple_type = repr(self.whattype())
        result = repr(self)
        result = result.replace("Pi", "pi")
        if maple_type == 'symbol':  # pi
            pass  # left to symbolic ring
        elif maple_type == 'string':  # "banane"
            return result
        elif maple_type == 'exprseq':  # 2, 2
            n = self.parent()(f"[{self._name}]").nops()._sage_()
            return tuple(self[i] for i in range(1, n + 1))
        elif maple_type == 'set':  # {1, 2}
            n = self.nops()._sage_()
            return set(self.op(i)._sage_() for i in range(1, n + 1))
        elif maple_type == 'list':  # [1, 2]
            n = self.nops()._sage_()
            return [self.op(i)._sage_() for i in range(1, n + 1)]
        elif maple_type == "Matrix":  # Matrix(2, 2, [[1,2],[3,4]])
            mn = self.op(1)
            m = mn[1]._sage_()
            n = mn[2]._sage_()
            coeffs = [
                self[i + 1, j + 1]._sage_() for i in range(m) for j in range(n)
            ]
            return matrix(m, n, coeffs)
        elif maple_type[:6] == "Vector":  # Vector[row](3, [4,5,6])
            n = self.op(1)._sage_()
            return vector([self[i + 1]._sage_() for i in range(n)])
        elif maple_type == 'integer':
            return ZZ(result)
        elif maple_type == 'fraction':
            return self.op(1)._sage_() / self.op(2)._sage_()
        elif maple_type == "function":
            pass  # TODO : here one should translate back function names
        elif maple_type == "float":
            from sage.rings.real_mpfr import RealField
            mantissa = len(repr(self.op(1)))
            prec = max(53, (mantissa * 13301) // 4004)
            R = RealField(prec)
            return R(result)
        elif maple_type == '`=`':  # (1, 1) = 2
            return (self.op(1)._sage_() == self.op(2)._sage())
        try:
            from sage.symbolic.all import SR
            return SR(result)
        except Exception:
            raise NotImplementedError("Unable to parse Maple output: %s" %
                                      result)
示例#9
0
def local_basis(dop, point, order=None):
    r"""
    Generalized series expansions the local basis.

    INPUT:

    * dop - Differential operator

    * point - Point where the local basis is to be computed

    * order (optional) - Number of terms to compute, **starting from each
      “leftmost” valuation of a group of solutions with valuations differing by
      integers**. (Thus, the absolute truncation order will be the same for all
      solutions in such a group, with some solutions having more actual
      coefficients computed that others.)

      The default is to choose the truncation order in such a way that the
      structure of the basis is apparent, and in particular that logarithmic
      terms appear if logarithms are involved at all in that basis. The
      corresponding order may be very large in some cases.

    EXAMPLES::

        sage: from ore_algebra import *
        sage: from ore_algebra.analytic.local_solutions import local_basis
        sage: Dops, x, Dx = DifferentialOperators(QQ, 'x')

        sage: local_basis(Dx - 1, 0)
        [1 + x + 1/2*x^2 + 1/6*x^3]

        sage: from ore_algebra.analytic.examples import ssw
        sage: local_basis(ssw.dop3, 0)
        [t^(-4) + 24*log(t)/t^2 - 48*log(t) - 96*t^2*log(t) - 88*t^2,
         t^(-2),
         1 + 2*t^2]

        sage: dop = (x^2*(x^2-34*x+1)*Dx^3 + 3*x*(2*x^2-51*x+1)*Dx^2
        ....:     + (7*x^2-112*x+1)*Dx + (x-5))
        sage: local_basis(dop, 0, 3)
        [1/2*log(x)^2 + 5/2*x*log(x)^2 + 12*x*log(x) + 73/2*x^2*log(x)^2
         + 210*x^2*log(x) + 72*x^2,
         log(x) + 5*x*log(x) + 12*x + 73*x^2*log(x) + 210*x^2,
         1 + 5*x + 73*x^2]

        sage: roots = dop.leading_coefficient().roots(AA)
        sage: local_basis(dop, roots[1][0], 3)
        [1 - (-239/12*a+169/6)*(x + 12*sqrt(2) - 17)^2,
         sqrt(x + 12*sqrt(2) - 17) - (-203/32*a+9)*(x + 12*sqrt(2) - 17)^(3/2)
         + (-24031/160*a+1087523/5120)*(x + 12*sqrt(2) - 17)^(5/2),
         x + 12*sqrt(2) - 17 - (-55/6*a+13)*(x + 12*sqrt(2) - 17)^2]

    TESTS::

        sage: local_basis(4*x^2*Dx^2 + (-x^2+8*x-11), 0, 2)
        [x^(-sqrt(3) + 1/2) + (-4/11*a+2/11)*x^(-sqrt(3) + 3/2),
         x^(sqrt(3) + 1/2) - (-4/11*a-2/11)*x^(sqrt(3) + 3/2)]

        sage: local_basis((27*x^2+4*x)*Dx^2 + (54*x+6)*Dx + 6, 0, 2)
        [1/sqrt(x) + 3/8*sqrt(x), 1 - x]

    """
    from .path import Point
    point = Point(point, dop)
    ldop = point.local_diffop()
    if order is None:
        ind = ldop.indicial_polynomial(ldop.base_ring().gen())
        order = max(dop.order(), ind.dispersion()) + 3
    sols = map_local_basis(ldop,
                           lambda ini, bwrec: log_series(ini, bwrec, order),
                           lambda leftmost, shift: {})
    dx = SR(dop.base_ring().gen()) - point.value

    # Working with symbolic expressions here is too complicated: let's try
    # returning FormalSums.
    def log_monomial(expo, n, k):
        expo = simplify_exponent(expo)
        return dx**(expo + n) * symbolic_log(dx, hold=True)**k

    cm = get_coercion_model()
    Coeffs = cm.common_parent(dop.base_ring().base_ring(),
                              point.value.parent(),
                              *(sol.leftmost for sol in sols))
    res = [
        FormalSum([(c / ZZ(k).factorial(), log_monomial(sol.leftmost, n, k))
                   for n, vec in enumerate(sol.value)
                   for k, c in reversed(list(enumerate(vec)))],
                  FormalSums(Coeffs)) for sol in sols
    ]
    return res