Changeset 5755:56321c1f164b


Ignore:
Timestamp:
08/08/07 14:01:30 (6 years ago)
Author:
Craig Citro <craigcitro@…>
Branch:
default
Message:

Fixed constructor for p-adic capped relative to be much faster.
Moved around/changed comments in rational.pyx so that you could
actually follow them to see documentation, as the comments themselves
suggest.

Location:
sage/rings
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • sage/rings/padics/padic_capped_relative_element.pxd

    r5430 r5755  
    99cimport sage.rings.integer 
    1010from sage.rings.integer cimport Integer 
     11 
     12cimport sage.rings.rational 
     13from sage.rings.rational cimport Rational 
    1114 
    1215cimport sage.rings.padics.pow_computer 
     
    2326    cdef void set_zero(pAdicCappedRelativeElement self, absprec) 
    2427    cdef void set_precs(pAdicCappedRelativeElement self, long relprec) 
    25     cdef void set_from_Integers(pAdicCappedRelativeElement self, Integer ordp, Integer unit, Integer relprec) 
    2628    cdef void set(pAdicCappedRelativeElement self, long ordp, Integer unit, long relprec) 
    2729    cdef pAdicCappedRelativeElement _new_c(pAdicCappedRelativeElement self) 
    2830    cdef void _normalize(pAdicCappedRelativeElement self) 
     31    cdef int _set_from_Integer( pAdicCappedRelativeElement self, parent, Integer x, absprec, relprec) except -1 
     32    cdef int _set_from_Rational( pAdicCappedRelativeElement self, parent, Rational x, absprec, relprec) except -1 
     33    cdef void set_from_Integers(pAdicCappedRelativeElement self, Integer ordp, Integer unit, Integer relprec) 
    2934    cdef ModuleElement _neg_c_impl(self) 
    3035    cdef RingElement _floordiv_c_impl(self, RingElement right) 
  • sage/rings/padics/padic_capped_relative_element.pyx

    r5430 r5755  
    8686            Traceback (most recent call last): 
    8787            ... 
    88             ValueError: p divides the denominator 
     88            ValueError: p divides the denominator. 
    8989 
    9090        Construct from IntegerMod: 
     
    120120        #print "x = %s, type = %s, absprec = %s, relprec = %s"%(x, type(x),absprec, relprec) 
    121121        cdef RingElement ordp 
     122        cdef mpz_t modulus 
     123        cdef Integer tmp 
     124        cdef unsigned long k 
    122125        mpz_init(self.unit) 
    123126        pAdicGenericElement.__init__(self, parent) 
     
    126129            return 
    127130        self._normalized = 1 
    128         if relprec > parent.precision_cap(): 
     131        if (relprec is infinity) or (relprec > parent.precision_cap()): 
    129132            relprec = parent.precision_cap() 
    130133        if not absprec is infinity and not PY_TYPE_CHECK(absprec, Integer): 
    131134            absprec = Integer(absprec) 
    132  
    133135        if isinstance(x, pAdicGenericElement): 
    134136            if self.prime_pow.in_field == 0 and x.valuation() < 0: 
    135137                raise ValueError, "element has negative valuation." 
    136138            if parent.prime() != x.parent().prime(): 
    137                 raise TypeError, "Cannot coerce between p-adic parents with different primes" 
     139                raise TypeError, "Cannot coerce between p-adic parents with different primes"             
    138140        if isinstance(x, pAdicLazyElement): 
    139             # One can do this in a better way to minimize the amount of increasing precision on x. 
     141            ## One can do this in a better way to minimize the amount of 
     142            ## increasing precision on x. 
    140143            if absprec is infinity: 
    141144                try: 
     
    148151                except PrecisionError: 
    149152                    pass 
    150             if x.precision_relative() < relprec: 
     153                 
     154            if (relprec is infinity) or (x.precision_relative() < relprec): 
    151155                try: 
    152156                    x.set_precision_relative(relprec) 
    153157                except PrecisionError: 
    154158                    pass 
    155         if isinstance(x, pAdicBaseGenericElement): 
     159                 
     160        if isinstance(x, Integer): 
     161            self._set_from_Integer(parent, x, absprec, relprec) 
     162            return 
     163                 
     164        elif isinstance(x, Rational): 
     165            self._set_from_Rational(parent, x, absprec, relprec) 
     166            return 
     167         
     168        elif isinstance(x, (int, long)): 
     169            x = Integer(x) 
     170            self._set_from_Integer(parent, x, absprec, relprec) 
     171            return 
     172             
     173        elif isinstance(x, pAdicBaseGenericElement): 
     174            ## this case could be rethought to remove the 
     175            ## potential arithmetic with infinity. 
    156176            ordp = x.valuation() 
    157             if ordp >= absprec: 
    158                 if absprec is infinity: 
    159                     self.set_exact_zero() 
    160                 else: 
    161                     self.set_inexact_zero(mpz_get_si((<Integer>absprec).value)) 
     177            if (ordp is infinity) and (absprec is infinity): 
     178                self.set_exact_zero() 
     179            elif ordp >= absprec: 
     180                self.set_inexact_zero(mpz_get_si((<Integer>absprec).value)) 
    162181            else: 
    163182                unit = x.unit_part().lift() 
    164183                relprec = min(relprec, absprec - ordp, x.precision_relative()) 
    165184                self.set_from_Integers(ordp, unit, relprec) 
     185                 
    166186            return 
    167187 
    168         if isinstance(x, pari_gen): 
    169             if x.type() == "t_PADIC": 
    170                 absprec = Integer(min(x.padicprec(parent.prime()), absprec)) 
    171                 x = x.lift() 
    172             if x.type() == "t_INT": 
    173                 x = Integer(x) 
    174             elif x.type() == "t_FRAC": 
    175                 x = Rational(x) 
    176             else: 
    177                 raise TypeError, "unsupported coercion from pari: only p-adics, integers and rationals allowed" 
    178  
    179         #if sage.rings.finite_field_element.is_FiniteFieldElement(x): 
    180         #    if x.parent().order() != parent.prime(): 
    181         #        raise TypeError, "can only create p-adic element out of finite field when order of field is p" 
    182         #    #prec = min(prec, 1) 
    183         #    x = x.lift() 
    184  
    185         cdef mpz_t modulus 
    186         cdef Integer tmp 
    187         cdef unsigned long k 
    188         cdef long ordp_c 
    189         cdef long absprec_c = maxint if absprec is infinity else mpz_get_si((<Integer>absprec).value) 
    190         cdef long relprec_c = relprec 
    191          
    192         if sage.rings.integer_mod.is_IntegerMod(x): 
     188        elif sage.rings.integer_mod.is_IntegerMod(x): 
    193189            mpz_init_set(modulus, (<Integer>x.modulus()).value) 
    194190            k = mpz_remove(modulus, modulus, self.prime_pow.prime.value) 
     
    199195                x = x.lift() 
    200196                mpz_clear(modulus) 
     197                self._set_from_Integer(parent, x, absprec, relprec) 
     198                return             
    201199            else: 
    202200                mpz_clear(modulus) 
    203201                raise TypeError, "cannot coerce from the given integer mod ring (not a power of the same prime)" 
    204202 
    205             # We now use the code, below, so don't make the next line elif 
    206         if isinstance(x, (int, long)): 
    207             x = Integer(x) 
    208         #print "before integer" 
    209         if isinstance(x, Integer): 
    210             ordp, unit = x.val_unit(parent.prime()) 
    211             #print "after pair" 
    212             if ordp >= absprec: 
    213                 if absprec is infinity: 
    214                     self.set_exact_zero() 
    215                 else: 
    216                     self.set_inexact_zero(mpz_get_si((<Integer>absprec).value)) 
    217                 return 
    218             #print "now 1" 
    219             relprec = min(relprec, absprec - ordp) 
    220             #print "now 2" 
    221             self.set_from_Integers(ordp, unit, relprec) 
    222             #print "now 3" 
    223         elif isinstance(x, Rational): 
    224             if not x: 
    225                 self.set_zero(absprec) 
    226             else: 
    227                 ordp_c, unit = x.val_unit(self.prime_pow.prime) 
    228                 if ordp_c >= absprec_c: 
    229                     self.set_zero(absprec) 
    230                 else: 
    231                     if not self.prime_pow.in_field and ordp_c < 0: 
    232                         raise ValueError, "p divides the denominator" 
    233                     if relprec_c > absprec_c - ordp_c: 
    234                         relprec_c = absprec_c - ordp_c 
    235                     unit = unit.numerator() * unit.denominator().inverse_mod(self.prime_pow.dense_list_Integer[relprec_c]) 
    236                     self.set(ordp_c, unit, relprec_c) 
     203        elif isinstance(x, pari_gen):             
     204            if x.type() == "t_PADIC": 
     205                absprec = Integer(min(x.padicprec(parent.prime()), absprec)) 
     206                x = x.lift() 
     207 
     208            if x.type() == "t_INT": 
     209                self._set_from_Integer(parent, Integer(x), absprec, relprec) 
     210            elif x.type() == "t_FRAC": 
     211                self._set_from_Rational(parent, Rational(x), absprec, relprec) 
     212            else: 
     213                raise TypeError, "unsupported coercion from pari: only p-adics, integers and rationals allowed" 
     214 
     215            return 
     216 
     217        ## 
     218        ## If this case gets included, it should be rewritten to 
     219        ## have the following new ending: 
     220        ## 
     221        #if sage.rings.finite_field_element.is_FiniteFieldElement(x): 
     222        #    if x.parent().order() != parent.prime(): 
     223        #        raise TypeError, "can only create p-adic element out of finite field when order of field is p" 
     224        #    #prec = min(prec, 1) 
     225        #    x = x.lift() 
     226        ##  self._set_from_Integer(parent,x,absprec,relprec) 
     227         
    237228        else: 
    238229            raise TypeError, "cannot create a p-adic out of %s"%(type(x)) 
     230         
     231        return 
     232 
     233    cdef int _set_from_Integer(pAdicCappedRelativeElement self, parent, 
     234                               Integer x, absprec, relprec) except -1: 
     235 
     236        cdef long absprec_c 
     237 
     238        if not x: 
     239            if (absprec is infinity): 
     240                self.set_exact_zero() 
     241            else: 
     242                self.set_inexact_zero(mpz_get_si((<Integer>absprec).value)) 
     243            return 0 
     244        else: 
     245            _sig_on 
     246            self.ordp = mpz_remove(self.unit, x.value, 
     247                                   self.prime_pow.prime.value) 
     248            _sig_off 
     249 
     250        if (absprec is infinity): 
     251            self.relprec = relprec 
     252        else: 
     253            absprec_c = mpz_get_si((<Integer>absprec).value) 
     254            if (self.ordp >= absprec_c): 
     255                self.set_inexact_zero(absprec_c) 
     256            else: 
     257                self.relprec = min(relprec, absprec_c - self.ordp) 
     258 
     259        if mpz_sgn(self.unit) == -1 or \ 
     260               (mpz_cmp(self.unit, self.prime_pow.dense_list[self.relprec]) >= 0): 
     261            _sig_on 
     262            mpz_mod(self.unit, self.unit, self.prime_pow.dense_list[self.relprec]) 
     263            _sig_off 
     264 
     265        return 0 
     266                     
     267    ### WORKING HERE 
     268    cdef int _set_from_Rational(pAdicCappedRelativeElement self, parent, 
     269                                Rational x, absprec, relprec) except -1: 
     270         
     271        cdef long ordp_c 
     272        cdef mpz_t num_unit, den_unit 
     273        cdef unsigned long num_ordp, den_ordp 
     274        cdef long absprec_c = maxint if absprec is infinity \ 
     275                              else mpz_get_si((<Integer>absprec).value) 
     276        cdef long relprec_c = relprec 
     277 
     278         
     279        if not x: 
     280            if absprec is infinity: 
     281                self.set_exact_zero() 
     282            else: 
     283                self.set_inexact_zero(mpz_get_si((<Integer>absprec).value)) 
     284            return 0 
     285        else: 
     286            _sig_on 
     287            mpz_init(num_unit) 
     288            mpz_init(den_unit) 
     289            num_ordp = mpz_remove(num_unit, mpq_numref(x.value), 
     290                                  self.prime_pow.prime.value) 
     291            den_ordp = mpz_remove(den_unit, mpq_denref(x.value), 
     292                                  self.prime_pow.prime.value) 
     293            _sig_off 
     294 
     295 
     296        self.ordp = num_ordp - den_ordp 
     297             
    239298        if self.ordp < 0 and self.prime_pow.in_field == 0: 
    240             raise ValueError, "element has negative valuation." 
     299            raise ValueError, "p divides the denominator."  
     300 
     301        if (absprec is infinity): 
     302            self.relprec = relprec 
     303        else: 
     304            if (self.ordp >= absprec_c): 
     305                self.set_inexact_zero(absprec_c) 
     306            else: 
     307                self.relprec = min(relprec, absprec_c - self.ordp) 
     308 
     309        if mpz_sgn(num_unit) == -1: #or \ 
     310#           (mpz_cmp(num_unit, self.prime_pow.dense_list[self.relprec]) >= 0): 
     311            _sig_on 
     312            mpz_mod(num_unit, num_unit, self.prime_pow.dense_list[self.relprec]) 
     313            _sig_off 
     314 
     315        ## if our denominator was a prime power, just finish 
     316        ## instead of doing extra work 
     317        if (mpz_cmp(den_unit, self.prime_pow.dense_list[0]) == 0): 
     318            mpz_set(self.unit, num_unit) 
     319        else: 
     320        ## 
     321        ## ignoring return value, since den_unit came from mpz_remove 
     322            mpz_invert(den_unit, den_unit, 
     323                       self.prime_pow.dense_list[self.relprec]) 
     324            if mpz_sgn(den_unit) == -1: 
     325                # or \ 
     326                # (mpz_cmp(den_unit, self.prime_pow.dense_list[self.relprec]) >= 0): 
     327                _sig_on 
     328                mpz_mod(den_unit, den_unit, self.prime_pow.dense_list[self.relprec]) 
     329                _sig_off             
     330 
     331            _sig_on 
     332            mpz_mul(self.unit, num_unit, den_unit) 
     333            _sig_off 
     334 
     335        if (mpz_cmp(self.unit, self.prime_pow.dense_list[self.relprec]) >= 0): #\ 
     336            #            or mpz_sgn(self.unit) == -1: 
     337            _sig_on 
     338            mpz_mod(self.unit, self.unit, self.prime_pow.dense_list[self.relprec]) 
     339            _sig_off 
     340 
     341        return 0 
    241342 
    242343    cdef void set_exact_zero(pAdicCappedRelativeElement self): 
     
    255356        else: 
    256357            mpz_set_ui(self.unit, 0) 
     358            self.relprec = 0 
    257359            self.ordp = mpz_get_si((<Integer>absprec).value) 
    258360        self._normalized = 1 
  • sage/rings/rational.pyx

    r5482 r5755  
    552552 
    553553    def val_unit(self, p): 
    554         return self._val_unit(p) 
    555  
    556     cdef _val_unit(Rational self, integer.Integer p): 
    557554        r""" 
    558         Returns a pair: the p-adic valuation of self, and the p-adic unit of self, as a Rational. 
     555        Returns a pair: the p-adic valuation of self, and the p-adic 
     556        unit of self, as a Rational. 
    559557 
    560558        We do not require the p be prime, but it must be at least 2. 
    561         For more documentation see \code{val_unit} 
     559        For more documentation see \code{Integer.val_unit} 
    562560 
    563561        AUTHOR: 
    564562            -- David Roe (4/12/07) 
    565563        """ 
     564        return self._val_unit(p) 
     565 
     566    cdef _val_unit(Rational self, integer.Integer p): 
    566567        cdef integer.Integer v 
    567568        cdef Rational u 
Note: See TracChangeset for help on using the changeset viewer.