Ticket #5749: power-series-poly-docs.patch

File power-series-poly-docs.patch, 18.3 KB (added by craigcitro, 14 years ago)
  • sage/rings/power_series_poly.pyx

    # HG changeset patch
    # User Craig Citro <craigcitro@gmail.com>
    # Date 1239438248 25200
    # Node ID 4ed00aed1ca1f7522f08fbb74f570e05ff77ed11
    # Parent  2267596459c42db473b23c8ea10d3a13a90bf53c
    Bring coverage of power_series_poly.pyx to 100%.
    
    diff -r 2267596459c4 -r 4ed00aed1ca1 sage/rings/power_series_poly.pyx
    a b  
    4848        PowerSeries.__init__(self, parent, prec, is_gen)
    4949
    5050    def __hash__(self):
     51        """
     52        Return a hash of self.
     53       
     54        EXAMPLES:
     55            sage: R.<t> = ZZ[[]]
     56            sage: t.__hash__()
     57            760233507         # 32-bit
     58            14848694839950883 # 64-bit
     59            sage: hash(t)
     60            760233507         # 32-bit
     61            14848694839950883 # 64-bit
     62        """
    5163        return hash(self.__f)
    5264
    5365    def __reduce__(self):
     66        """
     67        Used for pickling.
     68
     69        EXAMPLES:
     70            sage: A.<z> = RR[[]]
     71            sage: f = z - z^3 + O(z^10)
     72            sage: f == loads(dumps(f)) # uses __reduce__
     73            True
     74        """
    5475        # do *not* delete old versions.
    5576        return make_powerseries_poly_v0, (self._parent, self.__f, self._prec, self.__is_gen)
    5677
    5778    def __richcmp__(left, right, int op):
    58         return (<Element>left)._richcmp(right, op)
     79       """
     80       Used for comparing power series.
     81
     82       EXAMPLES:
     83           sage: R.<t> = ZZ[[]]
     84           sage: f = 1 + t + t^7 - 5*t^10
     85           sage: g = 1 + t + t^7 - 5*t^10 + O(t^15)
     86           sage: f == f
     87           True
     88           sage: f < g
     89           False
     90           sage: f == g
     91           True
     92       """
     93       return (<Element>left)._richcmp(right, op)
    5994       
    6095    def polynomial(self):
    6196        """
     
    68103        return self.__f
    69104       
    70105    def valuation(self):
     106        """
     107        Return the valuation of self.
     108
     109        EXAMPLES:
     110            sage: R.<t> = QQ[[]]
     111            sage: (5 - t^8 + O(t^11)).valuation()
     112            0
     113            sage: (-t^8 + O(t^11)).valuation()
     114            8
     115            sage: O(t^7).valuation()
     116            +Infinity
     117            sage: R(0).valuation()
     118            +Infinity
     119        """
    71120        return self.__f.valuation()
    72121       
    73122    def degree(self):
     123        """
     124        Return the degree of the polynomial associated to self. That
     125        is, if self is of the form f(x) + O(x^n), we return the degree
     126        of f(x). Note that if f(x) is 0, we return -1, just as with
     127        polynomials.
     128
     129        EXAMPLES:
     130            sage: R.<t> = ZZ[[]]
     131            sage: (5 + t^3 + O(t^4)).degree()
     132            3
     133            sage: (5 + O(t^4)).degree()
     134            0
     135            sage: O(t^4).degree()
     136            -1
     137        """
    74138        return self.__f.degree()
    75139       
    76140    def __nonzero__(self):
     141        """
     142        Return True if self is nonzero, and False otherwise.
     143
     144        EXAMPLES:
     145            sage: R.<t> = GF(11)[[]]
     146            sage: (1 + t + O(t^18)).__nonzero__()
     147            True
     148            sage: R(0).__nonzero__()
     149            False
     150            sage: O(t^18).__nonzero__()
     151            False
     152        """
    77153        return not not self.__f
    78154
    79 
    80155    def __call__(self, *xs):
    81156        """
    82157        EXAMPLE:
     
    84159            sage: f = 3 - t^3 + O(t^5)
    85160            sage: f(1)
    86161            2       
     162            sage: f(f)
     163            4 + 6*t^3 + O(t^5)
     164           
     165            sage: S.<w> = R[[]]
     166            sage: g = w + 2*w^3 + t*w^4 + O(w^5)
     167            sage: g(1)
     168            3 + t
     169            sage: g(1)(1)
     170            4
    87171        """
    88172        if isinstance(xs[0], tuple):
    89173            xs = xs[0]
     
    91175        try:
    92176            if x.parent() is self._parent:
    93177                if not (self.prec() is infinity):
    94                     x = x.add_bigoh(self.prec()*x.valuation())
     178                    if x.valuation() == 0:
     179                        x = x.add_bigoh(self.prec())
     180                    else:
     181                        x = x.add_bigoh(self.prec()*x.valuation())
    95182                    xs = list(xs); xs[0] = x; xs = tuple(xs) # tuples are immutable
    96183        except AttributeError:
    97184            pass
    98185        return self.__f(xs)
    99186
    100     def __getslice__(self, i, j):
    101         r"""
    102         Return slice of coefficient of this power series.
    103 
    104         This calls slice on the underlying polynomial, and makes a power
    105         series out of the result, with precision the precision of self.
    106 
    107         EXAMPLES:
    108             sage: R.<t> = ZZ[[]]
    109             sage: f = (2-t)^5 + O(t^7); f
    110             32 - 80*t + 80*t^2 - 40*t^3 + 10*t^4 - t^5 + O(t^7)
    111             sage: f[2:4]
    112             80*t^2 - 40*t^3 + O(t^7)
    113         """
    114         return PowerSeries_poly(self._parent, self.__f[i:j], prec=self.prec(), check=False)
    115    
    116187    def _unsafe_mutate(self, i, value):
    117188        """
    118189        SAGE assumes throughout that commutative ring elements are immutable.
     
    128199            sage: f._unsafe_mutate(0, 5)
    129200            sage: f
    130201            5 + 6*t^3 + O(t^5)
     202            sage: f._unsafe_mutate(2, 1) ; f
     203            5 + t^2 + 6*t^3 + O(t^5)
     204           
     205        Mutating can even bump up the precision.
     206            sage: f._unsafe_mutate(6, 1) ; f
     207            5 + t^2 + 6*t^3 + t^6 + O(t^7)
     208            sage: f._unsafe_mutate(0, 0) ; f
     209            t^2 + 6*t^3 + t^6 + O(t^7)
     210            sage: f._unsafe_mutate(1, 0) ; f
     211            t^2 + 6*t^3 + t^6 + O(t^7)
     212            sage: f._unsafe_mutate(11,0) ; f
     213            t^2 + 6*t^3 + t^6 + O(t^12)
    131214
    132         Mutating can even bump up the precision.
    133             sage: f._unsafe_mutate(7,2)
    134             sage: f
    135             5 + 6*t^3 + 2*t^7 + O(t^8)
     215            sage: g = t + O(t^7)
     216            sage: g._unsafe_mutate(1,0) ; g
     217            O(t^7)
    136218        """
    137219        self.__f._unsafe_mutate(i, value)
    138220        self._prec = max(self._prec, i+1)
    139221
    140222    def __getitem__(self, n):
    141223        """
    142         Return the n-th coefficient.
     224        Return the nth coefficient of self.
    143225
    144         Returns 0 for negative coefficients.  Raises an IndexError if
     226        If n is a slice object, this will return a power series of the
     227        same precision, whose coefficients are the same as self for
     228        those indices in the slice, and 0 otherwise.
     229
     230        Returns 0 for negative coefficients. Raises an IndexError if
    145231        try to access beyond known coefficients.
    146232
    147233        EXAMPLES:
     
    159245            IndexError: coefficient not known
    160246            sage: f[1:4]
    161247            -17/5*t^3 + O(t^5)       
     248
     249            sage: R.<t> = ZZ[[]]
     250            sage: f = (2-t)^5; f
     251            32 - 80*t + 80*t^2 - 40*t^3 + 10*t^4 - t^5
     252            sage: f[2:4]
     253            80*t^2 - 40*t^3
     254            sage: f[5:9]
     255            -t^5
     256            sage: f[2:7:2]
     257            80*t^2 + 10*t^4
     258            sage: f[10:20]
     259            0
     260            sage: f[10:]
     261            0
     262            sage: f[:4]
     263            32 - 80*t + 80*t^2 - 40*t^3
     264
     265            sage: f = 1 + t^3 - 4*t^4 + O(t^7) ; f
     266            1 + t^3 - 4*t^4 + O(t^7)
     267            sage: f[2:4]
     268            t^3 + O(t^7)
     269            sage: f[4:9]
     270            -4*t^4 + O(t^7)
     271            sage: f[2:7:2]
     272            -4*t^4 + O(t^7)
     273            sage: f[10:20]
     274            O(t^7)
     275            sage: f[10:]
     276            O(t^7)
     277            sage: f[:4]
     278            1 + t^3 + O(t^7)
    162279        """
    163         if n<0:
     280        if isinstance(n, slice):
     281            # get values from slice object
     282            start = n.start if n.start is not None else 0
     283            stop = self.prec() if n.stop is None else n.stop
     284            if stop is infinity: stop = self.degree()+1
     285            step = 1 if n.step is None else n.step
     286
     287            # find corresponding polynomial
     288            poly = self.__f[start:stop]
     289            if step is not None:
     290                coeffs = poly.padded_list(stop)
     291                for i in range(start, stop):
     292                    if (i-start) % step:
     293                        coeffs[i] = 0
     294                poly = self.__f.parent()(coeffs)
     295
     296            # return the power series
     297            return PowerSeries_poly(self._parent, poly,
     298                                    prec=self._prec, check=False)
     299        elif n < 0:
    164300            return self.base_ring()(0)
    165         if n > self.__f.degree():
     301        elif n > self.__f.degree():
    166302            if self._prec > n:
    167303                return self.base_ring()(0)
    168304            #elif isinstance(n, slice):
     
    224360            x^2 + O(x^3)
    225361            sage: f += g; f
    226362            x + x^2 + O(x^3)
     363            sage: f._iadd_(g)
     364            x + 2*x^2 + O(x^3)
    227365        """
    228366        cdef PowerSeries_poly right = <PowerSeries_poly>right_m
    229367        self.__f += right.__f
     
    240378
    241379    cpdef ModuleElement _sub_(self, ModuleElement right_m):
    242380        """
    243         Return difference of two power series.
     381        Return the difference of two power series.
    244382
    245383        EXAMPLES:
    246384            sage: k.<w> = ZZ[]
     
    269407                                         
    270408    cpdef RingElement _imul_(self, RingElement right_r):
    271409        """
    272         Return the product of two power series.
     410        Set self to self * right_r, and return this result.
    273411
    274412        EXAMPLES:
    275413            sage: k.<w> = ZZ[[]]
    276             sage: (1+17*w+15*w^3+O(w^5))*(19*w^10+O(w^12))
    277             19*w^10 + 323*w^11 + O(w^12)       
     414            sage: f = (1+17*w+15*w^3+O(w^5))
     415            sage: f *= (19*w^10+O(w^12))
     416            sage: f
     417            19*w^10 + 323*w^11 + O(w^12)
     418           
     419            sage: f = 1 + w^2 + O(w^5)
     420            sage: f._imul_(w^3)
     421            w^3 + w^5 + O(w^8)
    278422        """
    279423        prec = self._mul_prec(right_r)
    280424        self.__f *= (<PowerSeries_poly>right_r).__f
     
    284428        return self
    285429                                         
    286430    cpdef ModuleElement _rmul_(self, RingElement c):
     431        """
     432        Multiply self on the right by a scalar.
     433
     434        EXAMPLES:
     435            sage: R.<t> = GF(7)[[]]
     436            sage: f = t + 3*t^4 + O(t^11)
     437            sage: f * GF(7)(3)
     438            3*t + 2*t^4 + O(t^11)
     439            sage: f._rmul_(3)
     440            3*t + 2*t^4 + O(t^11)
     441        """
    287442        return PowerSeries_poly(self._parent, self.__f._rmul_(c), self._prec, check=False)
    288443
    289444    cpdef ModuleElement _lmul_(self, RingElement c):
     445        """
     446        Multiply self on the left by a scalar.
     447
     448        EXAMPLES:
     449            sage: R.<t> = GF(11)[[]]
     450            sage: f = 1 + 3*t^4 + O(t^120)
     451            sage: f._lmul_(2)
     452            2 + 6*t^4 + O(t^120)
     453            sage: 2 * f
     454            2 + 6*t^4 + O(t^120)
     455        """
    290456        return PowerSeries_poly(self._parent, self.__f._lmul_(c), self._prec, check=False)
    291457
    292458    cpdef ModuleElement _ilmul_(self, RingElement c):
    293 #        print "f", type(self.__f), self.__f
    294 #        print "c", type(c), c
    295 #        print "f*c", type(self.__f*c), self.__f*c
    296 #        ff = self.__f
     459        """
     460        Set self to self left-multiplied by a scalar.
     461
     462        EXAMPLES:
     463            sage: R.<t> = GF(13)[[]]
     464            sage: f = 3 + 7*t^3 + O(t^4)
     465            sage: f._ilmul_(2)
     466            6 + t^3 + O(t^4)
     467            sage: f *= 7 ; f
     468            3 + 7*t^3 + O(t^4)
     469        """
    297470        self.__f *= c
    298 #        ff *= c
    299 #        print "ff", type(ff), ff
    300 #        self.__f = ff
    301 #        self.__f = self.__f * c
    302471        return self
    303 
    304472   
    305473    def __floordiv__(self, denom):
     474        """
     475        EXAMPLES:
     476            sage: R.<t> = ZZ[[]] ; f = t**10-1 ; g = 1+t+t^7 ; h = f.add_bigoh(20)
     477            sage: f // g
     478            -1 + t - t^2 + t^3 - t^4 + t^5 - t^6 + 2*t^7 - 3*t^8 + 4*t^9 - 4*t^10 + 5*t^11 - 6*t^12 + 7*t^13 - 9*t^14 + 12*t^15 - 16*t^16 + 20*t^17 - 25*t^18 + 31*t^19 + O(t^20)
     479            sage: (f // g) * g
     480            -1 + t^10 + O(t^20)
     481            sage: g // h
     482            -1 - t - t^7 - t^10 - t^11 - t^17 + O(t^20)
     483            sage: (g // h) * h
     484            1 + t + t^7 + O(t^20)
     485            sage: h // g
     486            -1 + t - t^2 + t^3 - t^4 + t^5 - t^6 + 2*t^7 - 3*t^8 + 4*t^9 - 4*t^10 + 5*t^11 - 6*t^12 + 7*t^13 - 9*t^14 + 12*t^15 - 16*t^16 + 20*t^17 - 25*t^18 + 31*t^19 + O(t^20)
     487            sage: (h // g) * g
     488            -1 + t^10 + O(t^20)
     489        """
    306490        try:
    307491            return PowerSeries.__div__(self, denom)
    308492        except (PariError, ZeroDivisionError), e: # PariError to general?
     
    314498                                             self.__f // denom, self._prec)
    315499       
    316500    def __lshift__(PowerSeries_poly self, n):
     501        """
     502        Shift self to the left by n, i.e. multiply by x^n.
     503
     504        EXAMPLES:
     505            sage: R.<t> = QQ[[]]
     506            sage: f = 1 + t + t^4
     507            sage: f << 1
     508            t + t^2 + t^5
     509        """
    317510        if n:
    318511            return PowerSeries_poly(self._parent, self.__f << n, self._prec + n)
    319512        else:
    320513            return self
    321514
    322515    def __rshift__(PowerSeries_poly self, n):
     516        """
     517        Shift self to the right by n, i.e. multiply by x^-n and
     518        remove any terms of negative exponent.
     519
     520        EXAMPLES:
     521            sage: R.<t> = GF(2)[[]]
     522            sage: f = t + t^4 + O(t^7)
     523            sage: f >> 1
     524            1 + t^3 + O(t^6)
     525            sage: f >> 10
     526            O(t^0)
     527        """
    323528        if n:
    324             return PowerSeries_poly(self._parent, self.__f >> n, self._prec - n)
     529            return PowerSeries_poly(self._parent, self.__f >> n, max(0,self._prec - n))
    325530        else:
    326531            return self
    327532
     
    342547            return self.__f.truncate(prec)
    343548           
    344549    cdef _inplace_truncate(self, long prec):
     550        """
     551        Truncate self to precision prec in place.
     552
     553        NOTE: This is very unsafe, since power series are supposed to
     554        be immutable in Sage. Use at your own risk!
     555        """
    345556        self.__f = self.__f._inplace_truncate(prec)
    346557        self.prec = prec
    347558        return self
     
    350561        r"""
    351562        Returns the power series of degree $ < n$ which is equivalent to self
    352563        modulo $x^n$.
     564
     565        EXAMPLES:
     566            sage: R.<I> = GF(2)[[]]
     567            sage: f = 1/(1+I+O(I^8)); f
     568            1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8)
     569            sage: f.truncate_powerseries(5)
     570            1 + I + I^2 + I^3 + I^4 + O(I^5)
    353571        """
    354         return PowerSeries_poly(self._parent, self.__f.truncate(prec), self._prec if self._prec < prec else infinity, check=False)
     572        return PowerSeries_poly(self._parent, self.__f.truncate(prec),
     573                                min(self._prec, prec), check=False)
    355574       
    356575    def copy(self):
     576        """
     577        Return a copy of self.
     578
     579        EXAMPLES:
     580            sage: R.<t> = ZZ[[]]
     581            sage: f = t + t^3
     582            sage: f.copy()
     583            t + t^3
     584            sage: f.copy() == f
     585            True
     586            sage: f.copy() is f
     587            False
     588        """
    357589        return PowerSeries_poly(self._parent, self.__f, self._prec, check=False)
    358590
    359591    def list(self):
     592        """
     593        Return the list of known coefficients for self. This is just
     594        the list of coefficients of the underlying polynomial, so in
     595        particular, need not have length equal to self.prec().
     596
     597        EXAMPLES:
     598            sage: R.<t> = ZZ[[]]
     599            sage: f = 1 - 5*t^3 + t^5 + O(t^7)
     600            sage: f.list()
     601            [1, 0, 0, -5, 0, 1]
     602        """
    360603        return self.__f.list()
    361604
    362605    def dict(self):
     606        """
     607        Return a dictionary of coefficients for self. This is simply a
     608        dict for the underlying polynomial, so need not have keys
     609        corresponding to every number smaller than self.prec().
     610
     611        EXAMPLES:
     612            sage: R.<t> = ZZ[[]]
     613            sage: f = 1 + t^10 + O(t^12)
     614            sage: f.dict()
     615            {0: 1, 10: 1}
     616        """
    363617        return self.__f.dict()
    364618
    365619    def _derivative(self, var=None):
     
    412666            sage: k.<w> = QQ[[]]
    413667            sage: (1+17*w+15*w^3+O(w^5)).integral()
    414668            w + 17/2*w^2 + 15/4*w^4 + O(w^6)       
     669            sage: (w^3 + 4*w^4 + O(w^7)).integral()
     670            1/4*w^4 + 4/5*w^5 + O(w^8)
     671            sage: (3*w^2).integral()
     672            w^3
    415673        """
    416674        return PowerSeries_poly(self._parent, self.__f.integral(),
    417675                                         self.prec()+1, check=False)
     
    421679        Return the reversion of f, i.e., the series g such that
    422680        g(f(x)) = x.
    423681
     682        Note that this is only possible if self.valuation() is exactly
     683        1, and must have finite precision (i.e. this cannot be done
     684        for polynomials).
     685
    424686        EXAMPLES:
    425687            sage: R.<x> = PowerSeriesRing(QQ)
    426688            sage: f = 2*x + 3*x**2 - x**4 + O(x**5)
     
    431693            x + O(x^5)
    432694            sage: g(f)
    433695            x + O(x^5)
     696
     697            sage: f += 1
     698            sage: f.reversion()
     699            Traceback (most recent call last):
     700            ...
     701            ValueError: series must have valuation one for reversion
     702            sage: x.reversion()
     703            Traceback (most recent call last):
     704            ...
     705            ValueError: series must have finite precision for reversion
    434706        """
    435707        if not isinstance(self.parent().base_ring(), rational_field.RationalField):
    436708            raise NotImplementedError
    437709        if self.prec() is infinity:
    438             raise RuntimeError, "series must have finite precision for reversion."
     710            raise ValueError, "series must have finite precision for reversion"
     711        if self.valuation() != 1:
     712            raise ValueError, "series must have valuation one for reversion"
    439713        f = self._pari_()
    440714        g = f.serreverse()
    441715        return PowerSeries_poly(self.parent(),g.Vecrev(),self.prec())
    442716
    443717def make_powerseries_poly_v0(parent,  f, prec, is_gen):
     718    """
     719    Return the power series specified by f, prec, and is_gen.
     720
     721    This function exists for the purposes of pickling. Do not delete
     722    this function -- if you change the internal representation,
     723    instead make a new function and make sure that both kinds of
     724    objects correctly unpickle as the new type.
     725
     726    EXAMPLES:
     727        sage: R.<t> = QQ[[]]
     728        sage: sage.rings.power_series_poly.make_powerseries_poly_v0(R, t, infinity, True)
     729        t
     730    """
    444731    return PowerSeries_poly(parent, f, prec, 0, is_gen)