Ticket #4102: trac_symbolic_bessel_deprecation.patch

File trac_symbolic_bessel_deprecation.patch, 27.0 KB (added by benjaminfjones, 8 years ago)

add deprecation of old API

  • sage/functions/bessel.py

    # HG changeset patch
    # User Benjamin Jones <benjaminfjones@gmail.com>
    # Date 1364412253 25200
    # Node ID e9c0caf43434f06b4fd48b11fbfa7243a78d3f33
    # Parent  59616ddaef19d4c1975d4eacea72c842b475ad75
    Trac 4102: add deprecation of old API
    
    diff --git a/sage/functions/bessel.py b/sage/functions/bessel.py
    a b  
    172172#                  http://www.gnu.org/licenses/
    173173#*****************************************************************************
    174174
    175 from sage.rings.all import RR, Integer
    176 from sage.misc.latex import latex
    177 from sage.symbolic.function import BuiltinFunction, is_inexact
    178 from sage.symbolic.expression import Expression
    179 from sage.structure.coerce import parent
    180 import sage.structure.element
    181 from sage.libs.mpmath import utils as mpmath_utils
    182175from sage.functions.other import sqrt
    183176from sage.functions.log import exp
    184177from sage.functions.hyperbolic import sinh, cosh
     178from sage.libs.mpmath import utils as mpmath_utils
     179from sage.misc.latex import latex
     180from sage.rings.all import RR, Integer
     181from sage.structure.coerce import parent
     182from sage.structure.element import get_coercion_model
    185183from sage.symbolic.constants import pi
     184from sage.symbolic.function import BuiltinFunction, is_inexact
     185from sage.symbolic.expression import Expression
     186
     187# remove after deprecation period
     188from sage.calculus.calculus import maxima
     189from sage.functions.other import real, imag
     190from sage.functions.special import maxima_function
     191from sage.misc.sage_eval import sage_eval
     192from sage.rings.real_mpfr import RealField
     193from sage.plot.plot import plot
     194from sage.rings.all import ZZ
    186195
    187196
    188197class Function_Bessel_J(BuiltinFunction):
     
    283292                                 conversions=dict(maxima='bessel_j',
    284293                                                  mathematica='BesselJ'))
    285294
     295    # remove after deprecation period
     296    def __call__(self, *args, **kwds):
     297        """
     298        Custom `__call__` method which uses the old Bessel function code if the
     299        `algorithm` or `prec` arguments are used. This should be removed after
     300        the deprecation period.
     301
     302        EXAMPLES::
     303
     304            sage: bessel_J(0, 1.0, "maxima", 53)
     305            doctest:1: DeprecationWarning: precision argument is deprecated; algorithm argument is currently deprecated, but will be available as a named keyword in the future
     306            See http://trac.sagemath.org/4102 for details.
     307            0.765197686558
     308        """
     309        if len(args) > 2 or len(kwds) > 0:
     310            from sage.misc.superseded import deprecation
     311            deprecation(4102, 'precision argument is deprecated; algorithm '
     312                              'argument is currently deprecated, but will be '
     313                              'available as a named keyword in the future')
     314            return _bessel_J(*args, **kwds)
     315        else:
     316            return super(BuiltinFunction, self).__call__(*args, **kwds)
     317
    286318    def _eval_(self, n, x):
    287319        """
    288320        EXAMPLES::
     
    296328        if (not isinstance(n, Expression) and
    297329                not isinstance(x, Expression) and
    298330                (is_inexact(n) or is_inexact(x))):
    299             coercion_model = sage.structure.element.get_coercion_model()
     331            coercion_model = get_coercion_model()
    300332            n, x = coercion_model.canonical_coercion(n, x)
    301333            return self._evalf_(n, x, parent(n))
    302334
     
    420452                                 conversions=dict(maxima='bessel_y',
    421453                                                  mathematica='BesselY'))
    422454
     455    # remove after deprecation period
     456    def __call__(self, *args, **kwds):
     457        """
     458        Custom `__call__` method which uses the old Bessel function code if the
     459        `algorithm` or `prec` arguments are used. This should be removed after
     460        the deprecation period.
     461
     462        EXAMPLES::
     463
     464            sage: bessel_Y(0, 1, "maxima", 53)
     465            doctest:1: DeprecationWarning: precision argument is deprecated; algorithm argument is currently deprecated, but will be available as a named keyword in the future
     466            See http://trac.sagemath.org/4102 for details.
     467            0.0882569642156769
     468        """
     469        if len(args) > 2 or len(kwds) > 0:
     470            from sage.misc.superseded import deprecation
     471            deprecation(4102, 'precision argument is deprecated; algorithm '
     472                              'argument is currently deprecated, but will be '
     473                              'available as a named keyword in the future')
     474            return _bessel_Y(*args, **kwds)
     475        else:
     476            return super(BuiltinFunction, self).__call__(*args, **kwds)
     477
    423478    def _eval_(self, n, x):
    424479        """
    425480        EXAMPLES::
     
    432487        """
    433488        if (not isinstance(n, Expression) and not isinstance(x, Expression) and
    434489                (is_inexact(n) or is_inexact(x))):
    435             coercion_model = sage.structure.element.get_coercion_model()
     490            coercion_model = get_coercion_model()
    436491            n, x = coercion_model.canonical_coercion(n, x)
    437492            return self._evalf_(n, x, parent(n))
    438493
     
    560615                                 conversions=dict(maxima='bessel_i',
    561616                                                  mathematica='BesselI'))
    562617
     618    # remove after deprecation period
     619    def __call__(self, *args, **kwds):
     620        """
     621        Custom `__call__` method which uses the old Bessel function code if the
     622        `algorithm` or `prec` arguments are used. This should be removed after
     623        the deprecation period.
     624
     625        EXAMPLES::
     626
     627            sage: bessel_I(0, 1, "maxima", 53)
     628            doctest:1: DeprecationWarning: precision argument is deprecated; algorithm argument is currently deprecated, but will be available as a named keyword in the future
     629            See http://trac.sagemath.org/4102 for details.
     630            1.266065877752009
     631        """
     632        if len(args) > 2 or len(kwds) > 0:
     633            from sage.misc.superseded import deprecation
     634            deprecation(4102, 'precision argument is deprecated; algorithm '
     635                              'argument is currently deprecated, but will be '
     636                              'available as a named keyword in the future')
     637            return _bessel_I(*args, **kwds)
     638        else:
     639            return super(BuiltinFunction, self).__call__(*args, **kwds)
     640
    563641    def _eval_(self, n, x):
    564642        """
    565643        EXAMPLES::
     
    576654        """
    577655        if (not isinstance(n, Expression) and not isinstance(x, Expression) and
    578656                (is_inexact(n) or is_inexact(x))):
    579             coercion_model = sage.structure.element.get_coercion_model()
     657            coercion_model = get_coercion_model()
    580658            n, x = coercion_model.canonical_coercion(n, x)
    581659            return self._evalf_(n, x, parent(n))
    582660
     
    725803                                 conversions=dict(maxima='bessel_k',
    726804                                                  mathematica='BesselK'))
    727805
     806    # remove after deprecation period
     807    def __call__(self, *args, **kwds):
     808        """
     809        Custom `__call__` method which uses the old Bessel function code if the
     810        `algorithm` or `prec` arguments are used. This should be removed after
     811        the deprecation period.
     812
     813        EXAMPLES::
     814
     815            sage: bessel_K(0, 1, "maxima", 53)
     816            doctest:1: DeprecationWarning: precision argument is deprecated; algorithm argument is currently deprecated, but will be available as a named keyword in the future
     817            See http://trac.sagemath.org/4102 for details.
     818            0.0882569642156769
     819        """
     820        if len(args) > 2 or len(kwds) > 0:
     821            from sage.misc.superseded import deprecation
     822            deprecation(4102, 'precision argument is deprecated; algorithm '
     823                              'argument is currently deprecated, but will be '
     824                              'available as a named keyword in the future')
     825            return _bessel_Y(*args, **kwds)
     826        else:
     827            return super(BuiltinFunction, self).__call__(*args, **kwds)
     828
    728829    def _eval_(self, n, x):
    729830        """
    730831        EXAMPLES::
     
    738839        """
    739840        if (not isinstance(n, Expression) and not isinstance(x, Expression) and
    740841                (is_inexact(n) or is_inexact(x))):
    741             coercion_model = sage.structure.element.get_coercion_model()
     842            coercion_model = get_coercion_model()
    742843            n, x = coercion_model.canonical_coercion(n, x)
    743844            return self._evalf_(n, x, parent(n))
    744845
     
    9251026        _type = args[1]
    9261027        _nargs = 1
    9271028    else:
    928         raise TypeError("at most two positional arguments may be specified, "
    929                         + "see the docstring for Bessel")
     1029        from sage.misc.superseded import deprecation
     1030        deprecation(4102, 'precision argument is deprecated; algorithm '
     1031                          'argument is currently deprecated, but will be '
     1032                          'available as a named keyword in the future')
     1033        return _Bessel(*args, **kwds)
     1034
    9301035    # check for type inconsistency
    9311036    if _type is not None and 'typ' in kwds and _type != kwds['typ']:
    9321037        raise ValueError("inconsistent types given")
     
    9571062        return lambda x: _f(_order, x)
    9581063    else:
    9591064        return _f
     1065
     1066####################################################
     1067###  to be removed after the deprecation period  ###
     1068####################################################
     1069
     1070
     1071def _bessel_I(nu,z,algorithm = "pari",prec=53):
     1072    r"""
     1073    Implements the "I-Bessel function", or "modified Bessel function,
     1074    1st kind", with index (or "order") nu and argument z.
     1075
     1076    INPUT:
     1077
     1078
     1079    -  ``nu`` - a real (or complex, for pari) number
     1080
     1081    -  ``z`` - a real (positive) algorithm - "pari" or
     1082       "maxima" or "scipy" prec - real precision (for PARI only)
     1083
     1084
     1085    DEFINITION::
     1086
     1087            Maxima:
     1088                             inf
     1089                            ====   - nu - 2 k  nu + 2 k
     1090                            \     2          z
     1091                             >    -------------------
     1092                            /     k! Gamma(nu + k + 1)
     1093                            ====
     1094                            k = 0
     1095
     1096            PARI:
     1097
     1098                             inf
     1099                            ====   - 2 k  2 k
     1100                            \     2      z    Gamma(nu + 1)
     1101                             >    -----------------------
     1102                            /       k! Gamma(nu + k + 1)
     1103                            ====
     1104                            k = 0
     1105
     1106
     1107
     1108    Sometimes ``bessel_I(nu,z)`` is denoted
     1109    ``I_nu(z)`` in the literature.
     1110
     1111    .. warning::
     1112
     1113       In Maxima (the manual says) i0 is deprecated but
     1114       ``bessel_i(0,*)`` is broken. (Was fixed in recent CVS patch
     1115       though.)
     1116
     1117    EXAMPLES::
     1118
     1119        sage: from sage.functions.bessel import _bessel_I
     1120        sage: _bessel_I(1,1,"pari",500)
     1121        0.565159103992485027207696027609863307328899621621092009480294489479255640964371134092664997766814410064677886055526302676857637684917179812041131208121
     1122        sage: _bessel_I(1,1)
     1123        0.565159103992485
     1124        sage: _bessel_I(2,1.1,"maxima")
     1125        0.16708949925104...
     1126        sage: _bessel_I(0,1.1,"maxima")
     1127        1.32616018371265...
     1128        sage: _bessel_I(0,1,"maxima")
     1129        1.2660658777520...
     1130        sage: _bessel_I(1,1,"scipy")
     1131        0.565159103992...
     1132
     1133    Check whether the return value is real whenever the argument is real (#10251)::
     1134
     1135        sage: _bessel_I(5, 1.5, algorithm='scipy') in RR
     1136        True
     1137
     1138    """
     1139    if algorithm=="pari":
     1140        from sage.libs.pari.all import pari
     1141        try:
     1142            R = RealField(prec)
     1143            nu = R(nu)
     1144            z = R(z)
     1145        except TypeError:
     1146            C = ComplexField(prec)
     1147            nu = C(nu)
     1148            z = C(z)
     1149            K = C
     1150        K = z.parent()
     1151        return K(pari(nu).besseli(z, precision=prec))
     1152    elif algorithm=="scipy":
     1153        if prec != 53:
     1154            raise ValueError, "for the scipy algorithm the precision must be 53"
     1155        import scipy.special
     1156        ans = str(scipy.special.iv(float(nu),complex(real(z),imag(z))))
     1157        ans = ans.replace("(","")
     1158        ans = ans.replace(")","")
     1159        ans = ans.replace("j","*I")
     1160        ans = sage_eval(ans)
     1161        return real(ans) if z in RR else ans # Return real value when arg is real
     1162    elif algorithm == "maxima":
     1163        if prec != 53:
     1164            raise ValueError, "for the maxima algorithm the precision must be 53"
     1165        return sage_eval(maxima.eval("bessel_i(%s,%s)"%(float(nu),float(z))))
     1166    else:
     1167        raise ValueError, "unknown algorithm '%s'"%algorithm
     1168
     1169def _bessel_J(nu,z,algorithm="pari",prec=53):
     1170    r"""
     1171    Return value of the "J-Bessel function", or "Bessel function, 1st
     1172    kind", with index (or "order") nu and argument z.
     1173
     1174    ::
     1175
     1176            Defn:
     1177            Maxima:
     1178                             inf
     1179                            ====          - nu - 2 k  nu + 2 k
     1180                            \     (-1)^k 2           z
     1181                             >    -------------------------
     1182                            /        k! Gamma(nu + k + 1)
     1183                            ====
     1184                            k = 0
     1185
     1186            PARI:
     1187
     1188                             inf
     1189                            ====          - 2k    2k
     1190                            \     (-1)^k 2      z    Gamma(nu + 1)
     1191                             >    ----------------------------
     1192                            /         k! Gamma(nu + k + 1)
     1193                            ====
     1194                            k = 0
     1195
     1196
     1197    Sometimes bessel_J(nu,z) is denoted J_nu(z) in the literature.
     1198
     1199    .. warning::
     1200
     1201       Inaccurate for small values of z.
     1202
     1203    EXAMPLES::
     1204
     1205        sage: from sage.functions.bessel import _bessel_J
     1206        sage: _bessel_J(2,1.1)
     1207        0.136564153956658
     1208        sage: _bessel_J(0,1.1)
     1209        0.719622018527511
     1210        sage: _bessel_J(0,1)
     1211        0.765197686557967
     1212        sage: _bessel_J(0,0)
     1213        1.00000000000000
     1214        sage: _bessel_J(0.1,0.1)
     1215        0.777264368097005
     1216
     1217    We check consistency of PARI and Maxima::
     1218
     1219        sage: n(_bessel_J(3,10,"maxima"))
     1220        0.0583793793051...
     1221        sage: n(_bessel_J(3,10,"pari"))
     1222        0.0583793793051868
     1223        sage: _bessel_J(3,10,"scipy")
     1224        0.0583793793052...
     1225
     1226    Check whether the return value is real whenever the argument is real (#10251)::
     1227        sage: _bessel_J(5, 1.5, algorithm='scipy') in RR
     1228        True
     1229    """
     1230
     1231    if algorithm=="pari":
     1232        from sage.libs.pari.all import pari
     1233        try:
     1234            R = RealField(prec)
     1235            nu = R(nu)
     1236            z = R(z)
     1237        except TypeError:
     1238            C = ComplexField(prec)
     1239            nu = C(nu)
     1240            z = C(z)
     1241            K = C
     1242        if nu == 0:
     1243            nu = ZZ(0)
     1244        K = z.parent()
     1245        return K(pari(nu).besselj(z, precision=prec))
     1246    elif algorithm=="scipy":
     1247        if prec != 53:
     1248            raise ValueError, "for the scipy algorithm the precision must be 53"
     1249        import scipy.special
     1250        ans = str(scipy.special.jv(float(nu),complex(real(z),imag(z))))
     1251        ans = ans.replace("(","")
     1252        ans = ans.replace(")","")
     1253        ans = ans.replace("j","*I")
     1254        ans = sage_eval(ans)
     1255        return real(ans) if z in RR else ans
     1256    elif algorithm == "maxima":
     1257        if prec != 53:
     1258            raise ValueError, "for the maxima algorithm the precision must be 53"
     1259        return maxima_function("bessel_j")(nu, z)
     1260    else:
     1261        raise ValueError, "unknown algorithm '%s'"%algorithm
     1262
     1263def _bessel_K(nu,z,algorithm="pari",prec=53):
     1264    r"""
     1265    Implements the "K-Bessel function", or "modified Bessel function,
     1266    2nd kind", with index (or "order") nu and argument z. Defn::
     1267
     1268                    pi*(bessel_I(-nu, z) - bessel_I(nu, z))
     1269                   ----------------------------------------
     1270                                2*sin(pi*nu)
     1271
     1272
     1273    if nu is not an integer and by taking a limit otherwise.
     1274
     1275    Sometimes bessel_K(nu,z) is denoted K_nu(z) in the literature. In
     1276    PARI, nu can be complex and z must be real and positive.
     1277
     1278    EXAMPLES::
     1279
     1280        sage: from sage.functions.bessel import _bessel_K
     1281        sage: _bessel_K(3,2,"scipy")
     1282        0.64738539094...
     1283        sage: _bessel_K(3,2)
     1284        0.64738539094...
     1285        sage: _bessel_K(1,1)
     1286        0.60190723019...
     1287        sage: _bessel_K(1,1,"pari",10)
     1288        0.60
     1289        sage: _bessel_K(1,1,"pari",100)
     1290        0.60190723019723457473754000154
     1291
     1292    TESTS::
     1293
     1294        sage: _bessel_K(2,1.1, algorithm="maxima")
     1295        Traceback (most recent call last):
     1296        ...
     1297        NotImplementedError: The K-Bessel function is only implemented for the pari and scipy algorithms
     1298
     1299        Check whether the return value is real whenever the argument is real (#10251)::
     1300
     1301        sage: _bessel_K(5, 1.5, algorithm='scipy') in RR
     1302        True
     1303
     1304    """
     1305    if algorithm=="scipy":
     1306        if prec != 53:
     1307            raise ValueError, "for the scipy algorithm the precision must be 53"
     1308        import scipy.special
     1309        ans = str(scipy.special.kv(float(nu),float(z)))
     1310        ans = ans.replace("(","")
     1311        ans = ans.replace(")","")
     1312        ans = ans.replace("j","*I")
     1313        ans = sage_eval(ans)
     1314        return real(ans) if z in RR else ans
     1315    elif algorithm == 'pari':
     1316        from sage.libs.pari.all import pari
     1317        try:
     1318            R = RealField(prec)
     1319            nu = R(nu)
     1320            z = R(z)
     1321        except TypeError:
     1322            C = ComplexField(prec)
     1323            nu = C(nu)
     1324            z = C(z)
     1325            K = C
     1326        K = z.parent()
     1327        return K(pari(nu).besselk(z, precision=prec))
     1328    elif algorithm == 'maxima':
     1329        raise NotImplementedError, "The K-Bessel function is only implemented for the pari and scipy algorithms"
     1330    else:
     1331        raise ValueError, "unknown algorithm '%s'"%algorithm
     1332
     1333
     1334def _bessel_Y(nu,z,algorithm="maxima", prec=53):
     1335    r"""
     1336    Implements the "Y-Bessel function", or "Bessel function of the 2nd
     1337    kind", with index (or "order") nu and argument z.
     1338
     1339    .. note::
     1340
     1341       Currently only prec=53 is supported.
     1342
     1343    Defn::
     1344
     1345                    cos(pi n)*bessel_J(nu, z) - bessel_J(-nu, z)
     1346                   -------------------------------------------------
     1347                                     sin(nu*pi)
     1348
     1349    if nu is not an integer and by taking a limit otherwise.
     1350
     1351    Sometimes bessel_Y(n,z) is denoted Y_n(z) in the literature.
     1352
     1353    This is computed using Maxima by default.
     1354
     1355    EXAMPLES::
     1356
     1357        sage: from sage.functions.bessel import _bessel_Y
     1358        sage: _bessel_Y(2,1.1,"scipy")
     1359        -1.4314714939...
     1360        sage: _bessel_Y(2,1.1)
     1361        -1.4314714939590...
     1362        sage: _bessel_Y(3.001,2.1)
     1363        -1.0299574976424...
     1364
     1365    TESTS::
     1366
     1367        sage: _bessel_Y(2,1.1, algorithm="pari")
     1368        Traceback (most recent call last):
     1369        ...
     1370        NotImplementedError: The Y-Bessel function is only implemented for the maxima and scipy algorithms
     1371    """
     1372    if algorithm=="scipy":
     1373        if prec != 53:
     1374            raise ValueError, "for the scipy algorithm the precision must be 53"
     1375        import scipy.special
     1376        ans = str(scipy.special.yv(float(nu),complex(real(z),imag(z))))
     1377        ans = ans.replace("(","")
     1378        ans = ans.replace(")","")
     1379        ans = ans.replace("j","*I")
     1380        ans = sage_eval(ans)
     1381        return real(ans) if z in RR else ans
     1382    elif algorithm == "maxima":
     1383        if prec != 53:
     1384            raise ValueError, "for the maxima algorithm the precision must be 53"
     1385        return RR(maxima.eval("bessel_y(%s,%s)"%(float(nu),float(z))))
     1386    elif algorithm == "pari":
     1387        raise NotImplementedError, "The Y-Bessel function is only implemented for the maxima and scipy algorithms"
     1388    else:
     1389        raise ValueError, "unknown algorithm '%s'"%algorithm
     1390
     1391class _Bessel():
     1392    """
     1393    A class implementing the I, J, K, and Y Bessel functions.
     1394
     1395    EXAMPLES::
     1396
     1397        sage: from sage.functions.bessel import _Bessel
     1398        sage: g = _Bessel(2); g
     1399        J_{2}
     1400        sage: print g
     1401        J-Bessel function of order 2
     1402        sage: g.plot(0,10)
     1403
     1404    ::
     1405
     1406        sage: _Bessel(2, typ='I')(pi)
     1407        2.61849485263445
     1408        sage: _Bessel(2, typ='J')(pi)
     1409        0.485433932631509
     1410        sage: _Bessel(2, typ='K')(pi)
     1411        0.0510986902537926
     1412        sage: _Bessel(2, typ='Y')(pi)
     1413        -0.0999007139289404
     1414    """
     1415    def __init__(self, nu, typ = "J", algorithm = None, prec = 53):
     1416        """
     1417        Initializes new instance of the Bessel class.
     1418
     1419        INPUT:
     1420
     1421         - ``typ`` -- (default: J) the type of Bessel function: 'I', 'J', 'K'
     1422           or 'Y'.
     1423
     1424         - ``algorithm`` -- (default: maxima for type Y, pari for other types)
     1425           algorithm to use to compute the Bessel function: 'pari', 'maxima' or
     1426           'scipy'.  Note that type K is not implemented in Maxima and type Y
     1427           is not implemented in PARI.
     1428
     1429         - ``prec`` -- (default: 53) precision in bits of the Bessel function.
     1430           Only supported for the PARI algorithm.
     1431
     1432        EXAMPLES::
     1433
     1434            sage: from sage.functions.bessel import _Bessel
     1435            sage: g = _Bessel(2); g
     1436            J_{2}
     1437            sage: _Bessel(1,'I')
     1438            I_{1}
     1439            sage: _Bessel(6, prec=120)(pi)
     1440            0.014545966982505560573660369604001804
     1441            sage: _Bessel(6, algorithm="pari")(pi)
     1442            0.0145459669825056
     1443
     1444        For the Bessel J-function, Maxima returns a symbolic result.  For
     1445        types I and Y, we always get a numeric result::
     1446
     1447            sage: b = _Bessel(6, algorithm="maxima")(pi); b
     1448            bessel_j(6, pi)
     1449            sage: b.n(53)
     1450            0.0145459669825056
     1451            sage: _Bessel(6, typ='I', algorithm="maxima")(pi)
     1452            0.0294619840059568
     1453            sage: _Bessel(6, typ='Y', algorithm="maxima")(pi)
     1454            -4.33932818939038
     1455
     1456        SciPy usually gives less precise results::
     1457
     1458            sage: _Bessel(6, algorithm="scipy")(pi)
     1459            0.0145459669825000...
     1460
     1461        TESTS::
     1462
     1463            sage: _Bessel(1,'Z')
     1464            Traceback (most recent call last):
     1465            ...
     1466            ValueError: typ must be one of I, J, K, Y
     1467        """
     1468        if not (typ in ['I', 'J', 'K', 'Y']):
     1469            raise ValueError, "typ must be one of I, J, K, Y"
     1470
     1471        # Did the user ask for the default algorithm?
     1472        if algorithm is None:
     1473            if typ == 'Y':
     1474                algorithm = 'maxima'
     1475            else:
     1476                algorithm = 'pari'
     1477
     1478        self._system = algorithm
     1479        self._order = nu
     1480        self._type = typ
     1481        prec = int(prec)
     1482        if prec < 0:
     1483            raise ValueError, "prec must be a positive integer"
     1484        self._prec = int(prec)
     1485
     1486    def __str__(self):
     1487        """
     1488        Returns a string representation of this Bessel object.
     1489
     1490        TEST::
     1491
     1492            sage: from sage.functions.bessel import _Bessel
     1493            sage: a = _Bessel(1,'I')
     1494            sage: str(a)
     1495            'I-Bessel function of order 1'
     1496        """
     1497        return self.type()+"-Bessel function of order "+str(self.order())
     1498
     1499    def __repr__(self):
     1500        """
     1501        Returns a string representation of this Bessel object.
     1502
     1503        TESTS::
     1504
     1505            sage: from sage.functions.bessel import _Bessel
     1506            sage: _Bessel(1,'I')
     1507            I_{1}
     1508        """
     1509        return self.type()+"_{"+str(self.order())+"}"
     1510
     1511    def type(self):
     1512        """
     1513        Returns the type of this Bessel object.
     1514
     1515        TEST::
     1516
     1517            sage: from sage.functions.bessel import _Bessel
     1518            sage: a = _Bessel(3,'K')
     1519            sage: a.type()
     1520            'K'
     1521        """
     1522        return self._type
     1523
     1524    def prec(self):
     1525        """
     1526        Returns the precision (in number of bits) used to represent this
     1527        Bessel function.
     1528
     1529        TESTS::
     1530
     1531            sage: from sage.functions.bessel import _Bessel
     1532            sage: a = _Bessel(3,'K')
     1533            sage: a.prec()
     1534            53
     1535            sage: B = _Bessel(20,prec=100); B
     1536            J_{20}
     1537            sage: B.prec()
     1538            100
     1539        """
     1540        return self._prec
     1541
     1542    def order(self):
     1543        """
     1544        Returns the order of this Bessel function.
     1545
     1546        TEST::
     1547
     1548            sage: from sage.functions.bessel import _Bessel
     1549            sage: a = _Bessel(3,'K')
     1550            sage: a.order()
     1551            3
     1552        """
     1553        return self._order
     1554
     1555    def system(self):
     1556        """
     1557        Returns the package used, e.g. Maxima, PARI, or SciPy, to compute with
     1558        this Bessel function.
     1559
     1560        TESTS::
     1561
     1562            sage: from sage.functions.bessel import _Bessel
     1563            sage: _Bessel(20,algorithm='maxima').system()
     1564            'maxima'
     1565            sage: _Bessel(20,prec=100).system()
     1566            'pari'
     1567        """
     1568        return self._system
     1569
     1570    def __call__(self,z):
     1571        """
     1572        Implements evaluation of all the Bessel functions directly
     1573        from the Bessel class. This essentially allows a Bessel object to
     1574        behave like a function that can be invoked.
     1575
     1576        TESTS::
     1577
     1578            sage: from sage.functions.bessel import _Bessel
     1579            sage: _Bessel(3,'K')(5.0)
     1580            0.00829176841523093
     1581            sage: _Bessel(20,algorithm='maxima')(5.0)
     1582            2.77033005213e-11
     1583            sage: _Bessel(20,prec=100)(5.0101010101010101)
     1584            2.8809188227195382093062257967e-11
     1585            sage: B = _Bessel(2,'Y',algorithm='scipy',prec=50)
     1586            sage: B(2.0)
     1587            Traceback (most recent call last):
     1588            ...
     1589            ValueError: for the scipy algorithm the precision must be 53
     1590        """
     1591        nu = self.order()
     1592        t = self.type()
     1593        s = self.system()
     1594        p = self.prec()
     1595        if t == "I":
     1596            return _bessel_I(nu,z,algorithm=s,prec=p)
     1597        if t == "J":
     1598            return _bessel_J(nu,z,algorithm=s,prec=p)
     1599        if t == "K":
     1600            return _bessel_K(nu,z,algorithm=s,prec=p)
     1601        if t == "Y":
     1602            return _bessel_Y(nu,z,algorithm=s,prec=p)
     1603
     1604    def plot(self,a,b):
     1605        """
     1606        Enables easy plotting of all the Bessel functions directly
     1607        from the Bessel class.
     1608
     1609        TESTS::
     1610
     1611            sage: from sage.functions.bessel import _Bessel
     1612            sage: plot(_Bessel(2),3,4)
     1613            sage: _Bessel(2).plot(3,4)
     1614            sage: P = _Bessel(2,'I').plot(1,5)
     1615            sage: P += _Bessel(2,'J').plot(1,5)
     1616            sage: P += _Bessel(2,'K').plot(1,5)
     1617            sage: P += _Bessel(2,'Y').plot(1,5)
     1618            sage: show(P)
     1619        """
     1620        nu = self.order()
     1621        s = self.system()
     1622        t = self.type()
     1623        if t == "I":
     1624            f = lambda z: _bessel_I(nu,z,s)
     1625            P = plot(f,a,b)
     1626        if t == "J":
     1627            f = lambda z: _bessel_J(nu,z,s)
     1628            P = plot(f,a,b)
     1629        if t == "K":
     1630            f = lambda z: _bessel_K(nu,z,s)
     1631            P = plot(f,a,b)
     1632        if t == "Y":
     1633            f = lambda z: _bessel_Y(nu,z,s)
     1634            P = plot(f,a,b)
     1635        return P