Changeset 4146:fef02f066f8b
- Timestamp:
- 04/20/07 13:06:35 (6 years ago)
- Branch:
- default
- File:
-
- 1 edited
-
sage/schemes/elliptic_curves/monsky_washnitzer.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sage/schemes/elliptic_curves/monsky_washnitzer.py
r4143 r4146 2015 2015 2016 2016 from sage.misc.profiler import Profiler 2017 from sage.misc.misc import repr_lincomb 2017 2018 2018 2019 def matrix_of_frobenius_general(Q, p, prec): … … 2022 2023 extra_prec_ring = Integers(p**M) # pAdicField(p, M) # SLOW! 2023 2024 real_prec_ring = Integers(p**prec) # pAdicField(p, prec) # To capped absolute? 2024 S = SpecialHyperellipticQuotientRing(Q, extra_prec_ring, p, True) 2025 S = SpecialHyperellipticQuotientRing_2(Q, extra_prec_ring, p, True) 2026 # S = SpecialHyperellipticQuotientRing(Q, extra_prec_ring, p, True) 2025 2027 MW = S.monsky_washnitzer() 2026 2028 prof("frob basis elements") … … 2032 2034 M = M.change_ring(pAdicField(p, prec)) 2033 2035 print prof 2034 print len(S._monomials)2036 # print len(S._monomials) 2035 2037 return M.transpose() 2038 2039 2040 2041 2042 2043 2044 class SpecialHyperellipticQuotientRing_2(CommutativeAlgebra): 2045 def __init__(self, Q, R, p, invert_y=False): 2046 CommutativeAlgebra.__init__(self, R) 2047 self._p = p 2048 2049 x = PolynomialRing(R, 'x').gen(0) 2050 if is_EllipticCurve(Q): 2051 E = Q 2052 if E.a1() != 0 or E.a2() != 0: 2053 raise NotImplementedError, "Curve must be in Weierstrass normal form." 2054 Q = E.defining_polynomial()(x,0,1) 2055 2056 elif is_HyperellipticCurve(Q): 2057 C = Q 2058 if C.hyperelliptic_polynomials()[1] != 0: 2059 raise NotImplementedError, "Curve must be of form y^2 = Q(x)." 2060 Q = E.hyperelliptic_polynomials()[0]()(x) 2061 2062 if is_Polynomial(Q): 2063 self._Q = Q.change_ring(R) 2064 self._coeffs = self._Q.coeffs() 2065 if self._coeffs.pop() != 1: 2066 raise NotImplementedError, "Polynomial must be monic." 2067 2068 else: 2069 raise NotImplementedError, "Must be an elliptic curve or polynomial Q for y^2 = Q(x)" 2070 2071 self._n = degree = int(Q.degree()) 2072 2073 self._series_ring = (LaurentSeriesRing if invert_y else PolynomialRing)(R, 'y') 2074 self._series_ring_y = self._series_ring.gen(0) 2075 self._series_ring_0 = self._series_ring(0) 2076 2077 self._poly_ring = PolynomialRing(self._series_ring, 'x') 2078 2079 self._x = self(self._poly_ring.gen(0)) 2080 self._y = self(self._series_ring.gen(0)) 2081 2082 self._dQ = Q.derivative().change_ring(self)(self._x) 2083 self._monsky_washnitzer = MonskyWashnitzerDifferentialRing(self) 2084 2085 2086 def __call__(self, val): 2087 if isinstance(val, SpecialHyperellipticQuotientElement_2) and val.parent() is self: 2088 return val 2089 return SpecialHyperellipticQuotientElement_2(self, val) 2090 2091 def gens(self): 2092 return self._x, self._y 2093 2094 def x(self): 2095 return self._x 2096 2097 def y(self): 2098 return self._y 2099 2100 def monomial(self, i, j, b=None): 2101 """ 2102 Returns $b y^j x^i$, computed quickly. 2103 """ 2104 i = int(i) 2105 j = int(j) 2106 2107 if 0 < i and i < self._n: 2108 if b is None: 2109 by_to_j = self._series_ring_y << (j-1) 2110 else: 2111 by_to_j = self._series_ring(b) << j 2112 v = [self._series_ring_0] * self._n 2113 v[i] = by_to_j 2114 return self(v) 2115 else: 2116 return (self._x ** i) << j if b is None else self.base_ring()(b) * (self._x ** i) << j 2117 2118 def Q(self): 2119 return self._Q 2120 2121 def degree(self): 2122 return self._n 2123 2124 def prime(self): 2125 return self._p 2126 2127 def monsky_washnitzer(self): 2128 return self._monsky_washnitzer 2129 2130 def is_field(self): 2131 return False 2132 2133 2134 2135 class SpecialHyperellipticQuotientElement_2(CommutativeAlgebraElement): 2136 2137 def __init__(self, parent, val=0): 2138 CommutativeAlgebraElement.__init__(self, parent) 2139 self._f = parent._poly_ring(val) 2140 2141 def __invert__(self): 2142 """ 2143 The general element in our ring is not invertible, but y may be. 2144 We do not want to pass to the fraction field. 2145 """ 2146 if self._f.degree() == 0 and self._f[0].is_unit(): 2147 return SpecialHyperellipticQuotientElement_2(self.parent(), ~self._f[0]) 2148 else: 2149 raise ZeroDivisionError, "Element not invertible" 2150 2151 def is_zero(self): 2152 return self._f.is_zero() 2153 2154 def __eq__(self, other): 2155 if not isinstance(other, SpecialHyperellipticQuotientElement_2): 2156 other = self.parent()(other) 2157 return self._f == other._f 2158 2159 def _add_(self, other): 2160 return SpecialHyperellipticQuotientElement_2(self.parent(), self._f + other._f) 2161 2162 def _sub_(self, other): 2163 return SpecialHyperellipticQuotientElement_2(self.parent(), self._f - other._f) 2164 2165 def _mul_(self, other): 2166 prod = self._f * other._f 2167 v = prod.list() 2168 Q_coeffs = self.parent().Q().list() 2169 n = len(Q_coeffs) - 1 2170 y2 = self.parent()._series_ring_y << 1 2171 for i in range(len(v)-1, n-1, -1): 2172 for j in range(n): 2173 v[i-n+j] -= v[i] * Q_coeffs[j] 2174 v[i-n] += v[i] * y2 2175 return SpecialHyperellipticQuotientElement_2(self.parent(), v[0:n]) 2176 2177 def _rmul_(self, c): 2178 return self.parent()([c*a for a in self._f]) 2179 2180 def _lmul_(self, c): 2181 return self.parent()([a*c for a in self._f]) 2182 2183 def __lshift__(self, k): 2184 return self.parent()([a << k for a in self._f]) 2185 2186 def __rshift__(self, k): 2187 return self.parent()([a >> k for a in self._f]) 2188 2189 def _repr_(self): 2190 x = PolynomialRing(QQ, 'x').gen(0) 2191 coeffs = self._f.list() 2192 return repr_lincomb([x**i for i in range(len(coeffs))], coeffs) 2193 2194 def _latex_(self): 2195 x = PolynomialRing(QQ, 'x').gen(0) 2196 coeffs = self._f.list() 2197 return repr_lincomb([x**i for i in range(len(coeffs))], coeffs, is_latex=True) 2198 2199 2200 def diff(self): 2201 2202 # try: 2203 # return self._diff_x 2204 # except AttributeError: 2205 # pass 2206 2207 # d(self) = A dx + B dy 2208 # = (2y A + BQ') dx/2y 2209 parent = self.parent() 2210 R = parent.base_ring() 2211 x, y = parent.gens() 2212 v = self._f.list() 2213 n = len(v) 2214 A = parent([R(i) * v[i] for i in range(1,n)]) 2215 B = parent([a.derivative() for a in v]) 2216 dQ = parent._dQ 2217 return parent._monsky_washnitzer( (R(2) * A << 1) + dQ * B ) 2218 # self._diff = self.parent()._monsky_washnitzer( two_y * A + dQ * B ) 2219 # return self._diff 2220 2221 def extract_pow_y(self, k): 2222 v = [a[k] for a in self._f.list()] 2223 while len(v) < self.parent()._n: 2224 v.append(0) 2225 return v 2226 2227 def min_pow_y(self): 2228 return min([a.valuation() for a in self._f.list()]) 2229 2230 def max_pow_y(self): 2231 return max([a.degree() for a in self._f.list()]) 2232 2036 2233 2037 2234 class SpecialHyperellipticQuotientRing(FreeAlgebraQuotient): … … 2157 2354 def monsky_washnitzer(self): 2158 2355 return self._monsky_washnitzer 2159 2160 2356 2357 2161 2358 class SpecialHyperellipticQuotientElement(FreeAlgebraQuotientElement): 2162 2359 … … 2299 2496 def frob_Q(self): 2300 2497 x_to_p = self.x_to_p() 2301 return self.base_ring()._Q (x_to_p)2498 return self.base_ring()._Q.change_ring(self.base_ring())(x_to_p) 2302 2499 2303 2500 def frob_invariant_differential(self, prec): … … 2326 2523 # We are solving for t = a^{-1/2} = (F_pQ y^{-p})^{-1/2} 2327 2524 # This converges because we know the root is in the same residue class as 1. 2328 t = 12525 t = self.base_ring()(1) 2329 2526 print prec, "->", ceil(log(prec, 2))+1 2330 2527 # for _ in range(prec+1): … … 2455 2652 # reduced -= gg.diff() 2456 2653 g += S.monomial(i, j, lin_comb[i]) 2457 if g.vector() != 0:2654 if not g.is_zero(): 2458 2655 f += g 2459 2656 reduced -= g.diff()
Note: See TracChangeset
for help on using the changeset viewer.
