コード例 #1
0
    def test_rays(self):
        # test that analytic continuation to places at infinity work
        gammax = ComplexRay(-9)
        y0 = [-3.j,3.j]
        gamma = RiemannSurfacePathPuiseux(self.X1, gammax, y0)

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

        # note: the infinity behavior may change in the future
        y = gamma.get_y(1)
        self.assertTrue(numpy.isnan(y[0]))
        self.assertTrue(numpy.isnan(y[1]))
コード例 #2
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)
コード例 #3
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)
コード例 #4
0
    def test_analytic_continuation_X2(self):
        S = QQ['t']; t = S.gen()
        a,b,c = (t**3 - 1).roots(ring=QQbar, multiplicities=False)

        gammax = ComplexLine(1,0)
        y0 = [a,b,c]
        gamma = RiemannSurfacePathPuiseux(self.X2, gammax, y0)

        y = gamma.get_y(0)
        self.assertAlmostEqual(y[0], a)
        self.assertAlmostEqual(y[1], b)
        self.assertAlmostEqual(y[2], c)

        scale = (0.5)**(1/3.)
        y = gamma.get_y(0.5)
        self.assertAlmostEqual(y[0], scale*a)
        self.assertAlmostEqual(y[1], scale*b)
        self.assertAlmostEqual(y[2], scale*c)

        y = gamma.get_y(1)
        self.assertAlmostEqual(y[0], 0)
        self.assertAlmostEqual(y[1], 0)
        self.assertAlmostEqual(y[2], 0)
コード例 #5
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.
        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
コード例 #6
0
 def test_construction(self):
     gammax = ComplexLine(1, 0)
     y0 = [-1, 1]
     gamma = RiemannSurfacePathPuiseux(self.X1, gammax, y0)
コード例 #7
0
    def RiemannSurfacePath_from_complex_path(self,
                                             complex_path,
                                             x0=None,
                                             y0=None):
        r"""Constructs a :class:`RiemannSurfacePath` object from x-path data.

        Parameters
        ----------
        complex_path : ComplexPath
            A complex path.
        x0 : complex (default `self.base_point`)
            The starting x-point of the path.
        y0 : complex list (default `self.base_sheets`)
            The starting ordering of the y-sheets.

        Returns
        -------
        RiemannSurfacePath
            A path on the Riemann surface with the prescribed x-path.

        """
        if x0 is None:
            x0 = self.base_point
        if y0 is None:
            y0 = self.base_sheets

        # coerce and assert that x0,y0 lies on the path and curve
        x0 = complex(x0)
        y0 = array(y0, dtype=complex)
        if abs(x0 - complex_path(0)) > 1e-7:
            raise ValueError('The point %s is not at the start of the '
                             'ComplexPath %s' % (x0, complex_path))
        f = self.riemann_surface.f
        curve_error = [abs(complex(f(x0, y0k))) for y0k in y0]
        if max(curve_error) > 1e-7:
            raise ValueError('The fibre %s above %s does not lie on the '
                             'curve %s' % (y0.tolist(), x0, f))

        # build a list of path segments from each tuple of xdata. build a line
        # segment or arc depending on xdata input
        x0_segment = x0
        y0_segment = y0
        segments = []
        for segment_x in complex_path.segments:
            # for each segment determine if we're far enough away to use Smale
            # alpha theory paths or if we have to use Puiseux. we add a
            # relazation factor to the radius to account for monodromy paths
            xend = segment_x(1.0)
            b = self.complex_path_factory.closest_discriminant_point(xend)
            R = self.complex_path_factory.radius(b)
            if abs(xend - b) > 0.9 * R:
                segment = RiemannSurfacePathSmale(self.riemann_surface,
                                                  segment_x, y0_segment)
            else:
                segment = RiemannSurfacePathPuiseux(self.riemann_surface,
                                                    segment_x, y0_segment)

            # determine the starting place of the next segment
            x0_segment = segment.get_x(1.0)
            y0_segment = segment.get_y(1.0)
            segments.append(segment)

        # build the entire path from the path segments
        gamma = RiemannSurfacePath(self.riemann_surface, complex_path, y0,
                                   segments)
        return gamma