def test_path(self):
        CPF = ComplexPathFactory(self.f1, base_point=-2, kappa=1)
        b = CPF.discriminant_points[0]
        R = CPF.radius(b)
        self.assertAlmostEqual(R, 1.0)

        # straight line path from (-2,1) to (1,-2). this intersects the circle
        # of radius 1 about the origin at (-1,0) goes around to (0,-1).
        #
        # this test goes below the circle
        z0 = -2 + 1.j
        z1 = 1 - 2.j
        gamma = CPF.path(z0, z1)
        segments = gamma.segments
        self.assertEqual(segments[0], ComplexLine(z0, -1))
        self.assertEqual(segments[1], ComplexArc(1, 0, -pi, pi / 2))
        self.assertEqual(segments[2], ComplexLine(-1.j, z1))

        # straight line path from (-1,2) to (2,-1). this intersects the circle
        # of radius 1 about the origin at (0,1) goes around to (1,0).
        #
        # this test goes below the circle
        z0 = -1 + 2.j
        z1 = 2 - 1.j
        gamma = CPF.path(z0, z1)
        segments = gamma.segments
        self.assertEqual(segments[0], ComplexLine(z0, 1.j))
        self.assertEqual(segments[1], ComplexArc(1, 0, pi / 2, -pi / 2))
        self.assertEqual(segments[2], ComplexLine(1, z1))
Example #2
0
    def test_get_x(self):
        gamma1x = ComplexLine(1, 4)
        y01 = [-1, 1]
        gamma1 = RiemannSurfacePathSmale(self.X1, gamma1x, y01)

        gamma2x = ComplexLine(4, 9)
        y02 = [-2, 2]
        gamma2 = RiemannSurfacePathSmale(self.X1, gamma2x, y02)

        gamma = gamma1 + gamma2

        x = gamma.get_x(0)
        self.assertAlmostEqual(x, 1)

        x = gamma.get_x(0.25)
        self.assertAlmostEqual(x, 2.5)

        x = gamma.get_x(0.5)
        self.assertAlmostEqual(x, 4)

        x = gamma.get_x(0.75)
        self.assertAlmostEqual(x, 6.5)

        x = gamma.get_x(1.0)
        self.assertAlmostEqual(x, 9)
    def test_composite_line_smale(self):
        PF = RiemannSurfacePathFactory(self.X1, base_point=-3,
                                       base_sheets=[-1.j*sqrt(3),1.j*sqrt(3)])
        gamma_x = ComplexLine(-3,-2) + ComplexLine(-2,-1)
        gamma = PF.RiemannSurfacePath_from_complex_path(gamma_x)
        self.assertAlmostEqual(gamma.get_x(0.0), -3)
        self.assertAlmostEqual(gamma.get_y(0.0)[0], -1.j*sqrt(3))
        self.assertAlmostEqual(gamma.get_y(0.0)[1], 1.j*sqrt(3))

        self.assertAlmostEqual(gamma.get_x(0.5), -2)
        self.assertAlmostEqual(gamma.get_y(0.5)[0], -1.j*sqrt(2))
        self.assertAlmostEqual(gamma.get_y(0.5)[1], 1.j*sqrt(2))

        self.assertAlmostEqual(gamma.get_x(1.0), -1)
        self.assertAlmostEqual(gamma.get_y(1.0)[0], -1.j)
        self.assertAlmostEqual(gamma.get_y(1.0)[1], 1.j)

        # swap the base sheets
        PF = RiemannSurfacePathFactory(self.X1, base_point=-3,
                                       base_sheets=[1.j*sqrt(3),-1.j*sqrt(3)])
        gamma_x = ComplexLine(-3,-2) + ComplexLine(-2,-1)
        gamma = PF.RiemannSurfacePath_from_complex_path(gamma_x)
        self.assertAlmostEqual(gamma.get_x(0.0), -3)
        self.assertAlmostEqual(gamma.get_y(0.0)[0], 1.j*sqrt(3))
        self.assertAlmostEqual(gamma.get_y(0.0)[1], -1.j*sqrt(3))

        self.assertAlmostEqual(gamma.get_x(0.5), -2)
        self.assertAlmostEqual(gamma.get_y(0.5)[0], 1.j*sqrt(2))
        self.assertAlmostEqual(gamma.get_y(0.5)[1], -1.j*sqrt(2))

        self.assertAlmostEqual(gamma.get_x(1.0), -1)
        self.assertAlmostEqual(gamma.get_y(1.0)[0], 1.j)
        self.assertAlmostEqual(gamma.get_y(1.0)[1], -1.j)
    def path(self, z0, z1):
        r"""Returns the complex path to the bounding circle around `bi` which avoids
        other discriminant points.

        This is a specific implementation of the routine used in :meth:`path`.
        Although similar, this routine takes branch point ordering into account
        when determining whether to go above or below intersecting discriminant
        points. (See :meth:`intersecting_discriminant_points`)

        Parameters
        ----------
        bi : complex
            A discriminant / branch point of the curve.

        Returns
        -------
        gamma : ComplexPath
            The corresponding monodromy path.

        See Also
        --------
        intersecting_discriminant_points
        path
        """
        # compute the list points we need to stay sufficiently away from and
        # sort them in increasing distance from the base point
        points_to_avoid = self.intersecting_discriminant_points(z0,
                                                                z1,
                                                                exact=False)
        points_to_avoid.sort(key=lambda bj: abs(bj - z0))

        # for each points we want to avoid
        #
        # 1. determine the points of intersection with the bounding circle
        # 2. determine the appropriate arc along the bounding circle
        # 3. construct the path segment using a line (if necessary) and the arc
        segments = []
        for j in range(len(points_to_avoid)):
            bj = points_to_avoid[j]
            Rj = self.radius(bj)
            w0, w1 = self.intersection_points(z0, z1, bj, Rj)
            arc = self.avoiding_arc(w0, w1, bj, Rj)

            if abs(z0 - w0) > 1e-14:
                segments.append(ComplexLine(z0, w0))
            segments.append(arc)

            # repeat by setting the new "start point" to be w1, the last point
            # reached on the arc.
            z0 = w1

        # append the final line and build the avoiding path from the segments
        segments.append(ComplexLine(z0, z1))
        if len(segments) == 1:
            path = segments[0]
        else:
            path = ComplexPath(segments)
        return path
Example #5
0
 def test_single_line(self):
     gamma = ComplexLine(-1, 2)
     gamma_rev = gamma.reverse()
     self.assertAlmostEqual(gamma(0.0), gamma_rev(1.0))
     self.assertAlmostEqual(gamma(0.1), gamma_rev(0.9))
     self.assertAlmostEqual(gamma(0.25), gamma_rev(0.75))
     self.assertAlmostEqual(gamma(0.50), gamma_rev(0.50))
     self.assertAlmostEqual(gamma(0.75), gamma_rev(0.25))
     self.assertAlmostEqual(gamma(1.0), gamma_rev(0.0))
Example #6
0
 def test_indexing(self):
     gamma0 = ComplexLine(-1, 0)
     gamma1 = ComplexLine(0, 1.j)
     gamma2 = ComplexArc(1, 0, pi / 2, -pi / 2)
     gamma = gamma0 + gamma1 + gamma2
     self.assertEqual(gamma.segments, [gamma0, gamma1, gamma2])
     self.assertEqual(gamma[0], gamma0)
     self.assertEqual(gamma[1], gamma1)
     self.assertEqual(gamma[2], gamma2)
 def test_single_line(self):
     gamma = ComplexLine(-1,2)
     gamma_rev = gamma.reverse()
     self.assertAlmostEqual(gamma(0.0), gamma_rev(1.0))
     self.assertAlmostEqual(gamma(0.1), gamma_rev(0.9))
     self.assertAlmostEqual(gamma(0.25), gamma_rev(0.75))
     self.assertAlmostEqual(gamma(0.50), gamma_rev(0.50))
     self.assertAlmostEqual(gamma(0.75), gamma_rev(0.25))
     self.assertAlmostEqual(gamma(1.0), gamma_rev(0.0))
Example #8
0
    def test_analytic_continuation(self):
        # method 1: adding two RSPs
        gamma1x = ComplexLine(1, 4)
        y01 = [-1, 1]
        gamma1 = RiemannSurfacePathSmale(self.X1, gamma1x, y01)

        gamma2x = ComplexLine(4, 9)
        y02 = [-2, 2]
        gamma2 = RiemannSurfacePathSmale(self.X1, gamma2x, y02)

        gamma = gamma1 + gamma2

        y = gamma.get_y(0)
        self.assertAlmostEqual(y[0], -1)
        self.assertAlmostEqual(y[1], 1)

        y = gamma.get_y(0.25)
        self.assertAlmostEqual(y[0], -sqrt(2.5))
        self.assertAlmostEqual(y[1], sqrt(2.5))

        y = gamma.get_y(0.5)
        self.assertAlmostEqual(y[0], -2)
        self.assertAlmostEqual(y[1], 2)

        y = gamma.get_y(0.75)
        self.assertAlmostEqual(y[0], -sqrt(6.5))
        self.assertAlmostEqual(y[1], sqrt(6.5))

        y = gamma.get_y(1.0)
        self.assertAlmostEqual(y[0], -3)
        self.assertAlmostEqual(y[1], 3)

        # method 2: composite ComplexPath with one RSP
        gammax = gamma1x + gamma2x
        y0 = [-1, 1]
        gamma = RiemannSurfacePathSmale(self.X1, gammax, y0)

        y = gamma.get_y(0)
        self.assertAlmostEqual(y[0], -1)
        self.assertAlmostEqual(y[1], 1)

        y = gamma.get_y(0.25)
        self.assertAlmostEqual(y[0], -sqrt(2.5))
        self.assertAlmostEqual(y[1], sqrt(2.5))

        y = gamma.get_y(0.5)
        self.assertAlmostEqual(y[0], -2)
        self.assertAlmostEqual(y[1], 2)

        y = gamma.get_y(0.75)
        self.assertAlmostEqual(y[0], -sqrt(6.5))
        self.assertAlmostEqual(y[1], sqrt(6.5))

        y = gamma.get_y(1.0)
        self.assertAlmostEqual(y[0], -3)
        self.assertAlmostEqual(y[1], 3)
Example #9
0
    def test_composite(self):
        gamma1 = ComplexLine(-1, 0)
        gamma2 = ComplexLine(0, 1.j)
        gamma = gamma1 + gamma2

        self.assertAlmostEqual(gamma(0), -1)
        self.assertAlmostEqual(gamma(0.25), -0.5)
        self.assertAlmostEqual(gamma(0.5), 0)
        self.assertAlmostEqual(gamma(0.75), 0.5j)
        self.assertAlmostEqual(gamma(1), 1.j)
 def test_composite(self):
     x1 = (sqrt(2)+sqrt(2)*1.j)/2
     gamma = ComplexLine(0,x1) + ComplexArc(1,0,pi/4,3*pi/5)
     gamma_rev = gamma.reverse()
     self.assertAlmostEqual(gamma(0.0), gamma_rev(1.0))
     self.assertAlmostEqual(gamma(0.1), gamma_rev(0.9))
     self.assertAlmostEqual(gamma(0.25), gamma_rev(0.75))
     self.assertAlmostEqual(gamma(0.50), gamma_rev(0.50))
     self.assertAlmostEqual(gamma(0.75), gamma_rev(0.25))
     self.assertAlmostEqual(gamma(1.0), gamma_rev(0.0))
Example #11
0
 def test_composite(self):
     x1 = (sqrt(2) + sqrt(2) * 1.j) / 2
     gamma = ComplexLine(0, x1) + ComplexArc(1, 0, pi / 4, 3 * pi / 5)
     gamma_rev = gamma.reverse()
     self.assertAlmostEqual(gamma(0.0), gamma_rev(1.0))
     self.assertAlmostEqual(gamma(0.1), gamma_rev(0.9))
     self.assertAlmostEqual(gamma(0.25), gamma_rev(0.75))
     self.assertAlmostEqual(gamma(0.50), gamma_rev(0.50))
     self.assertAlmostEqual(gamma(0.75), gamma_rev(0.25))
     self.assertAlmostEqual(gamma(1.0), gamma_rev(0.0))
Example #12
0
    def test_singleton_segment(self):
        gamma1x = ComplexLine(1, 4)
        y01 = [-1, 1]
        gamma1 = RiemannSurfacePathSmale(self.X1, gamma1x, y01)
        self.assertEqual(gamma1.segments[0], gamma1)

        gamma2x = ComplexLine(4, 9)
        y02 = [-2, 2]
        gamma2 = RiemannSurfacePathSmale(self.X1, gamma2x, y02)
        self.assertEqual(gamma2.segments[0], gamma2)
Example #13
0
    def test_equality(self):
        gamma0 = ComplexLine(-1, 0)
        gamma1 = ComplexLine(-1, 0)
        self.assertEqual(gamma0, gamma1)

        gamma0 = ComplexArc(1, 0, 0, pi)
        gamma1 = ComplexArc(1, 0, 0, pi)
        self.assertEqual(gamma0, gamma1)

        gamma0 = ComplexRay(-1)
        gamma1 = ComplexRay(-1)
        self.assertEqual(gamma0, gamma1)
Example #14
0
    def test_line(self):
        # using AlmostEqual for floating point error
        gamma = ComplexLine(0, 1)
        self.assertAlmostEqual(gamma(0), 0)
        self.assertAlmostEqual(gamma(0.5), 0.5)
        self.assertAlmostEqual(gamma(0.75), 0.75)
        self.assertAlmostEqual(gamma(1), 1)

        gamma = ComplexLine(-1.j, 1.j)
        self.assertAlmostEqual(gamma(0), -1.j)
        self.assertAlmostEqual(gamma(0.5), 0)
        self.assertAlmostEqual(gamma(0.75), 0.5j)
        self.assertAlmostEqual(gamma(1), 1.j)
    def test_line_derivative(self):
        # using AlmostEqual for floating point error
        gamma = ComplexLine(0, 1)
        self.assertAlmostEqual(gamma.derivative(0), 1)
        self.assertAlmostEqual(gamma.derivative(0.5), 1)
        self.assertAlmostEqual(gamma.derivative(0.75), 1)
        self.assertAlmostEqual(gamma.derivative(0), 1)

        gamma = ComplexLine(-1.j, 1.j)
        self.assertAlmostEqual(gamma.derivative(0), 2.j)
        self.assertAlmostEqual(gamma.derivative(0.5), 2.j)
        self.assertAlmostEqual(gamma.derivative(0.75), 2.j)
        self.assertAlmostEqual(gamma.derivative(1), 2.j)
Example #16
0
    def monodromy_path_infinity(self, nrots=1):
        """Returns the complex path starting at the base point, going around
        infinity `nrots` times, and returning to the base point.

        This path is sure to not only encircle all of the discriminant
        points but also stay sufficiently outside the bounding circles
        of the points.

        Parameters
        ----------
        nrots : integer, (default `1`)
            The number of rotations around infinity.

        Returns
        -------
        RiemannSurfacePath
            The complex path encircling infinity.

        """
        path = []

        # determine the radius R of the circle, centered at the origin,
        # encircling all of the discriminant points and the bounding circles
        b = self.discriminant_points
        R = numpy.abs(self.base_point)
        for bi in b:
            radius = self.radius(bi)
            Ri = numpy.abs(bi) + 2*radius  # to be safely away
            R = Ri if Ri > R else R

        # the path begins with a line starting at the base point and ending at
        # the point -R (where the circle will begin)
        path = ComplexLine(self.base_point, -R)

        # the positive direction around infinity is equal to the
        # negative direction around the origin
        dtheta = -numpy.pi if nrots > 0 else numpy.pi
        for _ in range(abs(nrots)):
            path += ComplexArc(R, 0, numpy.pi, dtheta)
            path += ComplexArc(R, 0, 0, dtheta)

        # return to the base point
        path += ComplexLine(-R, self.base_point)

        # determine if the circle actually touches the base point. this occurs
        # when the base point is further away from the origin than the bounding
        # circles of discriminant points. in this case, the path only consists
        # of the arcs defining the circle
        if abs(self.base_point + R) < 1e-15:
            path = ComplexPath(path.segments[1:-1])
        return path
Example #17
0
    def test_composite(self):
        gamma1 = ComplexLine(-1, 0)  # derivative == 1
        gamma2 = ComplexLine(0, 1.j)  # derivative == 1.j
        gamma = gamma1 + gamma2

        # derivative is defined on the half-open intervals [s_i,s_{i+1}) except
        # for the last segment
        self.assertAlmostEqual(gamma.derivative(0), 1)
        self.assertAlmostEqual(gamma.derivative(0.25), 1)
        self.assertAlmostEqual(gamma.derivative(0.49), 1)
        self.assertAlmostEqual(gamma.derivative(0.5), 1.j)
        self.assertAlmostEqual(gamma.derivative(0.51), 1.j)
        self.assertAlmostEqual(gamma.derivative(0.75), 1.j)
        self.assertAlmostEqual(gamma.derivative(1), 1.j)
Example #18
0
    def test_segments(self):
        gamma1x = ComplexLine(1, 4)
        y01 = [-1, 1]
        gamma1 = RiemannSurfacePathSmale(self.X1, gamma1x, y01)

        gamma2x = ComplexLine(4, 9)
        y02 = [-2, 2]
        gamma2 = RiemannSurfacePathSmale(self.X1, gamma2x, y02)

        gamma = gamma1 + gamma2
        self.assertEqual(gamma.segments[0], gamma1)
        self.assertEqual(gamma.segments[1], gamma2)
        self.assertEqual(gamma[0], gamma1)
        self.assertEqual(gamma[1], gamma2)
Example #19
0
    def test_iteration_reverse(self):
        gamma0 = ComplexLine(-1, 0)
        gamma1 = ComplexLine(0, 1.j)
        gamma2 = ComplexArc(1, 0, pi / 2, -pi / 2)
        gamma = gamma0 + gamma1 + gamma2

        index = 0
        for segment in gamma[::-1]:
            if index == 0:
                self.assertEqual(segment, gamma2)
            elif index == 1:
                self.assertEqual(segment, gamma1)
            elif index == 2:
                self.assertEqual(segment, gamma0)
            index += 1
Example #20
0
    def test_analytic_continuation_X1(self):
        gammax = ComplexLine(1, 0)
        y0 = [-1, 1]
        gamma = RiemannSurfacePathPuiseux(self.X1, gammax, y0)

        y = gamma.get_y(0)
        self.assertAlmostEqual(y[0], -1)
        self.assertAlmostEqual(y[1], 1)

        y = gamma.get_y(0.5)
        self.assertAlmostEqual(y[0], -sqrt(complex(0.5)))
        self.assertAlmostEqual(y[1], sqrt(complex(0.5)))

        y = gamma.get_y(0.75)
        self.assertAlmostEqual(y[0], -sqrt(complex(0.25)))
        self.assertAlmostEqual(y[1], sqrt(complex(0.25)))

        y = gamma.get_y(1)
        self.assertAlmostEqual(y[0], 0)
        self.assertAlmostEqual(y[1], 0)

        gammax = ComplexArc(2, 2, 0, pi)
        y0 = [-2, 2]
        gamma = RiemannSurfacePathPuiseux(self.X1, gammax, y0)

        y = gamma.get_y(0)
        self.assertAlmostEqual(y[0], -2)
        self.assertAlmostEqual(y[1], 2)

        y = gamma.get_y(1)
        self.assertAlmostEqual(y[0], 0)
        self.assertAlmostEqual(y[1], 0)
    def test_primitive_line_smale(self):
        PF = RiemannSurfacePathFactory(self.X1, base_point=-1,
                                       base_sheets=[-1.j,1.j])
        gamma_x = ComplexLine(-1,-2)
        gamma = PF.RiemannSurfacePath_from_complex_path(gamma_x)
        self.assertAlmostEqual(gamma.get_x(1.0), -2)
        self.assertAlmostEqual(gamma.get_y(1.0)[0], -1.j*sqrt(2))
        self.assertAlmostEqual(gamma.get_y(1.0)[1], 1.j*sqrt(2))

        # swap the base sheets
        PF = RiemannSurfacePathFactory(self.X1, base_point=-1,
                                       base_sheets=[1.j,-1.j])
        gamma_x = ComplexLine(-1,-2)
        gamma = PF.RiemannSurfacePath_from_complex_path(gamma_x)
        self.assertAlmostEqual(gamma.get_x(1.0), -2)
        self.assertAlmostEqual(gamma.get_y(1.0)[0], 1.j*sqrt(2))
        self.assertAlmostEqual(gamma.get_y(1.0)[1], -1.j*sqrt(2))
    def test_composite_line_mixed(self):
        PF = RiemannSurfacePathFactory(self.X1, base_point=-2,
                                       base_sheets=[-1.j*sqrt(2),1.j*sqrt(2)])
        gamma_x = ComplexLine(-2,-1) + ComplexLine(-1,0)
        gamma = PF.RiemannSurfacePath_from_complex_path(gamma_x)
        self.assertEqual(len(gamma.segments), 2)
        self.assertTrue(
            isinstance(gamma.segments[0], RiemannSurfacePathSmale))
        self.assertTrue(
            isinstance(gamma.segments[1], RiemannSurfacePathPuiseux))

        self.assertAlmostEqual(gamma.get_x(0.0), -2)
        self.assertAlmostEqual(gamma.get_y(0.0)[0], -1.j*sqrt(2))
        self.assertAlmostEqual(gamma.get_y(0.0)[1], 1.j*sqrt(2))

        self.assertAlmostEqual(gamma.get_x(0.5), -1)
        self.assertAlmostEqual(gamma.get_y(0.5)[0], -1.j)
        self.assertAlmostEqual(gamma.get_y(0.5)[1], 1.j)

        self.assertAlmostEqual(gamma.get_x(1.0), 0)
        self.assertAlmostEqual(gamma.get_y(1.0)[0], 0)
        self.assertAlmostEqual(gamma.get_y(1.0)[1], 0)

        # swap the base sheets
        PF = RiemannSurfacePathFactory(self.X1, base_point=-2,
                                       base_sheets=[1.j*sqrt(2),-1.j*sqrt(2)])
        gamma_x = ComplexLine(-2,-1) + ComplexLine(-1,0)
        gamma = PF.RiemannSurfacePath_from_complex_path(gamma_x)
        self.assertEqual(len(gamma.segments), 2)
        self.assertTrue(
            isinstance(gamma.segments[0], RiemannSurfacePathSmale))
        self.assertTrue(
            isinstance(gamma.segments[1], RiemannSurfacePathPuiseux))

        self.assertAlmostEqual(gamma.get_x(0.0), -2)
        self.assertAlmostEqual(gamma.get_y(0.0)[0], 1.j*sqrt(2))
        self.assertAlmostEqual(gamma.get_y(0.0)[1], -1.j*sqrt(2))

        self.assertAlmostEqual(gamma.get_x(0.5), -1)
        self.assertAlmostEqual(gamma.get_y(0.5)[0], 1.j)
        self.assertAlmostEqual(gamma.get_y(0.5)[1], -1.j)

        self.assertAlmostEqual(gamma.get_x(1.0), 0)
        self.assertAlmostEqual(gamma.get_y(1.0)[0], 0)
        self.assertAlmostEqual(gamma.get_y(1.0)[1], 0)
Example #23
0
    def test_simple_line_smale(self):
        gammax = ComplexLine(1, 2)
        gamma = RiemannSurfacePathSmale(self.X1, gammax, [-1, 1])
        nu = lambda x, y: y
        nu_gamma = gamma.parameterize(nu)

        val = nu_gamma(0.0)
        self.assertAlmostEqual(val, -1)

        val = nu_gamma(0.5)
        self.assertAlmostEqual(val, -sqrt(1.5))

        val = nu_gamma(1.0)
        self.assertAlmostEqual(val, -sqrt(2.0))
Example #24
0
    def test_simple_line_dxds(self):
        gammax = ComplexLine(1, 3)  # dx/ds = 2
        gamma = RiemannSurfacePathSmale(self.X1, gammax, [-1, 1])
        nu = lambda x, y: y
        nu_gamma = gamma.parameterize(nu)

        val = nu_gamma(0.0)
        self.assertAlmostEqual(val, -2)

        val = nu_gamma(0.5)
        self.assertAlmostEqual(val, -2 * sqrt(2.0))

        val = nu_gamma(1.0)
        self.assertAlmostEqual(val, -2 * sqrt(3.0))
    def test_simple_composite(self):
        gammax1 = ComplexLine(4,1)
        gamma1 = RiemannSurfacePathSmale(self.X1, gammax1, [-2,2])
        gammax2 = ComplexArc(1,0,0,pi)
        gamma2 = RiemannSurfacePathSmale(self.X1, gammax2, [-1,1])
        gamma = gamma1 + gamma2
        nu = lambda x,y: y
        nu_gamma = gamma.parameterize(nu)

        val = nu_gamma(0.0)
        test = gammax1.derivative(0.0)*(-2)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.25)
        test = gammax1.derivative(0.5)*(-sqrt(2.5))
        self.assertAlmostEqual(val, test)

        eps = 1e-12
        val = nu_gamma(0.5-eps)
        test = gammax1.derivative(1.0-eps/2)*(-1)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.5)
        test = gammax2.derivative(0.0)*(-1)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.5+eps)
        test = gammax2.derivative(eps/2)*(-1)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.75)
        test = gammax2.derivative(0.5)*(-sqrt(1.j))
        self.assertAlmostEqual(val, test)

        val = nu_gamma(1.0)
        test = gammax2.derivative(1.0)*(-1.j)
        self.assertAlmostEqual(val, test)
Example #26
0
    def test_simple_composite(self):
        gammax1 = ComplexLine(4, 1)
        gamma1 = RiemannSurfacePathSmale(self.X1, gammax1, [-2, 2])
        gammax2 = ComplexArc(1, 0, 0, pi)
        gamma2 = RiemannSurfacePathSmale(self.X1, gammax2, [-1, 1])
        gamma = gamma1 + gamma2
        nu = lambda x, y: y
        nu_gamma = gamma.parameterize(nu)

        val = nu_gamma(0.0)
        test = gammax1.derivative(0.0) * (-2)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.25)
        test = gammax1.derivative(0.5) * (-sqrt(2.5))
        self.assertAlmostEqual(val, test)

        eps = 1e-12
        val = nu_gamma(0.5 - eps)
        test = gammax1.derivative(1.0 - eps / 2) * (-1)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.5)
        test = gammax2.derivative(0.0) * (-1)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.5 + eps)
        test = gammax2.derivative(eps / 2) * (-1)
        self.assertAlmostEqual(val, test)

        val = nu_gamma(0.75)
        test = gammax2.derivative(0.5) * (-sqrt(1.j))
        self.assertAlmostEqual(val, test)

        val = nu_gamma(1.0)
        test = gammax2.derivative(1.0) * (-1.j)
        self.assertAlmostEqual(val, test)
Example #27
0
    def test_addition_fails(self):
        # case 1: the x-points don't match
        gamma1x = ComplexLine(1, 4)
        y01 = [-1, 1]
        gamma1 = RiemannSurfacePathSmale(self.X1, gamma1x, y01)

        gamma2x = ComplexLine(9, 10)
        y02 = [-3, 3]
        gamma2 = RiemannSurfacePathSmale(self.X1, gamma2x, y02)

        with self.assertRaises(ValueError):
            gamma = gamma1 + gamma2

        # case 2: x-points match but y-fibre doesn't
        gamma1x = ComplexLine(1, 4)
        y01 = [-1, 1]
        gamma1 = RiemannSurfacePathSmale(self.X1, gamma1x, y01)

        gamma2x = ComplexLine(4, 9)
        y02 = [2, -2]  # swapped: gamma1 ends at [-2,2]
        gamma2 = RiemannSurfacePathSmale(self.X1, gamma2x, y02)

        with self.assertRaises(ValueError):
            gamma = gamma1 + gamma2
Example #28
0
    def test_simple_line_puiseux_discriminant(self):
        gammax = ComplexLine(2, 0)  #dxds = 2
        y0 = [-sqrt(2.0), sqrt(2.0)]
        gamma = RiemannSurfacePathPuiseux(self.X1, gammax, y0)
        nu = lambda x, y: y
        nu_gamma = gamma.parameterize(nu)

        val = nu_gamma(0.0)
        self.assertAlmostEqual(val, -sqrt(2.0))

        val = nu_gamma(0.5)
        self.assertAlmostEqual(val, -sqrt(1.0))

        val = nu_gamma(1.0)
        self.assertAlmostEqual(val, 0)
    def _path_to_discriminant_place(self, P):
        r"""Returns a path to a discriminant place on the surface.

        A "discriminant" place :math:`P` is a place on the Riemann
        surface where Puiseux series are required to determine the x-
        and y-projections of the place.

        Parameters
        ----------
        P : Place
            A place on the Riemann surface whose x-projection is a discriminant
            point of the curve.

        Returns
        -------
        gamma : RiemannSurfacePath
            A path from the base place to the discriminant place `P`.

        """
        # compute a valid y-value at x=a=b-R, where b is the
        # discriminant point center of the series and R is the radius of
        # bounding circle around b, such that analytically continuing
        # from that (x,y) to x=b will reach the designated place
        p = P.puiseux_series
        center, coefficient, ramification_index = p.xdata
        R = self.complex_path_factory.radius(center)
        a = center - R
        t = (-R / coefficient)**(1.0 / ramification_index)
        # p.coerce_to_numerical()
        p.extend_to_t(t)
        y = p.eval_y(t)

        # construct a path going from the base place to this regular
        # place to the left of the target discriminant point
        P1 = self.riemann_surface(a, y)
        gamma1 = self._path_to_regular_place(P1)

        # construct the RiemannSurfacePath going from this regular place to the
        # discriminant point.
        xend = complex(gamma1.get_x(1.0))
        yend = array(gamma1.get_y(1.0), dtype=complex)
        gamma_x = ComplexLine(complex(a), complex(center))
        segment = RiemannSurfacePathPuiseux(self.riemann_surface, gamma_x,
                                            yend)
        gamma = gamma1 + segment
        return gamma
Example #30
0
    def test_ordered_puiseux_series_regular(self):
        # testing f1
        target_point = 4
        gammax = ComplexLine(1, target_point)
        y0 = [-1, 1]
        p, place = ordered_puiseux_series(self.X1, gammax, y0, target_point)
        P = p[0].parent()
        x = P.gen()
        self.assertEqual(p[0].truncate(3),
                         -2 - QQ(1) / 4 * x + QQ(1) / 64 * x**2)
        self.assertEqual(p[1].truncate(3),
                         2 + QQ(1) / 4 * x - QQ(1) / 64 * x**2)

        y0 = [1, -1]
        p, place = ordered_puiseux_series(self.X1, gammax, y0, target_point)
        self.assertEqual(p[0].truncate(3),
                         2 + QQ(1) / 4 * x - QQ(1) / 64 * x**2)
        self.assertEqual(p[1].truncate(3),
                         -2 - QQ(1) / 4 * x + QQ(1) / 64 * x**2)
Example #31
0
    def test_analytic_continuation_X1(self):
        gammax = ComplexLine(1, 4)
        y0 = [-1, 1]
        gamma = RiemannSurfacePathSmale(self.X1, gammax, y0)

        y = gamma.get_y(0)
        self.assertAlmostEqual(y[0], -1)
        self.assertAlmostEqual(y[1], 1)

        y = gamma.get_y(0.5)
        self.assertAlmostEqual(y[0], -sqrt(2.5))
        self.assertAlmostEqual(y[1], sqrt(2.5))

        y = gamma.get_y(0.75)
        self.assertAlmostEqual(y[0], -sqrt(3.25))
        self.assertAlmostEqual(y[1], sqrt(3.25))

        y = gamma.get_y(1)
        self.assertAlmostEqual(y[0], -2)
        self.assertAlmostEqual(y[1], 2)
Example #32
0
 def apply_automorphism(self, f, fineness=200, clear=True, check_sheet=True, eps=1e-10):
     sheet = 0 #self.starting_sheet
     image = [f(self.get_x(t), self.get_y(t)[sheet])[0] for t in np.arange(0, 1.+1./fineness, 1./fineness)]
     # We currently have an issue that when we use apply_automorphism, cyclepainter is using the radio sheet without thinking what sheet we need to be on
     # to accurately represent the image of the path under the automorphism.
     # This is essentially an aesthetic change, as when saving an automorphism path will usually want to choose the sheet ordering manually, and when 
     # apply_automorphism is ran on its own CyclePainterPath is called with build_surface=False.
     # We first check for this problem:
     # These are the starting x & y after the automorphism is applied.
     if check_sheet:
         start_x = image[0]
         start_y = f(self.get_x(0), self.get_y(0)[sheet])[1]
         # This gives the mp and a complex path to the new start
         # The is treating the complex plane a star-shaped, which isn't true when we have branch points, see later. 
         mp_x = self.cp.surface.base_point
         path = ComplexLine(mp_x, start_x)
         # We now create an ordering of the fibre based on the current radio sheet s.t. the first entry correspond to y along the path. 
         y0 = list(self.cp.surface.base_sheets)
         tmp = y0[self.cp.radio_sheet]
         del y0[self.cp.radio_sheet]
         y0 = np.array([tmp] + y0)
         # Now create the Riemann surface path
         # Note that this method is sensitive to if the path passes close to a branch point. 
         # If this starts to occur too regularly, adjustment will need to be made. 
         check_path = self.cp.surface._path_factory.RiemannSurfacePath_from_complex_path(path, x0=mp_x, y0=y0)
         comp_y = check_path.get_y(1.)
         # Check against the range of possible y values to see if there is an issue with the sheet.
         diff = [np.abs(z-start_y) for z in comp_y]
         index = np.argmin(diff)
         if diff[index] > eps:
             print("Fibre values do not match up - investigate this error.")
             return
         elif index != 0:
             print("Radio sheet is incorect for the automorphism - changing to the sheet corresponding to y={}".format(y0[index]))
             print("The sheet buttons will now be out of sync.")
             self.cp._radio_handler(list(self.cp.surface.base_sheets).index(y0[index]))
         # If all sheet checks succeed carry on
     self.cp.path_builder.start(from_monodromy=False)
     for x in image:
         self.cp.path_builder.add(x)
     self.cp.path_builder.finish(to_monodromy=False, clear=clear)
Example #33
0
    def test_analytic_continuation_X1_big_jump(self):
        # tests that smale will handle the case when checkpoints don't exist or
        # are far away from each other
        gammax = ComplexLine(1, 9)
        y0 = [-1, 1]
        gamma = RiemannSurfacePathSmale(self.X1, gammax, y0, ncheckpoints=1)

        y = gamma.get_y(0)
        self.assertAlmostEqual(y[0], -1)
        self.assertAlmostEqual(y[1], 1)

        y = gamma.get_y(0.5)
        self.assertAlmostEqual(y[0], -sqrt(5))
        self.assertAlmostEqual(y[1], sqrt(5))

        y = gamma.get_y(0.75)
        self.assertAlmostEqual(y[0], -sqrt(7))
        self.assertAlmostEqual(y[1], sqrt(7))

        y = gamma.get_y(1)
        self.assertAlmostEqual(y[0], -3)
        self.assertAlmostEqual(y[1], 3)
Example #34
0
    def test_ordered_puiseux_series_discriminant(self):
        # testing f1
        target_point = 0
        gammax = ComplexLine(1, target_point)
        y0 = [-1, 1]
        p, place = ordered_puiseux_series(self.X1, gammax, y0, target_point)
        P = p[0].parent()
        x = P.gen()
        half = QQ(1) / 2
        self.assertEqual(p[0].truncate(1), -x**half)
        self.assertEqual(p[1].truncate(1), x**half)

        y0 = [1, -1]
        p, place = ordered_puiseux_series(self.X1, gammax, y0, target_point)
        self.assertEqual(p[0].truncate(1), x**half)
        self.assertEqual(p[1].truncate(1), -x**half)

        # testing f2
        S = QQ['t']
        t = S.gen()
        alpha, beta, gamma = (t**3 - 1).roots(ring=QQbar, multiplicities=False)
        third = QQ(1) / 3
        y0 = [alpha, beta, gamma]
        p, place = ordered_puiseux_series(self.X2, gammax, y0, target_point)
        self.assertEqual(p[0].truncate(1), alpha * x**third)
        self.assertEqual(p[1].truncate(1), beta * x**third)
        self.assertEqual(p[2].truncate(1), gamma * x**third)

        y0 = [beta, gamma, alpha]
        p, place = ordered_puiseux_series(self.X2, gammax, y0, target_point)
        self.assertEqual(p[0].truncate(1), beta * x**third)
        self.assertEqual(p[1].truncate(1), gamma * x**third)
        self.assertEqual(p[2].truncate(1), alpha * x**third)

        y0 = [beta, alpha, gamma]
        p, place = ordered_puiseux_series(self.X2, gammax, y0, target_point)
        self.assertEqual(p[0].truncate(1), beta * x**third)
        self.assertEqual(p[1].truncate(1), alpha * x**third)
        self.assertEqual(p[2].truncate(1), gamma * x**third)