Example #1
0
    def __init__(self, X):
        """
        Create a Set_object

        This function is called by the Set function; users
        shouldn't call this directly.

        EXAMPLES::

            sage: type(Set(QQ))
            <class 'sage.sets.set.Set_object_with_category'>

        TESTS::

            sage: _a, _b = get_coercion_model().canonical_coercion(Set([0]), 0)
            Traceback (most recent call last):
            ...
            TypeError: no common canonical parent for objects with parents:
            '<class 'sage.sets.set.Set_object_enumerated_with_category'>'
            and 'Integer Ring'
        """
        from sage.rings.integer import is_Integer
        if isinstance(X, (int, long)) or is_Integer(X):
            # The coercion model will try to call Set_object(0)
            raise ValueError('underlying object cannot be an integer')
        Parent.__init__(self, category=Sets())
        self.__object = X
Example #2
0
    def __classcall__(cls, *args, **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: A = AffineSpace(2, GF(4,'a'))
            sage: AffineGroup(A) is AffineGroup(2,4)
            True
            sage: AffineGroup(A) is AffineGroup(2, GF(4,'a'))
            True
            sage: A = AffineGroup(2, QQ)
            sage: V = QQ^2
            sage: A is AffineGroup(V)
            True
        """
        if len(args) == 1:
            V = args[0]
            if isinstance(V, AffineGroup):
                return V
            try:
                degree = V.dimension_relative()
            except AttributeError:
                degree = V.dimension()
            ring = V.base_ring()
        if len(args) == 2:
            degree, ring = args
            from sage.rings.integer import is_Integer
            if is_Integer(ring):
                from sage.rings.finite_rings.finite_field_constructor import FiniteField
                var = kwds.get('var', 'a')
                ring = FiniteField(ring, var)
        return super(AffineGroup, cls).__classcall__(cls, degree, ring)
Example #3
0
 def pyobject(self, ex, obj):
     from mathics.core import expression
     from mathics.core.expression import Number
     
     if obj is None:
         return expression.Symbol('Null')
     elif isinstance(obj, (list, tuple)) or is_Vector(obj):
         return expression.Expression('List', *(from_sage(item, self.subs) for item in obj))
     elif isinstance(obj, Constant):
         return expression.Symbol(obj._conversions.get('mathematica', obj._name))
     elif is_Integer(obj):
         return expression.Integer(str(obj))
     elif isinstance(obj, sage.Rational):
         rational = expression.Rational(str(obj))
         if rational.value.denom() == 1:
             return expression.Integer(rational.value.numer())
         else:
             return rational
     elif isinstance(obj, sage.RealDoubleElement) or is_RealNumber(obj):
         return expression.Real(str(obj))
     elif is_ComplexNumber(obj):
         real = Number.from_string(str(obj.real())).value
         imag = Number.from_string(str(obj.imag())).value
         return expression.Complex(real, imag)
     elif isinstance(obj, NumberFieldElement_quadratic):
         # TODO: this need not be a complex number, but we assume so!
         real = Number.from_string(str(obj.real())).value
         imag = Number.from_string(str(obj.imag())).value
         return expression.Complex(real, imag)
     else:
         return expression.from_python(obj)
Example #4
0
    def __init__(self, degree, base_ring, category=None):
        """
        Base class for matrix groups over generic base rings

        You should not use this class directly. Instead, use one of
        the more specialized derived classes.

        INPUT:

        - ``degree`` -- integer. The degree (matrix size) of the
          matrix group.

        - ``base_ring`` -- ring. The base ring of the matrices.

        TESTS::

            sage: G = GL(2, QQ)
            sage: from sage.groups.matrix_gps.matrix_group import MatrixGroup_generic
            sage: isinstance(G, MatrixGroup_generic)
            True
        """
        assert is_Ring(base_ring)
        assert is_Integer(degree)

        self._deg = degree
        if self._deg <= 0:
            raise ValueError('the degree must be at least 1')

        if (category is None) and is_FiniteField(base_ring):
            from sage.categories.finite_groups import FiniteGroups
            category = FiniteGroups()
        super(MatrixGroup_generic, self).__init__(base=base_ring, category=category)
Example #5
0
File: set.py Project: DrXyzzy/sage
    def __init__(self, X):
        """
        Create a Set_object

        This function is called by the Set function; users
        shouldn't call this directly.

        EXAMPLES::

            sage: type(Set(QQ))
            <class 'sage.sets.set.Set_object_with_category'>

        TESTS::

            sage: _a, _b = get_coercion_model().canonical_coercion(Set([0]), 0)
            Traceback (most recent call last):
            ...
            TypeError: no common canonical parent for objects with parents:
            '<class 'sage.sets.set.Set_object_enumerated_with_category'>'
            and 'Integer Ring'
        """
        from sage.rings.integer import is_Integer
        if isinstance(X, (int,long)) or is_Integer(X):
            # The coercion model will try to call Set_object(0)
            raise ValueError('underlying object cannot be an integer')
        Parent.__init__(self, category=Sets())
        self.__object = X
Example #6
0
    def __classcall__(cls, *args, **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES::

            sage: A = AffineSpace(2, GF(4,'a'))
            sage: AffineGroup(A) is AffineGroup(2,4)
            True
            sage: AffineGroup(A) is AffineGroup(2, GF(4,'a'))
            True
            sage: A = AffineGroup(2, QQ)
            sage: V = QQ^2
            sage: A is AffineGroup(V)
            True
        """
        if len(args) == 1:
            V = args[0]
            if isinstance(V, AffineGroup):
                return V
            try:
                degree = V.dimension_relative()
            except AttributeError:
                degree = V.dimension()
            ring = V.base_ring()
        if len(args) == 2:
            degree, ring = args
            from sage.rings.integer import is_Integer
            if is_Integer(ring):
                from sage.rings.finite_rings.finite_field_constructor import FiniteField
                var = kwds.get('var', 'a')
                ring = FiniteField(ring, var)
        return super(AffineGroup, cls).__classcall__(cls, degree, ring)
Example #7
0
def _check_trac_number(trac_number):
    """
    Check that the argument is likely to be a valid trac issue number.

    INPUT:

    - ``trac_number`` -- anything.

    OUTPUT:

    This function returns nothing. A ``ValueError`` is raised if the
    argument can not be a valid trac number.

    EXAMPLES::

        sage: from sage.misc.superseded import _check_trac_number
        sage: _check_trac_number(1)
        sage: _check_trac_number(int(10))
        sage: _check_trac_number(long(1000))
        sage: _check_trac_number('1')
        Traceback (most recent call last):
        ...
        ValueError: The argument "1" is not a valid trac issue number.
    """
    from sage.rings.integer import is_Integer
    err = ValueError('The argument "'+str(trac_number)+'" is not a valid trac issue number.')
    if not (is_Integer(trac_number) or isinstance(trac_number, (int,long))):
        raise err
    if trac_number < 0:
        raise err
Example #8
0
def _check_trac_number(trac_number):
    """
    Check that the argument is likely to be a valid trac issue number.

    INPUT:

    - ``trac_number`` -- anything.

    OUTPUT:

    This function returns nothing. A ``ValueError`` is raised if the
    argument can not be a valid trac number.

    EXAMPLES::

        sage: from sage.misc.superseded import _check_trac_number
        sage: _check_trac_number(1)
        sage: _check_trac_number(int(10))
        sage: _check_trac_number(long(1000))
        sage: _check_trac_number('1')
        Traceback (most recent call last):
        ...
        ValueError: The argument "1" is not a valid trac issue number.
    """
    from sage.rings.integer import is_Integer
    err = ValueError('The argument "' + str(trac_number) +
                     '" is not a valid trac issue number.')
    if not (is_Integer(trac_number) or isinstance(trac_number, (int, long))):
        raise err
    if trac_number < 0:
        raise err
Example #9
0
def Polyhedron(vertices=None,
               rays=None,
               lines=None,
               ieqs=None,
               eqns=None,
               ambient_dim=None,
               base_ring=None,
               minimize=True,
               verbose=False,
               backend=None):
    """
    Construct a polyhedron object.

    You may either define it with vertex/ray/line or
    inequalities/equations data, but not both. Redundant data will
    automatically be removed (unless ``minimize=False``), and the
    complementary representation will be computed.

    INPUT:

    - ``vertices`` -- list of point. Each point can be specified as
      any iterable container of ``base_ring`` elements. If ``rays`` or
      ``lines`` are specified but no ``vertices``, the origin is
      taken to be the single vertex.

    - ``rays`` -- list of rays. Each ray can be specified as any
      iterable container of ``base_ring`` elements.

    - ``lines`` -- list of lines. Each line can be specified as any
      iterable container of ``base_ring`` elements.

    - ``ieqs`` -- list of inequalities. Each line can be specified as any
      iterable container of ``base_ring`` elements. An entry equal to
      ``[-1,7,3,4]`` represents the inequality `7x_1+3x_2+4x_3\geq 1`.

    - ``eqns`` -- list of equalities. Each line can be specified as
      any iterable container of ``base_ring`` elements. An entry equal to
      ``[-1,7,3,4]`` represents the equality `7x_1+3x_2+4x_3= 1`.

    - ``base_ring`` -- a sub-field of the reals implemented in
      Sage. The field over which the polyhedron will be defined. For
      ``QQ`` and algebraic extensions, exact arithmetic will be
      used. For ``RDF``, floating point numbers will be used. Floating
      point arithmetic is faster but might give the wrong result for
      degenerate input.

    - ``ambient_dim`` -- integer. The ambient space dimension. Usually
      can be figured out automatically from the H/Vrepresentation
      dimensions.

    - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are

      * ``'cdd'``: use cdd
        (:mod:`~sage.geometry.polyhedron.backend_cdd`) with `\QQ` or
        `\RDF` coefficients depending on ``base_ring``.

      * ``'ppl'``: use ppl
        (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\ZZ` or
        `\QQ` coefficients depending on ``base_ring``.

      * ``'field'``: use python implementation
        (:mod:`~sage.geometry.polyhedron.backend_field`) for any field

    Some backends support further optional arguments:

    - ``minimize`` -- boolean (default: ``True``). Whether to
      immediately remove redundant H/V-representation data. Currently
      not used.

    - ``verbose`` -- boolean (default: ``False``). Whether to print
      verbose output for debugging purposes. Only supported by the cdd
      backends.

    OUTPUT:

    The polyhedron defined by the input data.

    EXAMPLES:

    Construct some polyhedra::

        sage: square_from_vertices = Polyhedron(vertices = [[1, 1], [1, -1], [-1, 1], [-1, -1]])
        sage: square_from_ieqs = Polyhedron(ieqs = [[1, 0, 1], [1, 1, 0], [1, 0, -1], [1, -1, 0]])
        sage: list(square_from_ieqs.vertex_generator())
        [A vertex at (1, -1),
         A vertex at (1, 1),
         A vertex at (-1, 1),
         A vertex at (-1, -1)]
        sage: list(square_from_vertices.inequality_generator())
        [An inequality (1, 0) x + 1 >= 0,
         An inequality (0, 1) x + 1 >= 0,
         An inequality (-1, 0) x + 1 >= 0,
         An inequality (0, -1) x + 1 >= 0]
        sage: p = Polyhedron(vertices = [[1.1, 2.2], [3.3, 4.4]], base_ring=RDF)
        sage: p.n_inequalities()
        2

    The same polyhedron given in two ways::

        sage: p = Polyhedron(ieqs = [[0,1,0,0],[0,0,1,0]])
        sage: p.Vrepresentation()
        (A line in the direction (0, 0, 1),
         A ray in the direction (1, 0, 0),
         A ray in the direction (0, 1, 0),
         A vertex at (0, 0, 0))
        sage: q = Polyhedron(vertices=[[0,0,0]], rays=[[1,0,0],[0,1,0]], lines=[[0,0,1]])
        sage: q.Hrepresentation()
        (An inequality (1, 0, 0) x + 0 >= 0,
         An inequality (0, 1, 0) x + 0 >= 0)

    Finally, a more complicated example. Take `\mathbb{R}_{\geq 0}^6` with
    coordinates `a, b, \dots, f` and

      * The inequality `e+b \geq c+d`
      * The inequality `e+c \geq b+d`
      * The equation `a+b+c+d+e+f = 31`

    ::

        sage: positive_coords = Polyhedron(ieqs=[
        ...       [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0],
        ...       [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]])
        sage: P = Polyhedron(ieqs=positive_coords.inequalities() + (
        ...       [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]), eqns=[[-31,1,1,1,1,1,1]])
        sage: P
        A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices
        sage: P.dim()
        5
        sage: P.Vrepresentation()
        (A vertex at (31, 0, 0, 0, 0, 0), A vertex at (0, 0, 0, 0, 0, 31),
         A vertex at (0, 0, 0, 0, 31, 0), A vertex at (0, 0, 31/2, 0, 31/2, 0),
         A vertex at (0, 31/2, 31/2, 0, 0, 0), A vertex at (0, 31/2, 0, 0, 31/2, 0),
         A vertex at (0, 0, 0, 31/2, 31/2, 0))

    .. NOTE::

      * Once constructed, a ``Polyhedron`` object is immutable.

      * Although the option ``field=RDF`` allows numerical data to
        be used, it might not give the right answer for degenerate
        input data - the results can depend upon the tolerance
        setting of cdd.
    """
    # Clean up the arguments
    vertices = _make_listlist(vertices)
    rays = _make_listlist(rays)
    lines = _make_listlist(lines)
    ieqs = _make_listlist(ieqs)
    eqns = _make_listlist(eqns)

    got_Vrep = (len(vertices + rays + lines) > 0)
    got_Hrep = (len(ieqs + eqns) > 0)

    if got_Vrep and got_Hrep:
        raise ValueError('You cannot specify both H- and V-representation.')
    elif got_Vrep:
        deduced_ambient_dim = _common_length_of(vertices, rays, lines)[1]
    elif got_Hrep:
        deduced_ambient_dim = _common_length_of(ieqs, eqns)[1] - 1
    else:
        if ambient_dim is None:
            deduced_ambient_dim = 0
        else:
            deduced_ambient_dim = ambient_dim
        if base_ring is None:
            base_ring = ZZ

    # set ambient_dim
    if ambient_dim is not None and deduced_ambient_dim != ambient_dim:
        raise ValueError(
            'Ambient space dimension mismatch. Try removing the "ambient_dim" parameter.'
        )
    ambient_dim = deduced_ambient_dim

    # figure out base_ring
    from sage.misc.flatten import flatten
    values = flatten(vertices + rays + lines + ieqs + eqns)
    if base_ring is not None:
        try:
            convert = not all(x.parent() is base_ring for x in values)
        except AttributeError:  # No x.parent() method?
            convert = True
    else:
        from sage.rings.integer import is_Integer
        from sage.rings.rational import is_Rational
        from sage.rings.real_double import is_RealDoubleElement
        if all(is_Integer(x) for x in values):
            if got_Vrep:
                base_ring = ZZ
            else:  # integral inequalities usually do not determine a lattice polytope!
                base_ring = QQ
            convert = False
        elif all(is_Rational(x) for x in values):
            base_ring = QQ
            convert = False
        elif all(is_RealDoubleElement(x) for x in values):
            base_ring = RDF
            convert = False
        else:
            try:
                for v in values:
                    ZZ(v)
                if got_Vrep:
                    base_ring = ZZ
                else:
                    base_ring = QQ
                convert = True
            except (TypeError, ValueError):
                from sage.structure.sequence import Sequence
                values = Sequence(values)
                common_ring = values.universe()
                if QQ.has_coerce_map_from(common_ring):
                    base_ring = QQ
                    convert = True
                elif common_ring is RR:  # DWIM: replace with RDF
                    base_ring = RDF
                    convert = True
                else:
                    base_ring = common_ring
                    convert = True

    # Add the origin if necesarry
    if got_Vrep and len(vertices) == 0:
        vertices = [[0] * ambient_dim]

    # Specific backends can override the base_ring
    from sage.geometry.polyhedron.parent import Polyhedra
    parent = Polyhedra(base_ring, ambient_dim, backend=backend)
    base_ring = parent.base_ring()

    # finally, construct the Polyhedron
    Hrep = Vrep = None
    if got_Hrep:
        Hrep = [ieqs, eqns]
    if got_Vrep:
        Vrep = [vertices, rays, lines]
    return parent(Vrep, Hrep, convert=convert, verbose=verbose)
Example #10
0
    def __call__(self, P):
        r"""
        Returns a rational point P in the abstract Homset J(K), given:

        0. A point P in J = Jac(C), returning P; 1. A point P on the curve
        C such that J = Jac(C), where C is an odd degree model, returning
        [P - oo]; 2. A pair of points (P, Q) on the curve C such that J =
        Jac(C), returning [P-Q]; 2. A list of polynomials (a,b) such that
        `b^2 + h*b - f = 0 mod a`, returning [(a(x),y-b(x))].

        EXAMPLES::

            sage: P.<x> = PolynomialRing(QQ)
            sage: f = x^5 - x + 1; h = x
            sage: C = HyperellipticCurve(f,h,'u,v')
            sage: P = C(0,1,1)
            sage: J = C.jacobian()
            sage: Q = J(QQ)(P)
            sage: for i in range(6): i*Q
            (1)
            (u, v - 1)
            (u^2, v + u - 1)
            (u^2, v + 1)
            (u, v + 1)
            (1)

        ::

            sage: F.<a> = GF(3)
            sage: R.<x> = F[]
            sage: f = x^5-1
            sage: C = HyperellipticCurve(f)
            sage: J = C.jacobian()
            sage: X = J(F)
            sage: a = x^2-x+1
            sage: b = -x +1
            sage: c = x-1
            sage: d = 0
            sage: D1 = X([a,b])
            sage: D1
            (x^2 + 2*x + 1, y + x + 2)
            sage: D2 = X([c,d])
            sage: D2
            (x + 2, y)
            sage: D1+D2
            (x^2 + 2*x + 2, y + 2*x + 1)

        """
        if isinstance(P, (int, long, Integer)) and P == 0:
            R = PolynomialRing(self.value_ring(), 'x')
            return JacobianMorphism_divisor_class_field(self, (R(1), R(0)))
        elif isinstance(P, (list, tuple)):
            if len(P) == 1 and P[0] == 0:
                R = PolynomialRing(self.value_ring(), 'x')
                return JacobianMorphism_divisor_class_field(self, (R(1), R(0)))
            elif len(P) == 2:
                P1 = P[0]
                P2 = P[1]
                if is_Integer(P1) and is_Integer(P2):
                    R = PolynomialRing(self.value_ring(), 'x')
                    P1 = R(P1)
                    P2 = R(P2)
                    return JacobianMorphism_divisor_class_field(
                        self, tuple([P1, P2]))
                if is_Integer(P1) and is_Polynomial(P2):
                    R = PolynomialRing(self.value_ring(), 'x')
                    P1 = R(P1)
                    return JacobianMorphism_divisor_class_field(
                        self, tuple([P1, P2]))
                if is_Integer(P2) and is_Polynomial(P1):
                    R = PolynomialRing(self.value_ring(), 'x')
                    P2 = R(P2)
                    return JacobianMorphism_divisor_class_field(
                        self, tuple([P1, P2]))
                if is_Polynomial(P1) and is_Polynomial(P2):
                    return JacobianMorphism_divisor_class_field(self, tuple(P))
                if is_SchemeMorphism(P1) and is_SchemeMorphism(P2):
                    return self(P1) - self(P2)
            raise TypeError("Argument P (= %s) must have length 2." % P)
        elif isinstance(
                P,
                JacobianMorphism_divisor_class_field) and self == P.parent():
            return P
        elif is_SchemeMorphism(P):
            x0 = P[0]
            y0 = P[1]
            R, x = PolynomialRing(self.value_ring(), 'x').objgen()
            return self((x - x0, R(y0)))
        raise TypeError(
            "Argument P (= %s) does not determine a divisor class" % P)
Example #11
0
    def to_cartesian(self, func, params=None):
        """
        Returns a 3-tuple of functions, parameterized over ``params``, that
        represents the Cartesian coordinates of the value of ``func``.

        INPUT:

         - ``func`` - A function in this coordinate space. Corresponds to the
           independent variable.

         - ``params`` - The parameters of ``func``. Corresponds to the dependent
           variables.

        EXAMPLES::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(x, y) = 2*x+y
            sage: T.to_cartesian(f, [x, y])
            (x + y, x - y, 2*x + y)
            sage: [h(1,2) for h in T.to_cartesian(lambda x,y: 2*x+y)]
            [3.0, -1.0, 4.0]

        We try to return a function having the same variable names as
        the function passed in::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(a, b) = 2*a+b
            sage: T.to_cartesian(f, [a, b])
            (a + b, a - b, 2*a + b)
            sage: t1,t2,t3=T.to_cartesian(lambda a,b: 2*a+b)
            sage: import inspect
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t2)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t3)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: def g(a,b): return 2*a+b
            sage: t1,t2,t3=T.to_cartesian(g)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: t1,t2,t3=T.to_cartesian(2*a+b)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)

        If we cannot guess the right parameter names, then the
        parameters are named `u` and `v`::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: t1,t2,t3=T.to_cartesian(operator.add)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['u', 'v'], varargs=None, keywords=None, defaults=None)
            sage: [h(1,2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]
            sage: [h(u=1,v=2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]

        The output of the function ``func`` is coerced to a float when
        it is evaluated if the function is something like a lambda or
        python callable. This takes care of situations like f returning a
        singleton numpy array, for example.

            sage: from numpy import array
            sage: v_phi=array([ 0.,  1.57079637,  3.14159274, 4.71238911,  6.28318548])
            sage: v_theta=array([ 0.,  0.78539819,  1.57079637,  2.35619456,  3.14159274])
            sage: m_r=array([[ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ....: [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ....: [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ....: [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ....: [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422]])
            sage: import scipy.interpolate
            sage: f=scipy.interpolate.RectBivariateSpline(v_phi,v_theta,m_r)
            sage: spherical_plot3d(f,(0,2*pi),(0,pi))
            Graphics3d Object

        """
        from sage.symbolic.expression import is_Expression
        from sage.rings.real_mpfr import is_RealNumber
        from sage.rings.integer import is_Integer
        if params is not None and (is_Expression(func) or is_RealNumber(func)
                                   or is_Integer(func)):
            return self.transform(
                **{
                    self.dep_var: func,
                    self.indep_vars[0]: params[0],
                    self.indep_vars[1]: params[1]
                })
        else:
            # func might be a lambda or a Python callable; this makes it slightly
            # more complex.
            import sage.symbolic.ring
            dep_var_dummy = sage.symbolic.ring.var(self.dep_var)
            indep_var_dummies = sage.symbolic.ring.var(','.join(
                self.indep_vars))
            transformation = self.transform(
                **{
                    self.dep_var: dep_var_dummy,
                    self.indep_vars[0]: indep_var_dummies[0],
                    self.indep_vars[1]: indep_var_dummies[1]
                })
            if params is None:
                if callable(func):
                    params = _find_arguments_for_callable(func)
                    if params is None:
                        params = ['u', 'v']
                else:
                    raise ValueError("function is not callable")

            def subs_func(t):
                # We use eval so that the lambda function has the same
                # variable names as the original function
                ll = """lambda {x},{y}: t.subs({{
                    dep_var_dummy: float(func({x}, {y})),
                    indep_var_dummies[0]: float({x}),
                    indep_var_dummies[1]: float({y})
                }})""".format(x=params[0], y=params[1])
                return eval(
                    ll,
                    dict(t=t,
                         func=func,
                         dep_var_dummy=dep_var_dummy,
                         indep_var_dummies=indep_var_dummies))

            return [subs_func(_) for _ in transformation]
Example #12
0
    def __call__(self, P):
        r"""
        Returns a rational point P in the abstract Homset J(K), given:

        0. A point P in J = Jac(C), returning P; 1. A point P on the curve
        C such that J = Jac(C), where C is an odd degree model, returning
        [P - oo]; 2. A pair of points (P, Q) on the curve C such that J =
        Jac(C), returning [P-Q]; 2. A list of polynomials (a,b) such that
        `b^2 + h*b - f = 0 mod a`, returning [(a(x),y-b(x))].

        EXAMPLES::

            sage: P.<x> = PolynomialRing(QQ)
            sage: f = x^5 - x + 1; h = x
            sage: C = HyperellipticCurve(f,h,'u,v')
            sage: P = C(0,1,1)
            sage: J = C.jacobian()
            sage: Q = J(QQ)(P)
            sage: for i in range(6): i*Q
            (1)
            (u, v - 1)
            (u^2, v + u - 1)
            (u^2, v + 1)
            (u, v + 1)
            (1)

        ::

            sage: F.<a> = GF(3)
            sage: R.<x> = F[]
            sage: f = x^5-1
            sage: C = HyperellipticCurve(f)
            sage: J = C.jacobian()
            sage: X = J(F)
            sage: a = x^2-x+1
            sage: b = -x +1
            sage: c = x-1
            sage: d = 0
            sage: D1 = X([a,b])
            sage: D1
            (x^2 + 2*x + 1, y + x + 2)
            sage: D2 = X([c,d])
            sage: D2
            (x + 2, y)
            sage: D1+D2
            (x^2 + 2*x + 2, y + 2*x + 1)

        """
        if isinstance(P,(int,long,Integer)) and P == 0:
            R = PolynomialRing(self.value_ring(), 'x')
            return JacobianMorphism_divisor_class_field(self, (R(1),R(0)))
        elif isinstance(P,(list,tuple)):
            if len(P) == 1 and P[0] == 0:
                R = PolynomialRing(self.value_ring(), 'x')
                return JacobianMorphism_divisor_class_field(self, (R(1),R(0)))
            elif len(P) == 2:
                P1 = P[0]
                P2 = P[1]
                if is_Integer(P1) and is_Integer(P2):
                    R = PolynomialRing(self.value_ring(), 'x')
                    P1 = R(P1)
                    P2 = R(P2)
                    return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
                if is_Integer(P1) and is_Polynomial(P2):
                    R = PolynomialRing(self.value_ring(), 'x')
                    P1 = R(P1)
                    return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
                if is_Integer(P2) and is_Polynomial(P1):
                    R = PolynomialRing(self.value_ring(), 'x')
                    P2 = R(P2)
                    return JacobianMorphism_divisor_class_field(self, tuple([P1,P2]))
                if is_Polynomial(P1) and is_Polynomial(P2):
                    return JacobianMorphism_divisor_class_field(self, tuple(P))
                if is_SchemeMorphism(P1) and is_SchemeMorphism(P2):
                    return self(P1) - self(P2)
            raise TypeError("Argument P (= %s) must have length 2."%P)
        elif isinstance(P,JacobianMorphism_divisor_class_field) and self == P.parent():
            return P
        elif is_SchemeMorphism(P):
            x0 = P[0]; y0 = P[1]
            R, x = PolynomialRing(self.value_ring(), 'x').objgen()
            return self((x-x0,R(y0)))
        raise TypeError("Argument P (= %s) does not determine a divisor class"%P)
Example #13
0
    def to_cartesian(self, func, params=None):
        """
        Returns a 3-tuple of functions, parameterized over ``params``, that
        represents the Cartesian coordinates of the value of ``func``.

        INPUT:

         - ``func`` - A function in this coordinate space. Corresponds to the
           independent variable.

         - ``params`` - The parameters of func. Corresponds to the dependent
           variables.

        EXAMPLE::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(x, y) = 2*x+y
            sage: T.to_cartesian(f, [x, y])
            (x + y, x - y, 2*x + y)
            sage: [h(1,2) for h in T.to_cartesian(lambda x,y: 2*x+y)]
            [3.0, -1.0, 4.0]

        We try to return a function having the same variable names as
        the function passed in::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(a, b) = 2*a+b
            sage: T.to_cartesian(f, [a, b])
            (a + b, a - b, 2*a + b)
            sage: t1,t2,t3=T.to_cartesian(lambda a,b: 2*a+b)
            sage: import inspect
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t2)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t3)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: def g(a,b): return 2*a+b
            sage: t1,t2,t3=T.to_cartesian(g)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: t1,t2,t3=T.to_cartesian(2*a+b)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)

        If we cannot guess the right parameter names, then the
        parameters are named `u` and `v`::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: t1,t2,t3=T.to_cartesian(operator.add)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['u', 'v'], varargs=None, keywords=None, defaults=None)
            sage: [h(1,2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]
            sage: [h(u=1,v=2) for h in T.to_cartesian(operator.mul)]
            [3.0, -1.0, 2.0]

        The output of the function `func` is coerced to a float when
        it is evaluated if the function is something like a lambda or
        python callable. This takes care of situations like f returning a
        singleton numpy array, for example.

            sage: from numpy import array
            sage: v_phi=array([ 0.,  1.57079637,  3.14159274, 4.71238911,  6.28318548])
            sage: v_theta=array([ 0.,  0.78539819,  1.57079637,  2.35619456,  3.14159274])
            sage: m_r=array([[ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ... [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ... [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422],
            ... [ 0.16763356,  0.19993708,  0.31403568,  0.47359696, 0.55282422],
            ... [ 0.16763356,  0.25683223,  0.16649297,  0.10594339, 0.55282422]])
            sage: import scipy.interpolate
            sage: f=scipy.interpolate.RectBivariateSpline(v_phi,v_theta,m_r)
            sage: spherical_plot3d(f,(0,2*pi),(0,pi))
            Graphics3d Object

        """
        from sage.symbolic.expression import is_Expression
        from sage.rings.real_mpfr import is_RealNumber
        from sage.rings.integer import is_Integer
        if params is not None and (is_Expression(func) or is_RealNumber(func) or is_Integer(func)):
            return self.transform(**{
                self.dep_var: func,
                self.indep_vars[0]: params[0],
                self.indep_vars[1]: params[1]
            })
        else:
            # func might be a lambda or a Python callable; this makes it slightly
            # more complex.
            import sage.symbolic.ring
            dep_var_dummy = sage.symbolic.ring.var(self.dep_var)
            indep_var_dummies = sage.symbolic.ring.var(','.join(self.indep_vars))
            transformation = self.transform(**{
                self.dep_var: dep_var_dummy,
                self.indep_vars[0]: indep_var_dummies[0],
                self.indep_vars[1]: indep_var_dummies[1]
            })
            if params is None:
                if callable(func):
                    params = _find_arguments_for_callable(func)
                    if params is None:
                        params=['u','v']
                else:
                    raise ValueError("function is not callable")
            def subs_func(t):
                # We use eval so that the lambda function has the same
                # variable names as the original function
                ll="""lambda {x},{y}: t.subs({{
                    dep_var_dummy: float(func({x}, {y})),
                    indep_var_dummies[0]: float({x}),
                    indep_var_dummies[1]: float({y})
                }})""".format(x=params[0], y=params[1])
                return eval(ll,dict(t=t, func=func, dep_var_dummy=dep_var_dummy,
                                    indep_var_dummies=indep_var_dummies))
            return [subs_func(_) for _ in transformation]
Example #14
0
def Polyhedron(vertices=None, rays=None, lines=None,
               ieqs=None, eqns=None,
               ambient_dim=None, base_ring=None, minimize=True, verbose=False,
               backend=None):
    """
    Construct a polyhedron object.

    You may either define it with vertex/ray/line or
    inequalities/equations data, but not both. Redundant data will
    automatically be removed (unless ``minimize=False``), and the
    complementary representation will be computed.

    INPUT:

    - ``vertices`` -- list of point. Each point can be specified as
      any iterable container of ``base_ring`` elements. If ``rays`` or
      ``lines`` are specified but no ``vertices``, the origin is
      taken to be the single vertex.

    - ``rays`` -- list of rays. Each ray can be specified as any
      iterable container of ``base_ring`` elements.

    - ``lines`` -- list of lines. Each line can be specified as any
      iterable container of ``base_ring`` elements.

    - ``ieqs`` -- list of inequalities. Each line can be specified as any
      iterable container of ``base_ring`` elements. An entry equal to
      ``[-1,7,3,4]`` represents the inequality `7x_1+3x_2+4x_3\geq 1`.

    - ``eqns`` -- list of equalities. Each line can be specified as
      any iterable container of ``base_ring`` elements. An entry equal to
      ``[-1,7,3,4]`` represents the equality `7x_1+3x_2+4x_3= 1`.

    - ``base_ring`` -- either ``QQ`` or ``RDF``. The field over which
      the polyhedron will be defined. For ``QQ``, exact arithmetic
      will be used. For ``RDF``, floating point numbers will be
      used. Floating point arithmetic is faster but might give the
      wrong result for degenerate input.

    - ``ambient_dim`` -- integer. The ambient space dimension. Usually
      can be figured out automatically from the H/Vrepresentation
      dimensions.

    - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are

      * ``'cdd'``: use cdd
        (:mod:`~sage.geometry.polyhedron.backend_cdd`) with `\QQ` or
        `\RDF` coefficients depending on ``base_ring``.


      * ``'ppl'``: use ppl
        (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\ZZ` or
        `\QQ` coefficients depending on ``base_ring``.

    Some backends support further optional arguments:

    - ``minimize`` -- boolean (default: ``True``). Whether to
      immediately remove redundant H/V-representation data. Currently
      not used.

    - ``verbose`` -- boolean (default: ``False``). Whether to print
      verbose output for debugging purposes. Only supported by the cdd
      backends.

    OUTPUT:

    The polyhedron defined by the input data.

    EXAMPLES:

    Construct some polyhedra::

        sage: square_from_vertices = Polyhedron(vertices = [[1, 1], [1, -1], [-1, 1], [-1, -1]])
        sage: square_from_ieqs = Polyhedron(ieqs = [[1, 0, 1], [1, 1, 0], [1, 0, -1], [1, -1, 0]])
        sage: list(square_from_ieqs.vertex_generator())
        [A vertex at (1, -1),
         A vertex at (1, 1),
         A vertex at (-1, 1),
         A vertex at (-1, -1)]
        sage: list(square_from_vertices.inequality_generator())
        [An inequality (1, 0) x + 1 >= 0,
         An inequality (0, 1) x + 1 >= 0,
         An inequality (-1, 0) x + 1 >= 0,
         An inequality (0, -1) x + 1 >= 0]
        sage: p = Polyhedron(vertices = [[1.1, 2.2], [3.3, 4.4]], base_ring=RDF)
        sage: p.n_inequalities()
        2

    The same polyhedron given in two ways::

        sage: p = Polyhedron(ieqs = [[0,1,0,0],[0,0,1,0]])
        sage: p.Vrepresentation()
        (A line in the direction (0, 0, 1),
         A ray in the direction (1, 0, 0),
         A ray in the direction (0, 1, 0),
         A vertex at (0, 0, 0))
        sage: q = Polyhedron(vertices=[[0,0,0]], rays=[[1,0,0],[0,1,0]], lines=[[0,0,1]])
        sage: q.Hrepresentation()
        (An inequality (1, 0, 0) x + 0 >= 0,
         An inequality (0, 1, 0) x + 0 >= 0)

    Finally, a more complicated example. Take `\mathbb{R}_{\geq 0}^6` with
    coordinates `a, b, \dots, f` and

      * The inequality `e+b \geq c+d`
      * The inequality `e+c \geq b+d`
      * The equation `a+b+c+d+e+f = 31`

    ::

        sage: positive_coords = Polyhedron(ieqs=[
        ...       [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0],
        ...       [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]])
        sage: P = Polyhedron(ieqs=positive_coords.inequalities() + (
        ...       [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]), eqns=[[-31,1,1,1,1,1,1]])
        sage: P
        A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices
        sage: P.dim()
        5
        sage: P.Vrepresentation()
        (A vertex at (31, 0, 0, 0, 0, 0), A vertex at (0, 0, 0, 0, 0, 31),
         A vertex at (0, 0, 0, 0, 31, 0), A vertex at (0, 0, 31/2, 0, 31/2, 0),
         A vertex at (0, 31/2, 31/2, 0, 0, 0), A vertex at (0, 31/2, 0, 0, 31/2, 0),
         A vertex at (0, 0, 0, 31/2, 31/2, 0))

    .. NOTE::

      * Once constructed, a ``Polyhedron`` object is immutable.
      * Although the option ``field=RDF`` allows numerical data to
        be used, it might not give the right answer for degenerate
        input data - the results can depend upon the tolerance
        setting of cdd.
    """
    # Clean up the arguments
    vertices = _make_listlist(vertices)
    rays     = _make_listlist(rays)
    lines    = _make_listlist(lines)
    ieqs     = _make_listlist(ieqs)
    eqns     = _make_listlist(eqns)

    got_Vrep = (len(vertices+rays+lines) > 0)
    got_Hrep = (len(ieqs+eqns) > 0)

    if got_Vrep and got_Hrep:
        raise ValueError('You cannot specify both H- and V-representation.')
    elif got_Vrep:
        deduced_ambient_dim = _common_length_of(vertices, rays, lines)[1]
    elif got_Hrep:
        deduced_ambient_dim = _common_length_of(ieqs, eqns)[1] - 1
    else:
        if ambient_dim is None:
            deduced_ambient_dim = 0
        else:
            deduced_ambient_dim = ambient_dim
        if base_ring is None:
            base_ring = ZZ

    # set ambient_dim
    if ambient_dim is not None and deduced_ambient_dim!=ambient_dim:
        raise ValueError('Ambient space dimension mismatch. Try removing the "ambient_dim" parameter.')
    ambient_dim = deduced_ambient_dim

    # figure out base_ring
    from sage.misc.flatten import flatten
    values = flatten(vertices+rays+lines+ieqs+eqns)
    if base_ring is not None:
        try:
            convert = not all(x.parent() is base_ring for x in values)
        except AttributeError:   # No x.parent() method?
            convert = True
    else:
        from sage.rings.integer import is_Integer
        from sage.rings.rational import is_Rational
        from sage.rings.real_double import is_RealDoubleElement
        if all(is_Integer(x) for x in values):
            if got_Vrep:
                base_ring = ZZ
            else:   # integral inequalities usually do not determine a latice polytope!
                base_ring = QQ
            convert=False
        elif all(is_Rational(x) for x in values):
            base_ring = QQ
            convert=False
        elif all(is_RealDoubleElement(x) for x in values):
            base_ring = RDF
            convert=False
        else:
            try:
                map(ZZ, values)
                if got_Vrep:
                    base_ring = ZZ
                else:
                    base_ring = QQ
                convert = True
            except TypeError:
                from sage.structure.sequence import Sequence
                values = Sequence(values)
                if QQ.has_coerce_map_from(values.universe()):
                    base_ring = QQ
                    convert = True
                else:
                    base_ring = RDF
                    convert = True

    # Add the origin if necesarry
    if got_Vrep and len(vertices)==0:
        vertices = [ [0]*ambient_dim ]

    # Specific backends can override the base_ring
    from sage.geometry.polyhedron.parent import Polyhedra
    parent = Polyhedra(base_ring, ambient_dim, backend=backend)
    base_ring = parent.base_ring()

    # Convert into base_ring if necessary
    def convert_base_ring(lstlst):
        return [ [base_ring(x) for x in lst] for lst in lstlst]
    Hrep = Vrep = None
    if got_Hrep:
        Hrep = [ieqs, eqns]
    if got_Vrep:
        Vrep = [vertices, rays, lines]

    # finally, construct the Polyhedron
    return parent(Vrep, Hrep, convert=convert)
Example #15
0
    def to_cartesian(self, func, params=None):
        """
        Returns a 3-tuple of functions, parameterized over ``params``, that
        represents the cartesian coordinates of the value of ``func``.

        INPUT:

         - ``func`` - A function in this coordinate space. Corresponds to the
           independent variable.

         - ``params`` - The parameters of func. Corresponds to the dependent
           variables.

        EXAMPLE::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(x, y) = 2*x+y
            sage: T.to_cartesian(f, [x, y])
            (x + y, x - y, 2*x + y)
            sage: [h(1,2) for h in T.to_cartesian(lambda x,y: 2*x+y)]
            [3, -1, 4]
            
        We try to return a function having the same variable names as
        the function passed in::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: f(a, b) = 2*a+b
            sage: T.to_cartesian(f, [a, b])
            (a + b, a - b, 2*a + b)
            sage: t1,t2,t3=T.to_cartesian(lambda a,b: 2*a+b)
            sage: import inspect
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t2)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: inspect.getargspec(t3)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: def g(a,b): return 2*a+b
            sage: t1,t2,t3=T.to_cartesian(g)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
            sage: t1,t2,t3=T.to_cartesian(2*a+b)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)

        If we cannot guess the right parameter names, then the
        parameters are named `u` and `v`::

            sage: from sage.plot.plot3d.plot3d import _ArbitraryCoordinates
            sage: x, y, z = var('x y z')
            sage: T = _ArbitraryCoordinates((x + y, x - y, z), z,[x,y])
            sage: t1,t2,t3=T.to_cartesian(operator.add)
            sage: inspect.getargspec(t1)
            ArgSpec(args=['u', 'v'], varargs=None, keywords=None, defaults=None)
            sage: [h(1,2) for h in T.to_cartesian(operator.mul)]
            [3, -1, 2]
            sage: [h(u=1,v=2) for h in T.to_cartesian(operator.mul)]
            [3, -1, 2]

        """
        from sage.symbolic.expression import is_Expression
        from sage.rings.real_mpfr import is_RealNumber
        from sage.rings.integer import is_Integer
        if params is not None and (is_Expression(func) or is_RealNumber(func) or is_Integer(func)):
            return self.transform(**{
                self.dep_var: func,
                self.indep_vars[0]: params[0],
                self.indep_vars[1]: params[1]
            })
        else:
            # func might be a lambda or a Python callable; this makes it slightly
            # more complex.
            import sage.symbolic.ring
            dep_var_dummy = sage.symbolic.ring.var(self.dep_var)
            indep_var_dummies = sage.symbolic.ring.var(','.join(self.indep_vars))
            transformation = self.transform(**{
                self.dep_var: dep_var_dummy,
                self.indep_vars[0]: indep_var_dummies[0],
                self.indep_vars[1]: indep_var_dummies[1]
            })
            if params is None:
                if callable(func):
                    params = _find_arguments_for_callable(func)
                    if params is None:
                        params=['u','v']
                else:
                    raise ValueError, "function is not callable"
            def subs_func(t):
                # We use eval so that the lambda function has the same 
                # variable names as the original function
                ll="""lambda {x},{y}: t.subs({{
                    dep_var_dummy: func({x}, {y}),
                    indep_var_dummies[0]: {x},
                    indep_var_dummies[1]: {y}
                }})""".format(x=params[0], y=params[1])
                return eval(ll,dict(t=t, func=func, dep_var_dummy=dep_var_dummy, 
                                    indep_var_dummies=indep_var_dummies))
            return map(subs_func, transformation)