Path: blob/master/sage/schemes/elliptic_curves/kodaira_symbol.py
4159 views
r"""1Kodaira symbols23Kodaira symbols encode the type of reduction of an elliptic curve at a4(finite) place.56The standard notation for Kodaira Symbols is as a string which is one7of `\rm{I}_m`, `\rm{II}`, `\rm{III}`, `\rm{IV}`, `\rm{I}^*_m`,8`\rm{II}^*`, `\rm{III}^*`, `\rm{IV}^*`, where `m` denotes a9non-negative integer. These have been encoded by single integers by10different people. For convenience we give here the conversion table11between strings, the eclib coding and the PARI encoding.1213+----------------------+----------------+--------------------+14| Kodaira Symbol | Eclib coding | PARI Coding |15+======================+================+====================+16| `\rm{I}_0` | `0` | `1` |17+----------------------+----------------+--------------------+18| `\rm{I}^*_0` | `1` | `-1` |19+----------------------+----------------+--------------------+20| `\rm{I}_m` `(m>0)` | `10m` | `m+4` |21+----------------------+----------------+--------------------+22| `\rm{I}^*_m` `(m>0)` | `10m+1` | `-(m+4)` |23+----------------------+----------------+--------------------+24| `\rm{II}` | `2` | `2` |25+----------------------+----------------+--------------------+26| `\rm{III}` | `3` | `3` |27+----------------------+----------------+--------------------+28| `\rm{IV}` | `4` | `4` |29+----------------------+----------------+--------------------+30| `\rm{II}^*` | `7` | `-2` |31+----------------------+----------------+--------------------+32| `\rm{III}^*` | `6` | `-3` |33+----------------------+----------------+--------------------+34| `\rm{IV}^*` | `5` | `-4` |35+----------------------+----------------+--------------------+363738AUTHORS:3940- David Roe <[email protected]>4142- John Cremona4344"""4546#*****************************************************************************47# Copyright (C) 2007 David Roe <[email protected]>48# William Stein <[email protected]>49#50# Distributed under the terms of the GNU General Public License (GPL)51#52# This code is distributed in the hope that it will be useful,53# but WITHOUT ANY WARRANTY; without even the implied warranty of54# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU55# General Public License for more details.56#57# The full text of the GPL is available at:58#59# http://www.gnu.org/licenses/60#*****************************************************************************6162from sage.structure.sage_object import SageObject63from sage.rings.integer import Integer64import weakref6566class KodairaSymbol_class(SageObject):67r"""68Class to hold a Kodaira symbol of an elliptic curve over a69`p`-adic local field.7071Users should use the ``KodairaSymbol()`` function to construct72Kodaira Symbols rather than use the class constructor directly.73"""74def __init__(self, symbol):75r"""76Constructor for Kodaira Symbol class.7778INPUT:7980- ``symbol`` (string or integer) -- The string should be a81standard string representation (e.g. III*) of a Kodaira82symbol, which will be parsed. Alternatively, use the PARI83encoding of Kodaira symbols as integers.8485EXAMPLES::8687sage: from sage.schemes.elliptic_curves.kodaira_symbol import KodairaSymbol_class88sage: KodairaSymbol_class(14)89I1090sage: KodairaSymbol_class('III*')91III*92sage: latex(KodairaSymbol_class('In'))93I_n94sage: KodairaSymbol_class('In')95In96"""97if not isinstance(symbol, str):98n = Integer(symbol)99self._n = None100if n == 0:101raise ValueError, "Kodaira Symbol code number must be nonzero."102if n == 1:103self._n = 0104self._roman = 1105self._str = 'I0'106self._latex = 'I_0'107elif n == 2:108self._roman = 2109self._str = 'II'110self._latex = 'II'111elif n == 3:112self._roman = 3113self._str = 'III'114self._latex = 'III'115elif n == 4:116self._roman = 4117self._str = 'IV'118self._latex = 'IV'119elif n > 4:120nu = n - 4121self._n = nu122self._roman = 1123self._str = 'I' + nu.str()124self._latex = 'I_{' + nu.str() + '}'125elif n == -1:126self._roman = 1127self._n = 0128self._str = 'I0*'129self._latex = 'I_0^{*}'130elif n == -2:131self._roman = 2132self._str = 'II*'133self._latex = 'II^{*}'134elif n == -3:135self._roman = 3136self._str = 'III*'137self._latex = 'III^{*}'138elif n == -4:139self._roman = 4140self._str = 'IV*'141self._latex = 'IV^{*}'142elif n < -4:143nu = -n - 4144self._roman = 1145self._n = nu146self._str = 'I' + nu.str() +'*'147self._latex = 'I_' + nu.str() + '^{*}'148self._starred = (n < 0)149self._pari = n150return151elif len(symbol) == 0:152raise TypeError, "symbol must be a nonempty string"153if symbol[0] == "I":154symbol = symbol[1:]155starred = False156if symbol[-1] == "*":157starred = True158symbol = symbol[:-1]159self._starred = starred160if symbol in ["I", "II", "V"]: # NB we have already stripped off the leading 'I'161self._roman = ["I", "II", "V"].index(symbol) + 2 # =2, 3 or 4162self._n = None163if starred:164sign = -1165self._str = "I" + symbol + "*"166self._latex = "I" + symbol + "^*"167else:168sign = 1169self._str = "I" + symbol170self._latex = "" + self._str + ""171if symbol == "I":172self._pari = 2 * sign173elif symbol == "II":174self._pari = 3 * sign175elif symbol == "V":176self._pari = 4 * sign177elif symbol == "n":178self._roman = 1179self._pari = None180self._n = "generic"181if starred:182self._str = "In*"183self._latex = "I_n^*"184else:185self._str = "In"186self._latex = "I_n"187elif symbol.isdigit():188self._roman = 1189self._n = Integer(symbol)190if starred:191if self._n == 0:192self._pari = -1193else:194self._pari = -self._n - 4195self._str = "I" + symbol + "*"196self._latex = "I_{%s}^*"%(symbol)197else:198if self._n == 0:199self._pari = 1200else:201self._pari = self._n + 4202self._str = "I" + symbol203self._latex = "I_{%s}"%(symbol)204else:205raise ValueError, "input is not a Kodaira symbol"206207def __repr__(self):208r"""209Return the string representation of this Kodaira Symbol.210211EXAMPLES::212213sage: from sage.schemes.elliptic_curves.kodaira_symbol import KodairaSymbol_class214sage: KS = KodairaSymbol_class(15)215sage: str(KS) # indirect doctest216'I11'217"""218return self._str219220def _latex_(self):221r"""222Return the string representation of this Kodaira Symbol.223224EXAMPLES::225226sage: from sage.schemes.elliptic_curves.kodaira_symbol import KodairaSymbol_class227sage: KS = KodairaSymbol_class(15)228sage: latex(KS)229I_{11}230"""231return self._latex232233def __cmp__(self, other):234r"""235Standard comparison function for Kodaira Symbols.236237EXAMPLES::238239sage: from sage.schemes.elliptic_curves.kodaira_symbol import KodairaSymbol_class240sage: KS1 = KodairaSymbol_class(15); KS1241I11242sage: KS2 = KodairaSymbol_class(-34); KS2243I30*244sage: KS1 < KS2245True246sage: KS2 < KS1247False248249::250251sage: Klist = [KodairaSymbol_class(i) for i in [-10..10] if i!=0]252sage: Klist.sort()253sage: Klist254[I0,255I0*,256I1,257I1*,258I2,259I2*,260I3,261I3*,262I4,263I4*,264I5,265I5*,266I6,267I6*,268II,269II*,270III,271III*,272IV,273IV*]274275"""276if isinstance(other, KodairaSymbol_class):277if (self._n == "generic" and not other._n is None) or (other._n == "generic" and not self._n is None):278return cmp(self._starred, other._starred)279return cmp(self._str, other._str)280else:281return cmp(type(self), type(other))282283def _pari_code(self):284"""285Return the PARI encoding of this Kodaira Symbol.286287EXAMPLES::288289sage: KodairaSymbol('I0')._pari_code()2901291sage: KodairaSymbol('I10')._pari_code()29214293sage: KodairaSymbol('I10*')._pari_code()294-14295sage: [KodairaSymbol(s)._pari_code() for s in ['II','III','IV']]296[2, 3, 4]297sage: [KodairaSymbol(s)._pari_code() for s in ['II*','III*','IV*']]298[-2, -3, -4]299"""300return self._pari301302_ks_cache = {}303def KodairaSymbol(symbol):304r"""305Returns the specified Kodaira symbol.306307INPUT:308309- ``symbol`` (string or integer) -- Either a string of the form "I0", "I1", ..., "In", "II", "III", "IV", "I0*", "I1*", ..., "In*", "II*", "III*", or "IV*", or an integer encoding a Kodaira symbol using PARI's conventions.310311OUTPUT:312313(KodairaSymbol) The corresponding Kodaira symbol.314315EXAMPLES::316317sage: KS = KodairaSymbol318sage: [KS(n) for n in range(1,10)]319[I0, II, III, IV, I1, I2, I3, I4, I5]320sage: [KS(-n) for n in range(1,10)]321[I0*, II*, III*, IV*, I1*, I2*, I3*, I4*, I5*]322sage: all([KS(str(KS(n)))==KS(n) for n in range(-10,10) if n!=0])323True324"""325if _ks_cache.has_key(symbol):326ks = _ks_cache[symbol]()327if not ks is None:328return ks329ks = KodairaSymbol_class(symbol)330_ks_cache[symbol] = weakref.ref(ks)331return ks332333334