コード例 #1
0
ファイル: hyperbolic_arc.py プロジェクト: sajedel/testsage
 def _hyperbolic_arc(self, z0, z3, first=False):
     """
     Function to construct Bezier path as an approximation to
     the hyperbolic arc between the complex numbers z0 and z3 in the
     hyperbolic plane.
     """
     if (z0 - z3).real() == 0:
         self.path.append([(z0.real(), z0.imag()), (z3.real(), z3.imag())])
         return
     z0, z3 = (CC(z0), CC(z3))
     if z0.imag() == 0 and z3.imag() == 0:
         p = (z0.real() + z3.real()) / 2
         r = abs(z0 - p)
         zm = CC(p, r)
         self._hyperbolic_arc(z0, zm, first)
         self._hyperbolic_arc(zm, z3)
         return
     else:
         p = (abs(z0) * abs(z0) - abs(z3) * abs(z3)) / (z0 - z3).real() / 2
         r = abs(z0 - p)
         zm = ((z0 + z3) / 2 - p) / abs((z0 + z3) / 2 - p) * r + p
         t = (8 * zm - 4 * (z0 + z3)).imag() / 3 / (z3 - z0).real()
         z1 = z0 + t * CC(z0.imag(), (p - z0.real()))
         z2 = z3 - t * CC(z3.imag(), (p - z3.real()))
     if first:
         self.path.append([(z0.real(), z0.imag()), (z1.real(), z1.imag()),
                           (z2.real(), z2.imag()), (z3.real(), z3.imag())])
         first = False
     else:
         self.path.append([(z1.real(), z1.imag()), (z2.real(), z2.imag()),
                           (z3.real(), z3.imag())])
コード例 #2
0
def braid_in_segment(f, x0, x1):
    """
    Return the braid formed by the `y` roots of ``f`` when `x` moves
    from ``x0`` to ``x1``.

    INPUT:

    - ``f`` -- a polynomial in two variables
    - ``x0`` -- a complex number
    - ``x1`` -- a complex number

    OUTPUT:

    A braid.

    EXAMPLES::

        sage: from sage.schemes.curves.zariski_vankampen import braid_in_segment # optional - sirocco
        sage: R.<x,y> = QQ[]
        sage: f = x^2 + y^3
        sage: x0 = CC(1,0)
        sage: x1 = CC(1, 0.5)
        sage: braid_in_segment(f, x0, x1) # optional - sirocco
        s1
    """
    CC = ComplexField(64)
    (x, y) = f.variables()
    I = QQbar.gen()
    X0 = QQ(x0.real()) + I*QQ(x0.imag())
    X1 = QQ(x1.real()) + I*QQ(x1.imag())
    F0 = QQbar[y](f(X0, y))
    y0s = F0.roots(multiplicities=False)
    strands = [followstrand(f, x0, x1, CC(a)) for a in y0s]
    complexstrands = [[(a[0], CC(a[1], a[2])) for a in b] for b in strands]
    centralbraid = braid_from_piecewise(complexstrands)
    initialstrands = []
    y0aps = [c[0][1] for c in complexstrands]
    used = []
    for y0ap in y0aps:
        distances = [((y0ap - y0).norm(), y0) for y0 in y0s]
        y0 = sorted(distances)[0][1]
        if y0 in used:
            raise ValueError("different roots are too close")
        used.append(y0)
        initialstrands.append([(0, CC(y0)), (1, y0ap)])
    initialbraid = braid_from_piecewise(initialstrands)
    F1 = QQbar[y](f(X1,y))
    y1s = F1.roots(multiplicities=False)
    finalstrands = []
    y1aps = [c[-1][1] for c in complexstrands]
    used = []
    for y1ap in y1aps:
        distances = [((y1ap - y1).norm(), y1) for y1 in y1s]
        y1 = sorted(distances)[0][1]
        if y1 in used:
            raise ValueError("different roots are too close")
        used.append(y1)
        finalstrands.append([(0, y1ap), (1, CC(y1))])
    finallbraid = braid_from_piecewise(finalstrands)
    return initialbraid * centralbraid * finallbraid
コード例 #3
0
    def __init__(self, sides, i_angle, center, options):
        """
        Initialize HyperbolicRegularPolygon.

        EXAMPLES::

            sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
            sage: print(HyperbolicRegularPolygon(5,pi/2,I, {}))
            Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I)
        """
        self.center = CC(center)
        if self.center.imag() <= 0 :
            raise ValueError("center: %s is not a valid point in the upper half plane model of the hyperbolic plane"%(self.center))
        if sides < 3 :
            raise ValueError("degenerated polygons (sides<=2) are not supported")
        if i_angle <=0 or i_angle >= pi:
            raise ValueError("interior angle %s must be in (0, pi) interval"%(i_angle))
        if pi*(sides-2) - sides*i_angle <= 0 :
            raise ValueError("there exists no hyperbolic regular compact polygon, for sides=%s the interior angle must be less than %s"%(sides, pi * (sides-2) / sides))
        self.sides = sides
        self.i_angle = i_angle
        beta = 2 * pi / self.sides # compute the rotation angle to be used ahead
        alpha = self.i_angle / Integer(2)
        I = CC(0, 1)
        # compute using cosine theorem the radius of the circumscribed circle
        # using the triangle formed by the radius and the three known angles
        r = arccosh(cot(alpha) * (1 + cos(beta)) / sin(beta))

        # The first point will be always on the imaginary axis limited
        # to 8 digits for efficiency in the subsequent calculations.
        z_0 = [I*(e**r).n(digits=8)]

        # Compute the dilation isometry used to move the center
        # from I to the imaginary part of the given center.
        scale = self.center.imag()

        # Compute the parabolic isometry to move the center to the
        # real part of the given center.
        h_disp = self.center.real()

        d_z_k = [z_0[0]*scale + h_disp]  #d_k has the points for the polygon in the given center
        z_k = z_0                      #z_k has the Re(z)>0 vertices for the I centered polygon 
        r_z_k = []                     #r_z_k has the Re(z)<0 vertices
        if is_odd(self.sides):
            vert = (self.sides - 1) / 2
        else:
            vert = self.sides / 2 - 1
        for k in range(0, vert):
            # Compute with 8 digits to accelerate calculations
            new_z_k = self._i_rotation(z_k[-1], beta).n(digits=8)
            z_k = z_k + [new_z_k]
            d_z_k = d_z_k + [new_z_k * scale + h_disp]
            r_z_k=[-(new_z_k).conjugate() * scale + h_disp] + r_z_k
        if is_odd(self.sides):
            HyperbolicPolygon.__init__(self, d_z_k + r_z_k, options)
        else:
            z_opo = [I * (e**(-r)).n(digits=8) * scale + h_disp]
            HyperbolicPolygon.__init__(self, d_z_k + z_opo + r_z_k, options)
コード例 #4
0
ファイル: hyperbolic_arc.py プロジェクト: BrentBaccala/sage
 def __init__(self, A, B, options):
     A, B = (CC(A), CC(B))
     if A.imag() < 0:
         raise ValueError("%s is not a valid point in the UHP model" % (A))
     if B.imag() < 0:
         raise ValueError("%s is not a valid point in the UHP model" % (B))
     self.path = []
     self._hyperbolic_arc(A, B, True)
     BezierPath.__init__(self, self.path, options)
     self.A, self.B = (A, B)
コード例 #5
0
ファイル: zariski_vankampen.py プロジェクト: ye-man/sage
def segments(points):
    """
    Return the bounded segments of the Voronoi diagram of the given points.

    INPUT:

    - ``points`` -- a list of complex points

    OUTPUT:

    A list of pairs ``(p1, p2)``, where ``p1`` and ``p2`` are the
    endpoints of the segments in the Voronoi diagram.

    EXAMPLES::

        sage: from sage.schemes.curves.zariski_vankampen import discrim, segments # optional - sirocco
        sage: R.<x,y> = QQ[]
        sage: f = y^3 + x^3 - 1
        sage: disc = discrim(f) # optional - sirocco
        sage: segments(disc) # optional - sirocco # abs tol 1e-15
        [(-2.84740787203333 - 2.84740787203333*I,
        -2.14285714285714 + 1.11022302462516e-16*I),
        (-2.84740787203333 + 2.84740787203333*I,
        -2.14285714285714 + 1.11022302462516e-16*I),
        (2.50000000000000 + 2.50000000000000*I,
        1.26513881334184 + 2.19128470333546*I),
        (2.50000000000000 + 2.50000000000000*I,
        2.50000000000000 - 2.50000000000000*I),
        (1.26513881334184 + 2.19128470333546*I, 0.000000000000000),
        (0.000000000000000, 1.26513881334184 - 2.19128470333546*I),
        (2.50000000000000 - 2.50000000000000*I,
        1.26513881334184 - 2.19128470333546*I),
        (-2.84740787203333 + 2.84740787203333*I,
        1.26513881334184 + 2.19128470333546*I),
        (-2.14285714285714 + 1.11022302462516e-16*I, 0.000000000000000),
        (-2.84740787203333 - 2.84740787203333*I,
        1.26513881334184 - 2.19128470333546*I)]
    """
    from numpy import array, vstack
    from scipy.spatial import Voronoi
    discpoints = array([(CC(a).real(), CC(a).imag()) for a in points])
    added_points = 3 * abs(discpoints).max() + 1.0
    configuration = vstack([
        discpoints,
        array([[added_points, 0], [-added_points, 0], [0, added_points],
               [0, -added_points]])
    ])
    V = Voronoi(configuration)
    res = []
    for rv in V.ridge_vertices:
        if not -1 in rv:
            p1 = CC(list(V.vertices[rv[0]]))
            p2 = CC(list(V.vertices[rv[1]]))
            res.append((p1, p2))
    return res
コード例 #6
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES:

        First some lines::

            sage: PD = HyperbolicPlane().PD()
            sage: PD.get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
            sage: PD.get_geodesic(0, 0.3+0.8*I).show()
            Graphics object consisting of 2 graphics primitives

        Then some generic geodesics::

            sage: PD.get_geodesic(-0.5, 0.3+0.4*I).show()
            Graphics object consisting of 2 graphics primitives
            sage: PD.get_geodesic(-1, exp(3*I*pi/7)).show(linestyle="dashed", color="red")
            Graphics object consisting of 2 graphics primitives
            sage: PD.get_geodesic(exp(2*I*pi/11), exp(1*I*pi/11)).show(thickness=6, color="orange")
            Graphics object consisting of 2 graphics primitives
        """
        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        # Check to see if it's a line
        if abs(bd_1 + bd_2) < EPSILON:
            pic = line([end_1, end_2], **opts)
        else:
            # If we are here, we know it's not a line
            # So we compute the center and radius of the circle
            invdet = RR.one() / (real(bd_1) * imag(bd_2) -
                                 real(bd_2) * imag(bd_1))
            centerx = (imag(bd_2) - imag(bd_1)) * invdet
            centery = (real(bd_1) - real(bd_2)) * invdet
            center = centerx + I * centery
            radius = RR(abs(bd_1 - center))
            # Now we calculate the angles for the arc
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            theta1, theta2 = sorted([theta1, theta2])
            # Make sure the sector is inside the disk
            if theta2 - theta1 > pi:
                theta1 += 2 * pi
            pic = arc((centerx, centery),
                      radius,
                      sector=(theta1, theta2),
                      **opts)
        if boundary:
            pic += self._model.get_background_graphic()
        return pic
コード例 #7
0
def segments(points):
    """
    Return the bounded segments of the Voronoi diagram of the given points.
    
    INPUT: 
    
    - A list of complex points.
    
    OUTPUT: 
    
    A list of pairs (p1, p2) where p1 and p2 are the endpoints of the segments in the Voronoi diagram
    
    EXAMPLES::
    
        sage: R.<x,y> = QQ[]
        sage: f = y^3 + x^3 -1          
        sage: disc = discrim(f)
        sage: segments(disc)
        [(-2.84740787203333 - 2.84740787203333*I,
        -2.14285714285714 + 1.11022302462516e-16*I),
        (-2.84740787203333 + 2.84740787203333*I,
        -2.14285714285714 + 1.11022302462516e-16*I),
        (2.50000000000000 + 2.50000000000000*I,
        1.26513881334184 + 2.19128470333546*I),
        (2.50000000000000 + 2.50000000000000*I,
        2.50000000000000 - 2.50000000000000*I),
        (1.26513881334184 + 2.19128470333546*I, 0.000000000000000),
        (0.000000000000000, 1.26513881334184 - 2.19128470333546*I),
        (2.50000000000000 - 2.50000000000000*I,
        1.26513881334184 - 2.19128470333546*I),
        (-2.84740787203333 + 2.84740787203333*I,
        1.26513881334184 + 2.19128470333546*I),
        (-2.14285714285714 + 1.11022302462516e-16*I, 0.000000000000000),
        (-2.84740787203333 - 2.84740787203333*I,
        1.26513881334184 - 2.19128470333546*I)]

    """
    discpoints = array([(CC(a).real(), CC(a).imag()) for a in points])
    added_points = 3 * abs(discpoints).max() + 1.0
    configuration = vstack([
        discpoints,
        array([[added_points, 0], [-added_points, 0], [0, added_points],
               [0, -added_points]])
    ])
    V = Voronoi(configuration)
    res = []
    for rv in V.ridge_vertices:
        if not -1 in rv:
            p1 = CC(list(V.vertices[rv[0]]))
            p2 = CC(list(V.vertices[rv[1]]))
            res.append((p1, p2))
    return res
コード例 #8
0
    def point_in_model(self, p):
        r"""
        Check whether a complex number lies in the open upper half plane.

        EXAMPLES::

            sage: UHP = HyperbolicPlane().UHP()
            sage: UHP.point_in_model(1 + I)
            True
            sage: UHP.point_in_model(infinity)
            False
            sage: UHP.point_in_model(CC(infinity))
            False
            sage: UHP.point_in_model(RR(infinity))
            False
            sage: UHP.point_in_model(1)
            False
            sage: UHP.point_in_model(12)
            False
            sage: UHP.point_in_model(1 - I)
            False
            sage: UHP.point_in_model(-2*I)
            False
            sage: UHP.point_in_model(I)
            True
            sage: UHP.point_in_model(0) # Not interior point
            False
        """
        if isinstance(p, HyperbolicPoint):
            return p.is_boundary()
        return bool(imag(CC(p)) > 0)
コード例 #9
0
    def boundary_point_in_model(self, p):
        r"""
        Check whether a complex number is a real number or ``\infty``.
        In the ``UHP.model_name_name``, this is the ideal boundary of
        hyperbolic space.

        EXAMPLES::

            sage: UHP = HyperbolicPlane().UHP()
            sage: UHP.boundary_point_in_model(1 + I)
            False
            sage: UHP.boundary_point_in_model(infinity)
            True
            sage: UHP.boundary_point_in_model(CC(infinity))
            True
            sage: UHP.boundary_point_in_model(RR(infinity))
            True
            sage: UHP.boundary_point_in_model(1)
            True
            sage: UHP.boundary_point_in_model(12)
            True
            sage: UHP.boundary_point_in_model(1 - I)
            False
            sage: UHP.boundary_point_in_model(-2*I)
            False
            sage: UHP.boundary_point_in_model(0)
            True
            sage: UHP.boundary_point_in_model(I)
            False
        """
        if isinstance(p, HyperbolicPoint):
            return p.is_boundary()
        im = abs(imag(CC(p)).n())
        return (im < EPSILON) or bool(p == infinity)
コード例 #10
0
def get_classified_solution_dicts(output_file_contents,
                                  input_ring,
                                  get_failures=True):
    """
    Returns a dictionary of lists of dictionaries of variable:value (key:value)
    pairs.  Only used internally; see the classified_solution_dict function in
    the PHC_Object class definition for details.

    INPUT:

    - output_file_contents -- phc solution output as a string
    - input_ring -- a PolynomialRing that variable names can be coerced into

    OUTPUT:

    - a dictionary of lists if dictionaries of solutions, classifies by type

    EXAMPLES::

        sage: from sage.interfaces.phc import *
        sage: R2.<x1,x2> = PolynomialRing(QQ,2)
        sage: test_sys = [(x1-2)^5-x2, (x2-1)^5-1]
        sage: sol = phc.blackbox(test_sys, R2)          # optional -- phc
        sage: sol_classes = get_classified_solution_dicts(sol.output_file_contents,R2)  # optional -- phc
        sage: len(sol_classes['real'])            # optional -- phc
        1
    """
    output_list = output_file_contents.splitlines()
    test = 'False'
    solution_dicts = {}
    solution_types = ['complex', 'real', 'failure']
    for sol_type in solution_types:
        solution_dicts[sol_type] = []
    for solution_line in range(len(output_list) - 1, -1, -1):
        if output_list[solution_line].find('THE SOLUTIONS') == 0:
            break
    var_number = int(output_list[solution_line + 2].split(' ')[1])
    sol_number = int(output_list[solution_line + 2].split(' ')[0])
    for i in range(solution_line + 1, len(output_list)):
        if output_list[i].count('the solution for t') == 1:
            phc_type = output_list[i + var_number + 1].split(' = ')[-1]
            if phc_type.find('complex') != -1:
                phc_type = 'complex'
            elif phc_type.find('real') != -1:
                phc_type = 'real'
            else:
                phc_type = 'failure'
            temp_dict = {}
            for j in range(1, var_number + 1):
                rawsplit = output_list[i + j].split(': ')[1].split(' ')
                for extras in range(rawsplit.count('')):
                    rawsplit.remove('')
                temp_var = output_list[i + j].split(': ')[0].replace(' ', '')
                if phc_type == 'real':
                    temp_dict[input_ring(temp_var)] = RR(rawsplit[0])
                else:
                    temp_dict[input_ring(temp_var)] = CC(
                        rawsplit[0], rawsplit[1])
            solution_dicts[phc_type].append(temp_dict)
    return solution_dicts
コード例 #11
0
    def fft(self):
        """
        Wraps the gsl ``FastFourierTransform.forward()`` in
        :mod:`~sage.gsl.fft`.

        If the length is a power of 2 then this automatically uses the
        radix2 method. If the number of sample points in the input is
        a power of 2 then the wrapper for the GSL function
        ``gsl_fft_complex_radix2_forward()`` is automatically called.
        Otherwise, ``gsl_fft_complex_forward()`` is used.

        EXAMPLES::

            sage: J = range(5)
            sage: A = [RR(1) for i in J]
            sage: s = IndexedSequence(A,J)
            sage: t = s.fft(); t
            Indexed sequence: [5.00000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000]
                indexed by [0, 1, 2, 3, 4]
        """
        from sage.rings.all import CC
        I = CC.gen()

        # elements must be coercible into RR
        J = self.index_object()   ## must be = range(N)
        N = len(J)
        S = self.list()
        a = FastFourierTransform(N)
        for i in range(N):
            a[i] = S[i]
        a.forward_transform()
        return IndexedSequence([a[j][0]+I*a[j][1] for j in J],J)
コード例 #12
0
    def __init__(self, A, B, C, options):
        """
        Initialize HyperbolicTriangle:

        Examples::
        
            sage: from sage.plot.hyperbolic_triangle import HyperbolicTriangle
            sage: print HyperbolicTriangle(0, 1/2, I, {})
            Hyperbolic triangle (0.000000000000000, 0.500000000000000, 1.00000000000000*I)
        """
        A, B, C = (CC(A), CC(B), CC(C))
        self.path = []
        self._hyperbolic_arc(A, B, True)
        self._hyperbolic_arc(B, C)
        self._hyperbolic_arc(C, A)
        BezierPath.__init__(self, self.path, options)
        self.A, self.B, self.C = (A, B, C)
コード例 #13
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: UHP = HyperbolicPlane().UHP()
            sage: UHP.get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
            sage: UHP.get_geodesic(I, 3+4*I).show(linestyle="dashed", color="red")
            Graphics object consisting of 2 graphics primitives
        """
        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        if (abs(real(end_1) - real(end_2)) < EPSILON) \
                or CC(infinity) in [end_1, end_2]:  # on same vertical line
            # If one of the endpoints is infinity, we replace it with a
            # large finite  point
            if end_1 == CC(infinity):
                end_1 = (real(end_2), (imag(end_2) + 10))
                end_2 = (real(end_2), imag(end_2))
            elif end_2 == CC(infinity):
                end_2 = (real(end_1), (imag(end_1) + 10))
                end_1 = (real(end_1), imag(end_1))
            pic = line((end_1, end_2), **opts)
            if boundary:
                cent = min(bd_1, bd_2)
                bd_dict = {'bd_min': cent - 3, 'bd_max': cent + 3}
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
                return pic
        else:
            center = (bd_1 + bd_2) / 2  # Circle center
            radius = abs(bd_1 - bd_2) / 2
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            if abs(theta1 - theta2) < EPSILON:
                theta2 += pi
            pic = arc((real(center), imag(center)),
                      radius,
                      sector=(theta1, theta2),
                      **opts)
            if boundary:
                # We want to draw a segment of the real line.  The
                # computations below compute the projection of the
                # geodesic to the real line, and then draw a little
                # to the left and right of the projection.
                shadow_1, shadow_2 = [real(k) for k in [end_1, end_2]]
                midpoint = (shadow_1 + shadow_2) / 2
                length = abs(shadow_1 - shadow_2)
                bd_dict = {
                    'bd_min': midpoint - length,
                    'bd_max': midpoint + length
                }
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
            return pic
コード例 #14
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: airy_ai_prime(0.0)
            -0.258819403792807

        We can use several methods for numerical evaluation::

            sage: airy_ai_prime(4).n(algorithm='mpmath')
            -0.00195864095020418
            sage: airy_ai_prime(4).n(algorithm='mpmath', prec=100)
            -0.0019586409502041789001381409184
            sage: airy_ai_prime(4).n(algorithm='scipy')    # rel tol 1e-10
            -0.00195864095020418
            sage: airy_ai_prime(I).n(algorithm='scipy')    # rel tol 1e-10
            -0.43249265984180707 + 0.09804785622924324*I

        TESTS::

            sage: parent(airy_ai_prime(3).n(algorithm='scipy'))
            Real Field with 53 bits of precision
            sage: airy_ai_prime(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_ai_prime not implemented
             for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent', None)
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError(
                    "%s not implemented for precision > 53" % self.name())
            from sage.rings.all import RR, CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[1]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[1]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airyai,
                                     x,
                                     derivative=1,
                                     parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
コード例 #15
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: airy_bi_prime(0.0)
            0.448288357353826

        We can use several methods for numerical evaluation::

            sage: airy_bi_prime(4).n(algorithm='mpmath')
            161.926683504613
            sage: airy_bi_prime(4).n(algorithm='mpmath', prec=100)
            161.92668350461340184309492429
            sage: airy_bi_prime(4).n(algorithm='scipy')  # rel tol 1e-10
            161.92668350461398
            sage: airy_bi_prime(I).n(algorithm='scipy')  # rel tol 1e-10
            0.135026646710819 - 0.1288373867812549*I

        TESTS::

            sage: parent(airy_bi_prime(3).n(algorithm='scipy'))
            Real Field with 53 bits of precision
            sage: airy_bi_prime(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_bi_prime not implemented
             for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent', None)
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError(
                    "%s not implemented for precision > 53" % self.name())
            from sage.rings.all import RR, CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[3]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[3]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airybi,
                                     x,
                                     derivative=1,
                                     parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
コード例 #16
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: from sage.functions.airy import airy_ai_simple
            sage: airy_ai_simple(0.0)
            0.355028053887817
            sage: airy_ai_simple(1.0 * I)
            0.331493305432141 - 0.317449858968444*I

        We can use several methods for numerical evaluation::

            sage: airy_ai_simple(3).n(algorithm='mpmath')
            0.00659113935746072
            sage: airy_ai_simple(3).n(algorithm='mpmath', prec=100)
            0.0065911393574607191442574484080
            sage: airy_ai_simple(3).n(algorithm='scipy')  # rel tol 1e-10
            0.006591139357460719
            sage: airy_ai_simple(I).n(algorithm='scipy')  # rel tol 1e-10
            0.33149330543214117 - 0.3174498589684438*I
            
        TESTS::

            sage: parent(airy_ai_simple(3).n(algorithm='scipy'))                                          
            Real Field with 53 bits of precision
            sage: airy_ai_simple(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_ai not implemented for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent')
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError(
                    "%s not implemented for precision > 53" % self.name())
            from sage.rings.all import RR, CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[0]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[0]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airyai, x, parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
コード例 #17
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: from sage.functions.airy import airy_bi_simple
            sage: airy_bi_simple(0.0)
            0.614926627446001
            sage: airy_bi_simple(1.0 * I)
            0.648858208330395 + 0.344958634768048*I

        We can use several methods for numerical evaluation::

            sage: airy_bi_simple(3).n(algorithm='mpmath')
            14.0373289637302
            sage: airy_bi_simple(3).n(algorithm='mpmath', prec=100)
            14.037328963730232031740267314
            sage: airy_bi_simple(3).n(algorithm='scipy')  # rel tol 1e-10
            14.037328963730136
            sage: airy_bi_simple(I).n(algorithm='scipy')  # rel tol 1e-10
            0.648858208330395 + 0.34495863476804844*I
            
        TESTS::

            sage: parent(airy_bi_simple(3).n(algorithm='scipy'))                                          
            Real Field with 53 bits of precision
            sage: airy_bi_simple(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_bi not implemented for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent', None)
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError(
                    "%s not implemented for precision > 53" % self.name())
            from sage.rings.all import RR, CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[2]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[2]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airybi, x, parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
コード例 #18
0
    def _element_constructor_(self, x):
        r"""
        Return the element of the algebra ``self`` corresponding to ``x``.

        EXAMPLES::

            sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
            sage: B = SiegelModularFormsAlgebra(coeff_ring=ZZ).1
            sage: S(B)
            Igusa_6
            sage: S(1/5)
            1/5
            sage: S(1/5).parent() is S
            True
            sage: S._element_constructor_(2.67)
            Traceback (most recent call last):
            ...
            TypeError: Unable to construct an element of Algebra of Siegel modular forms of degree 2 and even weights on Sp(4,Z) over Rational Field corresponding to 2.67000000000000
            sage: S.base_extend(RR)._element_constructor_(2.67)
            2.67000000000000
        """
        if isinstance(x, six.integer_types):
            x = ZZ(x)
        if isinstance(x, float):
            from sage.rings.all import RR
            x = RR(x)
        if isinstance(x, complex):
            from sage.rings.all import CC
            x = CC(x)

        if isinstance(x.parent(), SiegelModularFormsAlgebra_class):
            d = dict((f, self.coeff_ring()(x[f])) for f in x.coeffs())
            return self.element_class(parent=self,
                                      weight=x.weight(),
                                      coeffs=d,
                                      prec=x.prec(),
                                      name=x.name())

        R = self.base_ring()
        if R.has_coerce_map_from(x.parent()):
            d = {(0, 0, 0): R(x)}
            from sage.rings.all import infinity
            return self.element_class(parent=self,
                                      weight=0,
                                      coeffs=d,
                                      prec=infinity,
                                      name=str(x))
        else:
            raise TypeError(
                "Unable to construct an element of {0} corresponding to {1}".
                format(self, x))
コード例 #19
0
def get_solution_dicts(output_file_contents, input_ring, get_failures=True):
    """
    Returns a list of dictionaries of variable:value (key:value)
    pairs.  Only used internally; see the solution_dict function in
    the PHC_Object class definition for details.

    INPUT:

    - output_file_contents -- phc solution output as a string
    - input_ring -- a PolynomialRing that variable names can be coerced into

    OUTPUT:

    a list of dictionaries of solutions

    EXAMPLES::

        sage: from sage.interfaces.phc import *
        sage: R2.<x1,x2> = PolynomialRing(QQ,2)
        sage: test_sys = [(x1-1)^5-x2, (x2-1)^5-1]
        sage: sol = phc.blackbox(test_sys, R2)             # optional -- phc
        sage: test = get_solution_dicts(sol.output_file_contents,R2)  # optional -- phc
        sage: str(sum([q[x1].real() for q in test]))[0:4]  # optional -- phc
        '25.0'
    """
    output_list = output_file_contents.splitlines()
    test = 'False'
    solution_dicts = []
    for solution_line in range(len(output_list) - 1, -1, -1):
        if output_list[solution_line].find('THE SOLUTIONS') == 0:
            break
    try:
        var_number = int(output_list[solution_line + 2].split(' ')[1])
        sol_number = int(output_list[solution_line + 2].split(' ')[0])
    except IndexError:
        var_number = int(output_list[solution_line + 1].split(' ')[1])
        sol_number = int(output_list[solution_line + 1].split(' ')[0])
    for i in range(solution_line + 1, len(output_list)):
        if output_list[i].count('the solution for t') == 1:
            if output_list[i - 3].count('success') > 0 or get_failures == True:
                temp_dict = {}
                for j in range(1, var_number + 1):
                    rawsplit = output_list[i + j].split(': ')[1].split(' ')
                    for extras in range(rawsplit.count('')):
                        rawsplit.remove('')
                    temp_var = output_list[i + j].split(': ')[0].replace(
                        ' ', '')
                    temp_dict[input_ring(temp_var)] = CC(
                        rawsplit[0], rawsplit[1])
                solution_dicts.append(temp_dict)
    return solution_dicts
コード例 #20
0
    def boundary_point_in_model(self, p):
        r"""
        Check whether a complex number lies in the open unit disk.

        EXAMPLES::

            sage: PD = HyperbolicPlane().PD()
            sage: PD.boundary_point_in_model(1.00)
            True
            sage: PD.boundary_point_in_model(1/2 + I/2)
            False
            sage: PD.boundary_point_in_model(1 + .2*I)
            False
        """
        if isinstance(p, HyperbolicPoint):
            return p.is_boundary()
        return bool(abs(abs(CC(p)) - 1) < EPSILON)
コード例 #21
0
    def __init__(self, pts, options):
        """
        Initialize HyperbolicPolygon.

        EXAMPLES::

            sage: from sage.plot.hyperbolic_polygon import HyperbolicPolygon
            sage: print HyperbolicPolygon([0, 1/2, I], {})
            Hyperbolic polygon (0.000000000000000, 0.500000000000000, 1.00000000000000*I)
        """
        pts = [CC(_) for _ in pts]
        self.path = []
        self._hyperbolic_arc(pts[0], pts[1], True)
        for i in range(1, len(pts) - 1):
            self._hyperbolic_arc(pts[i], pts[i + 1])
        self._hyperbolic_arc(pts[-1], pts[0])
        BezierPath.__init__(self, self.path, options)
        self._pts = pts
コード例 #22
0
ファイル: hyperbolic_point.py プロジェクト: ozzie00/sage
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().PD().get_point(0).show()
            Graphics object consisting of 2 graphics primitives
            sage: HyperbolicPlane().KM().get_point((0,0)).show()
            Graphics object consisting of 2 graphics primitives
            sage: HyperbolicPlane().HM().get_point((0,0,1)).show()
            Graphics3d Object
        """
        p = self.coordinates()
        if p == infinity:
            raise NotImplementedError("can't draw the point infinity")

        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        opts.update(options)

        from sage.plot.point import point
        from sage.misc.functional import numerical_approx

        if self._bdry:  # It is a boundary point
            p = numerical_approx(p)
            pic = point((p, 0), **opts)
            if boundary:
                bd_pic = self._model.get_background_graphic(bd_min=p - 1,
                                                            bd_max=p + 1)
                pic = bd_pic + pic
        else:  # It is an interior point
            if p in RR:
                p = CC(p)
            elif hasattr(p, 'iteritems') or hasattr(p, '__iter__'):
                p = [numerical_approx(k) for k in p]
            else:
                p = numerical_approx(p)
            pic = point(p, **opts)
            if boundary:
                bd_pic = self.parent().get_background_graphic()
                pic = bd_pic + pic
        return pic
コード例 #23
0
    def _evalf_(self, n, x, **kwds):
        """
        Evaluate :class:`chebyshev_U` numerically with mpmath.

        EXAMPLES::

            sage: chebyshev_U(5,-4+3.*I)
            98280.0000000000 - 11310.0000000000*I
            sage: chebyshev_U(10,3).n(75)
            4.661117900000000000000e7
            sage: chebyshev_U._evalf_(1.5, Mod(8,9))
            Traceback (most recent call last):
            ...
            TypeError: cannot evaluate chebyshev_U with parent Ring of integers modulo 9
        """
        try:
            real_parent = kwds['parent']
        except KeyError:
            real_parent = parent(x)

            if not is_RealField(real_parent) and not is_ComplexField(
                    real_parent):
                # parent is not a real or complex field: figure out a good parent
                if x in RR:
                    x = RR(x)
                    real_parent = RR
                elif x in CC:
                    x = CC(x)
                    real_parent = CC

        if not is_RealField(real_parent) and not is_ComplexField(real_parent):
            raise TypeError(
                "cannot evaluate chebyshev_U with parent {}".format(
                    real_parent))

        from sage.libs.mpmath.all import call as mpcall
        from sage.libs.mpmath.all import chebyu as mpchebyu

        return mpcall(mpchebyu, n, x, parent=real_parent)
コード例 #24
0
def perron_right_eigenvector(M):
    r"""
    EXAMPLES::

        sage: from slabbe.matrix_cocycle import perron_right_eigenvector
        sage: m = matrix(2,[-11,14,-26,29])
        sage: perron_right_eigenvector(m)           # tolerance 0.00001
        (15.0000000000000, (0.35, 0.6499999999999999))
    """
    from sage.modules.free_module_element import vector
    from sage.rings.real_mpfr import RR
    from sage.rings.all import CC
    import numpy
    eig, vec = numpy.linalg.eig(M)
    index = abs(eig).argmax()
    rightv = vec.transpose()[index]
    if eig[index].imag == 0:
        eig_sage = RR(eig[index].real)
        vec_sage = vector(a.real for a in rightv)
    else:
        eig_sage = CC(eig[index])
        vec_sage = vector(CC, rightv)
    return eig_sage, vec_sage/sum(vec_sage)
コード例 #25
0
ファイル: assumptions.py プロジェクト: epettigrew/sage
    def contradicts(self, soln):
        """
        Return ``True`` if this assumption is violated by the given
        variable assignment(s).

        INPUT:

        - ``soln`` -- Either a dictionary with variables as keys or a symbolic
          relation with a variable on the left hand side.

        EXAMPLES::

            sage: from sage.symbolic.assumptions import GenericDeclaration
            sage: GenericDeclaration(x, 'integer').contradicts(x==4)
            False
            sage: GenericDeclaration(x, 'integer').contradicts(x==4.0)
            False
            sage: GenericDeclaration(x, 'integer').contradicts(x==4.5)
            True
            sage: GenericDeclaration(x, 'integer').contradicts(x==sqrt(17))
            True
            sage: GenericDeclaration(x, 'noninteger').contradicts(x==sqrt(17))
            False
            sage: GenericDeclaration(x, 'noninteger').contradicts(x==17)
            True
            sage: GenericDeclaration(x, 'even').contradicts(x==3)
            True
            sage: GenericDeclaration(x, 'complex').contradicts(x==3)
            False
            sage: GenericDeclaration(x, 'imaginary').contradicts(x==3)
            True
            sage: GenericDeclaration(x, 'imaginary').contradicts(x==I)
            False

            sage: var('y,z')
            (y, z)
            sage: GenericDeclaration(x, 'imaginary').contradicts(x==y+z)
            False

            sage: GenericDeclaration(x, 'rational').contradicts(y==pi)
            False
            sage: GenericDeclaration(x, 'rational').contradicts(x==pi)
            True
            sage: GenericDeclaration(x, 'irrational').contradicts(x!=pi)
            False
            sage: GenericDeclaration(x, 'rational').contradicts({x: pi, y: pi})
            True
            sage: GenericDeclaration(x, 'rational').contradicts({z: pi, y: pi})
            False
       """
        if isinstance(soln, dict):
            value = soln.get(self._var)
            if value is None:
                return False
        elif soln.lhs() == self._var:
            value = soln.rhs()
        else:
            return False
        try:
            CC(value)
        except TypeError:
            return False
        if self._assumption == 'integer':
            return value not in ZZ
        elif self._assumption == 'noninteger':
            return value in ZZ
        elif self._assumption == 'even':
            return value not in ZZ or ZZ(value) % 2 != 0
        elif self._assumption == 'odd':
            return value not in ZZ or ZZ(value) % 2 != 1
        elif self._assumption == 'rational':
            return value not in QQ
        elif self._assumption == 'irrational':
            return value in QQ
        elif self._assumption == 'real':
            return value not in RR
        elif self._assumption == 'imaginary':
            return value not in CC or CC(value).real() != 0
        elif self._assumption == 'complex':
            return value not in CC
コード例 #26
0
ファイル: hyperbolic_arc.py プロジェクト: sajedel/testsage
 def __init__(self, A, B, options):
     A, B = (CC(A), CC(B))
     self.path = []
     self._hyperbolic_arc(A, B, True)
     BezierPath.__init__(self, self.path, options)
     self.A, self.B = (A, B)
コード例 #27
0
    def _parse_path_file(self, input_filename, verbose=False):
        """
        Takes a phpack output file containing path tracking information
        and parses it into a list of lists of dictionaries - i.e. a
        list of solutions paths, where each solution path is a list of
        dictionaries of variable and homotopy parameter values.

        INPUT:
            input_filename -- file must have path-tracking information

        OUTPUT:
            a list of lists of dictionaries, described above

        EXAMPLES::

            sage: from sage.interfaces.phc import *
            sage: R2.<x,y> = PolynomialRing(QQ,2)
            sage: start_sys = [x^5-y^2,y^5-1]
            sage: sol = phc.blackbox(start_sys, R2)    # optional -- phc
            sage: start_save = sol.save_as_start()     # optional -- phc
            sage: end_sys = [x^5-2,y^5-x^2]            # optional -- phc
            sage: path_track_filename = phc._path_track_file(start_save, end_sys, R2, c_skew = .001)  # optional -- phc
            sage: sol_paths = phc._parse_path_file(path_track_filename)   # optional -- phc
            sage: len(sol_paths)  # optional -- phc
            25
        """

        if not os.path.exists(input_filename):
            raise RuntimeError("The file containing output from phc (" +
                               input_filename + ") cannot be found")

        fh = open(input_filename)
        line_idx = 0
        begin = 0
        count = 0
        solutions_dicts = []
        steps_dicts = []

        # regular expressions for matching certain output types
        var_cnt_regex = re.compile('^ +([0-9]+)')
        output_regex = re.compile('^OUTPUT INFORMATION DURING')
        t_regex = re.compile(
            '(^t +: +(-{0,1}[0-9]+\.[0-9]+E[-+][0-9]+) +(-{0,1}[0-9]+\.[0-9]+E[-+][0-9]+)$)',
            re.IGNORECASE)
        sols_regex = re.compile(
            '(^ *(([a-z]|[0-9])+) +: +(-?[0-9]+\.[0-9]+E[-+][0-9]+) +(-?[0-9]+\.[0-9]+E[-+][0-9]+)$)',
            re.IGNORECASE)
        complete_regex = re.compile('^TIMING INFORMATION')

        breakfast = False
        a_line = fh.readline()
        end_test = ''
        while a_line:
            # processing....
            a_line = a_line.replace("\n", '')
            if line_idx == 0:
                m = var_cnt_regex.match(a_line)
                if m:
                    count = Integer(m.group(1))
            if count > 0:
                m = output_regex.match(a_line)
                if m:
                    begin = 1
                if begin:
                    m = t_regex.match(a_line)
                    if m:
                        # put the t-values into a dict
                        # m.group(2) contains the real val
                        # m.group(3) contains the imaginary val
                        # fh_w.write( "T=> G1(" + m.group(2) + '),G2(' + m.group(3) + ")\n")
                        # read off two lines - this should be 'm' and 'the solution for t :'
                        a_line = fh.readline()
                        end_test = a_line  # store this to check for end of solution
                        a_line = fh.readline()
                        t_val = CC(m.group(2), m.group(3))
                        temp_dict = {}
                        temp_dict["t"] = t_val
                        for i in range(0, count):
                            a_line = fh.readline()
                            m = sols_regex.match(a_line)
                            if m:
                                # m.group(2) contains our var name
                                # m.group(4) contains our real val
                                # m.group(5) contains our imaginary val
                                temp_dict[m.group(2)] = CC(
                                    m.group(4), m.group(5))
                        steps_dicts.append(temp_dict)
                    # check if its the end of a solution
                    if end_test.find('Length of path') != -1:
                        if verbose: print "recording sol"
                        if steps_dicts != []:
                            solutions_dicts.append(steps_dicts)
                        steps_dicts = []
                    m = complete_regex.match(a_line)
                    if m:
                        breakfast = True
            if breakfast:
                break
            line_idx += 1
            a_line = fh.readline()
        fh.close()
        return solutions_dicts
コード例 #28
0
def followstrand(f, x0, x1, y0a, prec=53):
    r"""
    Return a piecewise linear aproximation of the homotopy continuation
    of the root ``y0a`` from ``x0`` to ``x1``.

    INPUT:

    - ``f`` -- a polynomial in two variables
    - ``x0`` -- a complex value, where the homotopy starts
    - ``x1`` -- a complex value, where the homotopy ends
    - ``y0a`` -- an approximate solution of the polynomial `F(y) = f(x_0, y)`
    - ``prec`` -- the precision to use

    OUTPUT:

    A list of values `(t, y_{tr}, y_{ti})` such that:

    - ``t`` is a real number between zero and one
    - `f(t \cdot x_1 + (1-t) \cdot x_0, y_{tr} + I \cdot y_{ti})`
      is zero (or a good enough aproximation)
    - the piecewise linear path determined by the points has a tubular
      neighborhood  where the actual homotopy continuation path lies, and
      no other root intersects it.

    EXAMPLES::

        sage: from sage.schemes.curves.zariski_vankampen import followstrand # optional - sirocco
        sage: R.<x,y> = QQ[]
        sage: f = x^2 + y^3
        sage: x0 = CC(1, 0)
        sage: x1 = CC(1, 0.5)
        sage: followstrand(f, x0, x1, -1.0) # optional - sirocco # abs tol 1e-15
        [(0.0, -1.0, 0.0),
         (0.7500000000000001, -1.015090921153253, -0.24752813818386948),
         (1.0, -1.026166099551513, -0.32768940253604323)]
    """
    CIF = ComplexIntervalField(prec)
    CC = ComplexField(prec)
    G = f.change_ring(QQbar).change_ring(CIF)
    (x, y) = G.variables()
    g = G.subs({x: (1-x)*CIF(x0) + x*CIF(x1)})
    coefs = []
    deg = g.total_degree()
    for d in range(deg + 1):
        for i in range(d + 1):
            c = CIF(g.coefficient({x: d-i, y: i}))
            cr = c.real()
            ci = c.imag()
            coefs += list(cr.endpoints())
            coefs += list(ci.endpoints())
    yr = CC(y0a).real()
    yi = CC(y0a).imag()
    from sage.libs.sirocco import contpath, contpath_mp
    try:
        if prec == 53:
            points = contpath(deg, coefs, yr, yi)
        else:
            points = contpath_mp(deg, coefs, yr, yi, prec)
        return points
    except Exception:
        return followstrand(f, x0, x1, y0a, 2*prec)
コード例 #29
0
ファイル: endPN_minimal_model.py プロジェクト: sagemath/sage
def smallest_dynamical(f, dynatomic=True, start_n=1, prec=53, emb=None, algorithm='HS', check_minimal=True):
    r"""
    Determine the poly with smallest coefficients in `SL(2,\ZZ)` orbit of ``F``

    Smallest is in the sense of global height.
    The method is the algorithm in Hutz-Stoll [HS2018]_.
    A binary form defining the periodic points is associated to ``f``.
    From this polynomial a bound on the search space can be determined.

    ``f`` should already be a minimal model or finding the orbit
    representatives may give wrong results.

    INPUT:

    - ``f`` -- a dynamical system on `P^1`

    - ``dyantomic`` -- boolean. whether ``F`` is the periodic points or the
      formal periodic points of period ``m`` for ``f``

    - ``start_n`` - positive integer. the period used to start trying to
      create associate binary form ``F``

    - ``prec``-- positive integer. precision to use in CC

    - ``emb`` -- embedding into CC

    - ``algorithm`` -- (optional) string; either ``'BM'`` for the Bruin-Molnar
      algorithm or ``'HS'`` for the Hutz-Stoll algorithm. If not specified,
      properties of the map are utilized to choose how to compute minimal
      orbit representatives

    - ``check_minimal`` -- (default: True), boolean, whether to check
      if this map is a minimal model

    OUTPUT: pair [dynamical system, matrix]

    EXAMPLES::

        sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import smallest_dynamical
        sage: P.<x,y> = ProjectiveSpace(QQ,1)
        sage: f = DynamicalSystem([50*x^2 + 795*x*y + 2120*y^2, 265*x^2 + 106*y^2])
        sage: smallest_dynamical(f)  #long time
        [
        Dynamical System of Projective Space of dimension 1 over Rational Field
          Defn: Defined on coordinates by sending (x : y) to
                (-480*x^2 - 1125*x*y + 1578*y^2 : 265*x^2 + 1060*x*y + 1166*y^2),
        <BLANKLINE>
        [1 2]
        [0 1]
        ]
    """
    def insert_item(pts, item, index):
        # binary insertion to maintain list of points left to consider
        N = len(pts)
        if N == 0:
          return [item]
        elif N == 1:
            if item[index] > pts[0][index]:
                pts.insert(0,item)
            else:
                pts.append(item)
            return pts
        else: # binary insertion
            left = 1
            right = N
            mid = (left + right) // 2  # these are ints so this is .floor()
            if item[index] > pts[mid][index]: # item goes into first half
                return insert_item(pts[:mid], item, index) + pts[mid:N]
            else: # item goes into second half
                return pts[:mid] + insert_item(pts[mid:N], item, index)

    def coshdelta(z):
        # The cosh of the hyperbolic distance from z = t+uj to j
        return (z.norm() + 1)/(2*z.imag())

    # can't be smaller if height 0
    f.normalize_coordinates()
    if f.global_height(prec=prec) == 0:
        return [f, matrix(ZZ,2,2,[1,0,0,1])]
    all_min = f.all_minimal_models(return_transformation=True, algorithm=algorithm, check_minimal=check_minimal)

    current_min = None
    current_size = None
    # search for minimum over all orbits
    for g,M in all_min:
        PS = g.domain()
        CR = PS.coordinate_ring()
        x,y = CR.gens()
        n = start_n # sometimes you get a problem later with 0,infty as roots
        if dynatomic:
            pts_poly = g.dynatomic_polynomial(n)
        else:
            gn = g.nth_iterate_map(n)
            pts_poly = y*gn[0] - x*gn[1]
        d = ZZ(pts_poly.degree())
        max_mult = max([ex for p,ex in pts_poly.factor()])
        while ((d < 3) or (max_mult >= d/2) and (n < 5)):
            n = n+1
            if dynatomic:
                pts_poly = g.dynatomic_polynomial(n)
            else:
                gn = g.nth_iterate_map(n)
                pts_poly = y*gn[0] - x*gn[1]
            d = ZZ(pts_poly.degree())
            max_mult = max([ex for p,ex in pts_poly.factor()])
        assert(n<=4), "n > 4, failed to find usable poly"

        R = get_bound_dynamical(pts_poly, g, m=n, dynatomic=dynatomic, prec=prec, emb=emb)
        # search starts in fundamental domain
        G,MG = pts_poly.reduced_form(prec=prec, emb=emb, smallest_coeffs=False)
        red_g = f.conjugate(M*MG)
        if G != pts_poly:
            R2 = get_bound_dynamical(G, red_g, m=n, dynatomic=dynatomic, prec=prec, emb=emb)
            if R2 < R:
                # use the better bound
                R = R2
        red_g.normalize_coordinates()
        if red_g.global_height(prec=prec) == 0:
            return [red_g, M*MG]

        # height
        if current_size is None:
            current_size = e**red_g.global_height(prec=prec)
        v0, th = covariant_z0(G, prec=prec, emb=emb)
        rep = 2*CC.gen(0)
        from math import isnan
        if isnan(v0.abs()):
            raise ValueError("invalid covariant: %s"%v0)

        # get orbit
        S = matrix(ZZ,2,2,[0,-1,1,0])
        T = matrix(ZZ,2,2,[1,1,0,1])
        TI = matrix(ZZ,2,2,[1,-1,0,1])

        count = 0
        pts = [[G, red_g, v0, rep, M*MG, coshdelta(v0), 0]]  # label - 0:None, 1:S, 2:T, 3:T^(-1)
        if current_min is None:
            current_min = [G, red_g, v0, rep, M*MG, coshdelta(v0)]
        while pts != []:
            G, g, v, rep, M, D, label = pts.pop()
            # apply ST and keep z, Sz
            if D > R:
                break #all remaining pts are too far away
            # check if it is smaller. If so, we can improve the bound
            count += 1
            new_size = e**g.global_height(prec=prec)
            if new_size < current_size:
                current_min = [G ,g, v, rep, M, coshdelta(v)]
                current_size = new_size
                if new_size == 1: # early exit
                    return [current_min[1], current_min[4]]
                new_R = get_bound_dynamical(G, g, m=n, dynatomic=dynatomic, prec=prec, emb=emb)
                if new_R < R:
                    R = new_R

            # add new points to check
            if label != 1 and min((rep+1).norm(), (rep-1).norm()) >= 1: # don't undo S
                # the 2nd condition is equivalent to |\Re(-1/rep)| <= 1/2
                # this means that rep can have resulted from an inversion step in
                # the shift-and-invert procedure, so don't invert

                # do inversion
                z = -1/v
                new_pt = [G.subs({x:-y, y:x}), g.conjugate(S), z, -1/rep, M*S, coshdelta(z), 1]
                pts = insert_item(pts, new_pt, 5)
            if label != 3:  # don't undo T on g
                # do right shift
                z = v-1
                new_pt = [G.subs({x:x+y}), g.conjugate(TI), z, rep-1, M*TI, coshdelta(z), 2]
                pts = insert_item(pts, new_pt, 5)
            if label != 2:  # don't undo TI on g
                # do left shift
                z = v+1
                new_pt = [G.subs({x:x-y}), g.conjugate(T), z, rep+1, M*T, coshdelta(z), 3]
                pts = insert_item(pts, new_pt, 5)

    return [current_min[1], current_min[4]]
コード例 #30
0
def smallest_dynamical(f,
                       dynatomic=True,
                       start_n=1,
                       prec=53,
                       emb=None,
                       algorithm='HS',
                       check_minimal=True):
    r"""
    Determine the poly with smallest coefficients in `SL(2,\ZZ)` orbit of ``F``

    Smallest is in the sense of global height.
    The method is the algorithm in Hutz-Stoll [HS2018]_.
    A binary form defining the periodic points is associated to ``f``.
    From this polynomial a bound on the search space can be determined.

    ``f`` should already be a minimal model or finding the orbit
    representatives may give wrong results.

    INPUT:

    - ``f`` -- a dynamical system on `P^1`

    - ``dynatomic`` -- boolean. whether ``F`` is the periodic points or the
      formal periodic points of period ``m`` for ``f``

    - ``start_n`` - positive integer. the period used to start trying to
      create associate binary form ``F``

    - ``prec``-- positive integer. precision to use in CC

    - ``emb`` -- embedding into CC

    - ``algorithm`` -- (optional) string; either ``'BM'`` for the Bruin-Molnar
      algorithm or ``'HS'`` for the Hutz-Stoll algorithm. If not specified,
      properties of the map are utilized to choose how to compute minimal
      orbit representatives

    - ``check_minimal`` -- (default: True), boolean, whether to check
      if this map is a minimal model

    OUTPUT: pair [dynamical system, matrix]

    EXAMPLES::

        sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import smallest_dynamical
        sage: P.<x,y> = ProjectiveSpace(QQ,1)
        sage: f = DynamicalSystem([50*x^2 + 795*x*y + 2120*y^2, 265*x^2 + 106*y^2])
        sage: smallest_dynamical(f)  #long time
        [
        Dynamical System of Projective Space of dimension 1 over Rational Field
          Defn: Defined on coordinates by sending (x : y) to
                (-480*x^2 - 1125*x*y + 1578*y^2 : 265*x^2 + 1060*x*y + 1166*y^2),
        <BLANKLINE>
        [1 2]
        [0 1]
        ]
    """
    def insert_item(pts, item, index):
        # binary insertion to maintain list of points left to consider
        N = len(pts)
        if N == 0:
            return [item]
        elif N == 1:
            if item[index] > pts[0][index]:
                pts.insert(0, item)
            else:
                pts.append(item)
            return pts
        else:  # binary insertion
            left = 1
            right = N
            mid = (left + right) // 2  # these are ints so this is .floor()
            if item[index] > pts[mid][index]:  # item goes into first half
                return insert_item(pts[:mid], item, index) + pts[mid:N]
            else:  # item goes into second half
                return pts[:mid] + insert_item(pts[mid:N], item, index)

    def coshdelta(z):
        # The cosh of the hyperbolic distance from z = t+uj to j
        return (z.norm() + 1) / (2 * z.imag())

    # can't be smaller if height 0
    f.normalize_coordinates()
    if f.global_height(prec=prec) == 0:
        return [f, matrix(ZZ, 2, 2, [1, 0, 0, 1])]
    all_min = f.all_minimal_models(return_transformation=True,
                                   algorithm=algorithm,
                                   check_minimal=check_minimal)

    current_min = None
    current_size = None
    # search for minimum over all orbits
    for g, M in all_min:
        PS = g.domain()
        CR = PS.coordinate_ring()
        x, y = CR.gens()
        n = start_n  # sometimes you get a problem later with 0,infty as roots
        if dynatomic:
            pts_poly = g.dynatomic_polynomial(n)
        else:
            gn = g.nth_iterate_map(n)
            pts_poly = y * gn[0] - x * gn[1]
        d = ZZ(pts_poly.degree())
        max_mult = max([ex for p, ex in pts_poly.factor()])
        while ((d < 3) or (max_mult >= d / 2) and (n < 5)):
            n = n + 1
            if dynatomic:
                pts_poly = g.dynatomic_polynomial(n)
            else:
                gn = g.nth_iterate_map(n)
                pts_poly = y * gn[0] - x * gn[1]
            d = ZZ(pts_poly.degree())
            max_mult = max([ex for p, ex in pts_poly.factor()])
        assert (n <= 4), "n > 4, failed to find usable poly"

        R = get_bound_dynamical(pts_poly,
                                g,
                                m=n,
                                dynatomic=dynatomic,
                                prec=prec,
                                emb=emb)
        # search starts in fundamental domain
        G, MG = pts_poly.reduced_form(prec=prec,
                                      emb=emb,
                                      smallest_coeffs=False)
        red_g = f.conjugate(M * MG)
        if G != pts_poly:
            R2 = get_bound_dynamical(G,
                                     red_g,
                                     m=n,
                                     dynatomic=dynatomic,
                                     prec=prec,
                                     emb=emb)
            if R2 < R:
                # use the better bound
                R = R2
        red_g.normalize_coordinates()
        if red_g.global_height(prec=prec) == 0:
            return [red_g, M * MG]

        # height
        if current_size is None:
            current_size = e**red_g.global_height(prec=prec)
        v0, th = covariant_z0(G, prec=prec, emb=emb)
        rep = 2 * CC.gen(0)
        from math import isnan
        if isnan(v0.abs()):
            raise ValueError("invalid covariant: %s" % v0)

        # get orbit
        S = matrix(ZZ, 2, 2, [0, -1, 1, 0])
        T = matrix(ZZ, 2, 2, [1, 1, 0, 1])
        TI = matrix(ZZ, 2, 2, [1, -1, 0, 1])

        count = 0
        pts = [[G, red_g, v0, rep, M * MG,
                coshdelta(v0), 0]]  # label - 0:None, 1:S, 2:T, 3:T^(-1)
        if current_min is None:
            current_min = [G, red_g, v0, rep, M * MG, coshdelta(v0)]
        while pts != []:
            G, g, v, rep, M, D, label = pts.pop()
            # apply ST and keep z, Sz
            if D > R:
                break  #all remaining pts are too far away
            # check if it is smaller. If so, we can improve the bound
            count += 1
            new_size = e**g.global_height(prec=prec)
            if new_size < current_size:
                current_min = [G, g, v, rep, M, coshdelta(v)]
                current_size = new_size
                if new_size == 1:  # early exit
                    return [current_min[1], current_min[4]]
                new_R = get_bound_dynamical(G,
                                            g,
                                            m=n,
                                            dynatomic=dynatomic,
                                            prec=prec,
                                            emb=emb)
                if new_R < R:
                    R = new_R

            # add new points to check
            if label != 1 and min((rep + 1).norm(),
                                  (rep - 1).norm()) >= 1:  # don't undo S
                # the 2nd condition is equivalent to |\Re(-1/rep)| <= 1/2
                # this means that rep can have resulted from an inversion step in
                # the shift-and-invert procedure, so don't invert

                # do inversion
                z = -1 / v
                new_pt = [
                    G.subs({
                        x: -y,
                        y: x
                    }),
                    g.conjugate(S), z, -1 / rep, M * S,
                    coshdelta(z), 1
                ]
                pts = insert_item(pts, new_pt, 5)
            if label != 3:  # don't undo T on g
                # do right shift
                z = v - 1
                new_pt = [
                    G.subs({x: x + y}),
                    g.conjugate(TI), z, rep - 1, M * TI,
                    coshdelta(z), 2
                ]
                pts = insert_item(pts, new_pt, 5)
            if label != 2:  # don't undo TI on g
                # do left shift
                z = v + 1
                new_pt = [
                    G.subs({x: x - y}),
                    g.conjugate(T), z, rep + 1, M * T,
                    coshdelta(z), 3
                ]
                pts = insert_item(pts, new_pt, 5)

    return [current_min[1], current_min[4]]
コード例 #31
0
ファイル: mandel_julia.py プロジェクト: sagemath/sage
def julia_plot(c=-1,
               x_center=0.0,
               y_center=0.0,
               image_width=4.0,
               max_iteration=500,
               pixel_count=500,
               base_color='steelblue',
               iteration_level=1,
               number_of_colors=50,
               point_color='yellow',
               interact=False,
               mandelbrot=True,
               period=None):
    r"""
    Plots the Julia set of a given complex `c` value. Users can specify whether
    they would like to display the Mandelbrot side by side with the Julia set.

    The Julia set of a given `c` value is the set of complex numbers for which
    the function `Q_c(z)=z^2+c` is bounded under iteration. The Julia set can
    be visualized by plotting each point in the set in the complex plane.
    Julia sets are examples of fractals when plotted in the complex plane.

    ALGORITHM:

    Define the map `Q_c(z) = z^2 + c` for some `c \in \mathbb{C}`. For every
    `p \in \mathbb{C}`, if `|Q_{c}^{k}(p)| > 2` for some `k \geq 0`,
    then `Q_{c}^{n}(p) \to \infty`. Let `N` be the maximum number of iterations.
    Compute the first `N` points on the orbit of `p` under `Q_c`. If for
    any `k < N`, `|Q_{c}^{k}(p)| > 2`, we stop the iteration and assign a color
    to the point `p` based on how quickly `p` escaped to infinity under
    iteration of `Q_c`. If `|Q_{c}^{i}(p)| \leq 2` for all `i \leq N`, we assume
    `p` is in the Julia set and assign the point `p` the color black.

    INPUT:

    - ``c`` -- complex (optional - default: ``-1``), complex point `c` that
      determines the Julia set.

    - ``period`` -- list (optional - default: ``None``), returns the Julia set
      for a random `c` value with the given (formal) cycle structure.

    - ``mandelbrot`` -- boolean (optional - default: ``True``), when set to
      ``True``, an image of the Mandelbrot set is appended to the right of the
      Julia set.

    - ``point_color`` -- RGB color (optional - default: ``'tomato'``),
      color of the point `c` in the Mandelbrot set (any valid input for Color).

    - ``x_center`` -- double (optional - default: ``-1.0``), Real part
      of center point.

    - ``y_center`` -- double (optional - default: ``0.0``), Imaginary part
      of center point.

    - ``image_width`` -- double (optional - default: ``4.0``), width of image
      in the complex plane.

    - ``max_iteration`` -- long (optional - default: ``500``), maximum number
      of iterations the map `Q_c(z)`.

    - ``pixel_count`` -- long (optional - default: ``500``), side length of
      image in number of pixels.

    - ``base_color`` -- RGB color (optional - default: ``'steelblue'``), color
      used to determine the coloring of set (any valid input for Color).

    - ``iteration_level`` -- long (optional - default: 1), number of iterations
      between each color level.

    - ``number_of_colors`` -- long (optional - default: 30), number of colors
      used to plot image.

    - ``interact`` -- boolean (optional - default: ``False``), controls whether
      plot will have interactive functionality.

    OUTPUT:

    24-bit RGB image of the Julia set in the complex plane.

    EXAMPLES::

        sage: julia_plot()
        1001x500px 24-bit RGB image

    To display only the Julia set, set ``mandelbrot`` to ``False``::

        sage: julia_plot(mandelbrot=False)
        500x500px 24-bit RGB image

    To display an interactive plot of the Julia set in the Notebook,
    set ``interact`` to ``True``::

        sage: julia_plot(interact=True)
        interactive(children=(FloatSlider(value=-1.0, description=u'Real c'...

    To return the Julia set of a random `c` value with (formal) cycle structure
    `(2,3)`, set ``period = [2,3]``::

        sage: julia_plot(period=[2,3])
        1001x500px 24-bit RGB image

    To return all of the Julia sets of `c` values with (formal) cycle structure
    `(2,3)`::

        sage: period = [2,3] # not tested
        ....: R.<c> = QQ[]
        ....: P.<x,y> = ProjectiveSpace(R,1)
        ....: f = DynamicalSystem([x^2+c*y^2, y^2])
        ....: L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC)
        ....: c_values = [k[0] for k in L]
        ....: for c in c_values:
        ....:     julia_plot(c)
    """
    if period is not None:
        R = PolynomialRing(QQ, 'c')
        c = R.gen()
        x, y = ProjectiveSpace(R, 1, 'x,y').gens()
        f = DynamicalSystem([x**2 + c * y**2, y**2])
        L = f.dynatomic_polynomial(period).subs({x: 0, y: 1}).roots(ring=CC)
        c = L[randint(0, len(L) - 1)][0]

    c = CC(c)
    c_real = c.real()
    c_imag = c.imag()

    base_color = Color(base_color)
    point_color = Color(point_color)

    if interact:
        from ipywidgets.widgets import FloatSlider, IntSlider, ColorPicker, interact
        widgets = dict(
            c_real = FloatSlider(min=-2.0, max=2.0, step=EPS,
                                 value=c_real, description="Real c"),
            c_imag = FloatSlider(min=-2.0, max=2.0, step=EPS,
                                 value=c_imag, description="Imag c"),
            x_center = FloatSlider(min=-1.0, max=1.0, step=EPS,
                                   value=x_center, description="Real center"),
            y_center = FloatSlider(min=-1.0, max=1.0, step=EPS,
                                   value=y_center, description="Imag center"),
            image_width = FloatSlider(min=EPS, max=4.0, step=EPS,
                                      value=image_width, description="Image width"),
            max_iteration = IntSlider(min=0, max=600,
                                      value=max_iteration, description="Iterations"),
            pixel_count = IntSlider(min=10, max=600,
                                    value=pixel_count, description="Pixels"),
            level_sep = IntSlider(min=1, max=20,
                                  value=iteration_level, description="Color sep"),
            color_num = IntSlider(min=1, max=100,
                                  value=number_of_colors, description="# Colors"),
            base_color = ColorPicker(value=base_color.html_color(),
                                     description="Base color"),
        )
        if mandelbrot:
            widgets["point_color"] = ColorPicker(value=point_color.html_color(),
                                                 description="Point color")
            return interact(**widgets).widget(julia_helper)
        else:
            return interact(**widgets).widget(fast_julia_plot)

    if mandelbrot:
        return julia_helper(c_real, c_imag, x_center, y_center,
                            image_width, max_iteration, pixel_count,
                            iteration_level,
                            number_of_colors, base_color, point_color)

    else:
        return fast_julia_plot(c_real, c_imag, x_center, y_center,
                               image_width, max_iteration, pixel_count,
                               iteration_level,
                               number_of_colors, base_color)
コード例 #32
0
def _closest_unsafe(lst, x):
    x = CC(x.value)
    return min(enumerate(lst), key=lambda (i, y): abs(CC(y.value) - x))
コード例 #33
0
class HyperbolicRegularPolygon(HyperbolicPolygon):
    r"""
    Primitive class for regular hyberbolic polygon type.

    See ``hyperbolic_regular_polygon?`` for information about plotting
    a hyperbolic regular polygon in the upper complex halfplane.

    INPUT:

    - ``sides`` -- number of sides of the polygon

    - ``i_angle`` -- interior angle of the polygon

    - ``center``-- center point as a complex number of the polygon

    EXAMPLES:

    Note that constructions should use :func:`hyperbolic_regular_polygon`::

         sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
         sage: print(HyperbolicRegularPolygon(5,pi/2,I, {}))
         Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I)

    The code verifies is there exists a compact hyperbolic regular polygon
    with the given data, checking

    .. MATH::

        A(\mathcal{P}) = \pi(s-2) - s \cdot \alpha > 0,

    where `s` is ``sides`` and `\alpha` is ``i_angle`. This raises an error if
    the ``i_angle`` is less than the minimum to generate a compact polygon::

        sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
        sage: P = HyperbolicRegularPolygon(4, pi/2, I, {})
        Traceback (most recent call last):
        ...
        ValueError: there exists no hyperbolic regular compact polygon,
         for sides=4 the interior angle must be less than 1/2*pi

    It is an error to give a center outside the upper half plane in this model ::

         sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
         sage: P = HyperbolicRegularPolygon(4, pi/4, 1-I, {})
         Traceback (most recent call last):
         ...
         ValueError: center: 1.00000000000000 - 1.00000000000000*I is not
          a valid point in the upper half plane model of the hyperbolic plane

    TESTS::

         sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
         sage: P = HyperbolicRegularPolygon(4, -pi/4, I, {})
         Traceback (most recent call last):
         ...
         ValueError: interior angle -1/4*pi must be in (0, pi) interval

         sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
         sage: P=HyperbolicRegularPolygon(16, 3*pi/2, I, {})
         Traceback (most recent call last):
         ...
         ValueError: interior angle 3/2*pi must be in (0, pi) interval

         sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
         sage: P = HyperbolicRegularPolygon(2, pi/10, I, {})
         Traceback (most recent call last):
         ...
         ValueError: degenerated polygons (sides<=2) are not supported
    """
    def __init__(self, sides, i_angle, center, options):
        """
        Initialize HyperbolicRegularPolygon.

        EXAMPLES::

            sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
            sage: print(HyperbolicRegularPolygon(5,pi/2,I, {}))
            Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I)
        """
        self.center = CC(center)
        if self.center.imag() <= 0 :
            raise ValueError("center: %s is not a valid point in the upper half plane model of the hyperbolic plane"%(self.center))
        if sides < 3 :
            raise ValueError("degenerated polygons (sides<=2) are not supported")
        if i_angle <=0 or i_angle >= pi:
            raise ValueError("interior angle %s must be in (0, pi) interval"%(i_angle))
        if pi*(sides-2) - sides*i_angle <= 0 :
            raise ValueError("there exists no hyperbolic regular compact polygon, for sides=%s the interior angle must be less than %s"%(sides, pi * (sides-2) / sides))
        self.sides = sides
        self.i_angle = i_angle
        beta = 2 * pi / self.sides # compute the rotation angle to be used ahead
        alpha = self.i_angle / Integer(2)
        I = CC(0, 1)
        # compute using cosine theorem the radius of the circumscribed circle
        # using the triangle formed by the radius and the three known angles
        r = arccosh(cot(alpha) * (1 + cos(beta)) / sin(beta))

        # The first point will be always on the imaginary axis limited
        # to 8 digits for efficiency in the subsequent calculations.
        z_0 = [I*(e**r).n(digits=8)]

        # Compute the dilation isometry used to move the center
        # from I to the imaginary part of the given center.
        scale = self.center.imag()

        # Compute the parabolic isometry to move the center to the
        # real part of the given center.
        h_disp = self.center.real()

        d_z_k = [z_0[0]*scale + h_disp]  #d_k has the points for the polygon in the given center
        z_k = z_0                      #z_k has the Re(z)>0 vertices for the I centered polygon 
        r_z_k = []                     #r_z_k has the Re(z)<0 vertices
        if is_odd(self.sides):
            vert = (self.sides - 1) / 2
        else:
            vert = self.sides / 2 - 1
        for k in range(0, vert):
            # Compute with 8 digits to accelerate calculations
            new_z_k = self._i_rotation(z_k[-1], beta).n(digits=8)
            z_k = z_k + [new_z_k]
            d_z_k = d_z_k + [new_z_k * scale + h_disp]
            r_z_k=[-(new_z_k).conjugate() * scale + h_disp] + r_z_k
        if is_odd(self.sides):
            HyperbolicPolygon.__init__(self, d_z_k + r_z_k, options)
        else:
            z_opo = [I * (e**(-r)).n(digits=8) * scale + h_disp]
            HyperbolicPolygon.__init__(self, d_z_k + z_opo + r_z_k, options)

    def _repr_(self):
        """
        String representation of HyperbolicRegularPolygon.

        TESTS::

            sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
            sage: HyperbolicRegularPolygon(5,pi/2,I, {})._repr_()
            'Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I)'
        """
        return ("Hyperbolic regular polygon (sides=%s, i_angle=%s, center=%s)"
                % (self.sides, self.i_angle, self.center))

    def _i_rotation(self, z, alpha):
        r"""
        Return the resulting point after applying a hyperbolic
        rotation centered at `0 + i` and angle ``alpha`` to ``z``.

        INPUT:

        - ``z``-- point in the upper complex halfplane to which
          apply the isometry

        - ``alpha``-- angle of rotation (radians,counterwise)

        OUTPUT:

        - rotated point in the upper complex halfplane

        TESTS::

            sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon
            sage: P = HyperbolicRegularPolygon(4, pi/4, 1+I, {})
            sage: P._i_rotation(2+I, pi/2)
            I - 2
        """
        _a = alpha / 2
        _c = cos(_a)
        _s = sin(_a)
        G = matrix([[_c, _s], [-_s, _c]])
        return (G[0][0] * z + G[0][1]) / (G[1][0] * z + G[1][1])