Ticket #6046: heights.patch

File heights.patch, 23.5 KB (added by cremona, 12 years ago)

applies to 3.4.2

  • sage/rings/number_field/number_field_element.pyx

    # HG changeset patch
    # User John Cremona <john.cremona@gmail.com>
    # Date 1242404657 -3600
    # Node ID 8d7f66a806fb85729d404e19b0cf0c8ee454edea
    # Parent  7f9164053b2a6e9302193d8a3c710b826c6041cf
    [mq]: nfht
    
    diff -r 7f9164053b2a -r 8d7f66a806fb sage/rings/number_field/number_field_element.pyx
    a b  
    1111
    1212- Robert Bradshaw (2007-09-15): specialized classes for relative and
    1313  absolute elements
     14
     15- John Cremona (2009-05-15): added support for local and global
     16  logarithmic heights.
     17
    1418"""
    1519
    1620# TODO -- relative extensions need to be completely rewritten, so one
     
    605609        return self.abs(prec=53, i=0)
    606610
    607611    def abs(self, prec=53, i=0):
    608         """
    609         Return the absolute value of this element with respect to the ith
    610         complex embedding of parent, to the given precision.
     612        r"""
     613        Return the absolute value of this element with respect to the
     614        `i`th complex embedding of parent, to the given precision.
    611615       
    612         If prec is 53 (the default), then the complex double field is used;
    613         otherwise the arbitrary precision (but slow) complex field is
    614         used.
     616        If prec is 53 (the default), then the complex double field is
     617        used; otherwise the arbitrary precision (but slow) complex
     618        field is used.
    615619       
    616620        INPUT:
    617621       
     
    653657        P = self.number_field().complex_embeddings(prec)[i]
    654658        return abs(P(self))
    655659
     660    def abs_non_arch(self, P, prec=None):
     661        r"""
     662        Return the non-archimedean absolute value of this element with
     663        respect to the prime `P`, to the given precision.
     664       
     665        INPUT:
     666       
     667        -  ``P`` - a prime ideal of the parent of self
     668       
     669        - ``prec`` (int) -- desired floating point precision (default:
     670          default RealField precision).
     671
     672        OUTPUT:
     673
     674        (real) the non-archimedean absolute value of this element with
     675        respect to the prime `P`, to the given precision.  This is the
     676        normalised absolute value, so that the underlying prime number
     677        `p` has absolute value `1/p`.
     678
     679       
     680        EXAMPLES::
     681
     682            sage: K.<a> = NumberField(x^2+5)
     683            sage: [1/K(2).abs_non_arch(P) for P in K.primes_above(2)]
     684            [2.00000000000000]
     685            sage: [1/K(3).abs_non_arch(P) for P in K.primes_above(3)]
     686            [3.00000000000000, 3.00000000000000]
     687            sage: [1/K(5).abs_non_arch(P) for P in K.primes_above(5)]
     688            [5.00000000000000]
     689
     690        """
     691        from sage.rings.real_mpfr import RealField
     692        if prec is None:
     693            R = RealField()
     694        else:
     695            R = RealField(prec)
     696
     697        if self.is_zero():
     698            return R.zero_element()
     699        val = self.valuation(P)
     700        nP = P.residue_class_degree()*P.absolute_ramification_index()
     701        return R(P.norm()) ** (-val // nP)
     702
    656703    def coordinates_in_terms_of_powers(self):
    657704        r"""
    658705        Let `\alpha` be self. Return a Python function that takes
     
    16031650            sage: a.multiplicative_order()
    16041651            +Infinity
    16051652
    1606         An example in a relative extension:
     1653        An example in a relative extension::
    16071654   
    16081655            sage: K.<a, b> = NumberField([x^2 + x + 1, x^2 - 3])
    16091656            sage: z = (a - 1)*b/3
     
    20022049            return infinity
    20032050        return Integer_sage(self.number_field()._pari_().elementval(self._pari_(), P._pari_prime))
    20042051
     2052    def local_height(self, P, prec=None, weighted=False):
     2053        r"""
     2054        Returns the local height of self at a given prime ideal `P`.
     2055       
     2056        INPUT:
     2057       
     2058       
     2059        -  ``P`` - a prime ideal of the parent of self
     2060       
     2061        - ``prec`` (int) -- desired floating point precision (defult:
     2062          default RealField precision).
     2063
     2064        - ``weighted`` (bool, default False) -- if True, apply local
     2065          degree weighting.
     2066
     2067        OUTPUT:
     2068
     2069        (real) The local height of this number field element at the
     2070        place `P`.  If ``weighted`` is True, this is multiplied by the
     2071        local degree (as required for global heights).
     2072       
     2073        EXAMPLES::
     2074       
     2075            sage: R.<x> = QQ[]
     2076            sage: K.<a> = NumberField(x^4+3*x^2-17)
     2077            sage: P = K.ideal(61).factor()[0][0]
     2078            sage: b = 1/(a^2 + 30)
     2079            sage: b.local_height(P)
     2080            4.11087386417331
     2081            sage: b.local_height(P, weighted=True)
     2082            8.22174772834662
     2083            sage: b.local_height(P, 200)
     2084            4.1108738641733112487513891034256147463156817430812610629374
     2085            sage: (b^2).local_height(P)
     2086            8.22174772834662
     2087            sage: (b^-1).local_height(P)
     2088            0.000000000000000
     2089        """
     2090        if self.valuation(P) >= 0: ## includes the case self=0
     2091            from sage.rings.real_mpfr import RealField
     2092            if prec is None:
     2093                return RealField().zero_element()
     2094            else:
     2095                return RealField(prec).zero_element()
     2096        ht = self.abs_non_arch(P,prec).log()
     2097        if not weighted:
     2098            return ht
     2099        nP = P.residue_class_degree()*P.absolute_ramification_index()
     2100        return nP*ht
     2101
     2102    def local_height_arch(self, i, prec=None, weighted=False):
     2103        r"""
     2104        Returns the local height of self at the `i`'th complex embedding.
     2105       
     2106        INPUT:
     2107       
     2108       
     2109        - ``i`` (int) - an integer in ``range(n)`` where `n` is the
     2110           degree of the parent field.
     2111       
     2112        - ``prec`` (int) -- desired floating point precision (default:
     2113          default RealField precision).
     2114
     2115        - ``weighted`` (bool, default False) -- if True, apply local
     2116          degree weighting.
     2117
     2118        OUTPUT:
     2119
     2120        (real) The archimedean local height of this number field
     2121        element at the `i`'th infinite place.  If ``weighted`` is
     2122        True, this is multiplied by the local degree (as required for
     2123        global heights), i.e. 1 for real places and 2 for complex
     2124        places.
     2125       
     2126        EXAMPLES::
     2127       
     2128            sage: R.<x> = QQ[]
     2129            sage: K.<a> = NumberField(x^4+3*x^2-17)
     2130            sage: [a.local_height_arch(i) for i in range(4)]
     2131            [0.530192454572, 0.886414217456, 0.886414217456, 0.530192454572]
     2132            sage: [a.local_height_arch(i, weighted=True) for i in range(4)]
     2133            [0.530192454572, 1.77282843491, 1.77282843491, 1.06038490914]
     2134        """
     2135        from sage.rings.real_mpfr import RealField
     2136        if prec is None:
     2137            R = RealField()
     2138            prec = 53
     2139        else:
     2140            R = RealField(prec)
     2141        a = self.abs(prec,i)
     2142        if a <= R.one_element():
     2143            return R.zero_element()
     2144        ht = a.log()
     2145        if not weighted:
     2146            return ht
     2147        K = self.number_field()
     2148        # Is there a better way to determine whether an embedding is
     2149        # real?  Note that we cannot use is_real() in case the
     2150        # codomain is the ComplexDoubleField.
     2151        if not K.complex_embeddings(prec)[i](K.gen()).imag().is_zero():
     2152            ht*=2
     2153        return ht
     2154
     2155    def global_height_non_arch(self, prec=None):
     2156        """
     2157        Returns the total non-archimedean component of the height of self.
     2158       
     2159        INPUT:
     2160       
     2161        - ``prec`` (int) -- desired floating point precision (defult:
     2162          default RealField precision).
     2163
     2164        OUTPUT:
     2165
     2166        (real) The total non-archimedean component of the height of
     2167        this number field element; that is, the sum of the local
     2168        heights at all finite places, weighted by the local degrees.
     2169
     2170        ALGORITHM:
     2171
     2172        An alternative formula is `\log(d)` where `d` is the norm of
     2173        the denominator ideal; this is used to avoid factorization.
     2174       
     2175        EXAMPLES::
     2176       
     2177            sage: R.<x> = QQ[]
     2178            sage: K.<a> = NumberField(x^4+3*x^2-17)
     2179            sage: b = a/6
     2180            sage: b.global_height_non_arch()
     2181            7.16703787691222
     2182           
     2183        Check that this is equal to the sum of the non-archimedean
     2184        local heights::
     2185
     2186            sage: [b.local_height(P) for P in b.support()]
     2187            [0.000000000000000, 0.693147180559945, 1.09861228866811, 1.09861228866811]
     2188            sage: [b.local_height(P, weighted=True) for P in b.support()]
     2189            [0.000000000000000, 2.77258872223978, 2.19722457733622, 2.19722457733622]
     2190            sage: sum([b.local_height(P,weighted=True) for P in b.support()])
     2191            7.16703787691222
     2192        """
     2193        from sage.rings.real_mpfr import RealField
     2194        if prec is None:
     2195            R = RealField()
     2196        else:
     2197            R = RealField(prec)
     2198        if self.is_zero():
     2199            return R.zero_element()
     2200        return R(self.denominator_ideal().norm()).log()
     2201
     2202    def global_height_arch(self, prec=None):
     2203        """
     2204        Returns the total archimedean component of the height of self.
     2205       
     2206        INPUT:
     2207       
     2208        - ``prec`` (int) -- desired floating point precision (defult:
     2209          default RealField precision).
     2210
     2211        OUTPUT:
     2212
     2213        (real) The total archimedean component of the height of
     2214        this number field element; that is, the sum of the local
     2215        heights at all infinite places.
     2216       
     2217        EXAMPLES::
     2218       
     2219            sage: R.<x> = QQ[]
     2220            sage: K.<a> = NumberField(x^4+3*x^2-17)
     2221            sage: b = a/2
     2222            sage: b.global_height_arch()
     2223            0.386534073792774
     2224        """
     2225        from sage.rings.real_mpfr import RealField
     2226        if prec is None:
     2227            R = RealField()
     2228        else:
     2229            R = RealField(prec)
     2230        if self.is_zero():
     2231            return R.zero_element()
     2232        n = self.number_field().degree()
     2233        # Note that the list of embeddings does have length n as it
     2234        # includes both conjugates for each non-real embedding.  This
     2235        # gives the correct total, since the contributions from the
     2236        # complex places should be multiplied by 2 anyway.
     2237        return sum([self.local_height_arch(i, prec) for i in range(n)], R.zero_element())
     2238
     2239    def global_height(self, prec=None):
     2240        """
     2241        Returns the absolute logarithmic height of this number field element.
     2242       
     2243        INPUT:
     2244       
     2245        - ``prec`` (int) -- desired floating point precision (defult:
     2246          default RealField precision).
     2247
     2248        OUTPUT:
     2249
     2250        (real) The absolute logarithmic height of this number field
     2251        element; that is, the sum of the local heights at all finite
     2252        and infinite places, with the contributions from the infinite
     2253        places scaled by the degree to make the result independent of
     2254        the parent field.
     2255       
     2256        EXAMPLES::
     2257       
     2258            sage: R.<x> = QQ[]
     2259            sage: K.<a> = NumberField(x^4+3*x^2-17)
     2260            sage: b = a/2
     2261            sage: b.global_height()
     2262            2.86922224068797
     2263            sage: b.global_height(prec=200)
     2264            2.8692222406879748488543678846959454765968722137813736080066
     2265
     2266        The global height of an algebraic number is absolute, i.e. it
     2267        does not depend on th parent field::
     2268
     2269            sage: QQ(6).global_height()
     2270            1.79175946922805
     2271            sage: K(6).global_height()
     2272            1.79175946922805
     2273
     2274            sage: L.<b> = NumberField((a^2).minpoly())
     2275            sage: L.degree()
     2276            2
     2277            sage: b.global_height() # element of L (degree 2 field)
     2278            1.41660667202811
     2279            sage: (a^2).global_height() # element of K (degree 4 field)
     2280            1.41660667202811
     2281        """
     2282        return self.global_height_non_arch(prec)+self.global_height_arch(prec)/self.number_field().degree()
     2283
     2284    def numerator_ideal(self):
     2285        """
     2286        Return the numerator ideal of this number field element.
     2287
     2288        .. note::
     2289
     2290           A ValueError will be saised if this function is called on
     2291           0.
     2292
     2293        .. note::
     2294
     2295           See also ``denominator_ideal()``
     2296       
     2297        OUTPUT:
     2298
     2299        (integral ideal) The numerator ideal `N` of this element,
     2300        where for a non-zero number field element `a`, the principal
     2301        ideal generated by `a` has the form `N/D` where `N` and `D`
     2302        are coprime integral ideals.  An error is raised if the
     2303        element is zero.
     2304       
     2305        EXAMPLES::
     2306       
     2307            sage: K.<a> = NumberField(x^2+5)
     2308            sage: b = (1+a)/2
     2309            sage: b.norm()
     2310            3/2
     2311            sage: N = b.numerator_ideal(); N
     2312            Fractional ideal (3, a + 1)
     2313            sage: N.norm()
     2314            3
     2315            sage: (1/b).numerator_ideal()
     2316            Fractional ideal (2, a + 1)
     2317       
     2318        TESTS:
     2319
     2320        Undefined for 0::
     2321       
     2322            sage: K(0).numerator_ideal()
     2323            Traceback (most recent call last):
     2324            ...
     2325            ValueError: numerator ideal of 0 is not defined.
     2326        """
     2327        if self.is_zero():
     2328            raise ValueError, "numerator ideal of 0 is not defined."
     2329        K = self.number_field()
     2330        one = K.ideal(1)
     2331        return one / (one + K.ideal(1/self))
     2332
     2333    def denominator_ideal(self):
     2334        """
     2335        Return the denominator ideal of this number field element.
     2336
     2337        .. note::
     2338
     2339           A ValueError will be saised if this function is called on
     2340           0.
     2341
     2342        .. note::
     2343
     2344           See also ``numerator_ideal()``
     2345       
     2346        OUTPUT:
     2347
     2348        (integral ideal) The denominator ideal `D` of this element,
     2349        where for a non-zero number field element `a`, the principal
     2350        ideal generated by `a` has the form `N/D` where `N` and `D`
     2351        are coprime integral ideals.  An error is raised if the
     2352        element is zero.
     2353       
     2354        EXAMPLES::
     2355       
     2356            sage: K.<a> = NumberField(x^2+5)
     2357            sage: b = (1+a)/2
     2358            sage: b.norm()
     2359            3/2
     2360            sage: D = b.denominator_ideal(); D
     2361            Fractional ideal (2, a + 1)
     2362            sage: D.norm()
     2363            2
     2364            sage: (1/b).denominator_ideal()
     2365            Fractional ideal (3, a + 1)
     2366       
     2367        TESTS:
     2368
     2369        Undefined for 0::
     2370       
     2371            sage: K(0).denominator_ideal()
     2372            Traceback (most recent call last):
     2373            ...
     2374            ValueError: denominator ideal of 0 is not defined.
     2375        """
     2376        if self.is_zero():
     2377            raise ValueError, "denominator ideal of 0 is not defined."
     2378        K = self.number_field()
     2379        one = K.ideal(1)
     2380        return one / (one + K.ideal(self))
     2381
    20052382    def support(self):
    20062383        """
    20072384        Return the support of this number field element.
  • sage/rings/rational.pyx

    diff -r 7f9164053b2a -r 8d7f66a806fb sage/rings/rational.pyx
    a b  
    1919  multiplicative_order, is_one; optimized __nonzero__ ; documented:
    2020  lcm,gcd
    2121
     22- John Cremona (2009-05-15): added support for local and global
     23  logarithmic heights.
     24
    2225TESTS::
    2326
    2427    sage: a = -2/3
     
    729732            return Rational(1)
    730733
    731734    def valuation(self, p):
    732         """
    733         Return the largest power of p that divides self.
     735        r"""
     736        Return the power of ``p`` in the factorization of self.
    734737       
    735738        INPUT:
    736739       
    737740       
    738741        -  ``p`` - a prime number
     742
     743        OUTPUT:
     744
     745        (integer or infinity) Infinity if self is zero, otherwise the
     746        (positive or negative) integer `e` such that self = `m*p^e`
     747        with `m` coprime to `p`.
     748
     749        .. note::
     750
     751           See also ``val_unit()`` which returns the pair `(e,m)`.
    739752       
    740        
    741         EXAMPLES::
     753        Examples::
    742754       
    743755            sage: x = -5/9
    744756            sage: x.valuation(5)
     
    757769        """
    758770        return self.numerator().valuation(p) - self.denominator().valuation(p)
    759771       
     772    def local_height(self, p, prec=None):
     773        r"""
     774        Returns the local height of this rational number at the prime `p`.
     775       
     776        INPUT:
     777       
     778       
     779        -  ``p`` - a prime number
     780       
     781        - ``prec`` (int) -- desired floating point precision (defult:
     782          default RealField precision).
     783
     784        OUTPUT:
     785
     786        (real) The local height of this rational number at the
     787        prime `p`.
     788       
     789        EXAMPLES::
     790       
     791            sage: a = QQ(25/6)
     792            sage: a.local_height(2)
     793            0.693147180559945
     794            sage: a.local_height(3)
     795            1.09861228866811
     796            sage: a.local_height(5)
     797            0.000000000000000
     798        """
     799        from sage.rings.real_mpfr import RealField
     800        if prec is None:
     801            R = RealField()
     802        else:
     803            R = RealField(prec)
     804        if self.is_zero():
     805            return R.zero_element()
     806        val = self.valuation(p)
     807        if val >= 0:
     808            return R.zero_element()
     809        return -val * R(p).log()
     810
     811    def local_height_arch(self, prec=None):
     812        r"""
     813        Returns the archimdean local height of this rational number at the infinite place.
     814       
     815        INPUT:
     816       
     817       
     818        - ``prec`` (int) -- desired floating point precision (defult:
     819          default RealField precision).
     820
     821        OUTPUT:
     822
     823        (real) The local height of this rational number `x` at the
     824        unique infinite place of `\QQ`, which is
     825        `\max(\log(|x|),0)`.
     826       
     827        EXAMPLES::
     828       
     829            sage: a = QQ(6/25)
     830            sage: a.local_height_arch()
     831            0.000000000000000
     832            sage: (1/a).local_height_arch()
     833            1.42711635564015
     834            sage: (1/a).local_height_arch(100)
     835            1.4271163556401457483890413081
     836        """
     837        from sage.rings.real_mpfr import RealField
     838        if prec is None:
     839            R = RealField()
     840        else:
     841            R = RealField(prec)
     842        a = self.abs()
     843        if a <= 1:
     844            return R.zero_element()
     845        return R(a).log()
     846
     847    def global_height_non_arch(self, prec=None):
     848        r"""
     849        Returns the total non-archimedean component of the height of this rational number.
     850       
     851        INPUT:
     852       
     853        - ``prec`` (int) -- desired floating point precision (defult:
     854          default RealField precision).
     855
     856        OUTPUT:
     857
     858        (real) The total non-archimedean component of the height of
     859        this rational number.
     860
     861        ALGORITHM:
     862       
     863        This is the sum of the local heights at all primes `p`, which
     864        may be computed without fatorization as the log of the
     865        denominator.
     866       
     867        EXAMPLES::
     868       
     869            sage: a = QQ(5/6)
     870            sage: a.support()
     871            [2, 3, 5]
     872            sage: a.global_height_non_arch()
     873            1.79175946922805
     874            sage: [a.local_height(p) for p in a.support()]
     875            [0.693147180559945, 1.09861228866811, 0.000000000000000]
     876            sage: sum([a.local_height(p) for p in a.support()])
     877            1.79175946922805
     878        """
     879        from sage.rings.real_mpfr import RealField
     880        if prec is None:
     881            R = RealField()
     882        else:
     883            R = RealField(prec)
     884        d = self.denominator()
     885        if d.is_one():
     886            return R.zero_element()
     887        return R(d).log()
     888
     889    def global_height_arch(self, prec=None):
     890        r"""
     891        Returns the total archimedean component of the height of this rational number.
     892       
     893        INPUT:
     894       
     895        - ``prec`` (int) -- desired floating point precision (defult:
     896          default RealField precision).
     897
     898        OUTPUT:
     899
     900        (real) The total archimedean component of the height of
     901        this rational number.
     902
     903        ALGORITHM:
     904       
     905        Since `\QQ` has only one infinite place this is just the value
     906        of the local height at that place.  This separate function is
     907        included for compatibility with number fields.
     908       
     909        EXAMPLES::
     910       
     911            sage: a = QQ(6/25)
     912            sage: a.global_height_arch()
     913            0.000000000000000
     914            sage: (1/a).global_height_arch()
     915            1.42711635564015
     916            sage: (1/a).global_height_arch(100)
     917            1.4271163556401457483890413081
     918        """
     919        return self.local_height_arch(prec)
     920
     921    def global_height(self, prec=None):
     922        r"""
     923        Returns the absolute logarithmic height of this rational number.
     924       
     925        INPUT:
     926       
     927        - ``prec`` (int) -- desired floating point precision (defult:
     928          default RealField precision).
     929
     930        OUTPUT:
     931
     932        (real) The absolute logarithmic height of this rational
     933        number.
     934
     935        ALGORITHM:
     936       
     937        The height is the sum of the total archimedean and
     938        non-archimedean components, which is equal to
     939        `\max(\log(n),\log(d))` where `n,d` are the numerator and
     940        denominator of the rational number.
     941       
     942        EXAMPLES::
     943       
     944            sage: a = QQ(6/25)
     945            sage: a.global_height_arch() + a.global_height_non_arch()
     946            3.21887582486820
     947            sage: a.global_height()
     948            3.21887582486820
     949            sage: (1/a).global_height()
     950            3.21887582486820
     951            sage: QQ(0).global_height()
     952            0.000000000000000
     953            sage: QQ(1).global_height()
     954            0.000000000000000
     955        """
     956        from sage.rings.real_mpfr import RealField
     957        if prec is None:
     958            R = RealField()
     959        else:
     960            R = RealField(prec)
     961        return R(max(self.numerator().abs(),self.denominator())).log()
     962
    760963    def is_square(self):
    761964        """
    762965        Return whether or not this rational number is a square.
     
    11871390        Return the period of the repeating part of the decimal expansion of
    11881391        this rational number.
    11891392       
    1190         ALGORITHM: When a rational number `n/d` with
    1191         `(n,d)==1` is expanded, the period begins after `s`
    1192         terms and has length `t`, where `s` and `t`
    1193         are the smallest numbers satisfying
    1194         `10^s=10^(s+t) (mod d)`. When `d` is coprime to 10,
    1195         this becomes a purely periodic decimal with
    1196         `10^t=1 (mod d)`. (Lehmer 1941 and Mathworld).
     1393        ALGORITHM: When a rational number `n/d` with `(n,d)==1` is
     1394        expanded, the period begins after `s` terms and has length
     1395        `t`, where `s` and `t` are the smallest numbers satisfying
     1396        `10^s=10^{s+t} (\mod d)`. In general if `d=2^a3^bm` where `m`
     1397        is coprime to 10, then `s=\max(a,b)` and `t` is the order of
     1398        10 modulo `d`.
    11971399       
    11981400        EXAMPLES::
    11991401       
     
    12171419        """
    12181420        cdef unsigned int alpha, beta
    12191421        d = self.denominator()
    1220         alpha = d.valuation(2)
    1221         beta = d.valuation(5)
    1222         P = d.parent()
    1223         if alpha > 0 or beta > 0:
    1224             d = d//(P(2)**alpha * P(5)**beta)
     1422        alpha, d = d.val_unit(2)
     1423        beta, d  = d.val_unit(5)
    12251424        from sage.rings.integer_mod import Mod
    1226         a = Mod(P(10),d)
    1227         return a.multiplicative_order()
     1425        return Mod(ZZ(10),d).multiplicative_order()
    12281426
    12291427    def nth_root(self, int n):
    12301428        r"""
     
    23182516        AUTHORS:
    23192517
    23202518        - Naqi Jaffery (2006-03-05): examples
     2519
     2520        .. note::
     2521
     2522           For the logarithmic height, use ``global_height()``.
     2523
    23212524        """
    23222525        x = abs(self.numer())
    23232526        if x > self.denom():