DeRhamComputation/deRhamComputation.ipynb

7.4 KiB

Theory

Let $C : y^m = f(x)$. Then:

  • the basis of $H^0(C, \Omega_{C/k})$ is given by: $$x^{i-1} dx/y^j,$$ where $1 \le i \le r-1$, $1 \le j \le m-1$, $-mi + rj \ge \delta$ and $\delta := GCD(m, r)$, $r := \deg f$.

# The program computes the basis of holomorphic differentials of y^m = f(x) in char p.
# The coefficient j means that we compute the j-th eigenpart, i.e.
# forms y^j * f(x) dx. Output is [f(x), 0]

def baza_holo(m, f, j, p):
    R.<x> = PolynomialRing(GF(p))
    f = R(f)
    r = f.degree()
    delta = GCD(m, r)
    baza = {}
    k = 0
    for i in range(1, r):
        if (r*j - m*i >= delta):
            baza[k] = [x^(i-1), R(0)]
            k = k+1
    return baza
# The program computes the basis of de Rham cohomology of y^m = f(x) in char p.
# We treat them as pairs [omega, f], where omega is regular on the affine part
# and omega - df is regular on the second atlas.
# The coefficient j means that we compute the j-th eigenpart, i.e.
# [y^j * f(x) dx, g(x)/y^j]. Output is [f(x), g(x)]

def baza_dr(m, f, j, p):
    R.<x> = PolynomialRing(GF(p))
    f = R(f)    
    r = f.degree()
    delta = GCD(m, r)
    baza = {}
    holo = baza_holo(m, f, j, p)
    for k in range(0, len(holo)):
        baza[k] = holo[k]
    
    k = len(baza)
    
    for i in range(1, r):
        if (r*(m-j) - m*i >= delta):
            s = R(m-j)*R(x)*R(f.derivative()) - R(m)*R(i)*f
            psi = R(obciecie(s, i, p))
            baza[k] = [psi, R(m)/x^i]
            k = k+1
    return baza
#auxiliary programs
def stopnie_bazy_holo(m, f, j, p):
    baza = baza_holo(m, f, j, p)
    stopnie = {}
    for k in range(0, len(baza)):
        stopnie[k] = baza[k][0].degree()
    return stopnie

def stopnie_bazy_dr(m, f, j, p):
    baza = baza_dr(m, f, j, p)
    stopnie = {}
    for k in range(0, len(baza)):
        stopnie[k] = baza[k][0].degree()
    return stopnie

def stopnie_drugiej_wspolrzednej_bazy_dr(m, f, j, p):
    baza = baza_dr(m, f, j, p)
    stopnie = {}
    for k in range(0, len(baza)):
        if baza[k][1] != 0:
            stopnie[k] = baza[k][1].denominator().degree()
    return stopnie

def obciecie(f, i, p):
    R.<x> = PolynomialRing(GF(p))
    f = R(f)
    coeff = f.coefficients(sparse = false)
    return sum(x^(j-i-1) * coeff[j] for j in range(i+1, f.degree() + 1))


#Any element [f dx, g] is represented as a combination of the basis vectors.

def zapis_w_bazie_dr(elt, m, f, j, p):
    R.<x> = PolynomialRing(GF(p))
    f = R(f)    
    r = f.degree()
    delta = GCD(m, r)
    baza = baza_dr(m, f, j, p)
    wymiar = len(baza)
    zapis = vector([GF(p)(0) for i in baza])
    stopnie = stopnie_bazy_dr(m, f, j, p)
    inv_stopnie = {v: k for k, v in stopnie.items()}
    stopnie_holo = stopnie_bazy_holo(m, f, j, p)
    inv_stopnie_holo = {v: k for k, v in stopnie_holo.items()}    
    
    ## zmiana
    if elt[0]== 0 and elt[1] == 0:
        return zapis
    
    if elt[1] == 0:
        d = elt[0].degree()
        a = elt[0].coefficients(sparse = false)[d]
        k = inv_stopnie_holo[d] #ktory element bazy jest stopnia d? ten o indeksie k
    
        a1 = baza[k][0].coefficients(sparse = false)[d]
        elt1 = [R(0),R(0)]
        elt1[0] = elt[0] - a/a1 * baza[k][0]
        elt1[1] = R(0)
        return zapis_w_bazie_dr(elt1, m, f, j, p) + vector([a/a1*GF(p)(i == k) for i in range(0, len(baza))])

    g = elt[1]
    g1 = R(elt[1].numerator())
    g2 = R(elt[1].denominator())
    d1 = g1.degree()
    d2 = g2.degree()
    a1 = g1.coefficients(sparse = false)[d1]
    a2 = g2.coefficients(sparse = false)[d2]
    a = a1/a2
    d = d2 - d1
    
    if (d*m - (m-j)*r >= 0):
        elt1 = [R(0), R(0)]
        elt1[0] = elt[0]
        return zapis_w_bazie_dr(elt1, m, f, j, p)
    
    
    stopnie2 = stopnie_drugiej_wspolrzednej_bazy_dr(m, f, j, p)
    inv_stopnie2 = {v: k for k, v in stopnie2.items()}  
    k = inv_stopnie2[d]
    elt1 = [R(0), R(0)]
    elt1[0] = elt[0] - a*baza[k][0]
    elt1[1] = elt[1] - a*baza[k][1]
    return zapis_w_bazie_dr(elt1, m, f, j, p) + vector([a*GF(p)(i == k) for i in range(0, len(baza))])
    
    
def zapis_w_bazie_holo(elt, m, f, j, p):
    R.<x> = PolynomialRing(GF(p))
    f = R(f)    
    r = f.degree()
    delta = GCD(m, r)
    baza = baza_holo(m, f, j, p)
    wymiar = len(baza)
    zapis = vector([GF(p)(0) for i in baza])
    stopnie = stopnie_bazy_holo(m, f, j, p)
    inv_stopnie = {v: k for k, v in stopnie.items()}
    
    if elt[0] == 0:
        return zapis
    
    d = elt[0].degree()
    a = elt[0].coefficients(sparse = false)[d]
    
    k = inv_stopnie[d] #ktory element bazy jest stopnia d? ten o indeksie k
    
    a1 = baza[k][0].coefficients(sparse = false)[d]
    elt1 = [R(0),R(0)]
    elt1[0] = elt[0] - a/a1 * baza[k][0]
    
    return zapis_w_bazie_holo(elt1, m, f, j, p) + vector([a/a1 * GF(p)(i == k) for i in range(0, len(baza))])
baza_dr(2, x^3 + 1, 0, 3)
{0: [x, 2/x], 1: [2, 2/x^2]}