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_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)
def tests_monodromy(self): gammax = ComplexArc(1, 0, 0, 2 * pi) y0 = [-1, 1] gamma = RiemannSurfacePathSmale(self.X1, gammax, y0) y = gamma.get_y(0.0) self.assertAlmostEqual(y[0], -1) self.assertAlmostEqual(y[1], 1) y = gamma.get_y(1.0) self.assertAlmostEqual(y[0], 1) self.assertAlmostEqual(y[1], -1)
def tests_monodromy(self): gammax = ComplexArc(1, 0, 0, 2*pi) y0 = [-1,1] gamma = RiemannSurfacePathSmale(self.X1, gammax, y0) y = gamma.get_y(0.0) self.assertAlmostEqual(y[0], -1) self.assertAlmostEqual(y[1], 1) y = gamma.get_y(1.0) self.assertAlmostEqual(y[0], 1) self.assertAlmostEqual(y[1], -1)
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)
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))
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_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_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))
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)
def test_simple_arc(self): gammax = ComplexArc(1,0,0,pi) gamma = RiemannSurfacePathSmale(self.X1, gammax, [-1,1]) nu = lambda x,y: y nu_gamma = gamma.parameterize(nu) val = nu_gamma(0.0) test = gammax.derivative(0.0)*(-1) self.assertAlmostEqual(val, test) val = nu_gamma(0.5) test = gammax.derivative(0.5)*(-sqrt(1.j)) self.assertAlmostEqual(val, test) val = nu_gamma(1.0) test = gammax.derivative(1.0)*(-1.j) self.assertAlmostEqual(val, test)
def test_simple_arc(self): gammax = ComplexArc(1, 0, 0, pi) gamma = RiemannSurfacePathSmale(self.X1, gammax, [-1, 1]) nu = lambda x, y: y nu_gamma = gamma.parameterize(nu) val = nu_gamma(0.0) test = gammax.derivative(0.0) * (-1) self.assertAlmostEqual(val, test) val = nu_gamma(0.5) test = gammax.derivative(0.5) * (-sqrt(1.j)) self.assertAlmostEqual(val, test) val = nu_gamma(1.0) test = gammax.derivative(1.0) * (-1.j) self.assertAlmostEqual(val, test)
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)
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)
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)
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)
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
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)
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)
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
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
def test_construction(self): gammax = ComplexLine(1, 4) y0 = [-1, 1] gamma = RiemannSurfacePathSmale(self.X1, gammax, y0)