Ticket #12455: trac_12455-newstyle-airy2-rebase.patch

File trac_12455-newstyle-airy2-rebase.patch, 41.3 KB (added by kcrisman, 6 years ago)
  • doc/en/reference/functions/index.rst

    # HG changeset patch
    # User Eviatar Bach <eviatarbach@gmail.com>
    # Date 1371600084 25200
    # Node ID 8845086a92ed24749d112c97c794aba717a85ca6
    # Parent  c062930f0159340f9d200948bfbacc0aa4def630
    Various fixes, including fixing an incorrect identity
    
    diff --git a/doc/en/reference/functions/index.rst b/doc/en/reference/functions/index.rst
    a b  
    1111   sage/functions/orthogonal_polys
    1212   sage/functions/other
    1313   sage/functions/special
     14   sage/functions/airy
    1415   sage/functions/bessel
    1516   sage/functions/exp_integral
    1617   sage/functions/wigner
  • sage/functions/airy.py

    diff --git a/sage/functions/airy.py b/sage/functions/airy.py
    a b  
     1r"""
     2Airy Functions
     3
     4This module implements Airy functions and their generalized derivatives. It
     5supports symbolic functionality through Maxima and numeric evaluation through
     6mpmath and Maxima.
     7
     8Airy functions are solutions to the differential equation `f''(z) +f(z)x=0`.
     9
     10AUTHORS:
     11
     12- Oscar Gerardo Lazo Arjona (2010): initial version
     13
     14- Douglas McNeil (2012): rewrite
     15
     16EXAMPLES:
     17
     18Verify that the Airy functions are solutions to the differential equation::
     19
     20    sage: diff(airy_ai(x), x, 2) - x * airy_ai(x)
     21    0
     22    sage: diff(airy_bi(x), x, 2) - x * airy_bi(x)
     23    0
     24"""
     25
    126#*****************************************************************************
    2 #       Copyright (C) 2010 Oscar Gerardo Lazo Arjona algebraicamente@gmail.com
     27#      Copyright (C) 2010 Oscar Gerardo Lazo Arjona <algebraicamente@gmail.com>
     28#      Copyright (C) 2012 Douglas McNeil <dsm054@gmail.com>
    329#
    430#  Distributed under the terms of the GNU General Public License (GPL)
    5 #
    6 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
    7 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8 #    General Public License for more details.
    9 #
    10 #  The full text of the GPL is available at:
    11 #
     31#  as published by the Free Software Foundation; either version 2 of
     32#  the License, or (at your option) any later version.
    1233#                  http://www.gnu.org/licenses/
    1334#*****************************************************************************
    1435
     
    1637from sage.symbolic.expression import Expression
    1738from sage.symbolic.function import is_inexact
    1839from sage.structure.coerce import parent as sage_structure_coerce_parent
    19 
    2040from sage.functions.other import gamma
    2141from sage.rings.integer_ring import ZZ
    2242from sage.rings.real_double import RDF
     43from sage.rings.rational import Rational as R
    2344from sage.functions.special import meval
    2445from sage.calculus.var import var
    2546from sage.calculus.functional import derivative
    2647
    27 # from sage.rings.real_mpfr import RR
    28 from sage.rings.rational import Rational as R
    2948
    3049class FunctionAiryAiGeneral(BuiltinFunction):
    3150    def __init__(self):
     
    3352        The generalized derivative of the Airy Ai function
    3453
    3554        INPUT:
    36        
    37         - ``alpha``.- Return the `\alpha`-th order fractional derivative with respect to `z`.
    38           For `\alpha = n = 1,2,3,\ldots` this gives the derivative `\operatorname{Ai}^{(n)}(z)`,
    39           and for `\alpha = -n = -1,-2,-3,\ldots` this gives the `n`-fold iterated integral
    40          
     55
     56        - ``alpha`` -- Return the `\alpha`-th order fractional derivative with
     57          respect to `z`.
     58          For `\alpha = n = 1,2,3,\ldots` this gives the derivative
     59          `\operatorname{Ai}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots`
     60          this gives the `n`-fold iterated integral.
     61
    4162        .. math ::
    42          
     63
    4364            f_0(z) = \operatorname{Ai}(z)
    44          
    45             f_n(z) = \int_0^z f_{n-1}(t) dt.
    4665
    47         - ``x``.- The argument of the function.
     66            f_n(z) = \int_0^z f_{n-1}(t) dt
    4867
    49         - ``hold``.- Whether or not to stop from returning higher derivatives in terms of
    50           `\operatorname{Ai}(x)` and `\operatorname{Ai}'(x)`.
    51        
     68        - ``x`` -- The argument of the function
     69
     70        - ``hold_derivative`` -- Whether or not to stop from returning higher
     71          derivatives in terms of `\operatorname{Ai}(x)` and
     72          `\operatorname{Ai}'(x)`
     73
    5274        EXAMPLES::
    5375
    54             sage: x,n=var('x n')
    55             sage: airy_ai(-2,x)
     76            sage: x, n = var('x n')
     77            sage: airy_ai(-2, x)
    5678            airy_ai(-2, x)
    57             sage: derivative(airy_ai(-2,x),x)
     79            sage: derivative(airy_ai(-2, x), x)
    5880            airy_ai(-1, x)
    59             sage: airy_ai(n,x)
     81            sage: airy_ai(n, x)
    6082            airy_ai(n, x)
    61             sage: derivative(airy_ai(n,x),x)
     83            sage: derivative(airy_ai(n, x), x)
    6284            airy_ai(n + 1, x)
    63             sage: airy_ai(2,x,True)
     85            sage: airy_ai(2, x, hold_derivative=True)
    6486            airy_ai(2, x)
    65             sage: derivative(airy_ai(2,x,hold_derivative=True),x)
     87            sage: derivative(airy_ai(2, x, hold_derivative=True), x)
    6688            airy_ai(3, x)
    6789        """
    68 
    6990        BuiltinFunction.__init__(self, "airy_ai", nargs=2,
    70                 latex_name=r"\operatorname{Ai}")
     91                                 latex_name=r"\operatorname{Ai}")
    7192
    7293    def _derivative_(self, alpha, *args, **kwds):
    7394        """
    7495        EXAMPLES::
    7596
    76             sage: x,n=var('x n')
    77             sage: derivative(airy_ai(n,x),x) # indirect doctest
     97            sage: x, n = var('x n')
     98            sage: derivative(airy_ai(n, x), x) # indirect doctest
    7899            airy_ai(n + 1, x)
    79100        """
    80 
    81         x=args[0]
    82         return airy_ai_general(alpha+1,x)
     101        x = args[0]
     102        return airy_ai_general(alpha + 1, x)
    83103
    84104    def _eval_(self, alpha, *args):
    85105        """
    86106        EXAMPLES::
    87107
    88             sage: x,n=var('x n')
    89             sage: airy_ai(-2,1.0) # indirect doctest
     108            sage: x, n = var('x n')
     109            sage: airy_ai(-2, 1.0) # indirect doctest
    90110            0.136645379421096
    91             sage: airy_ai(n,1.0) # indirect doctest
     111            sage: airy_ai(n, 1.0) # indirect doctest
    92112            airy_ai(n, 1.00000000000000)
    93113        """
     114        x = args[0]
    94115
    95         x=args[0]
    96         if not isinstance(x,Expression) and not isinstance(alpha,Expression):
     116        if not isinstance(x, Expression) and not isinstance(alpha, Expression):
    97117            if is_inexact(x):
    98                 return self._evalf_(alpha,x)
     118                return self._evalf_(alpha, x)
    99119        else:
    100120            return None
    101121
     
    103123        """
    104124        EXAMPLES::
    105125
    106             sage: airy_ai(-2,1.0) # indirect doctest
    107             0.136645379421096           
     126            sage: airy_ai(-2, 1.0) # indirect doctest
     127            0.136645379421096
    108128        """
    109129        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    110         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
    111         prec = parent.prec() if hasattr(parent, 'prec') else 53
     130        parent = sage_structure_coerce_parent(x)
    112131        if algorithm == 'mpmath':
    113132            import mpmath
    114133            from sage.libs.mpmath import utils as mpmath_utils
    115             return mpmath_utils.call(mpmath.airyai, x, derivative=alpha, parent=parent)
     134            return mpmath_utils.call(mpmath.airyai, x, derivative=alpha,
     135                                     parent=parent)
    116136        elif algorithm == 'maxima':
    117             raise NotImplementedError("general case not available in maxima")
     137            raise NotImplementedError("general case not available in Maxima")
    118138        else:
    119139            raise ValueError("unknown algorithm")
    120140
     141
    121142class FunctionAiryAiSimple(BuiltinFunction):
    122143    def __init__(self):
    123144        """
    124         The class for the Airy Ai function.
     145        The class for the Airy Ai function
    125146
    126147        EXAMPLES::
    127148
    128149            sage: from sage.functions.airy import FunctionAiryAiSimple
    129             sage: airy_ai_simple= FunctionAiryAiSimple()
    130             sage: f=airy_ai_simple(x); f
     150            sage: airy_ai_simple = FunctionAiryAiSimple()
     151            sage: f = airy_ai_simple(x); f
    131152            airy_ai(x)
    132153        """
    133 
    134         BuiltinFunction.__init__(self, "airy_ai", latex_name=r'\operatorname{Ai}',
    135                 conversions=dict(mathematica='AiryAi', maxima='airy_ai'))
     154        BuiltinFunction.__init__(self, "airy_ai",
     155                                 latex_name=r'\operatorname{Ai}',
     156                                 conversions=dict(mathematica='AiryAi',
     157                                                  maxima='airy_ai'))
    136158
    137159    def _derivative_(self, x, diff_param=None):
    138160        """
    139161        EXAMPLES::
    140        
    141             sage: derivative(airy_ai(x),x) # indirect doctest
     162
     163            sage: derivative(airy_ai(x), x) # indirect doctest
    142164            airy_ai_prime(x)
    143165        """
    144166        return airy_ai_prime(x)
     
    146168    def _eval_(self, x):
    147169        """
    148170        EXAMPLES::
    149        
    150             sage: airy_ai(0) # indirect doctest
     171
     172            sage: airy_ai(0)  # indirect doctest
    151173            1/3*3^(1/3)/gamma(2/3)
    152             sage: airy_ai(0.0) # indirect doctest
     174            sage: airy_ai(0.0)  # indirect doctest
    153175            0.355028053887817
    154             sage: airy_ai(I) # indirect doctest
     176            sage: airy_ai(I)  # indirect doctest
    155177            airy_ai(I)
    156             sage: airy_ai(1.0*I) # indirect doctest
     178            sage: airy_ai(1.0 * I) # indirect doctest
    157179            0.331493305432141 - 0.317449858968444*I
    158180        """
    159 
    160         if not isinstance(x,Expression):
     181        if not isinstance(x, Expression):
    161182            if is_inexact(x):
    162183                return self._evalf_(x)
    163             elif x==0:
    164                 r=ZZ(2)/3
    165                 return 1/(3**(r)*gamma(r))
     184            elif x == 0:
     185                r = ZZ(2) / 3
     186                return 1 / (3 ** (r) * gamma(r))
    166187        else:
    167188            return None
    168189
    169190    def _evalf_(self, x, **kwargs):
    170191        """
    171192        EXAMPLES::
    172        
    173             sage: airy_ai(0.0) # indirect doctest
     193
     194            sage: airy_ai(0.0)  # indirect doctest
    174195            0.355028053887817
    175             sage: airy_ai(1.0*I) # indirect doctest
     196            sage: airy_ai(1.0 * I) # indirect doctest
    176197            0.331493305432141 - 0.317449858968444*I
    177198
    178199        We can use several methods for numerical evaluation::
     
    181202            0.00659113935746
    182203            sage: airy_ai(3).n(algorithm='mpmath')
    183204            0.00659113935746072
    184             sage: airy_ai(3).n(algorithm='mpmath',prec=100)
     205            sage: airy_ai(3).n(algorithm='mpmath', prec=100)
    185206            0.0065911393574607191442574484080
    186            
     207
    187208        TESTS::
    188209
    189210            sage: airy_ai(3).n(algorithm='maxima', prec=70)
    190211            Traceback (most recent call last):
    191212            ...
    192             ValueError: for the maxima algorithm the precision must be 53
    193        
     213            ValueError: for the Maxima algorithm the precision must be 53
     214
    194215        """
    195216        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    196         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
     217        parent = sage_structure_coerce_parent(x)
    197218        prec = parent.prec() if hasattr(parent, 'prec') else 53
    198219        if algorithm == 'mpmath':
    199220            import mpmath
     
    201222            return mpmath_utils.call(mpmath.airyai, x, parent=parent)
    202223        elif algorithm == 'maxima':
    203224            if prec != 53:
    204                 raise ValueError, "for the maxima algorithm the precision must be 53"
    205             return RDF(meval("airy_ai(%s)" % RDF(x)))
     225                raise ValueError("for the Maxima algorithm the precision must "
     226                                 "be 53")
     227            return RDF(meval("airy_ai({})".format(RDF(x))))
    206228        else:
    207229            raise ValueError("unknown algorithm")
    208230
     231
    209232class FunctionAiryAiPrime(BuiltinFunction):
    210233    def __init__(self):
    211234        """
     
    214237
    215238        EXAMPLES::
    216239
    217             sage: x,n=var('x n')
     240            sage: x, n = var('x n')
    218241            sage: airy_ai_prime(x)
    219242            airy_ai_prime(x)
    220243            sage: airy_ai_prime(0)
    221244            -1/3*3^(2/3)/gamma(1/3)
    222245        """
    223 
    224246        BuiltinFunction.__init__(self, "airy_ai_prime",
    225                 latex_name=r"\operatorname{Ai}'",
    226                 conversions=dict(mathematica='AiryAiPrime', maxima='airy_dai'))
     247                                 latex_name=r"\operatorname{Ai}'",
     248                                 conversions=dict(mathematica='AiryAiPrime',
     249                                                  maxima='airy_dai'))
    227250
    228251    def _derivative_(self, x, diff_param=None):
    229252        """
    230253        EXAMPLES::
    231254
    232             sage: derivative(airy_ai_prime(x),x) # indirect doctest
     255            sage: derivative(airy_ai_prime(x), x) # indirect doctest
    233256            x*airy_ai(x)
    234257        """
    235         return x*airy_ai_simple(x)
     258        return x * airy_ai_simple(x)
    236259
    237260    def _eval_(self, x):
    238261        """
    239262        EXAMPLES::
    240263
    241             sage: airy_ai(1,0) # indirect doctest
     264            sage: airy_ai(1, 0) # indirect doctest
    242265            -1/3*3^(2/3)/gamma(1/3)
    243             sage: airy_ai(1,0.0) # indirect doctest
     266            sage: airy_ai(1, 0.0) # indirect doctest
    244267            -0.258819403792807
    245268        """
    246         if not isinstance(x,Expression):
     269        if not isinstance(x, Expression):
    247270            if is_inexact(x):
    248271                return self._evalf_(x)
    249             elif x==0:
    250                 r=ZZ(1)/3
    251                 return -1/(3**(r)*gamma(r))
     272            elif x == 0:
     273                r = ZZ(1) / 3
     274                return -1 / (3 ** (r) * gamma(r))
    252275        else:
    253276            return None
    254277
    255278    def _evalf_(self, x, **kwargs):
    256279        """
    257280        EXAMPLES::
    258        
    259             sage: airy_ai(1,0.0) # indirect doctest
     281
     282            sage: airy_ai(1, 0.0) # indirect doctest
    260283            -0.258819403792807
    261284
    262285        We can use several methods for numerical evaluation::
    263286
    264             sage: airy_ai(1,4).n(algorithm='maxima')
     287            sage: airy_ai(1, 4).n(algorithm='maxima')
    265288            -0.0019586409502
    266             sage: airy_ai(1,4).n(algorithm='mpmath')
     289            sage: airy_ai(1, 4).n(algorithm='mpmath')
    267290            -0.00195864095020418
    268             sage: airy_ai(1,4).n(algorithm='mpmath', prec=100)
     291            sage: airy_ai(1, 4).n(algorithm='mpmath', prec=100)
    269292            -0.0019586409502041789001381409184
    270293
    271294        TESTS::
     
    273296            sage: airy_ai(1, 4).n(algorithm='maxima', prec=70)
    274297            Traceback (most recent call last):
    275298            ...
    276             ValueError: for the maxima algorithm the precision must be 53
    277 
    278 
     299            ValueError: for the Maxima algorithm the precision must be 53
    279300        """
    280301        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    281         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
     302        parent = sage_structure_coerce_parent(x)
    282303        prec = parent.prec() if hasattr(parent, 'prec') else 53
    283304        if algorithm == 'mpmath':
    284305            import mpmath
    285306            from sage.libs.mpmath import utils as mpmath_utils
    286             return mpmath_utils.call(mpmath.airyai, x, derivative=1, parent=parent)
     307            return mpmath_utils.call(mpmath.airyai, x, derivative=1,
     308                                     parent=parent)
    287309        elif algorithm == 'maxima':
    288310            if prec != 53:
    289                 raise ValueError, "for the maxima algorithm the precision must be 53"
    290             return RDF(meval("airy_dai(%s)" % RDF(x)))
     311                raise ValueError("for the Maxima algorithm the precision must "
     312                                 "be 53")
     313            return RDF(meval("airy_dai({})".format(RDF(x))))
    291314        else:
    292315            raise ValueError("unknown algorithm")
    293316
     317airy_ai_general = FunctionAiryAiGeneral()
     318airy_ai_simple = FunctionAiryAiSimple()
     319airy_ai_prime = FunctionAiryAiPrime()
    294320
    295 airy_ai_general=FunctionAiryAiGeneral()
    296 airy_ai_simple= FunctionAiryAiSimple()
    297 airy_ai_prime=  FunctionAiryAiPrime()
    298321
    299 
    300 def airy_ai(alpha,x=None, hold_derivative=False, *args, **kwds):
    301     r"""
     322def airy_ai(alpha, x=None, hold_derivative=False, *args, **kwds):
     323    r"""
    302324    The Airy Ai function `\operatorname{Ai}(x)` is one of the two
    303     linearly independent solutions to the Airy differental equation
     325    linearly independent solutions to the Airy differential equation
    304326    `f''(z) +f(z)x=0`, defined by the initial conditions:
    305327
    306328    .. math ::
    307         \operatorname{Ai}(0)=\frac{1}{2^{2/3} \Gamma(\frac{2}{3})},
     329        \operatorname{Ai}(0)=\frac{1}{2^{2/3} \Gamma\left(\frac{2}{3}\right)},
    308330
    309         \operatorname{Ai}'(0)=-\frac{1}{2^{1/3} \Gamma(\frac{1}{3})}.
     331        \operatorname{Ai}'(0)=-\frac{1}{2^{1/3}\Gamma\left(\frac{1}{3}\right)}.
    310332
    311333    Another way to define the Airy Ai function is:
    312334
     
    315337        \cos\left(\frac{1}{3}t^3+xt\right) dt.
    316338
    317339    INPUT:
    318    
    319     - ``alpha``.- Return the `\alpha`-th order fractional derivative with respect to `z`.
    320       For `\alpha = n = 1,2,3,\ldots` this gives the derivative `\operatorname{Ai}^{(n)}(z)`,
    321       and for `\alpha = -n = -1,-2,-3,\ldots` this gives the `n`-fold iterated integral
    322      
     340
     341    - ``alpha`` -- Return the `\alpha`-th order fractional derivative with
     342      respect to `z`.
     343      For `\alpha = n = 1,2,3,\ldots` this gives the derivative
     344      `\operatorname{Ai}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots`
     345      this gives the `n`-fold iterated integral.
     346
    323347    .. math ::
    324      
     348
    325349        f_0(z) = \operatorname{Ai}(z)
    326      
    327         f_n(z) = \int_0^z f_{n-1}(t) dt.
    328350
    329     - ``x``.- The argument of the function.
     351        f_n(z) = \int_0^z f_{n-1}(t) dt
    330352
    331     - ``hold_derivative``.- Whether or not to stop from returning higher derivatives
    332        in terms of `\operatorname{Ai}(x)` and `\operatorname{Ai}'(x)`.
    333    
     353    - ``x`` -- The argument of the function
     354
     355    - ``hold_derivative`` -- Whether or not to stop from returning higher
     356      derivatives in terms of `\operatorname{Ai}(x)` and
     357      `\operatorname{Ai}'(x)`
    334358
    335359    EXAMPLES::
    336360
    337         sage: n,x=var('n x')
     361        sage: n, x = var('n x')
    338362        sage: airy_ai(x)
    339363        airy_ai(x)
    340364
    341365    It can return derivatives or integrals::
    342    
    343         sage: airy_ai(1,x)
     366
     367        sage: airy_ai(1, x)
    344368        airy_ai_prime(x)
    345         sage: airy_ai(2,x)
     369        sage: airy_ai(2, x)
    346370        x*airy_ai(x)
    347         sage: airy_ai(2,x,True)
     371        sage: airy_ai(2, x, hold_derivative=True)
    348372        airy_ai(2, x)
    349         sage: airy_ai(-2,x)
     373        sage: airy_ai(-2, x)
    350374        airy_ai(-2, x)
    351375        sage: airy_ai(n, x)
    352376        airy_ai(n, x)
    353377
    354     It can be evaluated symbolically or numerically for real or complex values::
     378    It can be evaluated symbolically or numerically for real or complex
     379    values::
    355380
    356381        sage: airy_ai(0)
    357382        1/3*3^(1/3)/gamma(2/3)
     
    362387        sage: airy_ai(1.0*I)
    363388        0.331493305432141 - 0.317449858968444*I
    364389
    365     The functions can be evaluated numerically using either mpmath (the default)
    366     or maxima, where mpmath can compute the values to arbitrary precision::
     390    The functions can be evaluated numerically using either mpmath (the
     391    default) or Maxima, where mpmath can compute the values to arbitrary
     392    precision::
    367393
    368394        sage: airy_ai(2).n(prec=100)
    369395        0.034924130423274379135322080792
    370         sage: airy_ai(2).n(algorithm='mpmath',prec=100)
     396        sage: airy_ai(2).n(algorithm='mpmath', prec=100)
    371397        0.034924130423274379135322080792
    372398        sage: airy_ai(2).n(algorithm='maxima')
    373399        0.0349241304233
    374400
    375401    And the derivatives can be evaluated::
    376402
    377         sage: airy_ai(1,0)
     403        sage: airy_ai(1, 0)
    378404        -1/3*3^(2/3)/gamma(1/3)
    379         sage: airy_ai(1,0.0)
     405        sage: airy_ai(1, 0.0)
    380406        -0.258819403792807
    381407
    382408    Plots::
    383409
    384         sage: plot(airy_ai(x),(x,-10,5))+plot(airy_ai_prime(x),(x,-10,5),color='red')
    385        
     410        sage: (plot(airy_ai(x), (x, -10, 5)) +\
     411               plot(airy_ai_prime(x), (x, -10, 5), color='red'))
     412
    386413    **References**
    387      
     414
    388415    - Abramowitz, Milton; Stegun, Irene A., eds. (1965), "Chapter 10"
    389416
    390417    - http://en.wikipedia.org/wiki/Airy_function
    391418    """
     419    # We catch the case with no alpha
     420    if x is None:
     421        x = alpha
     422        return airy_ai_simple(x, **kwds)
    392423
    393     #We catch the case with no alpha
    394     if x==None:
    395         x=alpha
     424    # We raise an error if there are too many arguments
     425    if len(args) > 0:
     426        raise TypeError(("symbolic function airy_ai takes at most 3 arguments "
     427                         "({} given)").format(len(args) + 3))
     428
     429    # We take care of all other cases.
     430    if not alpha in ZZ and not isinstance(alpha, Expression):
     431        raise ValueError("alpha must be an integer")
     432    if hold_derivative:
     433        return airy_ai_general(alpha, x, **kwds)
     434    elif alpha == 0:
    396435        return airy_ai_simple(x, **kwds)
    397     #We raise an error if there are too many arguments
    398     if len(args) > 0:
    399         raise TypeError("Symbolic function airy_ai takes at most 3 arguments (%s given)" %
    400                         (len(args)+3))
    401 
    402     #We take care of all other cases.
    403     if hold_derivative:
    404         return airy_ai_general(alpha,x,**kwds)
    405     elif alpha==0:
    406         return airy_ai_simple(x, **kwds)
    407     elif alpha==1:
     436    elif alpha == 1:
    408437        return airy_ai_prime(x, **kwds)
    409     elif alpha>1:
    410         #we use a different variable here because if x is a
    411         #particular value, we would be differentiating a constant
    412         #which would return 0. What we want is the value of
    413         #the derivative at the value and not the derivative of
    414         #a particular value of the function.
    415         v=var('v')
    416         return derivative(airy_ai_simple(v,**kwds),v,alpha).subs(v=x)
     438    elif alpha > 1:
     439        # We use a different variable here because if x is a
     440        # particular value, we would be differentiating a constant
     441        # which would return 0. What we want is the value of
     442        # the derivative at the value and not the derivative of
     443        # a particular value of the function.
     444        v = var('v')
     445        return derivative(airy_ai_simple(v, **kwds), v, alpha).subs(v=x)
    417446    else:
    418         return airy_ai_general(alpha,x,**kwds)
     447        return airy_ai_general(alpha, x, **kwds)
    419448
    420449########################################################################
    421450########################################################################
    422451
     452
    423453class FunctionAiryBiGeneral(BuiltinFunction):
    424454    def __init__(self):
    425455        r"""
    426456        The generalized derivative of the Airy Bi function
    427457
    428458        INPUT:
    429        
    430         - ``alpha``.- Return the `\alpha`-th order fractional derivative with respect to
    431           `z`. For `\alpha = n = 1,2,3,\ldots` this gives the derivative
    432           `\operatorname{Bi}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots` this gives
    433           the `n`-fold iterated integral
    434          
     459
     460        - ``alpha`` -- Return the `\alpha`-th order fractional derivative with
     461          respect to `z`.
     462          For `\alpha = n = 1,2,3,\ldots` this gives the derivative
     463          `\operatorname{Bi}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots`
     464          this gives the `n`-fold iterated integral.
     465
    435466        .. math ::
    436          
     467
    437468            f_0(z) = \operatorname{Bi}(z)
    438          
    439             f_n(z) = \int_0^z f_{n-1}(t) dt.
    440469
    441         - ``x``.- The argument of the function.
     470            f_n(z) = \int_0^z f_{n-1}(t) dt
    442471
    443         - ``hold``.- Whether or not to stop from returning higher derivatives in terms of
    444           `\operatorname{Bi}(x)` and `\operatorname{Bi}'(x)`.
    445        
     472        - ``x`` -- The argument of the function
     473
     474        - ``hold_derivative`` -- Whether or not to stop from returning higher
     475          derivatives in terms of `\operatorname{Bi}(x)` and
     476          `\operatorname{Bi}'(x)`
     477
    446478        EXAMPLES::
    447479
    448             sage: x,n=var('x n')
    449             sage: airy_bi(-2,x)
     480            sage: x, n = var('x n')
     481            sage: airy_bi(-2, x)
    450482            airy_bi(-2, x)
    451             sage: derivative(airy_bi(-2,x),x)
     483            sage: derivative(airy_bi(-2, x), x)
    452484            airy_bi(-1, x)
    453             sage: airy_bi(n,x)
     485            sage: airy_bi(n, x)
    454486            airy_bi(n, x)
    455             sage: derivative(airy_bi(n,x),x)
     487            sage: derivative(airy_bi(n, x), x)
    456488            airy_bi(n + 1, x)
    457             sage: airy_bi(2,x,True)
     489            sage: airy_bi(2, x, hold_derivative=True)
    458490            airy_bi(2, x)
    459             sage: derivative(airy_bi(2,x,hold_derivative=True),x)
     491            sage: derivative(airy_bi(2, x, hold_derivative=True), x)
    460492            airy_bi(3, x)
    461493        """
    462 
    463494        BuiltinFunction.__init__(self, "airy_bi", nargs=2,
    464             latex_name=r"\operatorname{Bi}")
     495                                 latex_name=r"\operatorname{Bi}")
    465496
    466497    def _derivative_(self, alpha, *args, **kwds):
    467498        """
    468499        EXAMPLES::
    469500
    470             sage: x,n=var('x n')
    471             sage: derivative(airy_bi(n,x),x) # indirect doctest
     501            sage: x, n = var('x n')
     502            sage: derivative(airy_bi(n, x), x) # indirect doctest
    472503            airy_bi(n + 1, x)
    473504        """
    474 
    475         x=args[0]
    476         return airy_bi_general(alpha+1,x)
     505        x = args[0]
     506        return airy_bi_general(alpha + 1, x)
    477507
    478508    def _eval_(self, alpha, *args):
    479509        """
    480510        EXAMPLES::
    481511
    482             sage: x,n=var('x n')
    483             sage: airy_bi(-2,1.0) # indirect doctest
     512            sage: x, n = var('x n')
     513            sage: airy_bi(-2, 1.0) # indirect doctest
    484514            0.388621540699059
    485             sage: airy_bi(n,1.0) # indirect doctest
     515            sage: airy_bi(n, 1.0) # indirect doctest
    486516            airy_bi(n, 1.00000000000000)
    487517        """
    488 
    489        
    490         x=args[0]
    491         if not isinstance(x,Expression) and not isinstance(alpha,Expression):
     518        x = args[0]
     519        if not isinstance(x, Expression) and not isinstance(alpha, Expression):
    492520            if is_inexact(x):
    493                 return self._evalf_(alpha,x)
     521                return self._evalf_(alpha, x)
    494522        else:
    495523            return None
    496524
     
    498526        """
    499527        EXAMPLES::
    500528
    501             sage: airy_bi(-2,1.0) # indirect doctest
     529            sage: airy_bi(-2, 1.0) # indirect doctest
    502530            0.388621540699059
    503531
    504532        """
    505533        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    506         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
    507         prec = parent.prec() if hasattr(parent, 'prec') else 53
     534        parent = sage_structure_coerce_parent(x)
    508535        if algorithm == 'mpmath':
    509536            import mpmath
    510537            from sage.libs.mpmath import utils as mpmath_utils
    511             return mpmath_utils.call(mpmath.airybi, x, derivative=alpha, parent=parent)
     538            return mpmath_utils.call(mpmath.airybi, x, derivative=alpha,
     539                                     parent=parent)
    512540        elif algorithm == 'maxima':
    513             raise NotImplementedError("general case not available in maxima")
     541            raise NotImplementedError("general case not available in Maxima")
    514542        else:
    515543            raise ValueError("unknown algorithm")
    516544
     545
    517546class FunctionAiryBiSimple(BuiltinFunction):
    518547    def __init__(self):
    519548        """
    520         The class for the Airy Bi function.
     549        The class for the Airy Bi function
    521550
    522551        EXAMPLES::
    523552
    524553            sage: from sage.functions.airy import FunctionAiryBiSimple
    525554            sage: airy_bi_simple= FunctionAiryBiSimple()
    526             sage: f=airy_bi_simple(x); f
     555            sage: f = airy_bi_simple(x); f
    527556            airy_bi(x)
    528557        """
    529 
    530         BuiltinFunction.__init__(self, "airy_bi", latex_name=r'\operatorname{Bi}',
    531                 conversions=dict(mathematica='AiryBi', maxima='airy_bi'))
     558        BuiltinFunction.__init__(self, "airy_bi",
     559                                 latex_name=r'\operatorname{Bi}',
     560                                 conversions=dict(mathematica='AiryBi',
     561                                                  maxima='airy_bi'))
    532562
    533563    def _derivative_(self, x, diff_param=None):
    534564        """
    535565        EXAMPLES::
    536        
    537             sage: derivative(airy_bi(x),x) # indirect doctest
     566
     567            sage: derivative(airy_bi(x), x) # indirect doctest
    538568            airy_bi_prime(x)
    539569        """
    540570        return airy_bi_prime(x)
     
    542572    def _eval_(self, x):
    543573        """
    544574        EXAMPLES::
    545        
    546             sage: airy_bi(0) # indirect doctest
    547             1/3*3^(5/6)/gamma(1/3)
    548             sage: airy_bi(0.0) # indirect doctest
     575
     576            sage: airy_bi(0)  # indirect doctest
     577            1/3*3^(5/6)/gamma(2/3)
     578            sage: airy_bi(0.0)  # indirect doctest
    549579            0.614926627446001
    550             sage: airy_bi(I) # indirect doctest
     580            sage: airy_bi(0).n() == airy_bi(0.0)  # indirect doctest
     581            True
     582            sage: airy_bi(I)  # indirect doctest
    551583            airy_bi(I)
    552             sage: airy_bi(1.0*I) # indirect doctest
     584            sage: airy_bi(1.0 * I) # indirect doctest
    553585            0.648858208330395 + 0.344958634768048*I
    554586        """
    555 
    556         if not isinstance(x,Expression):
     587        if not isinstance(x, Expression):
    557588            if is_inexact(x):
    558589                return self._evalf_(x)
    559             elif x==0:
    560                 one_sixth = ZZ(1)/6
    561                 return 1/(3**(one_sixth)*gamma(2*one_sixth))
     590            elif x == 0:
     591                one_sixth = ZZ(1) / 6
     592                return 1 / (3 ** (one_sixth) * gamma(4 * one_sixth))
    562593        else:
    563594            return None
    564595
    565596    def _evalf_(self, x, **kwargs):
    566597        """
    567598        EXAMPLES::
    568        
    569             sage: airy_bi(0.0) # indirect doctest
     599
     600            sage: airy_bi(0.0)  # indirect doctest
    570601            0.614926627446001
    571             sage: airy_bi(1.0*I) # indirect doctest
     602            sage: airy_bi(1.0 * I) # indirect doctest
    572603            0.648858208330395 + 0.344958634768048*I
    573604
    574605        We can use several methods for numerical evaluation::
     
    585616            sage: airy_bi(3).n(algorithm='maxima', prec=100)
    586617            Traceback (most recent call last):
    587618            ...
    588             ValueError: for the maxima algorithm the precision must be 53
     619            ValueError: for the Maxima algorithm the precision must be 53
    589620
    590621        """
    591622        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    592         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
     623        parent = sage_structure_coerce_parent(x)
    593624        prec = parent.prec() if hasattr(parent, 'prec') else 53
    594625        if algorithm == 'mpmath':
    595626            import mpmath
     
    597628            return mpmath_utils.call(mpmath.airybi, x, parent=parent)
    598629        elif algorithm == 'maxima':
    599630            if prec != 53:
    600                 raise ValueError, "for the maxima algorithm the precision must be 53"
    601             return RDF(meval("airy_bi(%s)" % RDF(x)))
     631                raise ValueError("for the Maxima algorithm the precision must "
     632                                 "be 53")
     633            return RDF(meval("airy_bi({})".format(RDF(x))))
    602634        else:
    603635            raise ValueError("unknown algorithm")
    604636
     637
    605638class FunctionAiryBiPrime(BuiltinFunction):
    606639    def __init__(self):
    607640        """
     
    610643
    611644        EXAMPLES::
    612645
    613             sage: x,n=var('x n')
    614             sage: airy_bi_prime(x) # indirect doctest
     646            sage: x, n = var('x n')
     647            sage: airy_bi_prime(x)  # indirect doctest
    615648            airy_bi_prime(x)
    616             sage: airy_bi_prime(0) # indirect doctest
     649            sage: airy_bi_prime(0)  # indirect doctest
    617650            3^(1/6)/gamma(1/3)
    618651        """
    619 
    620652        BuiltinFunction.__init__(self, "airy_bi_prime",
    621                 latex_name=r"\operatorname{Bi}'",
    622                 conversions=dict(mathematica='AiryBiPrime', maxima='airy_dbi'))
     653                                 latex_name=r"\operatorname{Bi}'",
     654                                 conversions=dict(mathematica='AiryBiPrime',
     655                                                  maxima='airy_dbi'))
    623656
    624657    def _derivative_(self, x, diff_param=None):
    625658        """
    626659        EXAMPLES::
    627660
    628             sage: derivative(airy_bi_prime(x),x) # indirect doctest
     661            sage: derivative(airy_bi_prime(x), x) # indirect doctest
    629662            x*airy_bi(x)
    630663        """
    631         return x*airy_bi_simple(x)
     664        return x * airy_bi_simple(x)
    632665
    633666    def _eval_(self, x):
    634667        """
    635668        EXAMPLES::
    636669
    637             sage: airy_bi(1,0) # indirect doctest
     670            sage: airy_bi(1, 0) # indirect doctest
    638671            3^(1/6)/gamma(1/3)
    639             sage: airy_bi(1,0.0) # indirect doctest
     672            sage: airy_bi(1, 0.0) # indirect doctest
    640673            0.448288357353826
    641674        """
    642         if not isinstance(x,Expression):
     675        if not isinstance(x, Expression):
    643676            if is_inexact(x):
    644677                return self._evalf_(x)
    645             elif x==0:
    646                 one_sixth = ZZ(1)/6
    647                 return 3**(one_sixth)/gamma(2*one_sixth)
     678            elif x == 0:
     679                one_sixth = ZZ(1) / 6
     680                return 3 ** (one_sixth) / gamma(2 * one_sixth)
    648681        else:
    649682            return None
    650683
    651684    def _evalf_(self, x, **kwargs):
    652685        """
    653686        EXAMPLES::
    654        
    655             sage: airy_bi(1,0.0) # indirect doctest
     687
     688            sage: airy_bi(1, 0.0) # indirect doctest
    656689            0.448288357353826
    657690
    658691        We can use several methods for numerical evaluation::
    659692
    660             sage: airy_bi(1,4).n(algorithm='maxima')
     693            sage: airy_bi(1, 4).n(algorithm='maxima')
    661694            161.926683505
    662             sage: airy_bi(1,4).n(algorithm='mpmath')
     695            sage: airy_bi(1, 4).n(algorithm='mpmath')
    663696            161.926683504613
    664             sage: airy_bi(1,4).n(algorithm='mpmath', prec=100)
     697            sage: airy_bi(1, 4).n(algorithm='mpmath', prec=100)
    665698            161.92668350461340184309492429
    666699
    667700        TESTS::
    668701
    669             sage: airy_bi(1,4).n(algorithm='maxima', prec=70)
     702            sage: airy_bi(1, 4).n(algorithm='maxima', prec=70)
    670703            Traceback (most recent call last):
    671704            ...
    672             ValueError: for the maxima algorithm the precision must be 53
    673 
     705            ValueError: for the Maxima algorithm the precision must be 53
    674706        """
    675707        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    676         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
     708        parent = sage_structure_coerce_parent(x)
    677709        prec = parent.prec() if hasattr(parent, 'prec') else 53
    678710        if algorithm == 'mpmath':
    679711            import mpmath
    680712            from sage.libs.mpmath import utils as mpmath_utils
    681             return mpmath_utils.call(mpmath.airybi, x, derivative=1, parent=parent)
     713            return mpmath_utils.call(mpmath.airybi, x, derivative=1,
     714                                     parent=parent)
    682715        elif algorithm == 'maxima':
    683716            if prec != 53:
    684                 raise ValueError, "for the maxima algorithm the precision must be 53"
    685             return RDF(meval("airy_dbi(%s)" % RDF(x)))
     717                raise ValueError("for the Maxima algorithm the precision must "
     718                                 "be 53")
     719            return RDF(meval("airy_dbi({})".format(RDF(x))))
    686720        else:
    687721            raise ValueError("unknown algorithm")
    688722
    689 airy_bi_general=FunctionAiryBiGeneral()
    690 airy_bi_simple= FunctionAiryBiSimple()
    691 airy_bi_prime= FunctionAiryBiPrime()
     723airy_bi_general = FunctionAiryBiGeneral()
     724airy_bi_simple = FunctionAiryBiSimple()
     725airy_bi_prime = FunctionAiryBiPrime()
    692726
    693 def airy_bi(alpha,x=None, hold_derivative=False, *args, **kwds):
     727
     728def airy_bi(alpha, x=None, hold_derivative=False, *args, **kwds):
    694729    r"""
    695730    The Airy Bi function `\operatorname{Bi}(x)` is one of the two
    696     linearly independent solutions to the Airy differental equation
     731    linearly independent solutions to the Airy differential equation
    697732    `f''(z) +f(z)x=0`, defined by the initial conditions:
    698733
    699734    .. math ::
    700         \operatorname{Bi}(0)=\frac{1}{3^{1/6} \Gamma(\frac{2}{3})},
     735        \operatorname{Bi}(0)=\frac{1}{3^{1/6} \Gamma\left(\frac{2}{3}\right)},
    701736
    702         \operatorname{Bi}'(0)=\frac{3^{1/6}}{ \Gamma(\frac{1}{3})}.
     737        \operatorname{Bi}'(0)=\frac{3^{1/6}}{ \Gamma\left(\frac{1}{3}\right)}.
    703738
    704739    Another way to define the Airy Bi function is:
    705740
     
    709744        +\sin\left(xt + \frac{1}{3}t^3\right) \right ] dt.
    710745
    711746    INPUT:
    712    
    713     - ``alpha``.- Return the `\alpha`-th order fractional derivative with respect to `z`.
    714       For `\alpha = n = 1,2,3,\ldots` this gives the derivative `\operatorname{Bi}^{(n)}(z)`,
    715       and for `\alpha = -n = -1,-2,-3,\ldots` this gives the `n`-fold iterated integral
    716      
     747
     748    - ``alpha`` -- Return the `\alpha`-th order fractional derivative with
     749      respect to `z`.
     750      For `\alpha = n = 1,2,3,\ldots` this gives the derivative
     751      `\operatorname{Bi}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots`
     752      this gives the `n`-fold iterated integral.
     753
    717754    .. math ::
    718      
     755
    719756        f_0(z) = \operatorname{Bi}(z)
    720      
    721         f_n(z) = \int_0^z f_{n-1}(t) dt.
    722757
    723     - ``x``.- The argument of the function.
     758        f_n(z) = \int_0^z f_{n-1}(t) dt
    724759
    725     - ``hold_derivative``.- Whether or not to stop from returning higher derivatives in
    726       terms of `\operatorname{Bi}(x)` and `\operatorname{Bi}'(x)`.
    727    
     760    - ``x`` -- The argument of the function
     761
     762    - ``hold_derivative`` -- Whether or not to stop from returning higher
     763      derivatives in terms of `\operatorname{Bi}(x)` and
     764      `\operatorname{Bi}'(x)`
    728765
    729766    EXAMPLES::
    730767
    731         sage: n,x=var('n x')
     768        sage: n, x = var('n x')
    732769        sage: airy_bi(x)
    733770        airy_bi(x)
    734771
    735772    It can return derivatives or integrals::
    736    
    737         sage: airy_bi(1,x)
     773
     774        sage: airy_bi(1, x)
    738775        airy_bi_prime(x)
    739         sage: airy_bi(2,x)
     776        sage: airy_bi(2, x)
    740777        x*airy_bi(x)
    741         sage: airy_bi(2,x,True)
     778        sage: airy_bi(2, x, hold_derivative=True)
    742779        airy_bi(2, x)
    743         sage: airy_bi(-2,x)
     780        sage: airy_bi(-2, x)
    744781        airy_bi(-2, x)
    745782        sage: airy_bi(n, x)
    746783        airy_bi(n, x)
    747784
    748     It can be evaluated symbolically or numerically for real or complex values::
     785    It can be evaluated symbolically or numerically for real or complex
     786    values::
    749787
    750788        sage: airy_bi(0)
    751         1/3*3^(5/6)/gamma(1/3)
     789        1/3*3^(5/6)/gamma(2/3)
    752790        sage: airy_bi(0.0)
    753791        0.614926627446001
    754792        sage: airy_bi(I)
     
    756794        sage: airy_bi(1.0*I)
    757795        0.648858208330395 + 0.344958634768048*I
    758796
    759     The functions can be evaluated numerically using either mpmath (the default)
    760     or maxima, where mpmath can compute the values to arbitrary precision::
     797    The functions can be evaluated numerically using either mpmath (the
     798    default) or Maxima, where mpmath can compute the values to arbitrary
     799    precision::
    761800
    762801        sage: airy_bi(2).n(prec=100)
    763802        3.2980949999782147102806044252
    764         sage: airy_bi(2).n(algorithm='mpmath',prec=100)
     803        sage: airy_bi(2).n(algorithm='mpmath', prec=100)
    765804        3.2980949999782147102806044252
    766805        sage: airy_bi(2).n(algorithm='maxima')
    767806        3.29809499998
    768807
    769808    And the derivatives can be evaluated::
    770809
    771         sage: airy_bi(1,0)
     810        sage: airy_bi(1, 0)
    772811        3^(1/6)/gamma(1/3)
    773         sage: airy_bi(1,0.0)
     812        sage: airy_bi(1, 0.0)
    774813        0.448288357353826
    775814
    776815    Plots::
    777816
    778         sage: plot(airy_bi(x),(x,-10,5))+plot(airy_bi_prime(x),(x,-10,5),color='red')
    779        
     817        sage: (plot(airy_bi(x), (x, -10, 5)) +\
     818               plot(airy_bi_prime(x), (x, -10, 5), color='red'))
     819
    780820    **References**
    781      
     821
    782822    - Abramowitz, Milton; Stegun, Irene A., eds. (1965), "Chapter 10"
    783823
    784824    - http://en.wikipedia.org/wiki/Airy_function
    785825    """
     826    # We catch the case with no alpha
     827    if x is None:
     828        x = alpha
     829        return airy_bi_simple(x, **kwds)
    786830
    787     #We catch the case with no alpha
    788     if x==None:
    789         x=alpha
     831    # We raise an error if there are too many arguments
     832    if len(args) > 0:
     833        raise TypeError(("symbolic function airy_ai takes at most 3 arguments "
     834                         "({} given)").format(len(args) + 3))
     835
     836    # We take care of all other cases.
     837    if hold_derivative:
     838        return airy_bi_general(alpha, x, **kwds)
     839    elif alpha == 0:
    790840        return airy_bi_simple(x, **kwds)
    791     #We raise an error if there are too many arguments
    792     if len(args) > 0:
    793         raise TypeError("Symbolic function airy_ai takes at most 3 arguments (%s given)" %
    794                         (len(args)+3))
    795 
    796     #We take care of all other cases.
    797     if hold_derivative:
    798         return airy_bi_general(alpha,x,**kwds)
    799     elif alpha==0:
    800         return airy_bi_simple(x, **kwds)
    801     elif alpha==1:
     841    elif alpha == 1:
    802842        return airy_bi_prime(x, **kwds)
    803     elif alpha>1:
    804         #we use a different variable here because if x is a
    805         #particular value, we would be differentiating a constant
    806         #which would return 0. What we want is the value of
    807         #the derivative at the value and not the derivative of
    808         #a particular value of the function.
    809         v=var('v')
    810         return derivative(airy_bi_simple(v,**kwds),v,alpha).subs(v=x)
     843    elif alpha > 1:
     844        # We use a different variable here because if x is a
     845        # particular value, we would be differentiating a constant
     846        # which would return 0. What we want is the value of
     847        # the derivative at the value and not the derivative of
     848        # a particular value of the function.
     849        v = var('v')
     850        return derivative(airy_bi_simple(v, **kwds), v, alpha).subs(v=x)
    811851    else:
    812         return airy_bi_general(alpha,x,**kwds)
    813 
     852        return airy_bi_general(alpha, x, **kwds)