예제 #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 automatic_name_eval(s, globals, max_names=10000):
        """
        Exec the string ``s`` in the scope of the ``globals``
        dictionary, and if any :exc:`NameError`\ s are raised, try to
        fix them by defining the variable that caused the error to be
        raised, then eval again.  Try up to ``max_names`` times.
        
        INPUT:

           - ``s`` -- a string
           - ``globals`` -- a dictionary
           - ``max_names`` -- a positive integer (default: 10000)
        """
        # This entire automatic naming system really boils down to
        # this bit of code below.  We simply try to exec the string s
        # in the globals namespace, defining undefined variables and
        # functions until everything is defined.
        for _ in range(max_names):
            try:
                exec s in globals
                return
            except NameError, msg:
                # Determine if we hit a NameError that is probably
                # caused by a variable or function not being defined:
                if len(msg.args) == 0: raise  # not NameError with
                # specific variable name
                v = msg.args[0].split("'")
                if len(v) < 2: raise  # also not NameError with
                # specific variable name We did
                # find an undefined variable: we
                # simply define it and try
                # again.
                nm = v[1]
                globals[nm] = AutomaticVariable(SR, SR.var(nm))
예제 #4
0
파일: support.py 프로젝트: sagemath/sagenb
def automatic_name_eval(s, globals, max_names=10000):
    r"""
    Exec the string ``s`` in the scope of the ``globals``
    dictionary, and if any :exc:`NameError`\ s are raised, try to
    fix them by defining the variable that caused the error to be
    raised, then eval again.  Try up to ``max_names`` times.

    INPUT:

    - ``s`` -- a string
    - ``globals`` -- a dictionary
    - ``max_names`` -- a positive integer (default: 10000)
    """
    # This entire automatic naming system really boils down to
    # this bit of code below.  We simply try to exec the string s
    # in the globals namespace, defining undefined variables and
    # functions until everything is defined.
    for _ in range(max_names):
        try:
            exec(s , globals)
            return
        except NameError as msg:
            # Determine if we hit a NameError that is probably
            # caused by a variable or function not being defined:
            if len(msg.args) == 0: raise  # not NameError with
                                          # specific variable name
            v = msg.args[0].split("'")
            if len(v) < 2: raise  # also not NameError with
                                  # specific variable name We did
                                  # find an undefined variable: we
                                  # simply define it and try
                                  # again.
            nm = v[1]
            globals[nm] = AutomaticVariable(SR, SR.var(nm))
    raise NameError("Too many automatic variable names and functions created (limit=%s)" % max_names)
예제 #5
0
파일: giac.py 프로젝트: thalespaiva/sagelib
    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]
예제 #6
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
예제 #7
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
예제 #8
0
파일: plot.py 프로젝트: timgates42/sage
def plot_hyperplane(hyperplane, **kwds):
    r"""
    Return the plot of a single hyperplane.

    INPUT:

    - ``**kwds`` -- plot options: see below

    OUTPUT:

    A graphics object of the plot.

    .. RUBRIC:: Plot Options

    Beside the usual plot options (enter ``plot?``), the plot command for
    hyperplanes includes the following:

    - ``hyperplane_label`` -- Boolean value or string (default: ``True``).
      If ``True``, the hyperplane is labeled with its equation, if a
      string, it is labeled by that string, otherwise it is not
      labeled.

    - ``label_color`` -- (Default: ``'black'``) Color for hyperplane_label.

    - ``label_fontsize`` -- Size for ``hyperplane_label`` font (default: 14)
      (does not work in 3d, yet).

    - ``label_offset`` -- (Default: 0-dim: 0.1, 1-dim: (0,1),
      2-dim: (0,0,0.2)) Amount by which label is offset from
      ``hyperplane.point()``.

    - ``point_size`` -- (Default: 50) Size of points in a zero-dimensional
      arrangement or of an arrangement over a finite field.

    - ``ranges`` -- Range for the parameters for the parametric plot of the
      hyperplane. If a single positive number ``r`` is given for the
      value of ``ranges``, then the ranges for all parameters are set to
      `[-r, r]`.  Otherwise, for a line in the plane, ``ranges`` has the
      form ``[a, b]`` (default: [-3,3]), and for a plane in 3-space, the
      ``ranges`` has the form ``[[a, b], [c, d]]`` (default: [[-3,3],[-3,3]]).
      (The ranges are centered around ``hyperplane.point()``.)

    EXAMPLES::

        sage: H1.<x> = HyperplaneArrangements(QQ)
        sage: a = 3*x + 4
        sage: a.plot()    # indirect doctest
        Graphics object consisting of 3 graphics primitives
        sage: a.plot(point_size=100,hyperplane_label='hello')
        Graphics object consisting of 3 graphics primitives

    
        sage: H2.<x,y> = HyperplaneArrangements(QQ)
        sage: b = 3*x + 4*y + 5
        sage: b.plot()
        Graphics object consisting of 2 graphics primitives
        sage: b.plot(ranges=(1,5),label_offset=(2,-1))
        Graphics object consisting of 2 graphics primitives
        sage: opts = {'hyperplane_label':True, 'label_color':'green',
        ....:         'label_fontsize':24, 'label_offset':(0,1.5)}
        sage: b.plot(**opts)
        Graphics object consisting of 2 graphics primitives

        sage: H3.<x,y,z> = HyperplaneArrangements(QQ)
        sage: c = 2*x + 3*y + 4*z + 5
        sage: c.plot()
        Graphics3d Object
        sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False)
        Graphics3d Object
        sage: d = -3*x + 2*y + 2*z + 3
        sage: d.plot(opacity=0.8)
        Graphics3d Object
        sage: e = 4*x + 2*z + 3
        sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1)
        Graphics3d Object
    """
    if hyperplane.base_ring().characteristic():
        raise NotImplementedError('base field must have characteristic zero')
    elif hyperplane.dimension() not in [
            0, 1, 2
    ]:  # dimension of hyperplane, not ambient space
        raise ValueError('can only plot hyperplanes in dimensions 1, 2, 3')
    # handle extra keywords
    if 'hyperplane_label' in kwds:
        hyp_label = kwds.pop('hyperplane_label')
        if not hyp_label:
            has_hyp_label = False
        else:
            has_hyp_label = True
    else:  # default
        hyp_label = True
        has_hyp_label = True
    if has_hyp_label:
        if hyp_label:  # then label hyperplane with its equation
            if hyperplane.dimension() == 2:  # jmol does not like latex
                label = hyperplane._repr_linear(include_zero=False)
            else:
                label = hyperplane._latex_()
        else:
            label = hyp_label  # a string
    if 'label_color' in kwds:
        label_color = kwds.pop('label_color')
    else:
        label_color = 'black'
    if 'label_fontsize' in kwds:
        label_fontsize = kwds.pop('label_fontsize')
    else:
        label_fontsize = 14
    if 'label_offset' in kwds:
        has_offset = True
        label_offset = kwds.pop('label_offset')
    else:
        has_offset = False  # give default values below
    if 'point_size' in kwds:
        pt_size = kwds.pop('point_size')
    else:
        pt_size = 50
    if 'ranges' in kwds:
        ranges_set = True
        ranges = kwds.pop('ranges')
    else:
        ranges_set = False  # give default values below
    # the extra keywords have now been handled
    # now create the plot
    if hyperplane.dimension() == 0:  # a point on a line
        x, = hyperplane.A()
        d = hyperplane.b()
        p = point((d / x, 0), size=pt_size, **kwds)
        if has_hyp_label:
            if not has_offset:
                label_offset = 0.1
            p += text(label, (d / x, label_offset),
                      color=label_color,
                      fontsize=label_fontsize)
            p += text('', (d / x, label_offset + 0.4))  # add space at top
        if 'ymax' not in kwds:
            kwds['ymax'] = 0.5
    elif hyperplane.dimension() == 1:  # a line in the plane
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        t = SR.var('t')
        if ranges_set:
            if isinstance(ranges, (list, tuple)):
                t0, t1 = ranges
            else:  # ranges should be a single positive number
                t0, t1 = -ranges, ranges
        else:  # default
            t0, t1 = -3, 3
        p = parametric_plot(pnt + t * w[0], (t, t0, t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1 = label_offset
            else:
                b0, b1 = 0, 0.2
            label = text(label, (pnt[0] + b0, pnt[1] + b1),
                         color=label_color,
                         fontsize=label_fontsize)
            p += label
    elif hyperplane.dimension() == 2:  # a plane in 3-space
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        s, t = SR.var('s t')
        if ranges_set:
            if isinstance(ranges, (list, tuple)):
                s0, s1 = ranges[0]
                t0, t1 = ranges[1]
            else:  # ranges should be a single positive integers
                s0, s1 = -ranges, ranges
                t0, t1 = -ranges, ranges
        else:  # default
            s0, s1 = -3, 3
            t0, t1 = -3, 3
        p = parametric_plot3d(pnt + s * w[0] + t * w[1], (s, s0, s1),
                              (t, t0, t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1, b2 = label_offset
            else:
                b0, b1, b2 = 0, 0, 0
            label = text3d(label, (pnt[0] + b0, pnt[1] + b1, pnt[2] + b2),
                           color=label_color,
                           fontsize=label_fontsize)
            p += label
    return p
예제 #9
0
def plot_hyperplane(hyperplane, **kwds):
    r"""
    Return the plot of a single hyperplane.

    INPUT:

    - ``**kwds`` -- plot options: see below

    OUTPUT:

    A graphics object of the plot.

    .. RUBRIC:: Plot Options

    Beside the usual plot options (enter ``plot?``), the plot command for
    hyperplanes includes the following:

    - ``hyperplane_label`` -- Boolean value or string (default: ``True``).
      If ``True``, the hyperplane is labeled with its equation, if a
      string, it is labeled by that string, otherwise it is not
      labeled.

    - ``label_color`` -- (Default: ``'black'``) Color for hyperplane_label.

    - ``label_fontsize`` -- Size for ``hyperplane_label`` font (default: 14)
      (does not work in 3d, yet).

    - ``label_offset`` -- (Default: 0-dim: 0.1, 1-dim: (0,1),
      2-dim: (0,0,0.2)) Amount by which label is offset from
      ``hyperplane.point()``.

    - ``point_size`` -- (Default: 50) Size of points in a zero-dimensional
      arrangement or of an arrangement over a finite field.

    - ``ranges`` -- Range for the parameters for the parametric plot of the
      hyperplane. If a single positive number ``r`` is given for the
      value of ``ranges``, then the ranges for all parameters are set to
      `[-r, r]`.  Otherwise, for a line in the plane, ``ranges`` has the
      form ``[a, b]`` (default: [-3,3]), and for a plane in 3-space, the
      ``ranges`` has the form ``[[a, b], [c, d]]`` (default: [[-3,3],[-3,3]]).
      (The ranges are centered around ``hyperplane.point()``.)

    EXAMPLES::

        sage: H1.<x> = HyperplaneArrangements(QQ)
        sage: a = 3*x + 4
        sage: a.plot()    # indirect doctest
        Graphics object consisting of 3 graphics primitives
        sage: a.plot(point_size=100,hyperplane_label='hello')
        Graphics object consisting of 3 graphics primitives

    
        sage: H2.<x,y> = HyperplaneArrangements(QQ)
        sage: b = 3*x + 4*y + 5
        sage: b.plot()
        Graphics object consisting of 2 graphics primitives
        sage: b.plot(ranges=(1,5),label_offset=(2,-1))
        Graphics object consisting of 2 graphics primitives
        sage: opts = {'hyperplane_label':True, 'label_color':'green',
        ....:         'label_fontsize':24, 'label_offset':(0,1.5)}
        sage: b.plot(**opts)
        Graphics object consisting of 2 graphics primitives

        sage: H3.<x,y,z> = HyperplaneArrangements(QQ)
        sage: c = 2*x + 3*y + 4*z + 5
        sage: c.plot()
        Graphics3d Object
        sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False)
        Graphics3d Object
        sage: d = -3*x + 2*y + 2*z + 3
        sage: d.plot(opacity=0.8)
        Graphics3d Object
        sage: e = 4*x + 2*z + 3
        sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1)
        Graphics3d Object
    """
    if hyperplane.base_ring().characteristic() != 0:
        raise NotImplementedError('base field must have characteristic zero')
    elif hyperplane.dimension() not in [0, 1, 2]: # dimension of hyperplane, not ambient space
        raise ValueError('can only plot hyperplanes in dimensions 1, 2, 3')
    # handle extra keywords
    if 'hyperplane_label' in kwds:
        hyp_label = kwds.pop('hyperplane_label')
        if not hyp_label:
            has_hyp_label = False
        else:
            has_hyp_label = True
    else: # default
        hyp_label = True
        has_hyp_label = True
    if has_hyp_label:
        if hyp_label: # then label hyperplane with its equation
            if hyperplane.dimension() == 2: # jmol does not like latex
                label = hyperplane._repr_linear(include_zero=False)
            else:
                label = hyperplane._latex_()
        else:
            label = hyp_label # a string
    if 'label_color' in kwds:
        label_color = kwds.pop('label_color')
    else:
        label_color = 'black'
    if 'label_fontsize' in kwds:
        label_fontsize = kwds.pop('label_fontsize')
    else:
        label_fontsize = 14
    if 'label_offset' in kwds:
        has_offset = True
        label_offset = kwds.pop('label_offset')
    else:
        has_offset = False # give default values below
    if 'point_size' in kwds:
        pt_size = kwds.pop('point_size')
    else:
        pt_size = 50
    if 'ranges' in kwds:
        ranges_set = True
        ranges = kwds.pop('ranges')
    else:
        ranges_set = False # give default values below
    # the extra keywords have now been handled
    # now create the plot
    if hyperplane.dimension() == 0: # a point on a line
        x, = hyperplane.A() 
        d = hyperplane.b()
        p = point((d/x,0), size = pt_size, **kwds)
        if has_hyp_label:
            if not has_offset:
                label_offset = 0.1
            p += text(label, (d/x,label_offset),
                    color=label_color,fontsize=label_fontsize)
            p += text('',(d/x,label_offset+0.4)) # add space at top
        if 'ymax' not in kwds:
            kwds['ymax'] = 0.5
    elif hyperplane.dimension() == 1: # a line in the plane
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        x, y = hyperplane.A()
        d = hyperplane.b()
        t = SR.var('t')
        if ranges_set:
            if type(ranges) in [list,tuple]:
                t0, t1 = ranges
            else:  # ranges should be a single positive number
                t0, t1 = -ranges, ranges
        else: # default
            t0, t1 = -3, 3
        p = parametric_plot(pnt+t*w[0], (t,t0,t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1 = label_offset
            else:
                b0, b1 = 0, 0.2
            label = text(label,(pnt[0]+b0,pnt[1]+b1),
                    color=label_color,fontsize=label_fontsize)
            p += label
    elif hyperplane.dimension() == 2: # a plane in 3-space
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        a, b, c = hyperplane.A()
        d = hyperplane.b()
        s,t = SR.var('s t')
        if ranges_set:
            if type(ranges) in [list,tuple]:
                s0, s1 = ranges[0]
                t0, t1 = ranges[1]
            else: # ranges should be a single positive integers
                s0, s1 = -ranges, ranges
                t0, t1 = -ranges, ranges
        else: # default
            s0, s1 = -3, 3
            t0, t1 = -3, 3
        p = parametric_plot3d(pnt+s*w[0]+t*w[1],(s,s0,s1),(t,t0,t1),**kwds)
        if has_hyp_label: 
            if has_offset:
                b0, b1, b2 = label_offset
            else:
                b0, b1, b2 = 0, 0, 0
            label = text3d(label,(pnt[0]+b0,pnt[1]+b1,pnt[2]+b2),
                    color=label_color,fontsize=label_fontsize)
            p += label
    return p
예제 #10
0
        def demazure_character(self, w, f=None):
            r"""
            Return the Demazure character associated to ``w``.

            INPUT:

            - ``w`` -- an element of the ambient weight lattice
              realization of the crystal, or a reduced word, or an element
              in the associated Weyl group

            OPTIONAL:

            - ``f`` -- a function from the crystal to a module

            This is currently only supported for crystals whose underlying
            weight space is the ambient space.

            The Demazure character is obtained by applying the Demazure operator
            `D_w` (see :meth:`sage.categories.regular_crystals.RegularCrystals.ParentMethods.demazure_operator`)
            to the highest weight element of the classical crystal. The simple
            Demazure operators `D_i` (see
            :meth:`sage.categories.regular_crystals.RegularCrystals.ElementMethods.demazure_operator_simple`)
            do not braid on the level of crystals, but on the level of characters they do.
            That is why it makes sense to input ``w`` either as a weight, a reduced word,
            or as an element of the underlying Weyl group.

            EXAMPLES::

                sage: T = crystals.Tableaux(['A',2], shape = [2,1])
                sage: e = T.weight_lattice_realization().basis()
                sage: weight = e[0] + 2*e[2]
                sage: weight.reduced_word()
                [2, 1]
                sage: T.demazure_character(weight)
                x1^2*x2 + x1*x2^2 + x1^2*x3 + x1*x2*x3 + x1*x3^2

                sage: T = crystals.Tableaux(['A',3],shape=[2,1])
                sage: T.demazure_character([1,2,3])
                x1^2*x2 + x1*x2^2 + x1^2*x3 + x1*x2*x3 + x2^2*x3
                sage: W = WeylGroup(['A',3])
                sage: w = W.from_reduced_word([1,2,3])
                sage: T.demazure_character(w)
                x1^2*x2 + x1*x2^2 + x1^2*x3 + x1*x2*x3 + x2^2*x3

                sage: T = crystals.Tableaux(['B',2], shape = [2])
                sage: e = T.weight_lattice_realization().basis()
                sage: weight = -2*e[1]
                sage: T.demazure_character(weight)
                x1^2 + x1*x2 + x2^2 + x1 + x2 + x1/x2 + 1/x2 + 1/x2^2 + 1

                sage: T = crystals.Tableaux("B2",shape=[1/2,1/2])
                sage: b2=WeylCharacterRing("B2",base_ring=QQ).ambient()
                sage: T.demazure_character([1,2],f=lambda x:b2(x.weight()))
                b2(-1/2,1/2) + b2(1/2,-1/2) + b2(1/2,1/2)

            REFERENCES:

            - [De1974]_

            - [Ma2009]_
            """
            from sage.misc.misc_c import prod
            from sage.rings.integer_ring import ZZ
            if hasattr(w, 'reduced_word'):
                word = w.reduced_word()
            else:
                word = w
            n = self.weight_lattice_realization().n
            u = self.algebra(ZZ).sum_of_monomials(self.module_generators)
            u = self.demazure_operator(u, word)
            if f is None:
                from sage.symbolic.all import SR as P
                x = [P.var('x%s' % (i + 1)) for i in range(n)]
                # TODO: use P.linear_combination when PolynomialRing will be a ModulesWithBasis
                return sum((coeff * prod((x[i]**(c.weight()[i])
                                          for i in range(n)), P.one())
                            for c, coeff in u), P.zero())
            else:
                return sum(coeff * f(c) for c, coeff in u)
예제 #11
0
        def demazure_character(self, w, f = None):
            r"""
            Return the Demazure character associated to ``w``.

            INPUT:

            - ``w`` -- an element of the ambient weight lattice
              realization of the crystal, or a reduced word, or an element
              in the associated Weyl group

            OPTIONAL:

            - ``f`` -- a function from the crystal to a module

            This is currently only supported for crystals whose underlying
            weight space is the ambient space.

            The Demazure character is obtained by applying the Demazure operator
            `D_w` (see :meth:`sage.categories.regular_crystals.RegularCrystals.ParentMethods.demazure_operator`)
            to the highest weight element of the classical crystal. The simple
            Demazure operators `D_i` (see
            :meth:`sage.categories.regular_crystals.RegularCrystals.ElementMethods.demazure_operator_simple`)
            do not braid on the level of crystals, but on the level of characters they do.
            That is why it makes sense to input ``w`` either as a weight, a reduced word,
            or as an element of the underlying Weyl group.

            EXAMPLES::

                sage: T = crystals.Tableaux(['A',2], shape = [2,1])
                sage: e = T.weight_lattice_realization().basis()
                sage: weight = e[0] + 2*e[2]
                sage: weight.reduced_word()
                [2, 1]
                sage: T.demazure_character(weight)
                x1^2*x2 + x1*x2^2 + x1^2*x3 + x1*x2*x3 + x1*x3^2

                sage: T = crystals.Tableaux(['A',3],shape=[2,1])
                sage: T.demazure_character([1,2,3])
                x1^2*x2 + x1*x2^2 + x1^2*x3 + x1*x2*x3 + x2^2*x3
                sage: W = WeylGroup(['A',3])
                sage: w = W.from_reduced_word([1,2,3])
                sage: T.demazure_character(w)
                x1^2*x2 + x1*x2^2 + x1^2*x3 + x1*x2*x3 + x2^2*x3

                sage: T = crystals.Tableaux(['B',2], shape = [2])
                sage: e = T.weight_lattice_realization().basis()
                sage: weight = -2*e[1]
                sage: T.demazure_character(weight)
                x1^2 + x1*x2 + x2^2 + x1 + x2 + x1/x2 + 1/x2 + 1/x2^2 + 1

                sage: T = crystals.Tableaux("B2",shape=[1/2,1/2])
                sage: b2=WeylCharacterRing("B2",base_ring=QQ).ambient()
                sage: T.demazure_character([1,2],f=lambda x:b2(x.weight()))
                b2(-1/2,1/2) + b2(1/2,-1/2) + b2(1/2,1/2)

            REFERENCES:

            - [De1974]_

            - [Ma2009]_
            """
            from sage.misc.misc_c import prod
            from sage.rings.integer_ring import ZZ
            if hasattr(w, 'reduced_word'):
                word = w.reduced_word()
            else:
                word = w
            n = self.weight_lattice_realization().n
            u = self.algebra(ZZ).sum_of_monomials(self.module_generators)
            u = self.demazure_operator(u, word)
            if f is None:
                from sage.symbolic.all import SR as P
                x = [P.var('x%s' % (i+1)) for i in range(n)]
                # TODO: use P.linear_combination when PolynomialRing will be a ModulesWithBasis
                return sum((coeff*prod((x[i]**(c.weight()[i]) for i in range(n)), P.one()) for c, coeff in u), P.zero())
            else:
                return sum(coeff * f(c) for c, coeff in u)
예제 #12
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)
예제 #13
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:
예제 #14
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)
예제 #15
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