Ticket #5777: symbolics_final1.patch

File symbolics_final1.patch, 97.8 KB (added by mhansen, 11 years ago)
  • c_lib/include/ccobject.h

    # HG changeset patch
    # User Robert Bradshaw <robertwb@math.washington.edu>
    # Date 1242686427 25200
    
    diff --git a/c_lib/include/ccobject.h b/c_lib/include/ccobject.h
    a b  
    8484}
    8585
    8686template <class T>
    87 void _from_str(T* dest, char* src){
     87void _from_str(T* dest, const char* src){
    8888  std::istringstream out(src);
    8989  out >> *dest;
    9090}
    9191
    9292template <class T>
     93void _from_str_len(T* dest, const char* src, unsigned int len){
     94  std::istringstream out(std::string(src, len));
     95  out >> *dest;
     96}
     97
     98template <class T>
    9399PyObject* _to_PyString(const T *x)
    94100{
    95101  std::ostringstream instore;
    96102  instore << (*x);
    97   return PyString_FromString(instore.str().data());
     103  std::string instr = instore.str();
     104  // using PyString_FromString truncates the output if whitespace is
     105  // encountered so we use Py_BuildValue and specify the length
     106  return Py_BuildValue("s#",instr.c_str(), instr.size());
    98107}
    99108
    100109#endif
  • c_lib/include/ginac_wrap.h

    diff --git a/c_lib/include/ginac_wrap.h b/c_lib/include/ginac_wrap.h
    a b  
    1414
    1515using namespace GiNaC;
    1616
    17 
    18 const symbol & get_symbol(const std::string & s)
    19 {
    20     static std::map<std::string, symbol> directory;
    21     std::map<std::string, symbol>::iterator i = directory.find(s);
    22     if (i != directory.end())
    23         return i->second;
    24     else
    25         return directory.insert(std::make_pair(s, symbol(s))).first->second;
    26 }
    27 
    2817void list_symbols(const ex& e, std::set<ex, ex_is_less> &s)
    2918{
    3019    if (is_a<symbol>(e)) {
     
    158147         *AND* sets success to true on success, and false on failure
    159148         if e is not coercible to a double
    160149  */     
    161   ex f = e.evalf();
     150  ex f = e.evalf(0, 53);
    162151  if (is_a<numeric>(f)) {
    163152    *success = true;
    164153    return (ex_to<numeric>(f)).to_double();
  • sage/libs/ginac/decl.pxi

    diff --git a/sage/libs/ginac/decl.pxi b/sage/libs/ginac/decl.pxi
    a b  
    4545    ctypedef struct GExList "GiNaC::lst":
    4646        GExListIter begin()
    4747        GExListIter end()
     48        GExList append_sym "append" (GSymbol e)
    4849
    4950    ctypedef struct GEx "ex":
    5051        unsigned int gethash()        except +
     
    7071        int nops()                    except +
    7172        GEx op(int i)                 except +
    7273        GEx eval(int level)           except +
    73         GEx evalf(int level)          except +
     74        GEx evalf(int level, int prec) except +
    7475        GEx conjugate()               except +
    7576        GEx real_part()               except +
    7677        GEx imag_part()               except +
     
    119120    GEx g_Pi "Pi"
    120121    GEx g_Catalan "Catalan"
    121122    GEx g_Euler "Euler"
     123    GEx g_UnsignedInfinity "UnsignedInfinity"
     124    GEx g_Infinity "Infinity"
     125    GEx g_mInfinity "-Infinity"
     126
     127    # I is not a constant, but a numeric object
     128    # we declare it here for easy reference
     129    GEx g_I "I"
    122130
    123131    # Destructor and constructor
    124132    void GEx_destruct "Destruct<ex>"(GEx *mem) except +
     
    139147    bint is_a_symbol "is_a<symbol>" (GEx e)
    140148    GSymbol ex_to_symbol "ex_to<symbol>" (GEx e)
    141149
     150    ctypedef struct GParamSetIter "paramset::const_iterator":
     151        void inc "operator++" ()
     152        unsigned obj "operator*" ()
     153        bint is_not_equal "operator!=" (GParamSetIter i)
     154
     155    ctypedef struct GParamSet "paramset":
     156        GParamSetIter begin()
     157        GParamSetIter end()
     158        int size()
     159
    142160    ctypedef struct GExVector "exvector":
    143161        void push_back(GEx)
    144162        int size()
     
    174192    GSymbol get_symbol(char* s)              except +
    175193    GEx g_collect_common_factors "collect_common_factors" (GEx e) except +
    176194
     195    # standard library string
     196    ctypedef struct stdstring "std::string":
     197        stdstring assign(char* s, Py_ssize_t l)
     198        char* c_str()
     199        unsigned int size()
     200        char at(unsigned int ind)
     201
     202    stdstring* stdstring_construct_cstr \
     203            "new std::string" (char* s, unsigned int l)
     204    void stdstring_delete "Delete<std::string>"(stdstring* s)
     205
     206    # Archive
     207    ctypedef struct GArchive "archive":
     208        void archive_ex(GEx e, char* name) except +
     209        GEx unarchive_ex(GExList sym_lst, unsigned ind) except +
     210        void printraw "printraw(std::cout); " (int t)
     211
     212    object GArchive_to_str "_to_PyString<archive>"(GArchive *s)
     213    void GArchive_from_str "_from_str_len<archive>"(GArchive *ar, char* s,
     214            unsigned int l)
     215
     216
    177217    GEx g_abs "GiNaC::abs" (GEx x)           except +
    178218    GEx g_step "GiNaC::step" (GEx x)         except +  # step function
    179219    GEx g_csgn "GiNaC::csgn" (GEx x)         except + # complex sign
     
    258298        GFunctionOpt derivative_func(object f)
    259299        GFunctionOpt power_func(object f)
    260300        GFunctionOpt series_func(object f)
    261         GFunctionOpt print_func(object f)
     301        GFunctionOpt latex_name(char* name)
     302        void set_print_latex_func(object f)
     303        void set_print_dflt_func(object f)
     304        char* get_name()
     305        char* get_latex_name()
     306
    262307
    263308    ctypedef struct GFunctionOptVector "vector<function_options>":
    264309        int size()
  • sage/misc/functional.py

    diff --git a/sage/misc/functional.py b/sage/misc/functional.py
    a b  
    757757   
    758758        sage: (pi^2 + e).n()
    759759        12.5878862295484
     760
     761    TESTS::
     762       
     763        sage: numerical_approx(I)
     764        1.00000000000000*I
     765        sage: x = QQ['x'].gen()
     766        sage: F.<k> = NumberField(x^2+2, embedding=sqrt(CC(2))*CC.0)
     767        sage: numerical_approx(k)
     768        1.41421356237309*I
     769
     770        sage: type(numerical_approx(CC(1/2)))
     771        <type 'sage.rings.complex_number.ComplexNumber'>
    760772    """
    761773    if prec is None:
    762774        if digits is None:
     
    768780    except AttributeError:
    769781        from sage.rings.complex_double import is_ComplexDoubleElement
    770782        from sage.rings.complex_number import is_ComplexNumber
    771         if is_ComplexNumber(x) or is_ComplexDoubleElement(x):
    772             return sage.rings.complex_field.ComplexField(prec)(x)
    773         else:
    774             return sage.rings.real_mpfr.RealField_constructor(prec)(x)
     783        if not (is_ComplexNumber(x) or is_ComplexDoubleElement(x)):
     784            try:
     785                return sage.rings.real_mpfr.RealField_constructor(prec)(x)
     786            except TypeError:
     787                pass
     788        return sage.rings.complex_field.ComplexField(prec)(x)
    775789
    776790n = numerical_approx
    777791N = numerical_approx
  • sage/rings/complex_field.py

    diff --git a/sage/rings/complex_field.py b/sage/rings/complex_field.py
    a b  
    3333AlgebraicReal = None
    3434AA = None
    3535QQbar = None
     36NSR = None
    3637CDF = CLF = RLF = None
    3738def late_import():
    3839    global NumberFieldElement_quadratic
    3940    global AlgebraicNumber_base
    4041    global AlgebraicNumber
    4142    global AlgebraicReal
    42     global AA, QQbar
     43    global AA, QQbar, NSR
    4344    global CLF, RLF, CDF
    4445    if NumberFieldElement_quadratic is None:
    4546        import sage.rings.number_field.number_field_element_quadratic as nfeq
     
    5051        AlgebraicReal = sage.rings.qqbar.AlgebraicReal
    5152        AA = sage.rings.qqbar.AA
    5253        QQbar = sage.rings.qqbar.QQbar
     54        import sage.symbolic.ring
     55        NSR = sage.symbolic.ring.NSR
    5356        from real_lazy import CLF, RLF
    5457        from complex_double import CDF
    5558
     
    309312        if is_ComplexField(S) and S._prec >= self._prec:
    310313            return self._generic_convert_map(S)
    311314        late_import()
    312         if S in [AA, QQbar, CLF, RLF] or (S == CDF and self._prec <= 53):
     315        if S in [AA, QQbar, CLF, RLF, NSR] or (S == CDF and self._prec <= 53):
    313316            return self._generic_convert_map(S)
    314317        return self._coerce_map_via([CLF], S)
    315318       
  • sage/rings/fraction_field_element.pyx

    diff --git a/sage/rings/fraction_field_element.pyx b/sage/rings/fraction_field_element.pyx
    a b  
    293293            sage: sum(parts) == q
    294294            True
    295295       
    296         We do the best we can over in-exact fields.
    297        
    298         ::
     296        We do the best we can over in-exact fields::
    299297       
    300298            sage: R.<x> = RealField(20)[]
    301299            sage: q = 1/(x^2 + 2)^2 + 1/(x-1); q
     
    304302            [1.0000/(1.0000*x - 1.0000), 1.0000/(1.0000*x^4 + 4.0000*x^2 + 4.0000)]
    305303            sage: sum(parts)
    306304            (1.0000*x^4 + 4.0000*x^2 + 1.0000*x + 3.0000)/(1.0000*x^5 - 1.0000*x^4 + 4.0000*x^3 - 4.0000*x^2 + 4.0000*x - 4.0000)
     305
     306        TESTS:
     307
     308        We test partial fraction for irreducible denominators::
     309       
     310            sage: R.<x> = ZZ[]
     311            sage: q = x^2/(x-1)
     312            sage: q.partial_fraction_decomposition()
     313            (x + 1, [1/(x - 1)])
     314            sage: q = x^10/(x-1)^5
     315            sage: whole, parts = q.partial_fraction_decomposition()
     316            sage: whole + sum(parts) == q
     317            True
     318
     319        And also over finite fields (see trac #6052)::
     320       
     321            sage: R.<x> = GF(2)[]
     322            sage: q = (x+1)/(x^3+x+1)
     323            sage: q.partial_fraction_decomposition()
     324            (0, [(x + 1)/(x^3 + x + 1)])
    307325        """
    308326        denom = self.denominator()
    309327        whole, numer = self.numerator().quo_rem(denom)
    310328        factors = denom.factor()
    311329        if factors.unit() != 1:
    312330            numer *= ~factors.unit()
     331        if len(factors) == 1:
     332            return whole, [numer/r**e for r,e in factors]
    313333        if not self._parent.is_exact():
    314334            # factors not grouped in this case
    315335            # TODO: think about changing the factor code itself
     
    322342        factors = [r**e for r,e in factors]
    323343        parts = []
    324344        for d in factors:
     345            # note that the product below is non-empty, since the case
     346            # of only one factor has been dealt with above
    325347            n = numer * prod([r for r in factors if r != d]).inverse_mod(d) % d # we know the inverse exists as the two are relatively prime
    326348            parts.append(n/d)
    327349        return whole, parts
  • sage/rings/polynomial/multi_polynomial.pyx

    diff --git a/sage/rings/polynomial/multi_polynomial.pyx b/sage/rings/polynomial/multi_polynomial.pyx
    a b  
    375375            z^5 + x*w*k*z + w^5 + 17*x*w^3 + x^3 + 3*x*w + 5
    376376            sage: f.polynomial(k)
    377377            x*w*z*k + w^5 + z^5 + 17*x*w^3 + x^3 + 3*x*w + 5
     378            sage: R.<x,y>=GF(5)[]
     379            sage: f=x^2+x+y
     380            sage: f.polynomial(x)
     381            x^2 + x + y
     382            sage: f.polynomial(y)
     383            y + x^2 + x
    378384        """
    379385        cdef int ind
    380386        R = self.parent()
     
    961967cdef remove_from_tuple(e, int ind):
    962968    w = list(e)
    963969    del w[ind]
    964     return tuple(w)
     970    if len(w) == 1:
     971        return w[0]
     972    else:
     973        return tuple(w)
    965974
  • sage/rings/polynomial/polynomial_element.pyx

    diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
    a b  
    596596            t^3 + 30*t^2 + 300*t + 1000
    597597            sage: list(f._fast_float_())
    598598            ['load 0', 'push 30.0', 'add', 'load 0', 'mul', 'push 300.0', 'add', 'load 0', 'mul', 'push 1000.0', 'add']
     599
     600        TESTS::
     601
     602            sage: f = t + 2 - t
     603            sage: ff = f._fast_float_()
     604            sage: ff(3)
     605            2.0
     606            sage: list(f._fast_float_())
     607            ['push 2.0']
     608
     609            sage: f = t - t
     610            sage: ff = f._fast_float_()
     611            sage: ff(3)
     612            0.0
     613            sage: list(f._fast_float_())
     614            ['push 0.0']
     615
    599616        """
    600617        from sage.ext.fast_eval import fast_float_arg, fast_float_constant
    601618        var = (<ParentWithGens>self._parent)._names[0]
     
    608625        cdef int i, d = self.degree()
    609626        expr = x
    610627        coeff = self[d]
     628        if d <= 0:
     629            return fast_float_constant(coeff)
    611630        if coeff != 1:
    612631            expr *= fast_float_constant(coeff)
    613632        for i from d > i >= 0:
     
    632651            -t^6 - 12*t^5 + 1/2*t^4 - 1/95*t^3 - 1/2*t^2 - 4
    633652            sage: v._fast_callable_(etb)
    634653            add(mul(mul(add(mul(add(mul(add(mul(add(mul(v_0, -1), -12), v_0), 1/2), v_0), -1/95), v_0), -1/2), v_0), v_0), -4)
     654
     655        TESTS::
     656
     657            sage: R(2)._fast_callable_(etb)
     658            2
     659            sage: R(0)._fast_callable_(etb)
     660            0
     661            sage: fast_callable(R(2))(3)
     662            2
    635663        """
    636664        x = etb.var(self.variable_name())
    637665        expr = x
     
    645673        else:
    646674            # There may be variables in our coefficients...
    647675            coeff_maker = etb.make
     676        if d <= 0:
     677            return coeff_maker(coeff)
    648678        if coeff != 1:
    649679            expr *= coeff_maker(coeff)
    650680        for i from d > i >= 0:
  • sage/rings/rational.pyx

    diff --git a/sage/rings/rational.pyx b/sage/rings/rational.pyx
    a b  
    6464import sage.structure.factorization
    6565
    6666import sage.rings.real_mpfr
     67import sage.rings.real_double
    6768
    6869cimport sage.rings.fast_arith
    6970import  sage.rings.fast_arith
     
    172173        5/2
    173174        sage: Rational(AA(209735/343 - 17910/49*golden_ratio).nth_root(3) + 3*golden_ratio)
    174175        53/7
     176        sage: QQ(float(1.5))
     177        3/2
     178        sage: QQ(RDF(1.2))
     179        6/5
    175180   
    176181    Conversion from PARI::
    177182   
     
    362367            temp_rational = x.rational_reconstruction()
    363368            mpq_set(self.value, temp_rational.value)
    364369       
     370        elif isinstance(x, (float, sage.rings.real_double.RealDoubleElement)):
     371            self.__set_value(sage.rings.real_mpfr.RealNumber(sage.rings.real_mpfr.RR, x), base)
     372       
    365373        else:
    366374           
    367375            raise TypeError, "Unable to coerce %s (%s) to Rational"%(x,type(x))
     
    16721680        if not PY_TYPE_CHECK(self, Rational):
    16731681            # If the base is not a rational, e.g., it is an int, complex, float, user-defined type, etc.
    16741682            try:
    1675                 self_coerced = Rational(self)
     1683                self_coerced = n.parent().coerce(self)
    16761684            except TypeError:
    16771685                n_coerced = type(self)(n)
    16781686                if n != n_coerced:
  • sage/symbolic/expression.pxd

    diff --git a/sage/symbolic/expression.pxd b/sage/symbolic/expression.pxd
    a b  
    66cdef class Expression(CommutativeRingElement):
    77    cdef GEx _gobj
    88    cdef Expression coerce_in(self, z)
     9    cpdef object _eval_self(self, R)
    910    cpdef bint is_polynomial(self, var)
    1011    cpdef bint is_relational(self)
    1112    cpdef object pyobject(self)
  • sage/symbolic/expression.pyx

    diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
    a b  
    7878    sage: expand((u + v + a + b + c)^2)
    7979    a^2 + 2*a*b + 2*a*c + b^2 + 2*b*c + c^2 + (2*u + 2*v)*a + (2*u + 2*v)*b + (2*u + 2*v)*c + u^2 + 2*u*v + v^2
    8080
    81    
     81TESTS:
     82
     83Test jacobian on pynac expressions. #5546 ::
     84
     85    sage: var('x,y', ns=1)
     86    (x, y)
     87    sage: f = x + y
     88    sage: jacobian(f, [x,y])
     89    [1 1]
     90
     91
     92Test if matrices work #5546 ::
     93
     94    sage: var('x,y,z', ns=1)
     95    (x, y, z)
     96    sage: M = matrix(2,2,[x,y,z,x])
     97    sage: v = vector([x,y])
     98    sage: M * v
     99    (x^2 + y^2, x*y + x*z)
     100    sage: v*M
     101    (x^2 + y*z, 2*x*y)
     102
    82103"""
    83104
    84105include "../ext/interrupt.pxi"
     
    90111import sage.rings.rational
    91112
    92113from sage.structure.element cimport ModuleElement, RingElement, Element
    93 from sage.symbolic.function cimport new_SFunction_from_serial
     114from sage.symbolic.function import get_sfunction_from_serial
    94115
    95116
    96117from sage.rings.rational import Rational  # Used for sqrt.
    97118
    98119from sage.calculus.calculus import CallableSymbolicExpressionRing
     120       
     121from sage.misc.derivative import multi_derivative
    99122
    100123cdef class Expression(CommutativeRingElement):
    101124    cpdef object pyobject(self):
     
    124147        """
    125148        GEx_destruct(&self._gobj)
    126149
     150    def __getstate__(self):
     151        """
     152        Returns a tuple describing the state of this expression for pickling.
     153
     154        This should return all information that will be required to unpickle
     155        the object. The functionality for unpickling is implemented in
     156        __setstate__().
     157
     158        In order to pickle Expression objects, we return a tuple containing
     159       
     160         * 0  - as pickle version number
     161                in case we decide to change the pickle format in the feature
     162         * names of symbols of this expression
     163         * a string representation of self stored in a Pynac archive.
     164
     165        TESTS::
     166            sage: var('x,y,z',ns=1)
     167            (x, y, z)
     168            sage: t = 2*x*y^z+3
     169            sage: s = dumps(t)
     170
     171            sage: t.__getstate__()
     172            (0,
     173             ['x', 'y', 'z'],
     174             ...)
     175       
     176        """
     177        cdef GArchive ar
     178        ar.archive_ex(self._gobj, "sage_ex")
     179        ar_str = GArchive_to_str(&ar)
     180        return (0, map(repr, self.variables()), ar_str)
     181
     182    def __setstate__(self, state):
     183        """
     184        Initializes the state of the object from data saved in a pickle.
     185
     186        During unpickling __init__ methods of classes are not called, the saved
     187        data is passed to the class via this function instead.
     188
     189        TESTS::
     190            sage: var('x,y,z',ns=1)
     191            (x, y, z)
     192            sage: t = 2*x*y^z+3
     193            sage: u = loads(dumps(t)) # indirect doctest
     194            sage: u
     195            2*y^z*x + 3
     196            sage: bool(t == u)
     197            True
     198            sage: u.subs(x=z)
     199            2*y^z*z + 3
     200
     201            sage: loads(dumps(x.parent()(2)))
     202            2
     203        """
     204        # check input
     205        if state[0] != 0 or len(state) != 3:
     206            raise ValueError, "unknown state information"
     207        # set parent
     208        self._set_parent(ring.NSR)
     209        # get variables
     210        cdef GExList sym_lst
     211        for name in state[1]:
     212            sym_lst.append_sym(get_symbol(name))
     213
     214        # initialize archive
     215        cdef GArchive ar
     216        GArchive_from_str(&ar, state[2], len(state[2]))
     217
     218        # extract the expression from the archive
     219        GEx_construct_ex(&self._gobj, ar.unarchive_ex(sym_lst, <unsigned>0))
     220
    127221    # TODO: The keyword argument simplify is for compatibility with
    128222    # old symbolics, once the switch is complete, it should be removed
    129223    def _repr_(self, simplify=None):
     
    165259            -I
    166260            sage: y + 3*(x^(-1))
    167261            y + 3/x
     262
     263        Printing the exp function::
     264       
     265            sage: x.parent(1).exp()
     266            e
     267            sage: x.exp()
     268            e^x
    168269        """
    169270        return GEx_to_str(&self._gobj)
    170271
    171272    def _latex_(self):
    172         """
     273        r"""
    173274        Return string representation of this symbolic expression.
    174275       
    175276        EXAMPLES:
     
    179280            sage: var('x,y,z',ns=1)
    180281            (x, y, z)
    181282            sage: latex(y + 3*(x^(-1)))
    182             y + 3\frac{1}{x}
     283            y + 3 \, \frac{1}{x}
    183284            sage: latex(x^(y+z^(1/y)))
    184285            x^{z^{\frac{1}{y}} + y}
    185286            sage: latex(1/sqrt(x+y))
    186287            \frac{1}{\sqrt{x + y}}
    187288            sage: latex(sin(x*(z+y)^x))
    188             \sin({(y + z)}^{x} x)
     289            \sin\left({(y + z)}^{x} x\right)
    189290            sage: latex(3/2*(x+y)/z/y)
    190             \frac{3}{2} \frac{{(x + y)}}{y z}
     291            \frac{3}{2} \, \frac{{(x + y)}}{y z}
    191292            sage: latex((2^(x^y)))
    192293            2^{x^{y}}
     294            sage: latex(abs(x))
     295            {\left|x\right|}
     296            sage: latex((x*y).conjugate())
     297            \bar{x} \bar{y}
     298
     299        Check spacing of coefficients of mul expressions (#3202)::
     300
     301            sage: latex(2*3^x)
     302            2 \, 3^{x}
    193303
    194304        """
    195305        return GEx_to_str_latex(&self._gobj)
     
    253363            return n
    254364        return sage.rings.rational.Rational(n)
    255365
     366    cpdef _eval_self(self, R):
     367        """
     368        Evaluate this expression numerically, and try to coerce it to R.
     369
     370        EXAMPLES::
     371
     372            sage: var('x,y,z',ns=1)
     373            (x, y, z)
     374            sage: sin(x).subs(x=5)._eval_self(RR)
     375            -0.958924274663138
     376            sage: gamma(x).subs(x=I)._eval_self(CC)
     377            -0.154949828301811 - 0.498015668118356*I
     378            sage: x._eval_self(CC)
     379            Traceback (most recent call last):
     380            ...
     381            TypeError: Cannot evaluate symbolic expression to a numeric value.
     382        """
     383        cdef GEx res = self._gobj.evalf(0, R.prec())
     384        if is_a_numeric(res):
     385            return R(py_object_from_numeric(res))
     386        else:
     387            raise TypeError, "Cannot evaluate symbolic expression to a numeric value."
     388
    256389    def _mpfr_(self, R):
    257390        """
    258         This is a very preliminary conversion to real numbers.  It
    259         doesn't unwind an expression, so is fairly useless.
     391        Return a numerical approximation to this expression in the RealField R.
     392
     393        The precision of the approximation is determined by the precision of
     394        the input R.
    260395       
    261         EXAMPLES:
     396        EXAMPLES::
     397
    262398            sage: var('x',ns=1); S = parent(x)
    263399            x
    264400            sage: RealField(200)(S(1/11))
    265401            0.090909090909090909090909090909090909090909090909090909090909
    266402
    267         This illustrates that this function is not done yet:
    268403            sage: a = S(3).sin(); a
    269404            sin(3)
    270405            sage: RealField(200)(a)
    271             Traceback (most recent call last):
    272             ...
    273             TypeError: self must be a numeric expression
     406            0.14112000805986722210074480280811027984693326425226558415188
     407            sage: a._mpfr_(RealField(100))
     408            0.14112000805986722210074480281
    274409        """
    275         # TODO: This is *not* good enough.
    276         return R(self.pyobject())
     410        return self._eval_self(R)
     411
     412    def _complex_mpfr_field_(self, R):
     413        """
     414        Return a numerical approximation to this expression in the given
     415        ComplexField R.
     416
     417        The precision of the approximation is determined by the precision of
     418        the input R.
     419       
     420        EXAMPLES::
     421
     422            sage: var('x',ns=1); S = parent(x)
     423            x
     424            sage: ComplexField(200)(S(1/11))
     425            0.090909090909090909090909090909090909090909090909090909090909
     426            sage: zeta(x).subs(x=I)._complex_mpfr_field_(ComplexField(70))
     427            0.0033002236853241028742 - 0.41815544914132167669*I
     428            sage: gamma(x).subs(x=I)._complex_mpfr_field_(ComplexField(60))
     429            -0.15494982830181069 - 0.49801566811835604*I
     430            sage: log(x).subs(x=I)._complex_mpfr_field_(ComplexField(50))
     431            1.5707963267949*I
     432
     433        """
     434        return self._eval_self(R)
     435
     436    def _complex_double_(self, R):
     437        """
     438        Return a numerical approximation to this expression in the given
     439        Complex Double Field R.
     440
     441        EXAMPLES::
     442
     443            sage: var('x',ns=1); S = parent(x)
     444            x
     445            sage: CDF(S(1/11))
     446            0.0909090909091
     447            sage: zeta(x).subs(x=I)._complex_double_(CDF)
     448            0.00330022368532 - 0.418155449141*I
     449            sage: gamma(x).subs(x=I)._complex_double_(CDF)
     450            -0.154949828302 - 0.498015668118*I
     451            sage: log(x).subs(x=I)._complex_double_(CDF)
     452            1.57079632679*I
     453        """
     454        return self._eval_self(R)
    277455
    278456    def __float__(self):
    279457        """
     
    296474            ...
    297475            TypeError: float() argument must be a string or a number
    298476            sage: float(SR(RIF(2)))
    299             Traceback (most recent call last):
    300             ...
    301             TypeError: float() argument must be a string or a number
     477            2.0
    302478        """
    303479        cdef bint success
    304480        cdef double ans = GEx_to_double(self._gobj, &success)
     
    326502            sage: d = {x+y: 5}
    327503            sage: d
    328504            {x + y: 5}
     505
     506        TESTS:
     507
     508        Test if exceptions during hashing are handled properly::
     509
     510            sage: t = S(matrix(2,2,range(4)))
     511            sage: hash(t)
     512            Traceback (most recent call last):
     513            ...
     514            TypeError: mutable matrices are unhashable
    329515        """
    330516        return self._gobj.gethash()
    331517
     
    527713            Traceback (most recent call last):
    528714            ...
    529715            TypeError: incompatible relations
     716
     717            sage: x + oo
     718            +Infinity
     719            sage: x - oo
     720            -Infinity
     721            sage: x + unsigned_infinity
     722            Infinity
     723            sage: x - unsigned_infinity
     724            Infinity
     725
     726            sage: nsr = x.parent()
     727            sage: nsr(oo) + nsr(oo)
     728            +Infinity
     729            sage: nsr(-oo) + nsr(-oo)
     730            -Infinity
     731            sage: nsr(oo) - nsr(oo)
     732            Traceback (most recent call last):
     733            ...
     734            RuntimeError: indeterminate expression: Infinity - Infinity encountered.
     735            sage: nsr(-oo) - nsr(-oo)
     736            Traceback (most recent call last):
     737            ...
     738            RuntimeError: indeterminate expression: Infinity - Infinity encountered.
     739
     740            sage: nsr(unsigned_infinity) + nsr(oo)
     741            Traceback (most recent call last):
     742            ...
     743            RuntimeError: indeterminate expression: unsigned_infinity + x where x is Infinity, -Infinity or unsigned infinity encountered.
     744            sage: nsr(unsigned_infinity) - nsr(oo)
     745            Traceback (most recent call last):
     746            ...
     747            RuntimeError: indeterminate expression: unsigned_infinity + x where x is Infinity, -Infinity or unsigned infinity encountered.
     748            sage: nsr(oo) + nsr(unsigned_infinity)
     749            Traceback (most recent call last):
     750            ...
     751            RuntimeError: indeterminate expression: unsigned_infinity + x where x is Infinity, -Infinity or unsigned infinity encountered.
     752            sage: nsr(oo) - nsr(unsigned_infinity)
     753            Traceback (most recent call last):
     754            ...
     755            RuntimeError: indeterminate expression: unsigned_infinity + x where x is Infinity, -Infinity or unsigned infinity encountered.
     756            sage: nsr(unsigned_infinity) + nsr(unsigned_infinity)
     757            Traceback (most recent call last):
     758            ...
     759            RuntimeError: indeterminate expression: unsigned_infinity + x where x is Infinity, -Infinity or unsigned infinity encountered.
     760
     761
    530762        """
    531763        cdef GEx x
    532764        cdef Expression _right = <Expression>right
     
    572804            Traceback (most recent call last):
    573805            ...
    574806            TypeError: incompatible relations
     807
     808            sage: x - oo
     809            -Infinity
     810            sage: oo - x
     811            +Infinity
    575812        """
    576813        cdef GEx x
    577814        cdef Expression _right = <Expression>right
     
    638875            sage: (y-1)*(y-2)
    639876            (y - 2)*(y - 1)
    640877
     878            sage: x*oo
     879            +Infinity
     880            sage: x*unsigned_infinity
     881            Infinity
     882            sage: -x*oo
     883            -Infinity
     884
     885            sage: nsr = x.parent()
     886            sage: nsr(oo)*nsr(oo)
     887            +Infinity
     888            sage: nsr(-oo)*nsr(oo)
     889            -Infinity
     890            sage: nsr(oo)*nsr(-oo)
     891            -Infinity
     892            sage: nsr(unsigned_infinity)*nsr(oo)
     893            Infinity
     894
    641895        """
    642896        cdef GEx x
    643897        cdef Expression _right = <Expression>right
     
    691945            Traceback (most recent call last):
    692946            ...
    693947            TypeError: incompatible relations
     948
     949            sage: x/oo
     950            0
     951            sage: oo/x
     952            +Infinity
     953
     954            sage: nsr = x.parent()
     955            sage: nsr(oo)/nsr(oo)
     956            Traceback (most recent call last):
     957            ...
     958            RuntimeError: indeterminate expression: 0*infinity encountered.
     959
     960            sage: nsr(-oo)/nsr(oo)
     961            Traceback (most recent call last):
     962            ...
     963            RuntimeError: indeterminate expression: 0*infinity encountered.
     964
     965            sage: nsr(oo)/nsr(-oo)
     966            Traceback (most recent call last):
     967            ...
     968            RuntimeError: indeterminate expression: 0*infinity encountered.
     969
     970            sage: nsr(oo)/nsr(unsigned_infinity)
     971            Traceback (most recent call last):
     972            ...
     973            RuntimeError: indeterminate expression: 0*infinity encountered.
     974
     975            sage: nsr(unsigned_infinity)/nsr(oo)
     976            Traceback (most recent call last):
     977            ...
     978            RuntimeError: indeterminate expression: 0*infinity encountered.
     979
     980            sage: nsr(0)/nsr(oo)
     981            0
     982
     983            sage: nsr(0)/nsr(unsigned_infinity)
     984            0
     985
     986
    694987        """
    695988        cdef GEx x
    696989        cdef Expression _right = <Expression>right
     
    7811074            sage: k = GF(7)
    7821075            sage: f = expand((k(1)*x^5 + k(1)*x^2 + k(2))^7); f
    7831076            x^35 + x^14 + 2
     1077
     1078            sage: x^oo
     1079            Traceback (most recent call last):
     1080            ...
     1081            RuntimeError: power::eval(): pow(x, Infinity) for non numeric x is not defined.
     1082            sage: S(oo)^2
     1083            +Infinity
     1084            sage: S(-oo)^2
     1085            +Infinity
     1086            sage: S(-oo)^3
     1087            -Infinity
     1088            sage: S(unsigned_infinity)^2
     1089            Infinity
     1090
     1091        Test powers of exp::
     1092           
     1093            sage: S(2).exp()^5
     1094            e^10
     1095            sage: x.exp()^5
     1096            e^(5*x)
    7841097        """
    7851098        cdef Expression nexp = self.coerce_in(exp)
    7861099        cdef GEx x
     
    7921105            x = g_pow(self._gobj, nexp._gobj)
    7931106        return new_Expression_from_GEx(x)
    7941107
    795     def diff(self, symb, deg=1):
     1108    def derivative(self, *args):
     1109        """
     1110        Returns the derivative of this expressions with respect to the variables
     1111        supplied in args.
     1112
     1113        Multiple variables and iteration counts may be supplied; see
     1114        documentation for the global derivative() function for more details.
     1115
     1116        .. seealso::
     1117
     1118            :meth:`_derivative`
     1119
     1120        EXAMPLES::
     1121            sage: var("x y", ns=1)
     1122            (x, y)
     1123            sage: t = (x^2+y)^2
     1124            sage: t.derivative(x)
     1125            4*(x^2 + y)*x
     1126            sage: t.derivative(x, 2)
     1127            12*x^2 + 4*y
     1128            sage: t.derivative(x, 2, y)
     1129            4
     1130            sage: t.derivative(y)
     1131            2*x^2 + 2*y
     1132
     1133        ::
     1134
     1135            sage: t = sin(x+y^2)*tan(x*y)
     1136            sage: t.derivative(x)
     1137            (tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
     1138            sage: t.derivative(y)
     1139            (tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)
     1140
     1141        TESTS:
     1142            sage: t.derivative()
     1143            Traceback (most recent call last):
     1144            ...
     1145            ValueError: No differentiation variable specified.
     1146        """
     1147        return multi_derivative(self, args)
     1148
     1149    def _derivative(self, symb=None, deg=1):
    7961150        """
    7971151        Return the deg-th (partial) derivative of self with respect to symb.
    7981152       
     
    8001154            sage: var("x y", ns=1)
    8011155            (x, y)
    8021156            sage: b = (x+y)^5
    803             sage: b.diff(x, 2)
     1157            sage: b._derivative(x, 2)
    8041158            20*(x + y)^3
    8051159
    8061160            sage: from sage.symbolic.function import function as myfunc
    8071161            sage: foo = myfunc('foo',2)
    808             sage: foo(x^2,x^2).diff(x)
    809             2*x*D[0](foo)(x^2,x^2) + 2*x*D[1](foo)(x^2,x^2)
     1162            sage: foo(x^2,x^2)._derivative(x)
     1163            2*x*D[0](foo)(x^2, x^2) + 2*x*D[1](foo)(x^2, x^2)
     1164
     1165        TESTS:
     1166            Raise error if no variable is specified::
     1167            sage: b._derivative()
     1168            Traceback (most recent call last):
     1169            ...
     1170            ValueError: No differentiation variable specified.
    8101171        """
     1172        if symb is None:
     1173            # we specify a default value of None for symb and check for it here
     1174            # to return more helpful error messages when no variable is
     1175            # given by the multi_derivative framework
     1176            raise ValueError, "No differentiation variable specified."
    8111177        if not isinstance(deg, (int, long, sage.rings.integer.Integer)) \
    8121178                or deg < 1:
    8131179            raise TypeError, "argument deg should be an integer >1."
     
    11191485            ...
    11201486            TypeError: subs takes either a single keyword argument, or a dictionary, or a symbolic relational expression
    11211487
     1488            # substitutions with infinity
     1489            sage: (x/y).subs(y=oo)
     1490            0
     1491            sage: (x/y).subs(x=oo)
     1492            +Infinity
     1493            sage: (x*y).subs(x=oo)
     1494            +Infinity
     1495            sage: (x^y).subs(x=oo)
     1496            Traceback (most recent call last):
     1497            ...
     1498            RuntimeError: power::eval(): pow(Infinity, x) for non numeric x is not defined.
     1499            sage: (x^y).subs(y=oo)
     1500            Traceback (most recent call last):
     1501            ...
     1502            RuntimeError: power::eval(): pow(x, Infinity) for non numeric x is not defined.
     1503            sage: (x+y).subs(x=oo)
     1504            +Infinity
     1505            sage: (x-y).subs(y=oo)
     1506            -Infinity
     1507            sage: gamma(x).subs(x=-1)
     1508            Infinity
     1509            sage: 1/gamma(x).subs(x=-1)
     1510            0
    11221511        """
    11231512        cdef dict sdict = {}
    11241513        if in_dict is not None:
     
    13431732                if fn is None:
    13441733                    raise NotImplementedError, "Sage equivalent of this special function is not implemented."
    13451734                return fn
    1346             else: # else, return a new SFunction object with the same serial
    1347                 return new_SFunction_from_serial(serial,
    1348                         <char *>ex_to_function(self._gobj).get_name(),
    1349                         g_registered_functions().index(serial).get_nparams())
     1735            else: # else, look up the serial in the sfunction database
     1736                res = get_sfunction_from_serial(serial)
     1737                if res is None:
     1738                    raise RuntimeError, "cannot find SFunction in table"
     1739                return res
    13501740
    13511741        # self._gobj is either a symbol, constant or numeric
    13521742        return None
     
    14301820        """
    14311821        Return a numerical approximation of self.
    14321822
     1823        ALIAS: .numerical_approx()
     1824
     1825        EXAMPLES::
     1826
     1827            sage: var('x', ns=1)
     1828            x
     1829            sage: sin(x).subs(x=5).n()
     1830            -0.958924274663138
     1831            sage: sin(x).subs(x=5).n(100)
     1832            -0.95892427466313846889315440616
     1833            sage: sin(x).subs(x=5).n(digits=50)
     1834            -0.95892427466313846889315440615599397335246154396460
     1835            sage: zeta(x).subs(x=2).numerical_approx(digits=50)
     1836            1.6449340668482264364724151666460251892189499012068
     1837
     1838        TESTS::
     1839
     1840        We test the evaluation of different infinities available in pynac::
     1841            sage: t = x - oo; t
     1842            -Infinity
     1843            sage: t.n()
     1844            -Infinity
     1845            sage: t = x + oo; t
     1846            +Infinity
     1847            sage: t.n()
     1848            +Infinity
     1849            sage: t = x - unsigned_infinity; t
     1850            Infinity
     1851            sage: t.n()
     1852            Infinity
    14331853        """
    1434         # TODO: prec and digits parameters
    1435         return new_Expression_from_GEx(self._gobj.evalf(0))
     1854        if prec is None:
     1855            if digits is None:
     1856                prec = 53
     1857            else:
     1858                prec = int((digits+1) * 3.32192) + 1
     1859        return new_Expression_from_GEx(self._gobj.evalf(0, prec))
     1860
     1861    numerical_approx = n
    14361862
    14371863    def function(self, *args):
    14381864        """
     
    17222148            csgn(x)
    17232149            sage: SR(CDF.0).csgn()
    17242150            1
     2151            sage: SR(I).csgn()
     2152            1
    17252153        """
    17262154        return new_Expression_from_GEx(g_csgn(self._gobj))
    17272155
     
    17292157        """
    17302158        Return the complex conjugate of self.
    17312159       
    1732         EXAMPLES:
     2160        EXAMPLES::
     2161
    17332162            sage: x = var('x', ns=1); SR = x.parent()
    17342163            sage: SR(CDF.0).conjugate()
    1735             -I
     2164            -1.0*I
    17362165            sage: x.conjugate()
    17372166            conjugate(x)
    17382167            sage: SR(RDF(1.5)).conjugate()
    17392168            1.5
    17402169            sage: SR(float(1.5)).conjugate()
    17412170            1.5
    1742             sage: I = SR(CDF.0)
    1743             sage: I.conjugate()
     2171            sage: SR(I).conjugate()
    17442172            -I
    17452173            sage: ( 1+I  + (2-3*I)*x).conjugate()
    1746             (2.0 + 3.0*I)*conjugate(x) + 1.0 - I
     2174            (3*I + 2)*conjugate(x) + 1 - I
    17472175        """
    17482176        return new_Expression_from_GEx(self._gobj.conjugate())
    17492177
     
    17552183            sage: x = var('x', ns=1); SR = x.parent()
    17562184            sage: x.real_part()
    17572185            real_part(x)
     2186            sage: SR(2+3*I).real_part()
     2187            2
    17582188            sage: SR(CDF(2,3)).real_part()
    17592189            2.0
    17602190            sage: SR(CC(2,3)).real_part()
     
    17702200            sage: x = var('x', ns=1); SR = x.parent()
    17712201            sage: x.imag_part()
    17722202            imag_part(x)
     2203            sage: SR(2+3*I).imag_part()
     2204            3
    17732205            sage: SR(CC(2,3)).imag_part()
    17742206            3.00000000000000
    17752207            sage: SR(CDF(2,3)).imag_part()
     
    17932225
    17942226    def sin(self):
    17952227        """
    1796         EXAMPLES:
     2228        EXAMPLES::
     2229
    17972230            sage: var('x, y', ns=1); S = parent(x)
    17982231            (x, y)
    17992232            sage: sin(x^2 + y^2)
     
    18032236            sage: sin(S(1))
    18042237            sin(1)
    18052238            sage: sin(S(RealField(150)(1)))
     2239            sin(1.0000000000000000000000000000000000000000000)
     2240
     2241        In order to get a numeric approximation use .n()::
     2242
     2243            sage: sin(S(1)).n(150)
    18062244            0.84147098480789650665250232163029899962256306
     2245
    18072246        """
    18082247        return new_Expression_from_GEx(g_sin(self._gobj))
    18092248
     
    18112250        """
    18122251        Return the cosine of self.
    18132252       
    1814         EXAMPLES:
     2253        EXAMPLES::
     2254
    18152255            sage: var('x, y', ns=1); S = parent(x)
    18162256            (x, y)
    18172257            sage: cos(x^2 + y^2)
     
    18212261            sage: cos(S(1))
    18222262            cos(1)
    18232263            sage: cos(S(RealField(150)(1)))
     2264            cos(1.0000000000000000000000000000000000000000000)
     2265
     2266        In order to get a numeric approximation use .n()::
     2267
     2268            sage: cos(S(1)).n(150)
    18242269            0.54030230586813971740093660744297660373231042
    1825             sage: S(RR(1)).cos()
     2270            sage: S(RR(1)).cos().n()
    18262271            0.540302305868140
    1827             sage: S(float(1)).cos()
    1828             0.54030230586813977
     2272            sage: S(float(1)).cos().n()
     2273            0.540302305868140
    18292274        """
    18302275        return new_Expression_from_GEx(g_cos(self._gobj))
    18312276
    18322277    def tan(self):
    18332278        """
    1834         EXAMPLES:
     2279        EXAMPLES::
     2280
    18352281            sage: var('x, y', ns=1); S = parent(x)
    18362282            (x, y)
    18372283            sage: tan(x^2 + y^2)
     
    18392285            sage: tan(sage.symbolic.constants.pi/2)
    18402286            Traceback (most recent call last):
    18412287            ...
    1842             ValueError: simple pole at 1/2*Pi
     2288            ValueError: simple pole at 1/2*pi
    18432289            sage: tan(S(1))
    18442290            tan(1)
    18452291            sage: tan(S(RealField(150)(1)))
     2292            tan(1.0000000000000000000000000000000000000000000)
     2293       
     2294        Use .n() to get a numerical approximation::
     2295       
     2296            sage: tan(S(1)).n(150)
    18462297            1.5574077246549022305069748074583601730872508
    18472298        """
    18482299        try:
     
    18552306        Return the arcsin of x, i.e., the number y between -pi and pi
    18562307        such that sin(y) == x.
    18572308       
    1858         EXAMPLES:
     2309        EXAMPLES::
     2310
    18592311            sage: x = var('x', ns=1); SR = x.parent()
    18602312            sage: x.arcsin()
    18612313            arcsin(x)
    18622314            sage: SR(0.5).arcsin()
     2315            arcsin(0.500000000000000)
     2316
     2317        Use .n() to get a numerical approximation::
     2318
     2319            sage: SR(0.5).arcsin().n()
    18632320            0.523598775598299
     2321
    18642322            sage: SR(0.999).arcsin()
     2323            arcsin(0.999000000000000)
     2324            sage: SR(-0.999).arcsin()
     2325            -arcsin(0.999000000000000)
     2326            sage: SR(0.999).arcsin().n()
    18652327            1.52607123962616
    1866             sage: SR(-0.999).arcsin()
    1867             -1.52607123962616
    18682328        """
    18692329        return new_Expression_from_GEx(g_asin(self._gobj))
    18702330
     
    18722332        """
    18732333        Return the arc cosine of self.
    18742334
    1875         EXAMPLES:
     2335        EXAMPLES::
     2336
    18762337            sage: x = var('x', ns=1); S = x.parent()
    18772338            sage: x.arccos()
    18782339            arccos(x)
    18792340            sage: S(1).arccos()
    18802341            0
    18812342            sage: S(1/2).arccos()
    1882             1/3*Pi
     2343            1/3*pi
    18832344            sage: S(0.4).arccos()
     2345            arccos(0.400000000000000)
     2346
     2347        Use .n() to get a numerical approximation::
     2348
     2349            sage: S(0.4).arccos().n()
    18842350            1.15927948072741
    18852351            sage: plot(lambda x: S(x).arccos(), -1,1)
    18862352        """
     
    18902356        """
    18912357        Return the arc tangent of self.
    18922358
    1893         EXAMPLES:
     2359        EXAMPLES::
     2360
    18942361            sage: x = var('x', ns=1); S = x.parent()
    18952362            sage: x.arctan()
    18962363            arctan(x)
    18972364            sage: S(1).arctan()
    1898             1/4*Pi
     2365            1/4*pi
    18992366            sage: S(1/2).arctan()
    19002367            arctan(1/2)
    19012368            sage: S(0.5).arctan()
     2369            arctan(0.500000000000000)
     2370
     2371        Use .n() to get a numerical approximation::
     2372
     2373            sage: S(0.5).arctan().n()
    19022374            0.463647609000806
    19032375            sage: plot(lambda x: S(x).arctan(), -20,20)
    19042376        """
     
    19082380        """
    19092381        Return the inverse of the 2-variable tan function on self and x.
    19102382       
    1911         EXAMPLES:
     2383        EXAMPLES::
     2384
    19122385            sage: var('x,y', ns=1); S = parent(x)
    19132386            (x, y)
    19142387            sage: x.arctan2(y)
    19152388            arctan2(x, y)
    19162389            sage: S(1/2).arctan2(1/2)
    1917             1/4*Pi
     2390            1/4*pi
    19182391            sage: maxima.eval('atan2(1/2,1/2)')
    19192392            '%pi/4'
    19202393
     2394            sage: S(-0.7).arctan2(S(-0.6))
     2395            -pi + arctan(1.16666666666667)
     2396
     2397        Use .n() to get a numerical approximation::
     2398
     2399            sage: S(-0.7).arctan2(S(-0.6)).n()
     2400            -2.27942259892257
     2401
    19212402        TESTS:
     2403
    19222404        We compare a bunch of different evaluation points between
    1923         Sage and Maxima:
    1924             sage: S(-0.7).arctan2(S(-0.6))
    1925             -Pi + 0.862170054667226
    1926            
     2405        Sage and Maxima::
     2406
    19272407            sage: float(S(0.7).arctan2(0.6))
    19282408            0.8621700546672264
    19292409            sage: maxima('atan2(0.7,0.6)')
     
    19512431            sage: S(0).arctan2(0)
    19522432            0
    19532433           
     2434            sage: S(I).arctan2(1)
     2435            arctan2(I, 1)
    19542436            sage: S(CDF(0,1)).arctan2(1)
    1955             arctan2(I, 1)
     2437            arctan2(1.0*I, 1)
    19562438            sage: S(1).arctan2(CDF(0,1))
    1957             arctan2(1, I)
     2439            arctan2(1, 1.0*I)
    19582440        """
    19592441        cdef Expression nexp = self.coerce_in(x)
    19602442        return new_Expression_from_GEx(g_atan2(self._gobj, nexp._gobj))
     
    19652447
    19662448        We have $\sinh(x) = (e^{x} - e^{-x})/2$.
    19672449
    1968         EXAMPLES:
     2450        EXAMPLES::
     2451
    19692452            sage: x = var('x', ns=1); S = x.parent()
    19702453            sage: x.sinh()
    19712454            sinh(x)
     
    19742457            sage: S(0).sinh()
    19752458            0
    19762459            sage: S(1.0).sinh()
     2460            sinh(1.00000000000000)
     2461
     2462        Use .n() to get a numerical approximation::
     2463
     2464            sage: S(1.0).sinh().n()
    19772465            1.17520119364380
    19782466            sage: maxima('sinh(1.0)')
    19792467            1.175201193643801
     2468
    19802469            sage: S(1.0000000000000000000000000).sinh()
     2470            sinh(1.0000000000000000000000000)
     2471            sage: S(1).sinh().n(90)
    19812472            1.1752011936438014568823819
    19822473            sage: S(RIF(1)).sinh()
    1983             1.175201193643802?
     2474            sinh(1)
     2475            sage: S(RIF(1)).sinh().n()
     2476            1.17520119364380
    19842477            sage: plot(lambda x: S(x).sinh(), -1, 1)
    19852478        """
    19862479        return new_Expression_from_GEx(g_sinh(self._gobj))
     
    19912484
    19922485        We have $\sinh(x) = (e^{x} + e^{-x})/2$.
    19932486
    1994         EXAMPLES:
     2487        EXAMPLES::
     2488
    19952489            sage: x = var('x', ns=1); S = x.parent()
    19962490            sage: x.cosh()
    19972491            cosh(x)
     
    20002494            sage: S(0).cosh()
    20012495            1
    20022496            sage: S(1.0).cosh()
     2497            cosh(1.00000000000000)
     2498
     2499        Use .n() to get a numerical approximation::
     2500
     2501            sage: S(1.0).cosh().n()
    20032502            1.54308063481524
    20042503            sage: maxima('cosh(1.0)')
    20052504            1.543080634815244
    20062505            sage: S(1.0000000000000000000000000).cosh()
     2506            cosh(1.0000000000000000000000000)
     2507            sage: S(1).cosh().n(90)
    20072508            1.5430806348152437784779056
    20082509            sage: S(RIF(1)).cosh()
    2009             1.543080634815244?
     2510            cosh(1)
     2511            sage: S(RIF(1)).cosh().n()
     2512            1.54308063481524
    20102513            sage: plot(lambda x: S(x).cosh(), -1, 1)
    20112514        """
    20122515        return new_Expression_from_GEx(g_cosh(self._gobj))
     
    20172520
    20182521        We have $\tanh(x) = \sinh(x) / \cosh(x)$.
    20192522
    2020         EXAMPLES:
     2523        EXAMPLES::
     2524
    20212525            sage: x = var('x', ns=1); S = x.parent()
    20222526            sage: x.tanh()
    20232527            tanh(x)
     
    20262530            sage: S(0).tanh()
    20272531            0
    20282532            sage: S(1.0).tanh()
     2533            tanh(1.00000000000000)
     2534
     2535        Use .n() to get a numerical approximation::
     2536
     2537            sage: S(1.0).tanh().n()
    20292538            0.761594155955765
    20302539            sage: maxima('tanh(1.0)')
    20312540            .7615941559557649
     
    20372546        """
    20382547        Return the inverse hyperbolic sine of self.
    20392548       
    2040         EXAMPLES:
     2549        EXAMPLES::
     2550
    20412551            sage: x = var('x', ns=1); S = x.parent()
    20422552            sage: x.arcsinh()
    20432553            arcsinh(x)
     
    20462556            sage: S(1).arcsinh()
    20472557            arcsinh(1)
    20482558            sage: S(1.0).arcsinh()
     2559            arcsinh(1.00000000000000)
     2560
     2561        Use .n() to get a numerical approximation::
     2562
     2563            sage: S(1.0).arcsinh().n()
    20492564            0.881373587019543
    20502565            sage: maxima('asinh(1.0)')
    20512566            0.881373587019543
    20522567
    2053         Sage automatically applies certain identies:
     2568        Sage automatically applies certain identies::
    20542569            sage: S(3/2).arcsinh().cosh()
    20552570            1/2*sqrt(13)
    20562571        """
     
    20602575        """
    20612576        Return the inverse hyperbolic cosine of self.
    20622577
    2063         EXAMPLES:
     2578        EXAMPLES::
     2579
    20642580            sage: x = var('x', ns=1); S = x.parent()
    20652581            sage: x.arccosh()
    20662582            arccosh(x)
    20672583            sage: S(0).arccosh()
    2068             0.5*I*Pi
     2584            1/2*I*pi
    20692585            sage: S(1/2).arccosh()
    20702586            arccosh(1/2)
    20712587            sage: S(CDF(1/2)).arccosh()
     2588            arccosh(0.5)
     2589
     2590        Use .n() to get a numerical approximation::
     2591
     2592            sage: S(CDF(1/2)).arccosh().n()
    20722593            1.0471975512*I
    20732594            sage: maxima('acosh(0.5)')
    20742595            1.047197551196598*%i
     
    20792600        """
    20802601        Return the inverse hyperbolic tangent of self.
    20812602
    2082         EXAMPLES:
     2603        EXAMPLES::
     2604
    20832605            sage: x = var('x', ns=1); S = x.parent()
    20842606            sage: x.arctanh()
    20852607            arctanh(x)
     
    20882610            sage: S(1/2).arctanh()
    20892611            arctanh(1/2)
    20902612            sage: S(0.5).arctanh()
     2613            arctanh(0.500000000000000)
     2614
     2615        Use .n() to get a numerical approximation::
     2616
     2617            sage: S(0.5).arctanh().n()
    20912618            0.549306144334055
    20922619            sage: S(0.5).arctanh().tanh()
    20932620            0.500000000000000
     
    21012628        Return exponential function of self, i.e., e to the
    21022629        power of self.
    21032630
    2104         EXAMPLES:
     2631        EXAMPLES::
     2632
    21052633            sage: x = var('x', ns=1); S = x.parent()
    21062634            sage: x.exp()
    21072635            e^x
     
    21102638            sage: S(1/2).exp()
    21112639            e^(1/2)
    21122640            sage: S(0.5).exp()
     2641            e^0.500000000000000
     2642
     2643           
     2644        Use .n() to get a numerical approximation::
     2645
     2646            sage: S(0.5).exp().n()
    21132647            1.64872127070013
     2648            sage: math.exp(0.5)
     2649            1.6487212707001282
     2650
    21142651            sage: S(0.5).exp().log()
    21152652            0.500000000000000
    2116             sage: math.exp(0.5)
    2117             1.6487212707001282
    21182653            sage: plot(lambda x: S(x).exp(), -2,1)
    21192654        """
    21202655        return new_Expression_from_GEx(g_exp(self._gobj))
     
    21232658        """
    21242659        Return the logarithm of self.
    21252660
    2126         EXAMPLES:
     2661        EXAMPLES::
     2662
    21272663            sage: x, y = var('x, y', ns=1); S = x.parent()
    21282664            sage: x.log()
    21292665            log(x)
     
    21382674            sage: S(1/2).log()
    21392675            log(1/2)
    21402676            sage: S(0.5).log()
     2677            log(0.500000000000000)
     2678
     2679        Use .n() to get a numerical approximation::
     2680
     2681            sage: S(0.5).log().n()
    21412682            -0.693147180559945
    21422683            sage: S(0.5).log().exp()
    21432684            0.500000000000000
     
    21492690
    21502691    def zeta(self):
    21512692        """
    2152         EXAMPLES:
     2693        EXAMPLES::
    21532694            sage: x, y = var('x, y', ns=1); S = x.parent()
    21542695            sage: (x/y).zeta()
    21552696            zeta(x/y)
    21562697            sage: S(2).zeta()
    2157             1/6*Pi^2
     2698            1/6*pi^2
    21582699            sage: S(3).zeta()
    21592700            zeta(3)
    21602701            sage: S(CDF(0,1)).zeta()
    2161             0.00330022368532-0.418155449141*I
     2702            zeta(1.0*I)
     2703            sage: S(CDF(0,1)).zeta().n()
     2704            0.00330022368532 - 0.418155449141*I
    21622705            sage: CDF(0,1).zeta()
    21632706            0.00330022368532 - 0.418155449141*I
    21642707            sage: plot(lambda x: S(x).zeta(), -10,10).show(ymin=-3,ymax=3)
     2708
     2709        TESTS::
     2710           
     2711            sage: t = S(1).zeta(); t
     2712            zeta(1)
     2713            sage: t.n()
     2714            Infinity
    21652715        """
    21662716        _sig_on
    21672717        cdef GEx x = g_zeta(self._gobj)
     
    22402790            sage: S(10).gamma()
    22412791            362880
    22422792            sage: S(10.0r).gamma()
     2793            gamma(10.0)
     2794
     2795        Use .n() to get a numerical approximation::
     2796
     2797            sage: S(10.0r).gamma().n()
    22432798            362880.000000000
    22442799            sage: S(CDF(1,1)).gamma()
    2245             0.498015668118-0.154949828302*I
     2800            gamma(1.0 + 1.0*I)
     2801            sage: S(CDF(1,1)).gamma().n()
     2802            0.498015668118 - 0.154949828302*I
    22462803
    22472804            sage: gp('gamma(1+I)') # 32-bit
    22482805            0.4980156681183560427136911175 - 0.1549498283018106851249551305*I
  • sage/symbolic/function.pxd

    diff --git a/sage/symbolic/function.pxd b/sage/symbolic/function.pxd
    a b  
    11 
    2 cdef new_SFunction_from_serial(int serial, char* name, int nargs)
     2cdef class SFunction:
     3    cdef unsigned int serial
     4    cdef object name
     5    cdef int nargs
     6
     7    cdef object eval_f
     8    cdef object evalf_f
     9    cdef object conjugate_f
     10    cdef object real_part_f
     11    cdef object imag_part_f
     12    cdef object derivative_f
     13    cdef object power_f
     14    cdef object series_f
     15    cdef object print_f
     16    cdef object print_latex_f
     17    cdef object latex_name
     18
     19    # cache hash value
     20    cdef long _hash_(self)
     21    cdef bint __hinit
     22    cdef long __hcache
     23
     24    # common initialization from __init__ and __setstate__
     25    cdef _init_(self)
  • sage/symbolic/function.pyx

    diff --git a/sage/symbolic/function.pyx b/sage/symbolic/function.pyx
    a b  
    2121from expression cimport new_Expression_from_GEx, Expression
    2222from ring import NSR as SR
    2323
     24cdef dict sfunction_serial_dict = {}
     25
    2426from pynac import get_ginac_serial
    2527
     28from sage.misc.fpickle import pickle_function, unpickle_function
     29
    2630cdef class SFunction:
    2731    """
    2832    Return a formal symbolic function.
    2933
    3034    EXAMPLES:
     35
    3136    We create a formal function of one variable, write down
    3237    an expression that involves first and second derivatives,
    33     and extract off coefficients. 
     38    and extract off coefficients.::
     39
    3440        sage: from sage.symbolic.function import function
    3541        sage: var('r,kappa', ns=1)
    3642        (r, kappa)
    3743        sage: psi = function('psi', 1)(r); psi
    3844        psi(r)
    39         sage: g = 1/r^2*(2*r*psi.diff(r,1) + r^2*psi.diff(r,2)); g
    40         (r^2*D[0,0](psi)(r) + 2*r*D[0](psi)(r))/r^2
     45        sage: g = 1/r^2*(2*r*psi.derivative(r,1) + r^2*psi.derivative(r,2)); g
     46        (r^2*D[0, 0](psi)(r) + 2*r*D[0](psi)(r))/r^2
    4147        sage: g.expand()
    42         2*D[0](psi)(r)/r + D[0,0](psi)(r)
    43         sage: g.coeff(psi.diff(r,2))
     48        2*D[0](psi)(r)/r + D[0, 0](psi)(r)
     49        sage: g.coeff(psi.derivative(r,2))
    4450        1
    45         sage: g.coeff(psi.diff(r,1))
     51        sage: g.coeff(psi.derivative(r,1))
    4652        2/r
    4753    """
    48     cdef unsigned int serial
    49     cdef object name
    50     cdef int nargs
    51 
    52     cdef object eval_f
    53     cdef object evalf_f
    54     cdef object conjugate_f
    55     cdef object real_part_f
    56     cdef object imag_part_f
    57     cdef object derivative_f
    58     cdef object power_f
    59     cdef object series_f
    60 
    6154    def __init__(self, name, nargs=0, eval_func=None, evalf_func=None,
    6255            conjugate_func=None, real_part_func=None, imag_part_func=None,
    63             derivative_func=None, power_func=None, series_func=None):
     56            derivative_func=None, power_func=None, series_func=None,
     57            latex_name=None, print_func=None, print_latex_func=None):
    6458        """
    65         EXAMPLES:
     59        EXAMPLES::
     60
    6661            sage: from sage.symbolic.function import function as nfunction
    6762            sage: foo = nfunction("foo", 2)
    6863            sage: x,y,z = var("x y z", ns=1)
    69             sage: foo(x,y) + foo(y,z)^2
    70             foo(y,z)^2 + foo(x,y)
     64            sage: foo(x, y) + foo(y, z)^2
     65            foo(y, z)^2 + foo(x, y)
    7166
    7267            sage: def ev(x): return 2*x
    7368            sage: foo = nfunction("foo", 1, eval_func=ev)
     
    7772            sage: foo(x)
    7873            5
    7974
    80             sage: foo = nfunction("foo", 1, evalf_func=lambda x: 5)
     75            sage: def evalf_f(x, prec=0): return 6
     76            sage: foo = nfunction("foo", 1, evalf_func=evalf_f)
    8177            sage: foo(x)
    8278            foo(x)
    8379            sage: foo(x).n()
    84             5
     80            6
    8581
    8682            sage: foo = nfunction("foo", 1, conjugate_func=ev)
    8783            sage: foo(x).conjugate()
     
    8985
    9086            sage: def deriv(*args,**kwds): print args, kwds; return args[kwds['diff_param']]^2
    9187            sage: foo = nfunction("foo", 2, derivative_func=deriv)
    92             sage: foo(x,y).diff(y)
     88            sage: foo(x,y).derivative(y)
    9389            (x, y) {'diff_param': 1}
    9490            y^2
    9591
     
    105101            (y,) {'var': y, 'options': 0, 'at': 0, 'order': 5}
    106102            y^4 + y^3 + y^2 + y + 1
    107103
     104            sage: def my_print(*args): return "my args are: " + ', '.join(map(repr, args))
     105            sage: foo = nfunction('t', 2, print_func=my_print)
     106            sage: foo(x,y^z)
     107            my args are: x, y^z
    108108
    109         TESTS:
     109            sage: latex(foo(x,y^z))
     110            \mbox{t}\left(x, y^{z}\right)
     111            sage: foo = nfunction('t', 2, print_latex_func=my_print)
     112            sage: foo(x,y^z)
     113            t(x, y^z)
     114            sage: latex(foo(x,y^z))
     115            my args are: x, y^z
     116            sage: foo = nfunction('t', 2, latex_name='foo')
     117            sage: latex(foo(x,y^z))
     118            \mbox{foo}\left(x, y^{z}\right)
     119
     120
     121        TESTS::
     122
    110123            # eval_func raises exception
    111124            sage: def ef(x): raise RuntimeError, "foo"
    112125            sage: bar = nfunction("bar", 1, eval_func=ef)
     
    138151            ValueError: eval_func parameter must be callable
    139152
    140153        """
    141         cdef GFunctionOpt opt
    142         serial = -1
    143         try:
    144             self.serial = find_function(name, nargs)
    145         except ValueError, err:
    146             pass
    147        
    148         opt = g_function_options_args(name, nargs)
    149         opt.set_python_func()
    150         if eval_func:
    151             if not callable(eval_func):
    152                 raise ValueError, "eval_func parameter must be callable"
    153             self.eval_f = eval_func
    154             opt.eval_func(eval_func)
    155         if evalf_func:
    156             if not callable(evalf_func):
    157                 raise ValueError, "evalf_func parameter must be callable"
    158             self.evalf_f = evalf_func
    159             opt.evalf_func(evalf_func)
    160         if conjugate_func:
    161             if not callable(conjugate_func):
    162                 raise ValueError, "conjugate_func parameter must be callable"
    163             self.conjugate_f = conjugate_func
    164             opt.conjugate_func(conjugate_func)
    165         if real_part_func:
    166             if not callable(real_part_func):
    167                 raise ValueError, "real_part_func parameter must be callable"
    168             self.real_part_f = real_part_func
    169             opt.real_part_func(real_part_func)
    170         if imag_part_func:
    171             if not callable(imag_part_func):
    172                 raise ValueError, "imag_part_func parameter must be callable"
    173             self.imag_part_f = imag_part_func
    174             opt.imag_part_func(imag_part_func)
    175         if derivative_func:
    176             if not callable(derivative_func):
    177                 raise ValueError, "derivative_func parameter must be callable"
    178             self.derivative_f = derivative_func
    179             opt.derivative_func(derivative_func)
    180         if power_func:
    181             if not callable(power_func):
    182                 raise ValueError, "power_func parameter must be callable"
    183             self.power_f = power_func
    184             opt.power_func(power_func)
    185         if series_func:
    186             if not callable(series_func):
    187                 raise ValueError, "series_func parameter must be callable"
    188             self.series_f = series_func
    189             opt.series_func(series_func)
    190 
    191 
    192         if serial is -1 or serial < get_ginac_serial():
    193             self.serial = g_register_new(opt)
    194         else:
    195             self.serial = serial
    196 
    197         g_foptions_assign(g_registered_functions().index(self.serial), opt)
    198 
    199154        self.name = name
    200155        if nargs:
    201156            self.nargs = nargs
    202157        else:
    203158            self.nargs = 0
    204159
     160        self.eval_f = eval_func
     161        if eval_func:
     162            if not callable(eval_func):
     163                raise ValueError, "eval_func parameter must be callable"
     164
     165        self.evalf_f = evalf_func
     166        if evalf_func:
     167            if not callable(evalf_func):
     168                raise ValueError, "evalf_func parameter must be callable"
     169
     170        self.conjugate_f = conjugate_func
     171        if conjugate_func:
     172            if not callable(conjugate_func):
     173                raise ValueError, "conjugate_func parameter must be callable"
     174
     175        self.real_part_f = real_part_func
     176        if real_part_func:
     177            if not callable(real_part_func):
     178                raise ValueError, "real_part_func parameter must be callable"
     179
     180        self.imag_part_f = imag_part_func
     181        if imag_part_func:
     182            if not callable(imag_part_func):
     183                raise ValueError, "imag_part_func parameter must be callable"
     184
     185        self.derivative_f = derivative_func
     186        if derivative_func:
     187            if not callable(derivative_func):
     188                raise ValueError, "derivative_func parameter must be callable"
     189
     190        self.power_f = power_func
     191        if power_func:
     192            if not callable(power_func):
     193                raise ValueError, "power_func parameter must be callable"
     194
     195        self.series_f = series_func
     196        if series_func:
     197            if not callable(series_func):
     198                raise ValueError, "series_func parameter must be callable"
     199
     200        # handle custom printing
     201        # if print_func is defined, it is used instead of name
     202        # latex printing can be customised either by setting a string latex_name
     203        # or giving a custom function argument print_latex_func
     204        if latex_name and print_latex_func:
     205            raise ValueError, "only one of latex_name and print_latex_name should be specified."
     206
     207        self.print_latex_f = print_latex_func
     208        self.latex_name = latex_name
     209        self.print_f = print_func
     210
     211        self._init_()
     212
     213    # this is separated from the constructor since it is also called
     214    # during unpickling
     215    cdef _init_(self):
     216        # see if there is already an SFunction with the same state
     217        cdef SFunction sfunc
     218        cdef long myhash = self._hash_()
     219        for sfunc in sfunction_serial_dict.itervalues():
     220            if myhash == sfunc._hash_():
     221                # found one, set self.serial to be a copy
     222                self.serial = sfunc.serial
     223                return
     224
     225        cdef GFunctionOpt opt
     226       
     227        opt = g_function_options_args(self.name, self.nargs)
     228        opt.set_python_func()
     229
     230        if self.eval_f:
     231            opt.eval_func(self.eval_f)
     232
     233        if self.evalf_f:
     234            opt.evalf_func(self.evalf_f)
     235
     236        if self.conjugate_f:
     237            opt.conjugate_func(self.conjugate_f)
     238
     239        if self.real_part_f:
     240            opt.real_part_func(self.real_part_f)
     241
     242        if self.imag_part_f:
     243            opt.imag_part_func(self.imag_part_f)
     244
     245        if self.derivative_f:
     246            opt.derivative_func(self.derivative_f)
     247
     248        if self.power_f:
     249            opt.power_func(self.power_f)
     250
     251        if self.series_f:
     252            opt.series_func(self.series_f)
     253
     254        if self.print_latex_f:
     255            opt.set_print_latex_func(self.print_latex_f)
     256
     257        if self.latex_name:
     258            opt.latex_name(self.latex_name)
     259
     260        if self.print_f:
     261            opt.set_print_dflt_func(self.print_f)
     262
     263        self.serial = g_register_new(opt)
     264
     265        g_foptions_assign(g_registered_functions().index(self.serial), opt)
     266        global sfunction_serial_dict
     267        sfunction_serial_dict[self.serial] = self
     268
     269        self.__hinit = False
     270
     271    # cache the hash value of this function
     272    # this is used very often while unpickling to see if there is already
     273    # a function with the same properties
     274    cdef long _hash_(self):
     275        if not self.__hinit:
     276            # create a string representation of this SFunction
     277            slist = [self.nargs, self.name, str(self.latex_name)]
     278            for f in [self.eval_f, self.evalf_f, self.conjugate_f,
     279                    self.real_part_f, self.imag_part_f, self.derivative_f,
     280                    self.power_f, self.series_f, self.print_f,
     281                    self.print_latex_f]:
     282                if f:
     283                    slist.append(hash(f.func_code))
     284                else:
     285                    slist.append(' ')
     286            self.__hcache = hash(tuple(slist))
     287            self.__hinit = True
     288        return self.__hcache
     289
     290    def __hash__(self):
     291        """
     292        TESTS::
     293            sage: from sage.symbolic.function import function as nfunction
     294            sage: foo = nfunction("foo", 2)
     295            sage: hash(foo)
     296            7313648655953480146
     297
     298            sage: def ev(x): return 2*x
     299            sage: foo = nfunction("foo", 2, eval_func = ev)
     300            sage: hash(foo)
     301            4884169210301491732
     302
     303        """
     304        return self.serial*self._hash_()
     305
     306    def __getstate__(self):
     307        """
     308        Returns a tuple describing the state of this object for pickling.
     309
     310        Pickling SFunction objects is limited by the ability to pickle
     311        functions in python. We use sage.misc.fpickle.pickle_function for
     312        this purpose, which only works if there are no nested functions.
     313
     314
     315        This should return all information that will be required to unpickle
     316        the object. The functionality for unpickling is implemented in
     317        __setstate__().
     318
     319        In order to pickle SFunction objects, we return a tuple containing
     320       
     321         * 0  - as pickle version number
     322                in case we decide to change the pickle format in the feature
     323         * name of this function
     324         * number of arguments
     325         * latex_name
     326         * a tuple containing attempts to pickle the following optional
     327           functions, in the order below
     328           * eval_f
     329           * evalf_f
     330           * conjugate_f
     331           * real_part_f
     332           * imag_part_f
     333           * derivative_f
     334           * power_f
     335           * series_f
     336           * print_f
     337           * print_latex_f
     338
     339        EXAMPLES::
     340            sage: from sage.symbolic.function import function as nfunction
     341            sage: foo = nfunction("foo", 2)
     342            sage: foo.__getstate__()
     343            (0, 'foo', 2, None, [None, None, None, None, None, None, None, None, None, None])
     344            sage: t = loads(dumps(foo))
     345            sage: t == foo
     346            True
     347            sage: var('x,y',ns=1)
     348            (x, y)
     349            sage: t(x,y)
     350            foo(x, y)
     351
     352            sage: def ev(x,y): return 2*x
     353            sage: foo = nfunction("foo", 2, eval_func = ev)
     354            sage: foo.__getstate__()
     355            (0, 'foo', 2, None, ["...", None, None, None, None, None, None, None, None, None])
     356
     357            sage: u = loads(dumps(foo))
     358            sage: u == foo
     359            True
     360            sage: t == u
     361            False
     362            sage: u(y,x)
     363            2*y
     364
     365            sage: def evalf_f(x, prec=0): return int(6)
     366            sage: foo = nfunction("foo", 1, evalf_func=evalf_f)
     367            sage: foo.__getstate__()
     368            (0, 'foo', 1, None, [None, "...", None, None, None, None, None, None, None, None])
     369
     370            sage: v = loads(dumps(foo))
     371            sage: v == foo
     372            True
     373            sage: v == u
     374            False
     375            sage: foo(y).n()
     376            6
     377            sage: v(y).n()
     378            6
     379
     380        Test pickling expressions with symbolic functions::
     381           
     382            sage: u = loads(dumps(foo(x)^2 + foo(y) + x^y)); u
     383            x^y + foo(x)^2 + foo(y)
     384            sage: u.subs(y=0)
     385            foo(x)^2 + foo(0) + 1
     386            sage: u.subs(y=0).n()
     387            43.0000000000000
     388        """
     389        return (0, self.name, self.nargs, self.latex_name,
     390                map(pickle_wrapper, [self.eval_f, self.evalf_f,
     391                    self.conjugate_f, self.real_part_f, self.imag_part_f,
     392                    self.derivative_f, self.power_f, self.series_f,
     393                    self.print_f, self.print_latex_f]))
     394
     395    def __setstate__(self, state):
     396        """
     397        Initializes the state of the object from data saved in a pickle.
     398
     399        During unpickling __init__ methods of classes are not called, the saved
     400        data is passed to the class via this function instead.
     401
     402        TESTS::
     403
     404            sage: from sage.symbolic.function import function as nfunction
     405            sage: var('x,y', ns=1)
     406            (x, y)
     407            sage: foo = nfunction("foo", 2)
     408            sage: bar = nfunction("bar", 1)
     409            sage: bar.__setstate__(foo.__getstate__())
     410
     411        Note that the other direction doesn't work here, since foo._hash_()
     412        hash already been initialized.::
     413
     414            sage: bar
     415            foo
     416            sage: bar(x,y)
     417            foo(x, y)
     418        """
     419        # check input
     420        if state[0] != 0 or len(state) != 5:
     421            raise ValueError, "unknown state information"
     422
     423        self.name = state[1]
     424        self.nargs = state[2]
     425        self.latex_name = state[3]
     426        self.eval_f = unpickle_wrapper(state[4][0])
     427        self.evalf_f = unpickle_wrapper(state[4][1])
     428        self.conjugate_f = unpickle_wrapper(state[4][2])
     429        self.real_part_f = unpickle_wrapper(state[4][3])
     430        self.imag_part_f = unpickle_wrapper(state[4][4])
     431        self.derivative_f = unpickle_wrapper(state[4][5])
     432        self.power_f = unpickle_wrapper(state[4][6])
     433        self.series_f = unpickle_wrapper(state[4][7])
     434        self.print_f = unpickle_wrapper(state[4][8])
     435        self.print_latex_f = unpickle_wrapper(state[4][9])
     436
     437        self._init_()
     438
    205439    def __repr__(self):
    206440        """
    207441        EXAMPLES:
     
    231465
    232466    def __call__(self, *args, coerce=True):
    233467        """
    234         EXAMPLES:
     468        EXAMPLES::
     469
    235470            sage: from sage.symbolic.function import function as nfunction
    236471            sage: foo = nfunction("foo", 2)
    237472            sage: x,y,z = var("x y z", ns=1)
    238473            sage: foo(x,y)
    239             foo(x,y)
     474            foo(x, y)
    240475
    241476            sage: foo(y)
    242477            Traceback (most recent call last):
     
    247482            sage: bar(x)
    248483            bar(x)
    249484            sage: bar(x,y)
    250             bar(x,y)
     485            bar(x, y)
    251486
    252         TESTS:
     487        TESTS::
     488
    253489            # test coercion
    254490            sage: bar(ZZ)
    255491            Traceback (most recent call last):
     
    359595
    360596function = SFunction
    361597
    362 cdef new_SFunction_from_serial(int serial, char* name, int nargs):
    363     cdef SFunction f = PY_NEW(SFunction)
    364     f.serial = serial
    365     f.name = name
    366     f.nargs = nargs
    367     return f
     598def get_sfunction_from_serial(serial):
     599    global sfunction_serial_dict
     600    return sfunction_serial_dict.get(serial)
     601
     602import base64
     603def pickle_wrapper(f):
     604    if f is None:
     605        return None
     606    return pickle_function(f)
     607
     608def unpickle_wrapper(p):
     609    if p is None:
     610        return None
     611    return unpickle_function(p)
    368612
    369613def init_sfunction_map():
    370614    """
  • sage/symbolic/pynac.pyx

    diff --git a/sage/symbolic/pynac.pyx b/sage/symbolic/pynac.pyx
    a b  
    1919from sage.structure.element import Element
    2020from sage.rings.integer_ring import ZZ
    2121from sage.rings.integer cimport Integer
    22 from sage.rings.real_mpfr import RR, RealField
     22from sage.rings.real_mpfr import RR, RealField_constructor
    2323from sage.rings.all import CC
    2424from sage.calculus.all import SR
    2525
    2626from sage.symbolic.expression cimport Expression, new_Expression_from_GEx
     27from sage.symbolic.function import get_sfunction_from_serial
     28from sage.symbolic.function cimport SFunction
    2729
    2830import constants
    2931import ring
     
    3234# Symbolic function helpers
    3335#################################################################
    3436
     37# We declare the functions defined below as extern here, to prevent Cython
     38# from generating separate declarations for them which confuse g++
    3539cdef extern from *:
    3640    object exvector_to_PyTuple(GExVector seq)
    3741    GEx pyExpression_to_ex(object res) except *
    3842    object ex_to_pyExpression(GEx juice)
     43    object paramset_to_PyTuple(GParamSet juice)
     44    int py_get_ginac_serial()
    3945
    4046cdef public object ex_to_pyExpression(GEx juice):
    4147    """
     
    7581        raise TypeError, "eval function did not return a symbolic expression or an element that can be coerced into a symbolic expression"
    7682    return (<Expression>t)._gobj
    7783
     84cdef public object paramset_to_PyTuple(GParamSet s):
     85    """
     86    Converts a std::multiset<unsigned> to a PyTuple.
     87   
     88    Used to pass a list of parameter numbers with respect to which a function
     89    is differentiaed to the printing functions py_print_fderivative and
     90    py_latex_fderivative.
     91    """
     92    cdef GParamSetIter itr = s.begin()
     93    res = []
     94    while itr.is_not_equal(s.end()):
     95        res.append(itr.obj())
     96        itr.inc()
     97    return res
     98
    7899cdef int GINAC_FN_SERIAL = 0
    79100
    80101cdef set_ginac_fn_serial():
     
    87108    global GINAC_FN_SERIAL
    88109    GINAC_FN_SERIAL = g_registered_functions().size()
    89110
    90 def get_ginac_serial():
     111cdef public int py_get_ginac_serial():
    91112    """
    92113    Returns the number of C++ level functions defined by GiNaC.
    93114
     
    96117        sage: get_ginac_serial() >= 40
    97118        True
    98119    """
     120    global GINAC_FN_SERIAL
     121    return GINAC_FN_SERIAL
     122
     123def get_ginac_serial():
     124    global GINAC_FN_SERIAL
    99125    return GINAC_FN_SERIAL
    100126
    101127#################################################################
    102128# Printing helpers
    103129#################################################################
    104130
     131# We declare the functions defined below as extern here, to prevent Cython
     132# from generating separate declarations for them which confuse g++
    105133cdef extern from *:
    106     char* py_latex(object o) except +
     134    stdstring* py_latex(object o) except +
     135    stdstring* py_latex_variable(char* var_name) except +
     136    stdstring* py_print_function(unsigned id, object args) except +
     137    stdstring* py_latex_function(unsigned id, object args) except +
     138    stdstring* py_print_fderivative(unsigned id, object params, object args) except +
     139    stdstring* py_latex_fderivative(unsigned id, object params, object args) except +
    107140
    108 cdef public char* py_latex(object o) except +:
     141cdef public stdstring* py_latex(object o) except +:
    109142    from sage.misc.latex import latex
    110143    s = latex(o)
    111     return s
     144    return string_from_pystr(s)
     145
     146cdef stdstring* string_from_pystr(object py_str):
     147    """
     148    Creates a C++ string with the same contents as the given python string.
     149
     150    Used when passing string output to pynac for printing, since we don't want
     151    to mess with reference counts of the python objects and we cannot guarantee
     152    they won't be garbage collected before the output is printed.
     153    """
     154    cdef char *t_str = PyString_AsString(py_str)
     155    cdef Py_ssize_t slen = len(py_str)
     156    cdef stdstring* sout = stdstring_construct_cstr(t_str, slen)
     157    return sout
     158
     159cdef public stdstring* py_latex_variable(char* var_name) except +:
     160    """
     161    Returns a c++ string containing the latex representation of the given
     162    variable name.
     163
     164    Real work is done by the function sage.misc.latex.latex_variable_name.
     165
     166    EXAMPLES::
     167
     168        sage: from sage.symbolic.pynac import py_latex_variable_for_doctests
     169        sage: py_latex_variable = py_latex_variable_for_doctests
     170
     171        sage: py_latex_variable('a')
     172        a
     173        sage: py_latex_variable('abc')
     174        \mbox{abc}
     175        sage: py_latex_variable('a_00')
     176        a_{00}
     177        sage: py_latex_variable('sigma_k')
     178        \sigma_{k}
     179        sage: py_latex_variable('sigma389')
     180        \sigma_{389}
     181        sage: py_latex_variable('beta_00')
     182        \beta_{00}
     183    """
     184    cdef Py_ssize_t slen
     185    from sage.misc.latex import latex_variable_name
     186    py_vlatex = latex_variable_name(var_name)
     187    return string_from_pystr(py_vlatex)
     188
     189def py_latex_variable_for_doctests(x):
     190    cdef stdstring* ostr = py_latex_variable(PyString_AsString(x))
     191    print(ostr.c_str())
     192    stdstring_delete(ostr)
     193
     194def py_print_function_pystring(id, args, fname_paren=False):
     195    """
     196    Return a string with the representation of the symbolic function specified
     197    by the given id applied to args.
     198   
     199    INPUT:
     200
     201        id --   serial number of the corresponding symbolic function
     202        params -- Set of parameter numbers with respect to which to take
     203                    the derivative.
     204        args -- arguments of the function.
     205
     206    EXAMPLES::
     207
     208        sage: from sage.symbolic.pynac import py_print_function_pystring
     209        sage: from sage.symbolic.function import function, get_sfunction_from_serial, get_ginac_serial
     210        sage: var('x,y,z',ns=1)
     211         (x, y, z)
     212        sage: foo = function('foo', 2)
     213        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     214        ...     if get_sfunction_from_serial(i) == foo: break
     215
     216        sage: get_sfunction_from_serial(i) == foo
     217        True
     218        sage: py_print_function_pystring(i, (x,y))
     219        'foo(x, y)'
     220        sage: py_print_function_pystring(i, (x,y), True)
     221        '(foo)(x, y)'
     222        sage: def my_print(*args): return "my args are: " + ', '.join(map(repr, args))
     223        sage: foo = function('foo', 2, print_func=my_print)
     224        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     225        ...     if get_sfunction_from_serial(i) == foo: break
     226
     227        sage: get_sfunction_from_serial(i) == foo
     228        True
     229        sage: py_print_function_pystring(i, (x,y))
     230        'my args are: x, y'
     231    """
     232    cdef SFunction func = get_sfunction_from_serial(id)
     233    # This function is called from two places, from function::print in pynac
     234    # and from py_print_fderivative. function::print checks if the serial
     235    # belongs to a function defined at the C++ level. There are no C++ level
     236    # functions that return an instance of fderivative when derivated. Hence,
     237    # func will never be None.
     238    assert(func is not None)
     239
     240    # if function has a custom print function call it
     241    if func.print_f is not None:
     242        res = func.print_f(*args)
     243        # make sure the output is a string
     244        if res is None:
     245            return ""
     246        if not isinstance(res, str):
     247            return str(res)
     248        return res
     249
     250    # otherwise use default output
     251    if fname_paren:
     252        olist = ['(', func.name, ')']
     253    else:
     254        olist = [func.name]
     255    olist.extend(['(', ', '.join(map(repr, args)), ')'])
     256    return ''.join(olist)
     257
     258cdef public stdstring* py_print_function(unsigned id, object args) except +:
     259    return string_from_pystr(py_print_function_pystring(id, args))
     260
     261def py_latex_function_pystring(id, args, fname_paren=False):
     262    """
     263    Return a string with the latex representation of the symbolic function
     264    specified by the given id applied to args.
     265   
     266    See documentation of py_print_function_pystring for more information.
     267
     268    EXAMPLES::
     269
     270        sage: from sage.symbolic.pynac import py_latex_function_pystring
     271        sage: from sage.symbolic.function import function, get_sfunction_from_serial, get_ginac_serial
     272        sage: var('x,y,z',ns=1)
     273         (x, y, z)
     274        sage: foo = function('foo', 2)
     275        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     276        ...     if get_sfunction_from_serial(i) == foo: break
     277
     278        sage: get_sfunction_from_serial(i) == foo
     279        True
     280        sage: py_latex_function_pystring(i, (x,y^z))
     281        '\\mbox{foo}\\left(x, y^{z}\\right)'
     282        sage: py_latex_function_pystring(i, (x,y^z), True)
     283         '\\left(\\mbox{foo}\\right)\\left(x, y^{z}\\right)'
     284
     285    Test latex_name::
     286
     287        sage: foo = function('foo', 2, latex_name=r'\mathrm{bar}')
     288        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     289        ...     if get_sfunction_from_serial(i) == foo: break
     290
     291        sage: get_sfunction_from_serial(i) == foo
     292        True
     293        sage: py_latex_function_pystring(i, (x,y^z))
     294        '\\mbox{\\mathrm{bar}}\\left(x, y^{z}\\right)'
     295
     296    Test custom func::
     297
     298        sage: def my_print(*args): return "my args are: " + ', '.join(map(repr, args))
     299        sage: foo = function('foo', 2, print_latex_func=my_print)
     300        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     301        ...     if get_sfunction_from_serial(i) == foo: break
     302
     303        sage: get_sfunction_from_serial(i) == foo
     304        True
     305        sage: py_latex_function_pystring(i, (x,y^z))
     306        'my args are: x, y^z'
     307
     308       
     309    """
     310    cdef SFunction func = get_sfunction_from_serial(id)
     311    # This function is called from two places, from function::print in pynac
     312    # and from py_latex_fderivative. function::print checks if the serial
     313    # belongs to a function defined at the C++ level. There are no C++ level
     314    # functions that return an instance of fderivative when derivated. Hence,
     315    # func will never be None.
     316    assert(func is not None)
     317
     318    # if function has a custom print function call it
     319    if func.print_latex_f:
     320        res = func.print_latex_f(*args)
     321        # make sure the output is a string
     322        if res is None:
     323            return ""
     324        if not isinstance(res, str):
     325            return str(res)
     326        return res
     327
     328    # otherwise, use the latex name if defined
     329    if func.latex_name:
     330        name = func.latex_name
     331    else:
     332        name = func.name # if latex_name is not defined, use default name
     333    if fname_paren:
     334        olist = [r'\left(', r'\mbox{', name, '}', r'\right)']
     335    else:
     336        olist = [r'\mbox{', name, '}']
     337    # print the arguments
     338    olist.extend([r'\left(', ', '.join([x._latex_() for x in args]),
     339        r'\right)'] )
     340    return ''.join(olist)
     341
     342cdef public stdstring* py_latex_function(unsigned id, object args) except +:
     343    return string_from_pystr(py_latex_function_pystring(id, args))
     344
     345cdef public stdstring* py_print_fderivative(unsigned id, object params,
     346        object args) except +:
     347    """
     348    Return a string with the representation of the derivative of the symbolic
     349    function specified by the given id, lists of params and args.
     350   
     351    INPUT:
     352
     353        id --   serial number of the corresponding symbolic function
     354        params -- Set of parameter numbers with respect to which to take
     355                    the derivative.
     356        args -- arguments of the function.
     357
     358    EXAMPLES::
     359
     360        sage: from sage.symbolic.pynac import py_print_fderivative_for_doctests as py_print_fderivative
     361        sage: var('x,y,z',ns=1)
     362        (x, y, z)
     363        sage: from sage.symbolic.function import function, get_sfunction_from_serial, get_ginac_serial
     364        sage: foo = function('foo', 2)
     365        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     366        ...     if get_sfunction_from_serial(i) == foo: break
     367
     368        sage: get_sfunction_from_serial(i) == foo
     369        True
     370        sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
     371        D[0, 1, 0, 1](foo)(x, y^z)
     372
     373    Test custom print function::
     374
     375        sage: def my_print(*args): return "func_with_args(" + ', '.join(map(repr, args)) +')'
     376        sage: foo = function('foo', 2, print_func=my_print)
     377        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     378        ...     if get_sfunction_from_serial(i) == foo: break
     379
     380        sage: get_sfunction_from_serial(i) == foo
     381        True
     382        sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
     383        D[0, 1, 0, 1]func_with_args(x, y^z)
     384
     385
     386    """
     387    ostr = ''.join(['D[', ', '.join([repr(int(x)) for x in params]), ']'])
     388    fstr = py_print_function_pystring(id, args, True)
     389    py_res = ostr + fstr
     390    return string_from_pystr(py_res)
     391
     392def py_print_fderivative_for_doctests(id, params, args):
     393    cdef stdstring* ostr = py_print_fderivative(id, params, args)
     394    print(ostr.c_str())
     395    stdstring_delete(ostr)
     396
     397cdef public stdstring* py_latex_fderivative(unsigned id, object params,
     398        object args) except +:
     399    """
     400    Return a string with the latex representation of the derivative of the
     401    symbolic function specified by the given id, lists of params and args.
     402
     403    See documentation of py_print_fderivative for more information.
     404
     405    EXAMPLES::
     406
     407        sage: from sage.symbolic.pynac import py_latex_fderivative_for_doctests as py_latex_fderivative
     408        sage: var('x,y,z',ns=1)
     409        (x, y, z)
     410        sage: from sage.symbolic.function import function, get_sfunction_from_serial, get_ginac_serial
     411        sage: foo = function('foo', 2)
     412        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     413        ...     if get_sfunction_from_serial(i) == foo: break
     414
     415        sage: get_sfunction_from_serial(i) == foo
     416        True
     417        sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
     418        D[0, 1, 0, 1]\left(\mbox{foo}\right)\left(x, y^{z}\right)
     419
     420    Test latex_name::
     421
     422        sage: foo = function('foo', 2, latex_name=r'\mathrm{bar}')
     423        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     424        ...     if get_sfunction_from_serial(i) == foo: break
     425
     426        sage: get_sfunction_from_serial(i) == foo
     427        True
     428        sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
     429        D[0, 1, 0, 1]\left(\mbox{\mathrm{bar}}\right)\left(x, y^{z}\right)
     430
     431    Test custom func::
     432
     433        sage: def my_print(*args): return "func_with_args(" + ', '.join(map(repr, args)) +')'
     434        sage: foo = function('foo', 2, print_latex_func=my_print)
     435        sage: for i in range(get_ginac_serial(), get_ginac_serial()+50):
     436        ...     if get_sfunction_from_serial(i) == foo: break
     437
     438        sage: get_sfunction_from_serial(i) == foo
     439        True
     440        sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
     441        D[0, 1, 0, 1]func_with_args(x, y^z)
     442
     443    """
     444    ostr = ''.join(['D[', ', '.join([repr(int(x)) for x in params]), ']'])
     445    fstr = py_latex_function_pystring(id, args, True)
     446    py_res = ostr + fstr
     447    return string_from_pystr(py_res)
     448
     449def py_latex_fderivative_for_doctests(id, params, args):
     450    cdef stdstring* ostr = py_latex_fderivative(id, params, args)
     451    print(ostr.c_str())
     452    stdstring_delete(ostr)
     453
     454#################################################################
     455# Archive helpers
     456#################################################################
     457
     458cdef extern from *:
     459    stdstring* py_dumps(object o) except +
     460    object py_loads(object s) except +
     461    object py_get_sfunction_from_serial(unsigned s) except +
     462    unsigned py_get_serial_from_sfunction(SFunction f) except +
     463
     464from sage.structure.sage_object import loads, dumps
     465cdef public stdstring* py_dumps(object o) except +:
     466    s = dumps(o, compress=False)
     467    # pynac archive format terminates atoms with zeroes.
     468    # since pickle output can break the archive format
     469    # we use the base64 data encoding
     470    import base64
     471    s = base64.b64encode(s)
     472    return string_from_pystr(s)
     473
     474cdef public object py_loads(object s) except +:
     475    import base64
     476    s = base64.b64decode(s)
     477    return loads(s)
     478
     479cdef public object py_get_sfunction_from_serial(unsigned s) except +:
     480    return get_sfunction_from_serial(s)
     481
     482cdef public unsigned py_get_serial_from_sfunction(SFunction f) except +:
     483    return f.serial
    112484
    113485#################################################################
    114486# Modular helpers
     
    116488
    117489from sage.structure.element cimport Element
    118490
     491# We declare the functions defined below as extern here, to prevent Cython
     492# from generating separate declarations for them which confuse g++
    119493cdef extern from *:
    120494    int py_get_parent_char(object o) except *
    121495
     
    145519    bint py_is_prime(object x)
    146520    object py_numer(object x)
    147521    object py_denom(object x)
    148     object py_float(object x)
     522    object py_float(object x, int prec) except +
    149523    object py_RDF_from_double(double x)
    150524    object py_factorial(object x)
    151525    object py_doublefactorial(object x)
     
    182556    object py_li2(object x)
    183557    object py_psi(object x)
    184558    object py_psi2(object x, object y)
    185     object py_eval_pi(long int)
    186     object py_eval_euler_gamma(long int)
    187     object py_eval_catalan(long int)
     559    object py_eval_pi(int)
     560    object py_eval_euler_gamma(int)
     561    object py_eval_catalan(int)
     562    object py_eval_unsigned_infinity()
     563    object py_eval_infinity()
     564    object py_eval_neg_infinity()
    188565    object py_integer_from_long(long int)
    189566    object py_integer_from_python_obj(object x)
    190567
     
    453830    except AttributeError:
    454831        return 1
    455832
    456 cdef public object py_float(object n):
    457     return float(n)
     833cdef public object py_float(object n, int prec) except +:
     834    """
     835    Evaluate pynac numeric objects numerically.
     836
     837    TESTS::
     838
     839        sage: from sage.symbolic.pynac import py_float_for_doctests as py_float
     840        sage: py_float(I, 10)
     841        1.0*I
     842        sage: py_float(pi, 100)
     843        3.1415926535897932384626433833
     844        sage: py_float(CDF(10), 53)
     845        10.0
     846        sage: type(py_float(CDF(10), 53))
     847        <type 'sage.rings.complex_double.ComplexDoubleElement'>
     848        sage: py_float(CC(1/2), 53)
     849        0.500000000000000
     850        sage: type(py_float(CC(1/2), 53))
     851        <type 'sage.rings.complex_number.ComplexNumber'>
     852    """
     853    if isinstance(n, (int, long, float)):
     854        return RealField_constructor(prec)(n)
     855    from sage.structure.coerce import parent
     856    if hasattr(parent(n), 'to_prec'):
     857        return parent(n).to_prec(prec)(n)
     858    from sage.misc.functional import numerical_approx
     859    return numerical_approx(n, prec)
     860
     861def py_float_for_doctests(n, prec):
     862    """
     863    This function is for testing py_float.
     864
     865    EXAMPLES::
     866       
     867        sage: from sage.symbolic.pynac import py_float_for_doctests
     868        sage: py_float_for_doctests(pi, 80)
     869        3.1415926535897932384626
     870    """
     871    return py_float(n, prec)
    458872
    459873# TODO: Optimize this
    460874from sage.rings.real_double import RDF
     
    533947        return cos(float(x))
    534948
    535949cdef public object py_zeta(object x):
     950    """
     951    Return the value of the zeta function at the given value.
     952
     953    The value is expected to be a numerical object, in RR, CC, RDF or CDF,
     954    different from 1.
     955
     956    TESTS::
     957
     958        sage: from sage.symbolic.pynac import py_zeta_for_doctests as py_zeta
     959        sage: py_zeta(CC.0)
     960        0.00330022368532410 - 0.418155449141322*I
     961        sage: py_zeta(CDF(5))
     962        1.03692775514
     963        sage: py_zeta(RealField(100)(5))
     964        1.0369277551433699263313654865
     965    """
    536966    try:
    537967        return x.zeta()
    538968    except AttributeError:
    539         return RR(x).zeta()
     969        pass
     970    # zeta() evaluates it's argument before calling this, so we should never
     971    # end up here. Precision is not a problem here, since zeta() passes that
     972    # on when it calls evalf() on the argument.
     973    raise RuntimeError, "py_zeta() received non evaluated argument"
     974
     975def py_zeta_for_doctests(x):
     976    """
     977    This function is for testing py_zeta().
     978
     979    EXAMPLES::
     980
     981        sage: from sage.symbolic.pynac import py_zeta_for_doctests
     982        sage: py_zeta_for_doctests(CC.0)
     983        0.00330022368532410 - 0.418155449141322*I
     984    """
     985    return py_zeta(x)
    540986
    541987cdef public object py_exp(object x):
     988    """
     989    Return the value of the exp function at the given value.
     990
     991    The value is expected to be a numerical object, in RR, CC, RDF or CDF.
     992
     993    TESTS::
     994
     995        sage: from sage.symbolic.pynac import py_exp_for_doctests as py_exp
     996        sage: py_exp(CC(1))
     997        2.71828182845905
     998        sage: py_exp(CC(.5*I))
     999        0.877582561890373 + 0.479425538604203*I
     1000    """
    5421001    try:
    5431002        return x.exp()
    5441003    except AttributeError:
    545         return RR(x).exp()
     1004        pass
     1005    # exp() evaluates it's argument before calling this, so we should never
     1006    # end up here. Precision is not a problem here, since exp() passes that
     1007    # on when it calls evalf() on the argument.
     1008    raise RuntimeError, "py_exp() received non evaluated argument"
     1009
     1010def py_exp_for_doctests(x):
     1011    """
     1012    This function tests py_exp.
     1013
     1014    EXAMPLES::
     1015
     1016        sage: from sage.symbolic.pynac import py_exp_for_doctests
     1017        sage: py_exp_for_doctests(CC(2))
     1018        7.38905609893065
     1019    """
     1020    return py_exp(x)
    5461021
    5471022cdef public object py_log(object x):
     1023    """
     1024    Return the value of the log function at the given value.
     1025
     1026    The value is expected to be a numerical object, in RR, CC, RDF or CDF.
     1027
     1028    TESTS::
     1029
     1030        sage: from sage.symbolic.pynac import py_log_for_doctests as py_log
     1031        sage: py_log(CC(e))
     1032        1.00000000000000
     1033        sage: py_log(CC.0)
     1034        1.57079632679490*I
     1035    """
    5481036    try:
    5491037        return x.log()
    5501038    except AttributeError:
    551         return RR(x).log()
     1039        pass
     1040    # log() evaluates it's argument before calling this, so we should never
     1041    # end up here. Precision is not a problem here, since log() passes that
     1042    # on when it calls evalf() on the argument.
     1043    raise RuntimeError, "py_log() received non evaluated argument"
    5521044
     1045def py_log_for_doctests(x):
     1046    """
     1047    This function tests py_log.
     1048
     1049    EXAMPLES::
     1050
     1051        sage: from sage.symbolic.pynac import py_log_for_doctests
     1052        sage: py_log_for_doctests(CC(e))
     1053        1.00000000000000
     1054    """
     1055    return py_log(x)
    5531056
    5541057cdef public object py_tan(object x):
    5551058    try:
     
    7121215# Constants
    7131216##################################################################
    7141217
    715 cdef int prec(long ndigits):
    716     return <int>((ndigits+1) * 3.32192 + 1)
     1218cdef public object py_eval_pi(int prec):
     1219    """
     1220    Return the value of pi with the given precision.
    7171221
    718 cdef public object py_eval_pi(long ndigits):
    719     return RealField(prec(ndigits)).pi()
     1222    TESTS::
     1223
     1224        sage: from sage.symbolic.pynac import py_eval_pi_for_doctests as py_eval_pi
     1225        sage: py_eval_pi(50)
     1226        3.1415926535898
     1227        sage: py_eval_pi(100)
     1228        3.1415926535897932384626433833
     1229    """
     1230    return RealField_constructor(prec).pi()
     1231
     1232def py_eval_pi_for_doctests(prec):
     1233    """
     1234    This function tests py_eval_pi.
     1235
     1236    EXAMPLES::
     1237
     1238        sage: from sage.symbolic.pynac import py_eval_pi_for_doctests
     1239        sage: py_eval_pi_for_doctests(40)
     1240        3.1415926536
     1241    """
     1242    return py_eval_pi(prec)
    7201243   
    721 cdef public object py_eval_euler_gamma(long ndigits):
    722     return RealField(prec(ndigits)).euler_constant()
     1244cdef public object py_eval_euler_gamma(int prec):
     1245    """
     1246    Return the value of euler_gamma with the given precision.
    7231247
    724 cdef public object py_eval_catalan(long ndigits):
    725     return RealField(prec(ndigits)).catalan_constant()
     1248    TESTS::
    7261249
     1250        sage: from sage.symbolic.pynac import py_eval_euler_gamma_for_doctests as py_eval_euler_gamma
     1251        sage: py_eval_euler_gamma(50)
     1252        0.57721566490153
     1253        sage: py_eval_euler_gamma(100)
     1254        0.57721566490153286060651209008
     1255    """
     1256    return RealField_constructor(prec).euler_constant()
    7271257
     1258def py_eval_euler_gamma_for_doctests(prec):
     1259    """
     1260    This function tests py_eval_euler_gamma.
     1261
     1262    EXAMPLES::
     1263
     1264        sage: from sage.symbolic.pynac import py_eval_euler_gamma_for_doctests
     1265        sage: py_eval_euler_gamma_for_doctests(40)
     1266        0.57721566490
     1267    """
     1268    return py_eval_euler_gamma(prec)
     1269   
     1270cdef public object py_eval_catalan(int prec):
     1271    """
     1272    Return the value of catalan with the given precision.
     1273
     1274    TESTS::
     1275
     1276        sage: from sage.symbolic.pynac import py_eval_catalan_for_doctests as py_eval_catalan
     1277        sage: py_eval_catalan(50)
     1278        0.91596559417722
     1279        sage: py_eval_catalan(100)
     1280        0.91596559417721901505460351493
     1281    """
     1282    return RealField_constructor(prec).catalan_constant()
     1283
     1284def py_eval_catalan_for_doctests(prec):
     1285    """
     1286    This function tests py_eval_catalan.
     1287
     1288    EXAMPLES::
     1289
     1290        sage: from sage.symbolic.pynac import py_eval_catalan_for_doctests
     1291        sage: py_eval_catalan_for_doctests(40)
     1292        0.91596559418
     1293    """
     1294    return py_eval_catalan(prec)
     1295   
     1296cdef public object py_eval_unsigned_infinity():
     1297    """
     1298    Returns unsigned_infinity.
     1299    """
     1300    from sage.rings.infinity import unsigned_infinity
     1301    return unsigned_infinity
     1302
     1303def py_eval_unsigned_infinity_for_doctests():
     1304    """
     1305    This function tests py_eval_unsigned_infinity.
     1306
     1307    TESTS::
     1308        sage: from sage.symbolic.pynac import py_eval_unsigned_infinity_for_doctests as py_eval_unsigned_infinity
     1309        sage: py_eval_unsigned_infinity()
     1310        Infinity
     1311    """
     1312    return py_eval_unsigned_infinity()
     1313
     1314cdef public object py_eval_infinity():
     1315    """
     1316    Returns positive infinity, i.e., oo.
     1317    """
     1318    from sage.rings.infinity import infinity
     1319    return infinity
     1320
     1321def py_eval_infinity_for_doctests():
     1322    """
     1323    This function tests py_eval_infinity.
     1324
     1325    TESTS::
     1326        sage: from sage.symbolic.pynac import py_eval_infinity_for_doctests as py_eval_infinity
     1327        sage: py_eval_infinity()
     1328        +Infinity
     1329    """
     1330    return py_eval_infinity()
     1331
     1332cdef public object py_eval_neg_infinity():
     1333    """
     1334    Returns minus_infinity.
     1335    """
     1336    from sage.rings.infinity import minus_infinity
     1337    return minus_infinity
     1338
     1339def py_eval_neg_infinity_for_doctests():
     1340    """
     1341    This function tests py_eval_neg_infinity.
     1342
     1343    TESTS::
     1344        sage: from sage.symbolic.pynac import py_eval_neg_infinity_for_doctests as py_eval_neg_infinity
     1345        sage: py_eval_neg_infinity()
     1346        -Infinity
     1347    """
     1348    return py_eval_neg_infinity()
    7281349
    7291350##################################################################
    7301351# Constructors
     
    7501371import sage.rings.real_double
    7511372ginac_pyinit_Float(sage.rings.real_double.RDF)
    7521373
    753 from sage.rings.complex_double import CDF
    754 ginac_pyinit_I(CDF.gen())
     1374def init_pynac_I():
     1375    """
     1376    Initialize the numeric I object in pynac. We use the generator of QQ(i).
     1377    """
     1378    from sage.rings.rational_field import QQ
     1379    from sage.rings.all import I
     1380    from sage.rings.number_field.number_field import NumberField
     1381    x = QQ['x'].gen()
     1382    K = NumberField(x**2 + 1, 'I', embedding=I)
     1383    ginac_pyinit_I(K.gen())
     1384
     1385init_pynac_I()
    7551386
    7561387
    7571388set_ginac_fn_serial()
  • sage/symbolic/ring.pyx

    diff --git a/sage/symbolic/ring.pyx b/sage/symbolic/ring.pyx
    a b  
    5050    cdef _coerce_c_impl(self, other):
    5151        """
    5252       
    53         EXAMPLES:
     53        EXAMPLES::
     54
    5455            sage: from sage.symbolic.ring import NSR
    5556            sage: NSR._coerce_(int(5))
    5657            5
     
    6162            sage: NSR._coerce_(5.0)
    6263            5.00000000000000
    6364
    64         An interval arithmetic number:
     65        An interval arithmetic number::
     66
    6567            sage: NSR._coerce_(RIF(pi))
    6668            3.141592653589794?
    6769
    68         A number modulo 7:
     70        A number modulo 7::
     71
    6972            sage: a = NSR._coerce_(Mod(3,7)); a
    7073            3
    7174            sage: a^2
    7275            2
     76
     77        TESTS::
     78
     79            sage: si = NSR.coerce(I)
     80            sage: si^2
     81            -1
     82            sage: bool(si == CC.0)
     83            True
    7384        """
    74         from sage.functions.constants import pi, catalan, euler_gamma
     85        from sage.functions.constants import pi, catalan, euler_gamma, I
     86        from sage.rings.infinity import infinity, minus_infinity, \
     87                unsigned_infinity
    7588        cdef GEx exp
    7689
    7790        if isinstance(other, int):
     
    8295            GEx_construct_pyobject(exp, other)
    8396        elif isinstance(other, RealNumber):
    8497            GEx_construct_pyobject(exp, other)
    85         elif isinstance(other, RingElement):
    86             GEx_construct_pyobject(exp, other)
     98        elif other is I:
     99            return new_Expression_from_GEx(g_I)
    87100        elif other is pi:
    88101            return new_Expression_from_GEx(g_Pi)
    89102        elif other is catalan:
    90103            return new_Expression_from_GEx(g_Catalan)
    91104        elif other is euler_gamma:
    92105            return new_Expression_from_GEx(g_Euler)
     106        elif other is infinity:
     107            return new_Expression_from_GEx(g_Infinity)
     108        elif other is minus_infinity:
     109            return new_Expression_from_GEx(g_mInfinity)
     110        elif other is unsigned_infinity:
     111            return new_Expression_from_GEx(g_UnsignedInfinity)
     112        elif isinstance(other, RingElement):
     113            GEx_construct_pyobject(exp, other)
    93114        else:
    94115            raise TypeError
    95116        return new_Expression_from_GEx(exp)
  • sage/symbolic/todo.txt

    diff --git a/sage/symbolic/todo.txt b/sage/symbolic/todo.txt
    a b  
    1701705 + (5)*x + (2)*x^3 + (4)*x^2
    171171sage: a.expand()*Mod(1,7)
    1721721000 + 300*x + x^3 + 30*x^2
     173
     174Test