Ticket #12455: trac_12455_newstyle_airy2.patch

File trac_12455_newstyle_airy2.patch, 41.4 KB (added by eviatarbach, 6 years ago)
  • doc/en/reference/functions/index.rst

    # HG changeset patch
    # User Eviatar Bach <eviatarbach@gmail.com>
    # Date 1371600084 25200
    # Branch airy
    # Node ID 7ae7060f2c1b674e08d62973eb44f939327e86f6
    # Parent  a52dffb6d915258df25e61dd167fe46dd72e0f4e
    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/exp_integral
    1516   sage/functions/wigner
    1617   sage/functions/generalized
  • 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)
    197         prec = parent.prec() if hasattr(parent, 'prec') else 53
     217        parent = sage_structure_coerce_parent(x)
    198218        if algorithm == 'mpmath':
    199219            import mpmath
    200220            from sage.libs.mpmath import utils as mpmath_utils
    201221            return mpmath_utils.call(mpmath.airyai, x, parent=parent)
    202222        elif algorithm == 'maxima':
    203223            if prec != 53:
    204                 raise ValueError, "for the maxima algorithm the precision must be 53"
    205             return RDF(meval("airy_ai(%s)" % RDF(x)))
     224                raise ValueError("for the Maxima algorithm the precision must "
     225                                 "be 53")
     226            return RDF(meval("airy_ai({})".format(RDF(x))))
    206227        else:
    207228            raise ValueError("unknown algorithm")
    208229
     230
    209231class FunctionAiryAiPrime(BuiltinFunction):
    210232    def __init__(self):
    211233        """
     
    214236
    215237        EXAMPLES::
    216238
    217             sage: x,n=var('x n')
     239            sage: x, n = var('x n')
    218240            sage: airy_ai_prime(x)
    219241            airy_ai_prime(x)
    220242            sage: airy_ai_prime(0)
    221243            -1/3*3^(2/3)/gamma(1/3)
    222244        """
    223 
    224245        BuiltinFunction.__init__(self, "airy_ai_prime",
    225                 latex_name=r"\operatorname{Ai}'",
    226                 conversions=dict(mathematica='AiryAiPrime', maxima='airy_dai'))
     246                                 latex_name=r"\operatorname{Ai}'",
     247                                 conversions=dict(mathematica='AiryAiPrime',
     248                                                  maxima='airy_dai'))
    227249
    228250    def _derivative_(self, x, diff_param=None):
    229251        """
    230252        EXAMPLES::
    231253
    232             sage: derivative(airy_ai_prime(x),x) # indirect doctest
     254            sage: derivative(airy_ai_prime(x), x) # indirect doctest
    233255            x*airy_ai(x)
    234256        """
    235         return x*airy_ai_simple(x)
     257        return x * airy_ai_simple(x)
    236258
    237259    def _eval_(self, x):
    238260        """
    239261        EXAMPLES::
    240262
    241             sage: airy_ai(1,0) # indirect doctest
     263            sage: airy_ai(1, 0) # indirect doctest
    242264            -1/3*3^(2/3)/gamma(1/3)
    243             sage: airy_ai(1,0.0) # indirect doctest
     265            sage: airy_ai(1, 0.0) # indirect doctest
    244266            -0.258819403792807
    245267        """
    246         if not isinstance(x,Expression):
     268        if not isinstance(x, Expression):
    247269            if is_inexact(x):
    248270                return self._evalf_(x)
    249             elif x==0:
    250                 r=ZZ(1)/3
    251                 return -1/(3**(r)*gamma(r))
     271            elif x == 0:
     272                r = ZZ(1) / 3
     273                return -1 / (3 ** (r) * gamma(r))
    252274        else:
    253275            return None
    254276
    255277    def _evalf_(self, x, **kwargs):
    256278        """
    257279        EXAMPLES::
    258        
    259             sage: airy_ai(1,0.0) # indirect doctest
     280
     281            sage: airy_ai(1, 0.0) # indirect doctest
    260282            -0.258819403792807
    261283
    262284        We can use several methods for numerical evaluation::
    263285
    264             sage: airy_ai(1,4).n(algorithm='maxima')
     286            sage: airy_ai(1, 4).n(algorithm='maxima')
    265287            -0.0019586409502
    266             sage: airy_ai(1,4).n(algorithm='mpmath')
     288            sage: airy_ai(1, 4).n(algorithm='mpmath')
    267289            -0.00195864095020418
    268             sage: airy_ai(1,4).n(algorithm='mpmath', prec=100)
     290            sage: airy_ai(1, 4).n(algorithm='mpmath', prec=100)
    269291            -0.0019586409502041789001381409184
    270292
    271293        TESTS::
     
    273295            sage: airy_ai(1, 4).n(algorithm='maxima', prec=70)
    274296            Traceback (most recent call last):
    275297            ...
    276             ValueError: for the maxima algorithm the precision must be 53
    277 
    278 
     298            ValueError: for the Maxima algorithm the precision must be 53
    279299        """
    280300        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    281         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
    282         prec = parent.prec() if hasattr(parent, 'prec') else 53
     301        parent = sage_structure_coerce_parent(x)
    283302        if algorithm == 'mpmath':
    284303            import mpmath
    285304            from sage.libs.mpmath import utils as mpmath_utils
    286             return mpmath_utils.call(mpmath.airyai, x, derivative=1, parent=parent)
     305            return mpmath_utils.call(mpmath.airyai, x, derivative=1,
     306                                     parent=parent)
    287307        elif algorithm == 'maxima':
    288308            if prec != 53:
    289                 raise ValueError, "for the maxima algorithm the precision must be 53"
    290             return RDF(meval("airy_dai(%s)" % RDF(x)))
     309                raise ValueError("for the Maxima algorithm the precision must "
     310                                 "be 53")
     311            return RDF(meval("airy_dai({})".format(RDF(x))))
    291312        else:
    292313            raise ValueError("unknown algorithm")
    293314
     315airy_ai_general = FunctionAiryAiGeneral()
     316airy_ai_simple = FunctionAiryAiSimple()
     317airy_ai_prime = FunctionAiryAiPrime()
    294318
    295 airy_ai_general=FunctionAiryAiGeneral()
    296 airy_ai_simple= FunctionAiryAiSimple()
    297 airy_ai_prime=  FunctionAiryAiPrime()
    298319
    299 
    300 def airy_ai(alpha,x=None, hold_derivative=False, *args, **kwds):
    301     r"""
     320def airy_ai(alpha, x=None, hold_derivative=False, *args, **kwds):
     321    r"""
    302322    The Airy Ai function `\operatorname{Ai}(x)` is one of the two
    303     linearly independent solutions to the Airy differental equation
     323    linearly independent solutions to the Airy differential equation
    304324    `f''(z) +f(z)x=0`, defined by the initial conditions:
    305325
    306326    .. math ::
    307         \operatorname{Ai}(0)=\frac{1}{2^{2/3} \Gamma(\frac{2}{3})},
     327        \operatorname{Ai}(0)=\frac{1}{2^{2/3} \Gamma\left(\frac{2}{3}\right)},
    308328
    309         \operatorname{Ai}'(0)=-\frac{1}{2^{1/3} \Gamma(\frac{1}{3})}.
     329        \operatorname{Ai}'(0)=-\frac{1}{2^{1/3}\Gamma\left(\frac{1}{3}\right)}.
    310330
    311331    Another way to define the Airy Ai function is:
    312332
     
    315335        \cos\left(\frac{1}{3}t^3+xt\right) dt.
    316336
    317337    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      
     338
     339    - ``alpha`` -- Return the `\alpha`-th order fractional derivative with
     340      respect to `z`.
     341      For `\alpha = n = 1,2,3,\ldots` this gives the derivative
     342      `\operatorname{Ai}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots`
     343      this gives the `n`-fold iterated integral.
     344
    323345    .. math ::
    324      
     346
    325347        f_0(z) = \operatorname{Ai}(z)
    326      
    327         f_n(z) = \int_0^z f_{n-1}(t) dt.
    328348
    329     - ``x``.- The argument of the function.
     349        f_n(z) = \int_0^z f_{n-1}(t) dt
    330350
    331     - ``hold_derivative``.- Whether or not to stop from returning higher derivatives
    332        in terms of `\operatorname{Ai}(x)` and `\operatorname{Ai}'(x)`.
    333    
     351    - ``x`` -- The argument of the function
     352
     353    - ``hold_derivative`` -- Whether or not to stop from returning higher
     354      derivatives in terms of `\operatorname{Ai}(x)` and
     355      `\operatorname{Ai}'(x)`
    334356
    335357    EXAMPLES::
    336358
    337         sage: n,x=var('n x')
     359        sage: n, x = var('n x')
    338360        sage: airy_ai(x)
    339361        airy_ai(x)
    340362
    341363    It can return derivatives or integrals::
    342    
    343         sage: airy_ai(1,x)
     364
     365        sage: airy_ai(1, x)
    344366        airy_ai_prime(x)
    345         sage: airy_ai(2,x)
     367        sage: airy_ai(2, x)
    346368        x*airy_ai(x)
    347         sage: airy_ai(2,x,True)
     369        sage: airy_ai(2, x, hold_derivative=True)
    348370        airy_ai(2, x)
    349         sage: airy_ai(-2,x)
     371        sage: airy_ai(-2, x)
    350372        airy_ai(-2, x)
    351373        sage: airy_ai(n, x)
    352374        airy_ai(n, x)
    353375
    354     It can be evaluated symbolically or numerically for real or complex values::
     376    It can be evaluated symbolically or numerically for real or complex
     377    values::
    355378
    356379        sage: airy_ai(0)
    357380        1/3*3^(1/3)/gamma(2/3)
     
    362385        sage: airy_ai(1.0*I)
    363386        0.331493305432141 - 0.317449858968444*I
    364387
    365     The functions can be evaluated numerically using either mpmath (the default)
    366     or maxima, where mpmath can compute the values to arbitrary precision::
     388    The functions can be evaluated numerically using either mpmath (the
     389    default) or Maxima, where mpmath can compute the values to arbitrary
     390    precision::
    367391
    368392        sage: airy_ai(2).n(prec=100)
    369393        0.034924130423274379135322080792
    370         sage: airy_ai(2).n(algorithm='mpmath',prec=100)
     394        sage: airy_ai(2).n(algorithm='mpmath', prec=100)
    371395        0.034924130423274379135322080792
    372396        sage: airy_ai(2).n(algorithm='maxima')
    373397        0.0349241304233
    374398
    375399    And the derivatives can be evaluated::
    376400
    377         sage: airy_ai(1,0)
     401        sage: airy_ai(1, 0)
    378402        -1/3*3^(2/3)/gamma(1/3)
    379         sage: airy_ai(1,0.0)
     403        sage: airy_ai(1, 0.0)
    380404        -0.258819403792807
    381405
    382406    Plots::
    383407
    384         sage: plot(airy_ai(x),(x,-10,5))+plot(airy_ai_prime(x),(x,-10,5),color='red')
    385        
     408        sage: (plot(airy_ai(x), (x, -10, 5)) +\
     409               plot(airy_ai_prime(x), (x, -10, 5), color='red'))
     410
    386411    **References**
    387      
     412
    388413    - Abramowitz, Milton; Stegun, Irene A., eds. (1965), "Chapter 10"
    389414
    390415    - http://en.wikipedia.org/wiki/Airy_function
    391416    """
     417    # We catch the case with no alpha
     418    if x is None:
     419        x = alpha
     420        return airy_ai_simple(x, **kwds)
    392421
    393     #We catch the case with no alpha
    394     if x==None:
    395         x=alpha
     422    # We raise an error if there are too many arguments
     423    if len(args) > 0:
     424        raise TypeError(("symbolic function airy_ai takes at most 3 arguments "
     425                         "({} given)").format(len(args) + 3))
     426
     427    # We take care of all other cases.
     428    if not alpha in ZZ and not isinstance(alpha, Expression):
     429        raise ValueError("alpha must be an integer")
     430    if hold_derivative:
     431        return airy_ai_general(alpha, x, **kwds)
     432    elif alpha == 0:
    396433        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:
     434    elif alpha == 1:
    408435        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)
     436    elif alpha > 1:
     437        # We use a different variable here because if x is a
     438        # particular value, we would be differentiating a constant
     439        # which would return 0. What we want is the value of
     440        # the derivative at the value and not the derivative of
     441        # a particular value of the function.
     442        v = var('v')
     443        return derivative(airy_ai_simple(v, **kwds), v, alpha).subs(v=x)
    417444    else:
    418         return airy_ai_general(alpha,x,**kwds)
     445        return airy_ai_general(alpha, x, **kwds)
    419446
    420447########################################################################
    421448########################################################################
    422449
     450
    423451class FunctionAiryBiGeneral(BuiltinFunction):
    424452    def __init__(self):
    425453        r"""
    426454        The generalized derivative of the Airy Bi function
    427455
    428456        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          
     457
     458        - ``alpha`` -- Return the `\alpha`-th order fractional derivative with
     459          respect to `z`.
     460          For `\alpha = n = 1,2,3,\ldots` this gives the derivative
     461          `\operatorname{Bi}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots`
     462          this gives the `n`-fold iterated integral.
     463
    435464        .. math ::
    436          
     465
    437466            f_0(z) = \operatorname{Bi}(z)
    438          
    439             f_n(z) = \int_0^z f_{n-1}(t) dt.
    440467
    441         - ``x``.- The argument of the function.
     468            f_n(z) = \int_0^z f_{n-1}(t) dt
    442469
    443         - ``hold``.- Whether or not to stop from returning higher derivatives in terms of
    444           `\operatorname{Bi}(x)` and `\operatorname{Bi}'(x)`.
    445        
     470        - ``x`` -- The argument of the function
     471
     472        - ``hold_derivative`` -- Whether or not to stop from returning higher
     473          derivatives in terms of `\operatorname{Bi}(x)` and
     474          `\operatorname{Bi}'(x)`
     475
    446476        EXAMPLES::
    447477
    448             sage: x,n=var('x n')
    449             sage: airy_bi(-2,x)
     478            sage: x, n = var('x n')
     479            sage: airy_bi(-2, x)
    450480            airy_bi(-2, x)
    451             sage: derivative(airy_bi(-2,x),x)
     481            sage: derivative(airy_bi(-2, x), x)
    452482            airy_bi(-1, x)
    453             sage: airy_bi(n,x)
     483            sage: airy_bi(n, x)
    454484            airy_bi(n, x)
    455             sage: derivative(airy_bi(n,x),x)
     485            sage: derivative(airy_bi(n, x), x)
    456486            airy_bi(n + 1, x)
    457             sage: airy_bi(2,x,True)
     487            sage: airy_bi(2, x, hold_derivative=True)
    458488            airy_bi(2, x)
    459             sage: derivative(airy_bi(2,x,hold_derivative=True),x)
     489            sage: derivative(airy_bi(2, x, hold_derivative=True), x)
    460490            airy_bi(3, x)
    461491        """
    462 
    463492        BuiltinFunction.__init__(self, "airy_bi", nargs=2,
    464             latex_name=r"\operatorname{Bi}")
     493                                 latex_name=r"\operatorname{Bi}")
    465494
    466495    def _derivative_(self, alpha, *args, **kwds):
    467496        """
    468497        EXAMPLES::
    469498
    470             sage: x,n=var('x n')
    471             sage: derivative(airy_bi(n,x),x) # indirect doctest
     499            sage: x, n = var('x n')
     500            sage: derivative(airy_bi(n, x), x) # indirect doctest
    472501            airy_bi(n + 1, x)
    473502        """
    474 
    475         x=args[0]
    476         return airy_bi_general(alpha+1,x)
     503        x = args[0]
     504        return airy_bi_general(alpha + 1, x)
    477505
    478506    def _eval_(self, alpha, *args):
    479507        """
    480508        EXAMPLES::
    481509
    482             sage: x,n=var('x n')
    483             sage: airy_bi(-2,1.0) # indirect doctest
     510            sage: x, n = var('x n')
     511            sage: airy_bi(-2, 1.0) # indirect doctest
    484512            0.388621540699059
    485             sage: airy_bi(n,1.0) # indirect doctest
     513            sage: airy_bi(n, 1.0) # indirect doctest
    486514            airy_bi(n, 1.00000000000000)
    487515        """
    488 
    489        
    490         x=args[0]
    491         if not isinstance(x,Expression) and not isinstance(alpha,Expression):
     516        x = args[0]
     517        if not isinstance(x, Expression) and not isinstance(alpha, Expression):
    492518            if is_inexact(x):
    493                 return self._evalf_(alpha,x)
     519                return self._evalf_(alpha, x)
    494520        else:
    495521            return None
    496522
     
    498524        """
    499525        EXAMPLES::
    500526
    501             sage: airy_bi(-2,1.0) # indirect doctest
     527            sage: airy_bi(-2, 1.0) # indirect doctest
    502528            0.388621540699059
    503529
    504530        """
    505531        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
     532        parent = sage_structure_coerce_parent(x)
    508533        if algorithm == 'mpmath':
    509534            import mpmath
    510535            from sage.libs.mpmath import utils as mpmath_utils
    511             return mpmath_utils.call(mpmath.airybi, x, derivative=alpha, parent=parent)
     536            return mpmath_utils.call(mpmath.airybi, x, derivative=alpha,
     537                                     parent=parent)
    512538        elif algorithm == 'maxima':
    513             raise NotImplementedError("general case not available in maxima")
     539            raise NotImplementedError("general case not available in Maxima")
    514540        else:
    515541            raise ValueError("unknown algorithm")
    516542
     543
    517544class FunctionAiryBiSimple(BuiltinFunction):
    518545    def __init__(self):
    519546        """
    520         The class for the Airy Bi function.
     547        The class for the Airy Bi function
    521548
    522549        EXAMPLES::
    523550
    524551            sage: from sage.functions.airy import FunctionAiryBiSimple
    525552            sage: airy_bi_simple= FunctionAiryBiSimple()
    526             sage: f=airy_bi_simple(x); f
     553            sage: f = airy_bi_simple(x); f
    527554            airy_bi(x)
    528555        """
    529 
    530         BuiltinFunction.__init__(self, "airy_bi", latex_name=r'\operatorname{Bi}',
    531                 conversions=dict(mathematica='AiryBi', maxima='airy_bi'))
     556        BuiltinFunction.__init__(self, "airy_bi",
     557                                 latex_name=r'\operatorname{Bi}',
     558                                 conversions=dict(mathematica='AiryBi',
     559                                                  maxima='airy_bi'))
    532560
    533561    def _derivative_(self, x, diff_param=None):
    534562        """
    535563        EXAMPLES::
    536        
    537             sage: derivative(airy_bi(x),x) # indirect doctest
     564
     565            sage: derivative(airy_bi(x), x) # indirect doctest
    538566            airy_bi_prime(x)
    539567        """
    540568        return airy_bi_prime(x)
     
    542570    def _eval_(self, x):
    543571        """
    544572        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
     573
     574            sage: airy_bi(0)  # indirect doctest
     575            1/3*3^(5/6)/gamma(2/3)
     576            sage: airy_bi(0.0)  # indirect doctest
    549577            0.614926627446001
    550             sage: airy_bi(I) # indirect doctest
     578            sage: airy_bi(0).n() == airy_bi(0.0)  # indirect doctest
     579            True
     580            sage: airy_bi(I)  # indirect doctest
    551581            airy_bi(I)
    552             sage: airy_bi(1.0*I) # indirect doctest
     582            sage: airy_bi(1.0 * I) # indirect doctest
    553583            0.648858208330395 + 0.344958634768048*I
    554584        """
    555 
    556         if not isinstance(x,Expression):
     585        if not isinstance(x, Expression):
    557586            if is_inexact(x):
    558587                return self._evalf_(x)
    559             elif x==0:
    560                 one_sixth = ZZ(1)/6
    561                 return 1/(3**(one_sixth)*gamma(2*one_sixth))
     588            elif x == 0:
     589                one_sixth = ZZ(1) / 6
     590                return 1 / (3 ** (one_sixth) * gamma(4 * one_sixth))
    562591        else:
    563592            return None
    564593
    565594    def _evalf_(self, x, **kwargs):
    566595        """
    567596        EXAMPLES::
    568        
    569             sage: airy_bi(0.0) # indirect doctest
     597
     598            sage: airy_bi(0.0)  # indirect doctest
    570599            0.614926627446001
    571             sage: airy_bi(1.0*I) # indirect doctest
     600            sage: airy_bi(1.0 * I) # indirect doctest
    572601            0.648858208330395 + 0.344958634768048*I
    573602
    574603        We can use several methods for numerical evaluation::
     
    585614            sage: airy_bi(3).n(algorithm='maxima', prec=100)
    586615            Traceback (most recent call last):
    587616            ...
    588             ValueError: for the maxima algorithm the precision must be 53
     617            ValueError: for the Maxima algorithm the precision must be 53
    589618
    590619        """
    591620        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    592         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
    593         prec = parent.prec() if hasattr(parent, 'prec') else 53
     621        parent = sage_structure_coerce_parent(x)
    594622        if algorithm == 'mpmath':
    595623            import mpmath
    596624            from sage.libs.mpmath import utils as mpmath_utils
    597625            return mpmath_utils.call(mpmath.airybi, x, parent=parent)
    598626        elif algorithm == 'maxima':
    599627            if prec != 53:
    600                 raise ValueError, "for the maxima algorithm the precision must be 53"
    601             return RDF(meval("airy_bi(%s)" % RDF(x)))
     628                raise ValueError("for the Maxima algorithm the precision must "
     629                                 "be 53")
     630            return RDF(meval("airy_bi({})".format(RDF(x))))
    602631        else:
    603632            raise ValueError("unknown algorithm")
    604633
     634
    605635class FunctionAiryBiPrime(BuiltinFunction):
    606636    def __init__(self):
    607637        """
     
    610640
    611641        EXAMPLES::
    612642
    613             sage: x,n=var('x n')
    614             sage: airy_bi_prime(x) # indirect doctest
     643            sage: x, n = var('x n')
     644            sage: airy_bi_prime(x)  # indirect doctest
    615645            airy_bi_prime(x)
    616             sage: airy_bi_prime(0) # indirect doctest
     646            sage: airy_bi_prime(0)  # indirect doctest
    617647            3^(1/6)/gamma(1/3)
    618648        """
    619 
    620649        BuiltinFunction.__init__(self, "airy_bi_prime",
    621                 latex_name=r"\operatorname{Bi}'",
    622                 conversions=dict(mathematica='AiryBiPrime', maxima='airy_dbi'))
     650                                 latex_name=r"\operatorname{Bi}'",
     651                                 conversions=dict(mathematica='AiryBiPrime',
     652                                                  maxima='airy_dbi'))
    623653
    624654    def _derivative_(self, x, diff_param=None):
    625655        """
    626656        EXAMPLES::
    627657
    628             sage: derivative(airy_bi_prime(x),x) # indirect doctest
     658            sage: derivative(airy_bi_prime(x), x) # indirect doctest
    629659            x*airy_bi(x)
    630660        """
    631         return x*airy_bi_simple(x)
     661        return x * airy_bi_simple(x)
    632662
    633663    def _eval_(self, x):
    634664        """
    635665        EXAMPLES::
    636666
    637             sage: airy_bi(1,0) # indirect doctest
     667            sage: airy_bi(1, 0) # indirect doctest
    638668            3^(1/6)/gamma(1/3)
    639             sage: airy_bi(1,0.0) # indirect doctest
     669            sage: airy_bi(1, 0.0) # indirect doctest
    640670            0.448288357353826
    641671        """
    642         if not isinstance(x,Expression):
     672        if not isinstance(x, Expression):
    643673            if is_inexact(x):
    644674                return self._evalf_(x)
    645             elif x==0:
    646                 one_sixth = ZZ(1)/6
    647                 return 3**(one_sixth)/gamma(2*one_sixth)
     675            elif x == 0:
     676                one_sixth = ZZ(1) / 6
     677                return 3 ** (one_sixth) / gamma(2 * one_sixth)
    648678        else:
    649679            return None
    650680
    651681    def _evalf_(self, x, **kwargs):
    652682        """
    653683        EXAMPLES::
    654        
    655             sage: airy_bi(1,0.0) # indirect doctest
     684
     685            sage: airy_bi(1, 0.0) # indirect doctest
    656686            0.448288357353826
    657687
    658688        We can use several methods for numerical evaluation::
    659689
    660             sage: airy_bi(1,4).n(algorithm='maxima')
     690            sage: airy_bi(1, 4).n(algorithm='maxima')
    661691            161.926683505
    662             sage: airy_bi(1,4).n(algorithm='mpmath')
     692            sage: airy_bi(1, 4).n(algorithm='mpmath')
    663693            161.926683504613
    664             sage: airy_bi(1,4).n(algorithm='mpmath', prec=100)
     694            sage: airy_bi(1, 4).n(algorithm='mpmath', prec=100)
    665695            161.92668350461340184309492429
    666696
    667697        TESTS::
    668698
    669             sage: airy_bi(1,4).n(algorithm='maxima', prec=70)
     699            sage: airy_bi(1, 4).n(algorithm='maxima', prec=70)
    670700            Traceback (most recent call last):
    671701            ...
    672             ValueError: for the maxima algorithm the precision must be 53
    673 
     702            ValueError: for the Maxima algorithm the precision must be 53
    674703        """
    675704        algorithm = kwargs.get('algorithm', None) or 'mpmath'
    676         parent = kwargs.get('parent', None) or sage_structure_coerce_parent(x)
    677         prec = parent.prec() if hasattr(parent, 'prec') else 53
     705        parent = sage_structure_coerce_parent(x)
    678706        if algorithm == 'mpmath':
    679707            import mpmath
    680708            from sage.libs.mpmath import utils as mpmath_utils
    681             return mpmath_utils.call(mpmath.airybi, x, derivative=1, parent=parent)
     709            return mpmath_utils.call(mpmath.airybi, x, derivative=1,
     710                                     parent=parent)
    682711        elif algorithm == 'maxima':
    683712            if prec != 53:
    684                 raise ValueError, "for the maxima algorithm the precision must be 53"
    685             return RDF(meval("airy_dbi(%s)" % RDF(x)))
     713                raise ValueError("for the Maxima algorithm the precision must "
     714                                 "be 53")
     715            return RDF(meval("airy_dbi({})".format(RDF(x))))
    686716        else:
    687717            raise ValueError("unknown algorithm")
    688718
    689 airy_bi_general=FunctionAiryBiGeneral()
    690 airy_bi_simple= FunctionAiryBiSimple()
    691 airy_bi_prime= FunctionAiryBiPrime()
     719airy_bi_general = FunctionAiryBiGeneral()
     720airy_bi_simple = FunctionAiryBiSimple()
     721airy_bi_prime = FunctionAiryBiPrime()
    692722
    693 def airy_bi(alpha,x=None, hold_derivative=False, *args, **kwds):
     723
     724def airy_bi(alpha, x=None, hold_derivative=False, *args, **kwds):
    694725    r"""
    695726    The Airy Bi function `\operatorname{Bi}(x)` is one of the two
    696     linearly independent solutions to the Airy differental equation
     727    linearly independent solutions to the Airy differential equation
    697728    `f''(z) +f(z)x=0`, defined by the initial conditions:
    698729
    699730    .. math ::
    700         \operatorname{Bi}(0)=\frac{1}{3^{1/6} \Gamma(\frac{2}{3})},
     731        \operatorname{Bi}(0)=\frac{1}{3^{1/6} \Gamma\left(\frac{2}{3}\right)},
    701732
    702         \operatorname{Bi}'(0)=\frac{3^{1/6}}{ \Gamma(\frac{1}{3})}.
     733        \operatorname{Bi}'(0)=\frac{3^{1/6}}{ \Gamma\left(\frac{1}{3}\right)}.
    703734
    704735    Another way to define the Airy Bi function is:
    705736
     
    709740        +\sin\left(xt + \frac{1}{3}t^3\right) \right ] dt.
    710741
    711742    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      
     743
     744    - ``alpha`` -- Return the `\alpha`-th order fractional derivative with
     745      respect to `z`.
     746      For `\alpha = n = 1,2,3,\ldots` this gives the derivative
     747      `\operatorname{Bi}^{(n)}(z)`, and for `\alpha = -n = -1,-2,-3,\ldots`
     748      this gives the `n`-fold iterated integral.
     749
    717750    .. math ::
    718      
     751
    719752        f_0(z) = \operatorname{Bi}(z)
    720      
    721         f_n(z) = \int_0^z f_{n-1}(t) dt.
    722753
    723     - ``x``.- The argument of the function.
     754        f_n(z) = \int_0^z f_{n-1}(t) dt
    724755
    725     - ``hold_derivative``.- Whether or not to stop from returning higher derivatives in
    726       terms of `\operatorname{Bi}(x)` and `\operatorname{Bi}'(x)`.
    727    
     756    - ``x`` -- The argument of the function
     757
     758    - ``hold_derivative`` -- Whether or not to stop from returning higher
     759      derivatives in terms of `\operatorname{Bi}(x)` and
     760      `\operatorname{Bi}'(x)`
    728761
    729762    EXAMPLES::
    730763
    731         sage: n,x=var('n x')
     764        sage: n, x = var('n x')
    732765        sage: airy_bi(x)
    733766        airy_bi(x)
    734767
    735768    It can return derivatives or integrals::
    736    
    737         sage: airy_bi(1,x)
     769
     770        sage: airy_bi(1, x)
    738771        airy_bi_prime(x)
    739         sage: airy_bi(2,x)
     772        sage: airy_bi(2, x)
    740773        x*airy_bi(x)
    741         sage: airy_bi(2,x,True)
     774        sage: airy_bi(2, x, hold_derivative=True)
    742775        airy_bi(2, x)
    743         sage: airy_bi(-2,x)
     776        sage: airy_bi(-2, x)
    744777        airy_bi(-2, x)
    745778        sage: airy_bi(n, x)
    746779        airy_bi(n, x)
    747780
    748     It can be evaluated symbolically or numerically for real or complex values::
     781    It can be evaluated symbolically or numerically for real or complex
     782    values::
    749783
    750784        sage: airy_bi(0)
    751         1/3*3^(5/6)/gamma(1/3)
     785        1/3*3^(5/6)/gamma(2/3)
    752786        sage: airy_bi(0.0)
    753787        0.614926627446001
    754788        sage: airy_bi(I)
     
    756790        sage: airy_bi(1.0*I)
    757791        0.648858208330395 + 0.344958634768048*I
    758792
    759     The functions can be evaluated numerically using either mpmath (the default)
    760     or maxima, where mpmath can compute the values to arbitrary precision::
     793    The functions can be evaluated numerically using either mpmath (the
     794    default) or Maxima, where mpmath can compute the values to arbitrary
     795    precision::
    761796
    762797        sage: airy_bi(2).n(prec=100)
    763798        3.2980949999782147102806044252
    764         sage: airy_bi(2).n(algorithm='mpmath',prec=100)
     799        sage: airy_bi(2).n(algorithm='mpmath', prec=100)
    765800        3.2980949999782147102806044252
    766801        sage: airy_bi(2).n(algorithm='maxima')
    767802        3.29809499998
    768803
    769804    And the derivatives can be evaluated::
    770805
    771         sage: airy_bi(1,0)
     806        sage: airy_bi(1, 0)
    772807        3^(1/6)/gamma(1/3)
    773         sage: airy_bi(1,0.0)
     808        sage: airy_bi(1, 0.0)
    774809        0.448288357353826
    775810
    776811    Plots::
    777812
    778         sage: plot(airy_bi(x),(x,-10,5))+plot(airy_bi_prime(x),(x,-10,5),color='red')
    779        
     813        sage: (plot(airy_bi(x), (x, -10, 5)) +\
     814               plot(airy_bi_prime(x), (x, -10, 5), color='red'))
     815
    780816    **References**
    781      
     817
    782818    - Abramowitz, Milton; Stegun, Irene A., eds. (1965), "Chapter 10"
    783819
    784820    - http://en.wikipedia.org/wiki/Airy_function
    785821    """
     822    # We catch the case with no alpha
     823    if x is None:
     824        x = alpha
     825        return airy_bi_simple(x, **kwds)
    786826
    787     #We catch the case with no alpha
    788     if x==None:
    789         x=alpha
     827    # We raise an error if there are too many arguments
     828    if len(args) > 0:
     829        raise TypeError(("symbolic function airy_ai takes at most 3 arguments "
     830                         "({} given)").format(len(args) + 3))
     831
     832    # We take care of all other cases.
     833    if hold_derivative:
     834        return airy_bi_general(alpha, x, **kwds)
     835    elif alpha == 0:
    790836        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:
     837    elif alpha == 1:
    802838        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)
     839    elif alpha > 1:
     840        # We use a different variable here because if x is a
     841        # particular value, we would be differentiating a constant
     842        # which would return 0. What we want is the value of
     843        # the derivative at the value and not the derivative of
     844        # a particular value of the function.
     845        v = var('v')
     846        return derivative(airy_bi_simple(v, **kwds), v, alpha).subs(v=x)
    811847    else:
    812         return airy_bi_general(alpha,x,**kwds)
    813 
     848        return airy_bi_general(alpha, x, **kwds)