def compact_form(p): """ Given a palindromic polynomial p(x) of degree 2n, return a polynomial g so that p(x) = x^n g(x + 1/x). """ assert is_palindromic(p) and p.degree() % 2 == 0 R = p.parent() x = R.gen() f, g = p, R(0) while f != 0: c = f.leading_coefficient() assert f.degree() % 2 == 0 d = f.degree() // 2 g += c * x**d f = (f - c * (x**2 + 1)**d) if f != 0: e = min(f.exponents()) assert e > 0 and f % x**e == 0 f = f // x**e # Double check L = LaurentPolynomialRing(R.base_ring(), repr(x)) y = L.gen() assert p == y**(p.degree() // 2) * g(y + 1 / y) return g
def induced_rep_from_twisted_cocycle(p, rho, chi, cocycle): """ The main metabelian representation from Section 7 of [HKL] for the group of a knot complement, where p is the degree of the branched cover, rho is an irreducible cyclic representation acting on the F_q vector space V, chi is a homomorpism V -> F_q, and cocycle describes the semidirect product extension. We differ from [HKL] in that all actions are on the left, meaning that this representation is defined in terms of the convention for the semidirect product discussed in:: MatrixRepresentation.semidirect_rep_from_twisted_cocycle Here is an example:: sage: G = Manifold('K12n132').fundamental_group() sage: A = matrix(GF(5), [[0, 4], [1, 4]]) sage: rho = cyclic_rep(G, A) sage: cocycle = (0, 0, 0, 1, 1, 2) sage: chi = lambda v: v[0] + 4*v[1] sage: rho_ind = induced_rep_from_twisted_cocycle(3, rho, chi, cocycle) sage: rho_ind('c').list() [0, 0, (-z^3 - z^2 - z - 1), z^2*t^-1, 0, 0, 0, (-z^3 - z^2 - z - 1)*t^-1, 0] """ q = rho.base_ring.order() n = rho.dim K = CyclotomicField(q, 'z') z = K.gen() A = rho.A R = LaurentPolynomialRing(K, 't') t = R.gen() MatSp = MatrixSpace(R, p) gens = rho.generators images = dict() for s, g in enumerate(gens): v = vector(cocycle[s * n:(s + 1) * n]) e = rho.epsilon(g)[0] U = MatSp(0) for j in range(0, p): k, l = (e + j).quo_rem(p) U[l, j] = t**k * z**chi(A**(-l) * v) images[g] = U e, v = -e, -A**(-e) * v V = MatSp(0) for j in range(0, p): k, l = (e + j).quo_rem(p) V[l, j] = t**k * z**chi(A**(-l) * v) images[g.swapcase()] = V alpha = MatrixRepresentation(gens, rho.relators, MatSp, images) alpha.epsilon = rho.epsilon return alpha
def x5_jacobi_pwsr(prec): mx = int(ceil(sqrt(8 * prec) / QQ(2)) + 1) mn = int(floor(-(sqrt(8 * prec) - 1) / QQ(2))) mx1 = int(ceil((sqrt(8 * prec + 1) - 1) / QQ(2)) + 1) mn1 = int(floor((-sqrt(8 * prec + 1) - 1) / QQ(2))) R = LaurentPolynomialRing(QQ, names="t") t = R.gens()[0] S = PowerSeriesRing(R, names="q1") q1 = S.gens()[0] eta_3 = sum([QQ(-1) ** n * (2 * n + 1) * q1 ** (n * (n + 1) // 2) for n in range(mn1, mx1)]) + bigO(q1 ** (prec + 1)) theta = sum([QQ(-1) ** n * q1 ** (((2 * n + 1) ** 2 - 1) // 8) * t ** (n + 1) for n in range(mn, mx)]) # ct = qexp_eta(ZZ[['q1']], prec + 1) return theta * eta_3 ** 3 * QQ(8) ** (-1)
def rings1(): """ Return an iterator over random rings. Return a list of pairs (f, desc), where f is a function that outputs a random ring that takes a ring and possibly some other data as constructor. RINGS: - polynomial ring in one variable over a rings0() ring. - polynomial ring over a rings1() ring. - multivariate polynomials - power series rings in one variable over a rings0() ring. EXAMPLES:: sage: import sage.rings.tests sage: type(sage.rings.tests.rings0()) <... 'list'> """ v = rings0() X = random_rings(level=0) from sage.all import (PolynomialRing, PowerSeriesRing, LaurentPolynomialRing, ZZ) v = [(lambda: PolynomialRing(next(X), names='x'), 'univariate polynomial ring over level 0 ring'), (lambda: PowerSeriesRing(next(X), names='x'), 'univariate power series ring over level 0 ring'), (lambda: LaurentPolynomialRing(next(X), names='x'), 'univariate Laurent polynomial ring over level 0 ring'), (lambda: PolynomialRing(next(X), abs(ZZ.random_element(x=2, y=10)), names='x'), 'multivariate polynomial ring in between 2 and 10 variables over a level 0 ring')] return v
def jones_polynomial_of_sage(knot): """ To match our conventions (which seem to agree with KnotAtlas), we need to swap q and 1/q. """ q = LaurentPolynomialRing(ZZ, 'q').gen() p = knot.jones_polynomial(skein_normalization=True) exps = p.exponents() assert all(e % 4 == 0 for e in exps) return sum(c * q**(-e // 4) for c, e in zip(p.coefficients(), exps))
class MapToGroupRingOfFreeAbelianization(MapToFreeAbelianization): def __init__(self, fund_group, base_ring=ZZ): MapToFreeAbelianization.__init__(self, fund_group) n = self.elementary_divisors.count(0) self.R = LaurentPolynomialRing(base_ring, list(string.ascii_lowercase[:n])) def range(self): return self.R def __call__(self, word): v = MapToFreeAbelianization.__call__(self, word) return prod([g**v[i] for i, g in enumerate(self.R.gens())])
def __init__(self, fund_group, base_ring=ZZ): MapToFreeAbelianization.__init__(self, fund_group) n = self.elementary_divisors.count(0) self.R = LaurentPolynomialRing(base_ring, list(string.ascii_lowercase[:n]))
""" Conventions follow Jake's lectures at PCMI, Summer 2019. """ from sage.all import ZZ, LaurentPolynomialRing, PerfectMatchings, PerfectMatching import exhaust from spherogram import Link import snappy R = LaurentPolynomialRing(ZZ, 'q') q = R.gen() def num_Pn(n): """ An element of Jake's P_{0, n} of planar tangles from 0 points to n points will be a PerfectMatching of [0,..,n-1] where is_noncrossing is True. """ return len([m for m in PerfectMatchings(n) if m.is_noncrossing()]) def insert_cup(matching, i): """ Insert a new adjacent matching which joins i and i + 1. >>> m = PerfectMatching([(0, 1), (2, 5), (3, 4)]) >>> insert_cup(m, 0) [(0, 1), (2, 3), (4, 7), (5, 6)] >>> insert_cup(m, 1) [(0, 3), (1, 2), (4, 7), (5, 6)]