DeRhamComputation/deRhamComputation.ipynb

48 KiB
Raw Blame History

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 above forms along with $$\lambda_{ij} = \left[ \left( \frac{\psi_{ij} , dx}{m x^{i+1} y^{m - j}}, \frac{-\phi_{ij} , dx}{m x^{i+1} y^{m - j}}, \frac{y^j}{x^i} \right) \right]$$ (where $s_{ij} = jx f'(x) - mi f(x)$, $\psi_{ij}(x) = s_{ij}^{\ge i+1}$, $\phi_{ij}(x) = s_{ij}^{< i+1}$) form a basis of $H^1_{dR}(C/K)$.

# 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.
# [f(x) dx/y^j, y^(m-j)*g(x)]. 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):
    print(elt, 'czy w dr', czy_w_de_rhamie(elt, m, f, j, p))
    R.<x> = PolynomialRing(GF(p))
    RR = FractionField(R)
    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:
        print('p1')
        return zapis
    
    if elt[1] == 0:
        print('p2')
        elt[0] = R(elt[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]
    a = wspolczynnik_wiodacy(g)
    d = -stopien_roznica(g)
    Rr = r/delta
    Mm = m/delta
    
    stopnie2 = stopnie_drugiej_wspolrzednej_bazy_dr(m, f, j, p)
    inv_stopnie2 = {v: k for k, v in stopnie2.items()}      
    print('d', d, 'a', a, 'dostepne:', stopnie2, 'czy w stopnie 2', d not in stopnie2)
    if (d not in stopnie2.values()):
        print('p3')
        if d>= 0:
            print('p3a')
            j1 = m-j
            print('?', -j1*Rr+d*Mm)
            elt1 = [elt[0], RR(elt[1]) - a*1/R(x^d)]
        else:
            print('p3b')
            d1 = -d
            j1 = m-j
            elt1 = [elt[0] - a*(j1*x^(d1) * f.derivative()/m + d1*f*x^(d1 - 1)), RR(elt[1]) - a*R(x^(d1))]
        return zapis_w_bazie_dr(elt1, m, f, j, p)
    
    print('p4')
    k = inv_stopnie2[d]
    b = wspolczynnik_wiodacy(baza[k][1])
    print('k', k, 'a', a)
    elt1 = [R(0), R(0)]
    elt1[0] = elt[0] - a/b*baza[k][0]
    elt1[1] = elt[1] - a/b*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))])

We have: $V(\omega, f) = (C(\omega), 0)$ and $F(\omega, f) = (0, f^p)$, where C denotes the Cartier operator. Moreover:

let $t = multord_m(p)$, $M := (p^t - 1)/m$. Then: $y^{p^t - 1} = f(x)^M$ and $1/y = f(x)^M/y^{p^t}$. Thus:

$$ C(P(x) , dx / y^j) = C(P(x) , f(x)^{M \cdot j} , dx /y^{p^t \cdot j}) = \frac{1}{y^{p^{t - 1} \cdot j}} C(P(x) , f(x)^{M \cdot j} , dx) = \frac{1}{y^{(p^{t - 1} \cdot j) , mod , m}} \cdot \frac{1}{f(x)^{[p^{t - 1} \cdot j/m]}} \cdot C(P(x) , f(x)^{M \cdot j} , dx)$$

def czesc_wielomianu(p, h):
    R.<x> = PolynomialRing(GF(p))
    h = R(h)
    wynik = R(0)
    for i in range(0, h.degree()+1):
        if (i%p) == p-1:
            potega = Integer((i-(p-1))/p)
            wynik = wynik + Integer(h[i]) * x^(potega)    
    return wynik

def cartier_dr(p, m, f, elt, j): #Cartier na y^m = f dla elt = [forma rozniczkowa, fkcja]
    R.<x> = PolynomialRing(GF(p))
    f = R(f)
    r = f.degree()
    delta = GCD(m, r)
    rzad = Integers(m)(p).multiplicative_order()
    M = Integer((p^(rzad)-1)/m)
    W = R(elt[0])
    h = R(W*f^(M*j))
    B = floor(p^(rzad-1)*j/m)
    g = czesc_wielomianu(p, h)/f^B
    jj = (p^(rzad-1)*j)%m
    #jj = Integers(m)(j/p)
    return [g, 0] #jest to w czesci indeksowanej jj

def macierz_cartier_dr(p, m, f, j):
    baza = baza_dr(m, f, j, p)
    A = matrix(GF(p), len(baza), len(baza))
    for k in range(0, len(baza)):
        cart = cartier_dr(p, m, f, baza[k], j)
        v = zapis_w_bazie_dr(cart, m, f, j, p)
        A[k, :] = matrix(v)
    return A.transpose()

$F((\omega, P(x) \cdot y^j)) = (0, P(x)^p \cdot y^{p \cdot j}) = (0, P(x)^p \cdot f(x)^{[p \cdot j/m]} \cdot y^{(p \cdot j) , mod , m})$

def frobenius_dr(p, m, f, elt, j): #Cartier na y^m = f dla elt = [forma rozniczkowa, fkcja]
    R.<x> = PolynomialRing(GF(p))
    RR = FractionField(R)
    f = R(f)
    j1 = m-j
    M = floor(j1*p/m)
    return [0, f^M * RR(elt[1])^p] #eigenspace = j1*p mod m

def macierz_frob_dr(p, m, f, j):
    baza = baza_dr(m, f, j, p)
    A = matrix(GF(p), len(baza), len(baza))
    for k in range(0, len(baza)):
        frob = frobenius_dr(p, m, f, baza[k], j)
        v = zapis_w_bazie_dr(frob, m, f, j, p)
        A[k, :] = matrix(v)
    return A.transpose()

def wspolczynnik_wiodacy(f):
    R.<x> = PolynomialRing(GF(p))
    RR = FractionField(R)
    f = RR(f)
    f1 = f.numerator()
    f2 = f.denominator()
    d1 = f1.degree()
    d2 = f2.degree()
    a1 = f1.coefficients(sparse = false)[d1]
    a2 = f2.coefficients(sparse = false)[d2]
    return(a1/a2)

def stopien_roznica(f):
    R.<x> = PolynomialRing(GF(p))
    RR = FractionField(R)
    f = RR(f)
    f1 = f.numerator()
    f2 = f.denominator()
    d1 = f1.degree()
    d2 = f2.degree()
    return(d1 - d2)

def czy_w_de_rhamie(elt, m, f, j, p):
    j1 = m - j
    R.<x> = PolynomialRing(GF(p))
    RR = FractionField(R)
    f = R(f)
    elt = [RR(elt[0]), RR(elt[1])]
    auxiliary = elt[0] - j1/m*elt[1]*f.derivative() - f*elt[1].derivative()
    deg = stopien_roznica(auxiliary)
    
    r = f.degree()
    delta = GCD(r, m)
    Rr = r/delta
    Mm = m/delta
    return(j*Rr - deg*Mm >= 0)
m = 2
j = 1
p = 5
f = x^3 + x+3
print(baza_dr(m, f, j, p))
macierz_frob_dr(p, m, f, j)
{0: [1, 0], 1: [x, 2/x]}
[0, 0] czy w dr True
p1
[0, (2*x^6 + 4*x^4 + 2*x^3 + 2*x^2 + 2*x + 3)/x^5] czy w dr True
d -1 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
[2*x + 4, (4*x^4 + 2*x^3 + 2*x^2 + 2*x + 3)/x^5] czy w dr True
d 1 a 4 dostepne: {1: 1} czy w stopnie 2 False
p4
k 1 a 4
[4, (2*x^3 + 2*x^2 + 2*x + 3)/x^5] czy w dr True
d 2 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
? 1
[4, (2*x^2 + 2*x + 3)/x^5] czy w dr True
d 3 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
? 3
[4, (2*x + 3)/x^5] czy w dr True
d 4 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
? 5
[4, 3/x^5] czy w dr True
d 5 a 3 dostepne: {1: 1} czy w stopnie 2 True
p3
? 7
[4, 0] czy w dr True
p2
[0, 0] czy w dr True
p1
[0 4]
[0 4]
frobenius_dr(p, m, f, [x, 2/x], j)
[0, (2*x^6 + 4*x^4 + 2*x^3 + 2*x^2 + 2*x + 3)/x^5]
zapis_w_bazie_dr([0, (2*x^6 + 4*x^4 + 2*x^3 + 2*x^2 + 2*x + 3)/x^5], m, f, j, p)
[0, (2*x^6 + 4*x^4 + 2*x^3 + 2*x^2 + 2*x + 3)/x^5] czy w dr True
d -1 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
[2*x + 4, (4*x^4 + 2*x^3 + 2*x^2 + 2*x + 3)/x^5] czy w dr True
d 1 a 4 dostepne: {1: 1} czy w stopnie 2 False
p4
k 1 a 4
[4, (2*x^3 + 2*x^2 + 2*x + 3)/x^5] czy w dr True
d 2 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
? 1
[4, (2*x^2 + 2*x + 3)/x^5] czy w dr True
d 3 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
? 3
[4, (2*x + 3)/x^5] czy w dr True
d 4 a 2 dostepne: {1: 1} czy w stopnie 2 True
p3
? 5
[4, 3/x^5] czy w dr True
d 5 a 3 dostepne: {1: 1} czy w stopnie 2 True
p3
? 7
[4, 0] czy w dr True
p2
[0, 0] czy w dr True
p1
(4, 4)
h = sum(i*x^i for i in range(0, p^2))
czesc_wielomianu(p, h)
4*x^4 + 4*x^3 + 4*x^2 + 4*x + 4
m = 4
j = 1
p = 5
f = x^3 + x+2
print(baza_dr(m, f, j, p))
print(stopnie_drugiej_wspolrzednej_bazy_dr(m, f, j, p))
t = stopnie_drugiej_wspolrzednej_bazy_dr(m, f, j, p)
1 in t.values()
{0: [0, 4/x], 1: [1, 4/x^2]}
{0: 1, 1: 2}
True
macierz_frob_dr(p, m, f, 1)
[0, (4*x^9 + 2*x^7 + 4*x^6 + 2*x^5 + 3*x^4 + 2*x^3 + 4*x^2 + 3*x + 2)/x^5] czy w dr True
d -4 a 4 dostepne: {0: 1, 1: 2} czy w stopnie 2 True
p3
p3b
[x^4 + 3*x^3, (2*x^7 + 4*x^6 + 2*x^5 + 3*x^4 + 2*x^3 + 4*x^2 + 3*x + 2)/x^5] czy w dr True
d -2 a 2 dostepne: {0: 1, 1: 2} czy w stopnie 2 True
p3
p3b
[3*x^3 + 2*x^2 + 2*x, (4*x^6 + 2*x^5 + 3*x^4 + 2*x^3 + 4*x^2 + 3*x + 2)/x^5] czy w dr True
d -1 a 4 dostepne: {0: 1, 1: 2} czy w stopnie 2 True
p3
p3b
[2*x^2 + 2, (2*x^5 + 3*x^4 + 2*x^3 + 4*x^2 + 3*x + 2)/x^5] czy w dr True
d 0 a 2 dostepne: {0: 1, 1: 2} czy w stopnie 2 False
p3
p3a
? -9
[2*x^2 + 2, (3*x^4 + 2*x^3 + 4*x^2 + 3*x + 2)/x^5] czy w dr False
d 1 a 3 dostepne: {0: 1, 1: 2} czy w stopnie 2 False
p4
k 0 a 3
[2*x^2 + 2, (2*x^3 + 4*x^2 + 3*x + 2)/x^5] czy w dr False
d 2 a 2 dostepne: {0: 1, 1: 2} czy w stopnie 2 True
p4
k 1 a 2
[2*x^2 + 4, (4*x^2 + 3*x + 2)/x^5] czy w dr False
d 3 a 4 dostepne: {0: 1, 1: 2} czy w stopnie 2 True
p3
p3a
? 3
[2*x^2 + 4, (3*x + 2)/x^5] czy w dr False
d 4 a 3 dostepne: {0: 1, 1: 2} czy w stopnie 2 True
p3
p3a
? 7
[2*x^2 + 4, 2/x^5] czy w dr False
d 5 a 2 dostepne: {0: 1, 1: 2} czy w stopnie 2 True
p3
p3a
? 11
[2*x^2 + 4, 0] czy w dr False
p2
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-141-86a3d5ca17ee> in <module>()
----> 1 macierz_frob_dr(p, m, f, Integer(1))

<ipython-input-132-3ef6f7d47fcd> in macierz_frob_dr(p, m, f, j)
     12     for k in range(Integer(0), len(baza)):
     13         frob = frobenius_dr(p, m, f, baza[k], j)
---> 14         v = zapis_w_bazie_dr(frob, m, f, j, p)
     15         A[k, :] = matrix(v)
     16     return A.transpose()

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     85             j1 = m-j
     86             elt1 = [elt[Integer(0)] - a*(j1*x**(d1) * f.derivative()/m + d1*f*x**(d1 - Integer(1))), RR(elt[Integer(1)]) - a*R(x**(d1))]
---> 87         return zapis_w_bazie_dr(elt1, m, f, j, p)
     88 
     89     print('p4')

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     85             j1 = m-j
     86             elt1 = [elt[Integer(0)] - a*(j1*x**(d1) * f.derivative()/m + d1*f*x**(d1 - Integer(1))), RR(elt[Integer(1)]) - a*R(x**(d1))]
---> 87         return zapis_w_bazie_dr(elt1, m, f, j, p)
     88 
     89     print('p4')

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     85             j1 = m-j
     86             elt1 = [elt[Integer(0)] - a*(j1*x**(d1) * f.derivative()/m + d1*f*x**(d1 - Integer(1))), RR(elt[Integer(1)]) - a*R(x**(d1))]
---> 87         return zapis_w_bazie_dr(elt1, m, f, j, p)
     88 
     89     print('p4')

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     85             j1 = m-j
     86             elt1 = [elt[Integer(0)] - a*(j1*x**(d1) * f.derivative()/m + d1*f*x**(d1 - Integer(1))), RR(elt[Integer(1)]) - a*R(x**(d1))]
---> 87         return zapis_w_bazie_dr(elt1, m, f, j, p)
     88 
     89     print('p4')

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     94     elt1[Integer(0)] = elt[Integer(0)] - a/b*baza[k][Integer(0)]
     95     elt1[Integer(1)] = elt[Integer(1)] - a/b*baza[k][Integer(1)]
---> 96     return zapis_w_bazie_dr(elt1, m, f, j, p) + vector([a*GF(p)(i == k) for i in range(Integer(0), len(baza))])
     97 
     98 

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     94     elt1[Integer(0)] = elt[Integer(0)] - a/b*baza[k][Integer(0)]
     95     elt1[Integer(1)] = elt[Integer(1)] - a/b*baza[k][Integer(1)]
---> 96     return zapis_w_bazie_dr(elt1, m, f, j, p) + vector([a*GF(p)(i == k) for i in range(Integer(0), len(baza))])
     97 
     98 

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     85             j1 = m-j
     86             elt1 = [elt[Integer(0)] - a*(j1*x**(d1) * f.derivative()/m + d1*f*x**(d1 - Integer(1))), RR(elt[Integer(1)]) - a*R(x**(d1))]
---> 87         return zapis_w_bazie_dr(elt1, m, f, j, p)
     88 
     89     print('p4')

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     85             j1 = m-j
     86             elt1 = [elt[Integer(0)] - a*(j1*x**(d1) * f.derivative()/m + d1*f*x**(d1 - Integer(1))), RR(elt[Integer(1)]) - a*R(x**(d1))]
---> 87         return zapis_w_bazie_dr(elt1, m, f, j, p)
     88 
     89     print('p4')

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     85             j1 = m-j
     86             elt1 = [elt[Integer(0)] - a*(j1*x**(d1) * f.derivative()/m + d1*f*x**(d1 - Integer(1))), RR(elt[Integer(1)]) - a*R(x**(d1))]
---> 87         return zapis_w_bazie_dr(elt1, m, f, j, p)
     88 
     89     print('p4')

<ipython-input-140-9ce96c4e8631> in zapis_w_bazie_dr(elt, m, f, j, p)
     56         d = elt[Integer(0)].degree()
     57         a = elt[Integer(0)].coefficients(sparse = false)[d]
---> 58         k = inv_stopnie_holo[d] #ktory element bazy jest stopnia d? ten o indeksie k
     59 
     60         a1 = baza[k][Integer(0)].coefficients(sparse = false)[d]

KeyError: 2
wspolczynnik_wiodacy(2/x)
2
(2/x).degree()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-97-2687f469fb6b> in <module>()
----> 1 (Integer(2)/x).degree()

TypeError: degree() takes exactly one argument (0 given)