def regular_ngon(n): r""" Return a regular n-gon. EXAMPLES:: sage: from flatsurf.geometry.polygon import polygons sage: p = polygons.regular_ngon(17) sage: p Polygon: (0, 0), (1, 0), ..., (-1/2*a^14 + 15/2*a^12 - 45*a^10 + 275/2*a^8 - 225*a^6 + 189*a^4 - 70*a^2 + 15/2, 1/2*a) """ # The code below crashes for n=4! if n==4: return polygons.square(QQ(1)) from sage.rings.qqbar import QQbar c = QQbar.zeta(n).real() s = QQbar.zeta(n).imag() field, (c,s) = number_field_elements_from_algebraics((c,s)) cn = field.one() sn = field.zero() edges = [(cn,sn)] for _ in range(n-1): cn,sn = c*cn - s*sn, c*sn + s*cn edges.append((cn,sn)) return Polygons(field)(edges=edges)
def xseries(self, all_conjugates=True): r"""Returns the corresponding x-series. Parameters ---------- all_conjugates : bool (default: True) If ``True``, returns all conjugates x-representations of this Puiseux t-series. If ``False``, only returns one representative. Returns ------- list List of PuiseuxXSeries representations of this PuiseuxTSeries. """ # obtain relevant rings: # o R = parent ring of curve # o L = parent ring of T-series # o S = temporary polynomial ring over base ring of T-series # o P = Puiseux series ring L = self.ypart.parent() t = L.gen() S = L.base_ring()['z'] z = S.gen() R = self.f.parent() x,y = R.gens() P = PuiseuxSeriesRing(L.base_ring(), str(x)) x = P.gen() # given x = alpha + lambda*t^e solve for t. this involves finding an # e-th root of either (1/lambda) or of lambda, depending on e's sign ## (A sign on a ramification index ? hm) e = self.ramification_index abse = abs(e) lamb = S(self.xcoefficient) order = self.order if e > 0: phi = lamb*z**e - 1 else: phi = z**abse - lamb mu = phi.roots(QQbar, multiplicities=False)[0] if all_conjugates: zeta_e=QQbar.zeta(abse) conjugates = [mu*zeta_e**k for k in range(abse)] else: conjugates = [mu] map(lambda x: x.exactify(), conjugates) # determine the resulting x-series xseries = [] for c in conjugates: t = self.ypart.parent().gen() fconj = self.ypart(c*t) p = P(fconj(x**(QQ(1)/e))) p = p.add_bigoh(QQ(order+1)/abse) xseries.append(p) return xseries
def dim_Joli( k, L, h): """ Return the dimension of the space $J_{k,L}(\varepsilon^h)$. INPUT k -- a half integer L -- an instance of Lattice_class h -- an integer """ h = Integer(h) g = k - h/2 try: g = Integer(g) except: return Integer(0) # preparations o_inv = L.o_invariant() V = L.shadow_vectors() V2 = L.shadow_vectors_of_order_2() n = L.rank() if k < n/2: return Integer(0) if n/2 <= k and k < 2+n/2: raise NotImplementedError( 'special weight %s: not yet implemented'%k) # scalar term scal = (L.det() + len(V2) * (-1)**(g+o_inv)) * (k-n/2-1)/24 # elliptic S-term ell_S = (L.chi(2) * QQbar.zeta(4)**g).real()/4 + Rational(Integer(12).kronecker(2*g+2*n+1))/6 # elliptic R-term ell_R = (L.chi(-3) * QQbar.zeta(24)**(n+2) * QQbar.zeta(6)**g).real() * (-1)**g/QQbar(27).sqrt() # parabolic term B = lambda t: t - t.floor() - Rational(1)/2 par = -sum( B(h/24-L.beta(x)) for x in V)/2 par -= (-1)**(g+o_inv) * sum(B(h/24-L.beta(x)) for x in V2)/2 return Integer(scal + ell_S + ell_R + par)
def family_two(n, backend=None): r""" Return the vector configuration of the simplicial arrangement `A(n,1)` from the family `\mathcal R(1)` in Grunbaum's list [Gru]_. The arrangement will have an ``n`` hyperplanes, with ``n`` even, consisting of the edges of the regular `n/2`-gon and the `n/2` lines of mirror symmetry. INPUT: - ``n`` -- integer. ``n`` `\geq 6`. The number of lines in the arrangement. - ``backend`` -- string (default = ``None``). The backend to use. OUTPUT: A vector configuration. EXAMPLES:: sage: from cn_hyperarr.infinite_families import * sage: pf = family_two(8,'normaliz'); pf # optional - pynormaliz Vector configuration of 8 vectors in dimension 3 The number of lines must be even:: sage: pf3 = family_two(3,'normaliz'); # optional - pynormaliz Traceback (most recent call last): ... AssertionError: n must be even The number of lines must be at least 6:: sage: pf4 = family_two(4,'normaliz') # optional - pynormaliz Traceback (most recent call last): ... ValueError: n (=2) must be an integer greater than 2 """ assert n % 2 == 0, "n must be even" reg_poly = polytopes.regular_polygon(n / QQ(2), backend='normaliz') reg_cone = Polyhedron( rays=[list(v.vector()) + [1] for v in reg_poly.vertices()], backend=backend) vecs = [h.A() for h in reg_cone.Hrepresentation()] z = QQbar.zeta(n) vecs += [[(z**k).real(), (z**k).imag(), 0] for k in range(n / QQ(2))] return VectorConfiguration(vecs, backend=backend)
def chi( self, t): """ Return the value of the Gauss sum $\sum_{x\in L^\bullet/L} e(tG[x]/2)/\sqrt D$, where $D = |L^\bullet/L|$. """ t = Integer(t)%self.shadow_level() if self.__chi.has_key(t): return self.__chi[t] l = self.shadow_level() z = QQbar.zeta(l) w = QQbar(self.det().sqrt()) V = self.values() self.__chi[t] = sum(len(V[a])*z**(t*a) for a in V)/w return self.__chi[t]
def _call_(self, x): r""" TESTS:: sage: UCF = UniversalCyclotomicField() sage: UCFtoQQbar = UCF.coerce_embedding() sage: UCFtoQQbar(UCF.gen(3)) # indirect doctest -0.500000000000000? + 0.866025403784439?*I """ obj = x._obj QQbar = self.codomain() if obj.IsRat(): return QQbar(obj.sage()) k = obj.Conductor().sage() coeffs = obj.CoeffsCyc(k).sage() zeta = QQbar.zeta(k) return QQbar(sum(coeffs[a] * zeta**a for a in range(1,k)))
def _call_(self, x): r""" TESTS:: sage: UCF = UniversalCyclotomicField() sage: UCFtoQQbar = UCF.coerce_embedding() sage: UCFtoQQbar(UCF.gen(3)) # indirect doctest -0.500000000000000? + 0.866025403784439?*I """ obj = x._obj QQbar = self.codomain() if obj.IsRat(): return QQbar(obj.sage()) k = obj.Conductor().sage() coeffs = obj.CoeffsCyc(k).sage() zeta = QQbar.zeta(k) return QQbar(sum(coeffs[a] * zeta**a for a in range(1, k)))
def near_pencil_family(n, backend=None): r""" Return the vector configuration of the near pencil with ``n`` lines. All lines except for one share a common intersection point. INPUT: - ``n`` -- integer. ``n`` `\geq 3`. The number of lines in the near pencil. - ``backend`` -- string (default = ``None``). The backend to use. OUTPUT: A vector configuration. EXAMPLES: The near pencil with three hyperplanes:: sage: from cn_hyperarr.infinite_families import * sage: np = near_pencil_family(3,'normaliz'); np # optional - pynormaliz Vector configuration of 3 vectors in dimension 3 The near pencil arrangements are always congruence normal. Note, this test just shows there exists a region such that they are CN:: sage: near_pencils = [near_pencil_family(n,'normaliz') for n in range(3,6)] # optional - pynormaliz sage: [ np.is_congruence_normal() for np in near_pencils] # optional - pynormaliz [True, True, True] TESTS: Test that the backend is normaliz:: sage: np = near_pencil_family(3,'normaliz'); # optional - pynormaliz sage: np.backend() # optional - pynormaliz 'normaliz' """ z = QQbar.zeta(2 * n) vecs = [[(z**k).real(), (z**k).imag(), 0] for k in range(1, n)] vecs += [vector([0, -1, 1])] return VectorConfiguration(vecs, backend=backend)
def right_triangle(angle,leg0=None, leg1=None, hypotenuse=None): r""" Return a right triangle in a numberfield with an angle of pi*m/n. You can specify the length of the first leg (leg0), the second leg (leg1), or the hypotenuse. """ from sage.rings.qqbar import QQbar z=QQbar.zeta(2*angle.denom())**angle.numer() c = z.real() s = z.imag() if not leg0 is None: c,s = leg0*c/c,leg0*s/c elif not leg1 is None: c,s = leg1*c/s,leg1*s/s elif not hypotenuse is None: c,s = hypotenuse*c, hypotenuse*s field, (c,s) = number_field_elements_from_algebraics((c,s)) return Polygons(field)(edges=[(c,field.zero()),(field.zero(),s),(-c,-s)])