Ticket #4036: trac_4036-2.patch

File trac_4036-2.patch, 17.6 KB (added by mhansen, 13 years ago)
  • sage/interfaces/axiom.py

    # HG changeset patch
    # User Mike Hansen <mhansen@gmail.com>
    # Date 1220773837 25200
    # Node ID 998d88b931eddd05a54ba7836716635294015b31
    # Parent  433b5445e0eaa15b18451610c35e8ae14a31820f
    [mq]: expect_conversions.patch
    
    diff -r 433b5445e0ea -r 998d88b931ed sage/interfaces/axiom.py
    a b  
    654654            re.sub(r'\\leqno\(.*?\)','',s)) # no eq number!
    655655        return s
    656656
     657    def as_type(self, type):
     658        """
     659        Returns self as type.
     660
     661        EXAMPLES:
     662            sage: a = axiom(1.2); a  #optional -- requires Axiom
     663            1.2
     664            sage: a.as_type(axiom.DoubleFloat) #optional
     665            1.2
     666            sage: _.type()  #optional
     667            DoubleFloat
     668        """
     669        P = self._check_valid()
     670        type = P(type)
     671        return P.new("%s :: %s"%(self.name(), type.name()))
     672
     673    def unparsed_input_form(self):
     674        """
     675        Get the linear string representation of this object, if possible
     676        (often it isn't).
     677
     678        EXAMPLES:
     679            sage: a = axiom(x^2+1); a #optional -- requires Axiom
     680               2
     681              x  + 1
     682            sage: a.unparsed_input_form() #optional
     683            'x*x+1'
     684        """
     685        P = self._check_valid()
     686        s = P.eval('unparse(%s::InputForm)'%self._name)
     687        if 'translation error' in s or 'Cannot convert' in s:
     688            raise NotImplementedError
     689        s = multiple_replace({'\r\n':'', # fix stupid Fortran-ish
     690                              'DSIN(':'sin(',
     691                              'DCOS(':'cos(',
     692                              'DTAN(':'tan(',
     693                              'DSINH(':'sinh('}, s)
     694        r = re.search(r'"(.*)"',s)
     695        if r:
     696            return r.groups(0)[0]
     697        else:
     698            return s
     699
     700
     701    def _sage_(self):
     702        """
     703        Convert self to a Sage object.
     704
     705
     706        EXAMPLES:
     707            sage: a = axiom(1/2); a #optional -- requires Axiom
     708              1
     709              -
     710              2
     711            sage: a._sage_()  #optional
     712            1/2
     713            sage: _.parent()  #optional
     714            Rational Field
     715
     716            sage: gp(axiom(1/2))  #optional
     717            1/2
     718
     719
     720        DoubleFloat's in Axiom are converted to be in RDF in Sage.
     721            sage: axiom(2.0).as_type('DoubleFloat')._sage_()  #optional
     722            2.0
     723            sage: _.parent() #optional
     724            Real Double Field
     725
     726
     727            sage: RealField(68)((2.1234).exact_rational())
     728            2.1234000000000001762
     729            sage: axiom(2.1234)._sage_() #optional
     730            2.1234000000000001762
     731            sage: _.parent()             #optional
     732            Real Field with 68 bits of precision
     733
     734
     735        We can also convert Axiom's polynomials to Sage polynomials.
     736            sage: a = axiom(x^2 + 1)   #optional
     737            sage: a.type()             #optional
     738            Polynomial Integer
     739            sage: a.sage()             #optional
     740            x^2 + 1
     741            sage: _.parent()           #optional
     742            Univariate Polynomial Ring in x over Integer Ring
     743            sage: axiom('x^2 + y^2 + 1/2').sage()    #optional
     744            y^2 + x^2 + 1/2
     745            sage: _.parent()                         #optional
     746            Multivariate Polynomial Ring in y, x over Rational Field
     747
     748       
     749        """
     750        P = self._check_valid()
     751        type = str(self.type())
     752       
     753        if type == "Domain":
     754            return self._sage_domain()
     755       
     756        if type == "Float":
     757            from sage.rings.all import RealField, ZZ
     758            prec = P('precision()$Float')._sage_()
     759            R = RealField(prec)
     760            x,e,b = self.unparsed_input_form().lstrip('float(').rstrip(')').split(',')
     761            return R(ZZ(x)*ZZ(b)**ZZ(e))
     762        elif type == "DoubleFloat":
     763            from sage.rings.all import RDF
     764            return RDF(repr(self))
     765        elif type.startswith('Polynomial'):
     766            from sage.rings.all import PolynomialRing
     767            base_ring = P(type.lstrip('Polynomial '))._sage_domain()
     768            vars = str(self.variables())[1:-1]
     769            R = PolynomialRing(base_ring, vars)
     770            return R(self.unparsed_input_form())
     771       
     772        #If all else fails, try using the unparsed input form
     773        try:
     774            import sage.misc.sage_eval
     775            return sage.misc.sage_eval.sage_eval(self.unparsed_input_form())
     776        except:
     777            raise NotImplementedError
     778
     779
     780    def _sage_domain(self):
     781        """
     782        A helper function for converting Axiom domains to the corresponding
     783        Sage object.
     784       
     785        EXAMPLES:
     786            sage: axiom('Integer').sage() #optional -- requires Axiom
     787            Integer Ring
     788            sage: axiom('Fraction Integer').sage() #optional
     789            Rational Field
     790
     791            sage: axiom('DoubleFloat').sage() #optional
     792            Real Double Field
     793
     794        """
     795        P = self._check_valid()
     796        name = str(self)
     797        if name == 'Integer':
     798            from sage.rings.all import ZZ
     799            return ZZ
     800        elif name == 'DoubleFloat':
     801            from sage.rings.all import RDF
     802            return RDF
     803        elif name.startswith('Fraction '):
     804            return P(name.lstrip('Fraction '))._sage_domain().fraction_field()
     805
     806        raise NotImplementedError
     807           
    657808       
    658809class AxiomFunctionElement(FunctionElement):
    659810    def __init__(self, object, name):
  • sage/interfaces/expect.py

    diff -r 433b5445e0ea -r 998d88b931ed sage/interfaces/expect.py
    a b  
    949949        work.  Morever if foo is a function then
    950950                      X.foo(y,z,...)
    951951        calls foo(X, y, z, ...) and returns the corresponding object.
     952
     953        EXAMPLES:
     954            sage: gp(2)
     955            2
     956            sage: gp('2')
     957            2
     958            sage: a = gp(2); gp(a) is a
     959            True
    952960        """
    953961        cls = self._object_class()
    954962
    955         if isinstance(x, cls) and x.parent() is self:
    956             return x
     963        #Handle the case when x is an object
     964        #in some interface.
     965        if isinstance(x, ExpectElement):
     966            if x.parent() is self:
     967                return x
     968
     969            #We convert x into an object in this
     970            #interface by first going through Sage.
     971            try:
     972                return self(x._sage_())
     973            except NotImplementedError:
     974                pass
     975           
    957976        if isinstance(x, basestring):
    958977            return cls(self, x, name=name)
    959978        try:
     
    13771396            #print msg
    13781397            pass
    13791398
     1399    def _interface_(self, G):
     1400        """
     1401        We don't want to run any of the generic code for interface conversion.
     1402
     1403        EXAMPLES:
     1404            sage: a = gp(1/2)
     1405            sage: a._interface_(gp)
     1406            Traceback (most recent call last):
     1407            ...
     1408            NotImplementedError
     1409        """
     1410        raise NotImplementedError
     1411
    13801412    def _sage_(self):
     1413        """
     1414        Attempt to return a Sage version of this object.
     1415        This is a generic routine that just tries to evaluate
     1416        the repr(self).
     1417
     1418        EXAMPLES:
     1419            sage: gp(1/2)._sage_()
     1420            1/2
     1421            sage: _.parent()
     1422            Rational Field
     1423        """
    13811424        #TO DO: this could use file transfers when self.is_remote()
    1382         return sage.misc.sage_eval.sage_eval(repr(self).replace('\n',''))
     1425        try:
     1426            return sage.misc.sage_eval.sage_eval(repr(self).replace('\n',''))
     1427        except:
     1428            raise NotImplementedError
    13831429       
    13841430
    13851431    def sage(self):
    13861432        """
    1387         Attempt to return a SAGE version of this object.
     1433        Attempt to return a Sage version of this object.
     1434
     1435        EXAMPLES:
     1436            sage: gp(1/2).sage()
     1437            1/2
     1438            sage: _.parent()
     1439            Rational Field
    13881440        """
    13891441        return self._sage_()
    13901442       
  • sage/interfaces/macaulay2.py

    diff -r 433b5445e0ea -r 998d88b931ed sage/interfaces/macaulay2.py
    a b  
    321321            sage: macaulay2.cputime()       #optional random
    322322            0.48393700000000001
    323323        """
    324         _t = float(self.cpuTime().to_sage())
     324        _t = float(self.cpuTime().sage())
    325325        if t:
    326326            return _t - t
    327327        else:
     
    778778            sage: x, = R.gens()                     #optional
    779779            sage: a = x^2 + 1                       #optional
    780780            sage: a = a.substitute(P)               #optional
    781             sage: a.to_sage().parent()              #optional
     781            sage: a.sage().parent()              #optional
    782782            Univariate Polynomial Ring in x over Finite Field of size 7
    783783
    784784        """
     
    877877    ####################
    878878    #Conversion to Sage#
    879879    ####################
    880     def to_sage(self):
     880    def _sage_(self):
    881881        """
    882882        EXAMPLES:
    883             sage: macaulay2(ZZ).to_sage()      #optional
     883            sage: macaulay2(ZZ).sage()      #optional
    884884            Integer Ring
    885             sage: macaulay2(QQ).to_sage()      #optional
     885            sage: macaulay2(QQ).sage()      #optional
    886886            Rational Field
    887887
    888             sage: macaulay2(2).to_sage()       #optional
     888            sage: macaulay2(2).sage()       #optional
    889889            2
    890             sage: macaulay2(1/2).to_sage()     #optional
     890            sage: macaulay2(1/2).sage()     #optional
    891891            1/2
    892             sage: macaulay2(2/1).to_sage()     #optional
     892            sage: macaulay2(2/1).sage()     #optional
    893893            2
    894894            sage: _.parent()                   #optional
    895895            Rational Field
    896             sage: macaulay2([1,2,3]).to_sage() #optional
     896            sage: macaulay2([1,2,3]).sage() #optional
    897897            [1, 2, 3]
    898898
    899899            sage: m = matrix([[1,2],[3,4]])
    900             sage: macaulay2(m).to_sage()       #optional
     900            sage: macaulay2(m).sage()       #optional
    901901            [1 2]
    902902            [3 4]
    903903
    904             sage: macaulay2(QQ['x,y']).to_sage()    #optional
     904            sage: macaulay2(QQ['x,y']).sage()    #optional
    905905            Multivariate Polynomial Ring in x, y over Rational Field
    906             sage: macaulay2(QQ['x']).to_sage()      #optional
     906            sage: macaulay2(QQ['x']).sage()      #optional
    907907            Univariate Polynomial Ring in x over Rational Field
    908             sage: macaulay2(GF(7)['x,y']).to_sage() #optional
     908            sage: macaulay2(GF(7)['x,y']).sage() #optional
    909909            Multivariate Polynomial Ring in x, y over Finite Field of size 7
    910910
    911             sage: macaulay2(GF(7)).to_sage()       #optional
     911            sage: macaulay2(GF(7)).sage()       #optional
    912912            Finite Field of size 7
    913             sage: macaulay2(GF(49, 'a')).to_sage() #optional
     913            sage: macaulay2(GF(49, 'a')).sage() #optional
    914914            Finite Field in a of size 7^2
    915915
    916916            sage: R.<x,y> = QQ[]             
    917             sage: macaulay2(x^2+y^2+1).to_sage()   #optional
     917            sage: macaulay2(x^2+y^2+1).sage()   #optional
    918918            x^2 + y^2 + 1
    919919
    920920            sage: R = macaulay2("QQ[x,y]")         #optional
    921921            sage: I = macaulay2("ideal (x,y)")     #optional
    922             sage: I.to_sage()                      #optional
     922            sage: I.sage()                      #optional
    923923            Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field
    924924           
    925925            sage: X = R/I       #optional
    926             sage: X.to_sage()   #optional
     926            sage: X.sage()   #optional
    927927            Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y)
    928928
    929929            sage: R = macaulay2("QQ^2")  #optional
    930             sage: R.to_sage()            #optional
     930            sage: R.sage()            #optional
    931931            Vector space of dimension 2 over Rational Field
    932932
    933933            sage: m = macaulay2('"hello"')  #optional
    934             sage: m.to_sage()               #optional
     934            sage: m.sage()               #optional
    935935            'hello'
    936936
    937937        """
     
    948948
    949949        if cls_cls_str == "Type":
    950950            if cls_str == "List":
    951                 return [entry.to_sage() for entry in self]
     951                return [entry.sage() for entry in self]
    952952            elif cls_str == "Matrix":
    953953                from sage.matrix.all import matrix
    954                 base_ring = self.ring().to_sage()
    955                 entries = self.entries().to_sage()
     954                base_ring = self.ring().sage()
     955                entries = self.entries().sage()
    956956                return matrix(base_ring, entries)
    957957            elif cls_str == "Ideal":
    958                 parent = self.ring().to_sage()
    959                 gens = self.gens().entries().flatten().to_sage()
     958                parent = self.ring().sage()
     959                gens = self.gens().entries().flatten().sage()
    960960                return parent.ideal(*gens)
    961961            elif cls_str == "QuotientRing":
    962962                #Handle the ZZ/n case
     
    969969                    #coming from Macaulay 2
    970970                    return GF(ZZ(n))
    971971
    972                 ambient = self.ambient().to_sage()
    973                 ideal = self.ideal().to_sage()
     972                ambient = self.ambient().sage()
     973                ideal = self.ideal().sage()
    974974                return ambient.quotient(ideal)
    975975            elif cls_str == "PolynomialRing":
    976976                from sage.rings.all import PolynomialRing
    977977                from sage.rings.polynomial.term_order import inv_macaulay2_name_mapping
    978978
    979979                #Get the base ring
    980                 base_ring = self.coefficientRing().to_sage()
     980                base_ring = self.coefficientRing().sage()
    981981           
    982982                #Get a string list of generators
    983983                gens = str(self.gens())[1:-1]
     
    10151015                return str(repr_str)
    10161016            elif cls_str == "Module":
    10171017                from sage.modules.all import FreeModule
    1018                 if self.isFreeModule().to_sage():
    1019                     ring = self.ring().to_sage()
    1020                     rank = self.rank().to_sage()
     1018                if self.isFreeModule().sage():
     1019                    ring = self.ring().sage()
     1020                    rank = self.rank().sage()
    10211021                    return FreeModule(ring, rank)
    10221022        else:
    10231023            #Handle the integers and rationals separately
     
    10321032                return QQ(repr_str)
    10331033
    10341034            m2_parent = self.cls()
    1035             parent = m2_parent.to_sage()
     1035            parent = m2_parent.sage()
    10361036
    10371037            if cls_cls_str == "PolynomialRing":
    10381038                from sage.misc.sage_eval import sage_eval
     
    10451045        except:
    10461046            raise NotImplementedError, "cannot convert %s to a Sage object"%repr_str
    10471047     
     1048    to_sage = ExpectElement.sage
     1049
    10481050
    10491051class Macaulay2Function(ExpectFunction):
    10501052    def _sage_doc_(self):
  • sage/interfaces/sage0.py

    diff -r 433b5445e0ea -r 998d88b931ed sage/interfaces/sage0.py
    a b  
    218218            Sage
    219219            sage: a is sage0(a)
    220220            True
     221
     222        TESTS:
     223            sage: sage0(axiom(x^2+1)) #optional -- requires Axiom
     224            x^2 + 1
     225
    221226        """
    222         if isinstance(x, SageElement) and x.parent() is self:
    223             return x
     227        if isinstance(x, ExpectElement):
     228            if x.parent() is self:
     229                return x
     230            else:
     231                return self(x.sage())
     232           
    224233        if isinstance(x, str):
    225234            return SageElement(self, x)
    226235
  • sage/interfaces/singular.py

    diff -r 433b5445e0ea -r 998d88b931ed sage/interfaces/singular.py
    a b  
    579579            sage: I.parent()
    580580            Singular
    581581        """
    582         if isinstance(x, SingularElement):
     582        if isinstance(x, SingularElement) and x.parent() is self:
    583583            return x
    584 
    585         elif (not isinstance(x, ExpectElement) and hasattr(x, '_singular_')) or  \
    586                 (isinstance(x, ExpectElement) and x.hasattr('_singular_')):
    587             return getattr(x, '_singular_')(self)
     584        elif isinstance(x, ExpectElement):
     585            return self(x.sage()) 
     586        elif not isinstance(x, ExpectElement) and hasattr(x, '_singular_'):
     587            return x._singular_(self)
    588588
    589589        # some convenient conversions
    590590        if type in ("module","list") and isinstance(x,(list,tuple,Sequence)):
  • sage/rings/real_mpfr.pyx

    diff -r 433b5445e0ea -r 998d88b931ed sage/rings/real_mpfr.pyx
    a b  
    18601860    def _complex_number_(self):
    18611861        return sage.rings.complex_field.ComplexField(self.prec())(self)
    18621862
     1863    def _axiom_(self, axiom):
     1864        """
     1865        Returns self as a floating point number in Axiom.
     1866       
     1867        EXAMPLES:
     1868            sage: R = RealField(100)
     1869            sage: R(pi)
     1870            3.1415926535897932384626433833
     1871            sage: axiom(R(pi)) # optional -- requires Axiom
     1872            3.1415926535 8979323846 26433833
     1873        """
     1874        prec = self.parent().prec()
     1875
     1876        #Set the precision in Axiom
     1877        old_prec = axiom('precision(%s)$Float'%prec)
     1878        res = axiom('%s :: Float'%self.exact_rational())
     1879        axiom.eval('precision(%s)$Float'%old_prec)
     1880
     1881        return res
     1882
    18631883    def _pari_(self):
    18641884        """
    18651885        Returns self as a Pari floating-point number.