Ticket #9130: trac_9130_combined.patch

File trac_9130_combined.patch, 8.6 KB (added by benjaminfjones, 8 years ago)

combined reviewer patch folding up previously uploaded 5 patches

  • doc/en/reference/functions.rst

    # HG changeset patch
    # User Benjamin Jones <benjaminfjones@gmail.com>
    # Date 1326258444 18000
    # Node ID e2d1948c001a1127b1f9280d9ca08f456622c354
    # Parent  92c93226b64f933e0af00bbcbd1a8a79c444f43f
    * * *
    Trac 9130: symbolic beta function
    * * *
    trac 9130: fix segfault in sage.symbolic.pynac.py_float
    
    When the second argument of py_float() is declared as object, Cython assumes
    that this is initialized and it can do reference counting, etc. Calls to
    py_float() from pynac cannot provide a valid python object for the second
    argument. In this case pynac just passes, a NULL pointer to py_float(), which
    lead to crashes.
    
    Changing the declaration from object to PyObject* and checking for NULL fixes
    the problem.
    * * *
    Trac 9130:  beta function access with error for complex input
    * * *
    Trac 9130:  beta function --include in radom tests
    Trac 9130:  beta function--include in random tests
    * * *
    Trac 9130:  beta function--additional comments and examples
    
    diff --git a/doc/en/reference/functions.rst b/doc/en/reference/functions.rst
    a b  
    99   sage/functions/transcendental
    1010   sage/functions/piecewise
    1111   sage/functions/orthogonal_polys
     12   sage/functions/other
    1213   sage/functions/special
    1314   sage/functions/wigner
    1415   sage/functions/generalized
    15    sage/functions/prime_pi
    16  No newline at end of file
     16   sage/functions/prime_pi
  • sage/functions/all.py

    diff --git a/sage/functions/all.py b/sage/functions/all.py
    a b  
    1515
    1616
    1717
    18 from other import ( ceil, floor, gamma, psi, factorial,
     18from other import ( ceil, floor, gamma, psi, factorial, beta,
    1919                    abs_symbolic, erf, sqrt,
    2020                    gamma_inc, incomplete_gamma,
    2121                    real_part, real,
  • sage/functions/other.py

    diff --git a/sage/functions/other.py b/sage/functions/other.py
    a b  
    11811181
    11821182binomial = Function_binomial()
    11831183
     1184class Function_beta(GinacFunction):
     1185    def __init__(self):
     1186        r"""
     1187        Return the beta function.  This is defined by
     1188
     1189        .. math::
     1190
     1191            B(p,q) = \int_0^1 t^{p-1}(1-t)^{1-q} dt
     1192
     1193        for complex or symbolic input `p` and `q`.
     1194        Note that the order of inputs does not matter:  `B(p,q)=B(q,p)`.
     1195
     1196        GiNaC is used to compute `B(p,q)`.  However, complex inputs
     1197        are not yet handled in general.  When GiNaC raises an error on
     1198        such inputs, we raise a NotImplementedError.
     1199
     1200        If either input is 1, GiNaC returns the reciprocal of the
     1201        other.  In other cases, GiNaC uses one of the following
     1202        formulas:
     1203
     1204        .. math::
     1205
     1206            B(p,q) = \Gamma(p)\Gamma(q)/\Gamma(p+q)
     1207
     1208        or
     1209
     1210        .. math::
     1211
     1212            B(p,q) = (-1)^q B(1-p-q, q).
     1213
     1214
     1215        For numerical inputs, GiNaC uses the formula
     1216
     1217        .. math::
     1218
     1219            B(p,q) =  \exp[\log\Gamma(p)+\log\Gamma(q)-\log\Gamma(p+q)]
     1220
     1221
     1222        INPUT:
     1223
     1224        -  ``p`` - number or symbolic expression
     1225
     1226        -  ``q`` - number or symbolic expression
     1227
     1228
     1229        OUTPUT: number or symbolic expression (if input is symbolic)
     1230
     1231        EXAMPLES::
     1232
     1233            sage: beta(3,2)
     1234            1/12
     1235            sage: beta(3,1)
     1236            1/3
     1237            sage: beta(1/2,1/2)
     1238            beta(1/2, 1/2)
     1239            sage: beta(-1,1)
     1240            -1
     1241            sage: beta(-1/2,-1/2)
     1242            0
     1243            sage: beta(x/2,3)
     1244            beta(1/2*x, 3)
     1245            sage: beta(.5,.5)
     1246            3.14159265358979
     1247            sage: beta(1,2.0+I)
     1248            0.400000000000000 - 0.200000000000000*I
     1249            sage: beta(3,x+I)
     1250            beta(x + I, 3)
     1251
     1252        Note that the order of arguments does not matter::
     1253
     1254            sage: beta(1/2,3*x)
     1255            beta(3*x, 1/2)
     1256
     1257        The following fails because GiNaC does not handle general
     1258        complex values::
     1259
     1260            sage: beta(2,1+5*I)
     1261            Traceback (most recent call last):
     1262            ...
     1263            NotImplementedError: beta not implemented for complex inputs
     1264
     1265        """
     1266        GinacFunction.__init__(self, "beta", nargs=2,
     1267                conversions=dict(maxima='beta', mathematica='Beta'))
     1268
     1269    def __call__(self, p, q, prec=None, coerce=True, hold=False):
     1270        """
     1271
     1272        TESTS::
     1273
     1274            sage: beta(3,2)
     1275            1/12
     1276            sage: beta(3,1)
     1277            1/3
     1278            sage: beta(1/2,1/2)
     1279            beta(1/2, 1/2)
     1280            sage: beta(-1,1)
     1281            -1
     1282            sage: beta(-1/2,-1/2)
     1283            0
     1284            sage: beta(x/2,3)
     1285            beta(1/2*x, 3)
     1286            sage: beta(.5,.5)
     1287            3.14159265358979
     1288            sage: beta(1,2.0+I)
     1289            0.400000000000000 - 0.200000000000000*I
     1290            sage: beta(3,x+I)
     1291            beta(x + I, 3)
     1292            sage: beta(2,1+5*I)
     1293            Traceback (most recent call last):
     1294            ...
     1295            NotImplementedError: beta not implemented for complex inputs
     1296
     1297        """
     1298
     1299        try:
     1300            res = GinacFunction.__call__(self, p, q, coerce=coerce, hold=hold)
     1301        except TypeError, err:
     1302            if not str(err).startswith("cannot coerce"):
     1303                raise NotImplementedError, "beta not implemented for complex inputs"
     1304
     1305        return res
     1306
     1307
     1308beta = Function_beta()
     1309
    11841310def _do_sqrt(x, prec=None, extend=True, all=False):
    11851311        r"""
    11861312        Used internally to compute the square root of x.
  • sage/libs/ginac/decl.pxi

    diff --git a/sage/libs/ginac/decl.pxi b/sage/libs/ginac/decl.pxi
    a b  
    1111# we do *not* have to use sig_on() and sig_off(). We do use it a little
    1212# in the actual pyx code to catch control-c for long running functions.
    1313
     14from cpython cimport PyObject
     15
    1416cdef extern from "ginac_wrap.h":
    1517    void ginac_pyinit_Integer(object)
    1618    void ginac_pyinit_Float(object)
     
    431433        object (*py_integer_from_long)(long int x) except +
    432434        object (*py_integer_from_python_obj)(object x) except +
    433435
    434         object (*py_float)(object a, object parent) except +
     436        object (*py_float)(object a, PyObject* parent) except +
    435437        object (*py_RDF_from_double)(double x)
    436438
    437439
  • sage/symbolic/pynac.pyx

    diff --git a/sage/symbolic/pynac.pyx b/sage/symbolic/pynac.pyx
    a b  
    10541054    """
    10551055    return py_is_cinteger(x)
    10561056
    1057 cdef public object py_float(object n, object parent) except +:
     1057cdef public object py_float(object n, PyObject* parent) except +:
    10581058    """
    10591059    Evaluate pynac numeric objects numerically.
    10601060
     
    10741074        sage: type(py_float(1/2, CC))
    10751075        <type 'sage.rings.complex_number.ComplexNumber'>
    10761076    """
    1077     return parent(n)
     1077    if parent is not NULL:
     1078        return (<object>parent)(n)
     1079    else:
     1080        try:
     1081            return RR(n)
     1082        except ValueError:
     1083            return CC(n)
    10781084
    10791085def py_float_for_doctests(n, prec):
    10801086    """
     
    10861092        sage: py_float_for_doctests(pi, RealField(80))
    10871093        3.1415926535897932384626
    10881094    """
    1089     return py_float(n, prec)
     1095    return py_float(n, <PyObject*>prec)
    10901096
    10911097# TODO: Optimize this
    10921098from sage.rings.real_double import RDF
  • sage/symbolic/random_tests.py

    diff --git a/sage/symbolic/random_tests.py b/sage/symbolic/random_tests.py
    a b  
    1616        sage: [f for (one,f,arity) in _mk_full_functions()]
    1717        [Ei, abs, arccos, arccosh, arccot, arccoth, arccsc, arccsch,
    1818        arcsec, arcsech, arcsin, arcsinh, arctan, arctan2, arctanh,
    19         binomial, ceil, conjugate, cos, cosh, cot, coth, csc, csch,
     19        beta, binomial, ceil, conjugate, cos, cosh, cot, coth, csc, csch,
    2020        dickman_rho, dilog, dirac_delta, elliptic_e, elliptic_ec,
    2121        elliptic_eu, elliptic_f, elliptic_kc, elliptic_pi, erf, exp,
    2222        factorial, floor, heaviside, imag_part, integrate,
     
    237237        (euler_gamma - v3^(-e) + (v2 - factorial(-e/v2))^(((2.85879036573 - 1.18163393202*I)*v2 + (2.85879036573 - 1.18163393202*I)*v3)*pi - 0.247786879678 + 0.931826724898*I)*arccsc((0.891138386848 - 0.0936820840629*I)/v1) - (0.553423153995 - 0.5481180572*I)*v3 + 0.149683576515 - 0.155746451854*I)*v1 + arccsch(pi + e)*elliptic_f(khinchin*v2, 1.4656989704 + 0.863754357069*I)
    238238        sage: random_expr(5, verbose=True)
    239239        About to apply dirac_delta to [1]
    240         About to apply arccsch to [0]
    241         About to apply <built-in function add> to [0, arccsch(0)]
    242         arccsch(0)
     240        About to apply arcsec to [0]
     241        About to apply <built-in function add> to [0, arcsec(0)]
     242        arcsec(0)
     243
    243244    """
    244245    vars = [(1.0, sage.calculus.calculus.var('v%d' % (n+1))) for n in range(nvars)]
    245246    if ncoeffs is None: