import numberdb.sage as numberdb # initialize Sage before named imports
from math import factorial, prod
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.rational_field import QQ
def bernoulli_plus(n):
values = [QQ(0)] * (n + 1)
for m in range(n + 1):
values[m] = QQ(1) / QQ(m + 1)
for j in range(m, 0, -1):
values[j - 1] = QQ(j) * (values[j - 1] - values[j])
return values[0]
def log_q_coefficient(m):
if m == 1:
return QQ(1) / QQ(2)
if m % 2:
return QQ(0)
return -bernoulli_plus(m) / QQ(m * factorial(m))
def weight(exponents):
return sum((i + 1) * exponent for i, exponent in enumerate(exponents))
def monomial(parent, variables, exponents):
return parent(prod(variables[i] ** exponent
for i, exponent in enumerate(exponents)))
def weighted_terms(polynomial, degree, exact):
parent = polynomial.parent()
variables = parent.gens()
total = parent(0)
for exponents, coeff in polynomial.dict().items():
term_weight = weight(exponents)
if (exact and term_weight == degree) or (not exact and term_weight <= degree):
total += coeff * monomial(parent, variables, exponents)
return total
def todd_component(n):
R = PolynomialRing(QQ, ["c%s" % i for i in range(1, n + 1)])
c = R.gens()
power_sums = {}
for m in range(1, n + 1):
p_m = sum(((-1) ** (i + 1) * c[i - 1] * power_sums[m - i]
for i in range(1, m)), R(0))
power_sums[m] = p_m + (-1) ** (m + 1) * m * c[m - 1]
exponent = sum((log_q_coefficient(m) * power_sums[m]
for m in range(1, n + 1)), R(0))
total = R(1)
term = R(1)
for k in range(1, n + 1):
term = weighted_terms(term * exponent / QQ(k), n, False)
total = weighted_terms(total + term, n, False)
return weighted_terms(total, n, True)
print(todd_component(8))Every stored component was checked against the terms printed in [1] and [2], and by substituting the Chern classes of $T\mathbb P^m$ for $1\leq m\leq7$, which gives Todd genus $1$ [2].
The generator computes exact rational coefficients from Formula (1).