# 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


11  11  sage/functions/orthogonal_polys 
12  12  sage/functions/other 
13  13  sage/functions/special 
 14  sage/functions/airy 
14  15  sage/functions/exp_integral 
15  16  sage/functions/wigner 
16  17  sage/functions/generalized 
diff git a/sage/functions/airy.py b/sage/functions/airy.py
a

b


 1  r""" 
 2  Airy Functions 
 3  
 4  This module implements Airy functions and their generalized derivatives. It 
 5  supports symbolic functionality through Maxima and numeric evaluation through 
 6  mpmath and Maxima. 
 7  
 8  Airy functions are solutions to the differential equation `f''(z) +f(z)x=0`. 
 9  
 10  AUTHORS: 
 11  
 12   Oscar Gerardo Lazo Arjona (2010): initial version 
 13  
 14   Douglas McNeil (2012): rewrite 
 15  
 16  EXAMPLES: 
 17  
 18  Verify 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  
1  26  #***************************************************************************** 
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> 
3  29  # 
4  30  # 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. 
12  33  # http://www.gnu.org/licenses/ 
13  34  #***************************************************************************** 
14  35  
… 
… 

16  37  from sage.symbolic.expression import Expression 
17  38  from sage.symbolic.function import is_inexact 
18  39  from sage.structure.coerce import parent as sage_structure_coerce_parent 
19   
20  40  from sage.functions.other import gamma 
21  41  from sage.rings.integer_ring import ZZ 
22  42  from sage.rings.real_double import RDF 
 43  from sage.rings.rational import Rational as R 
23  44  from sage.functions.special import meval 
24  45  from sage.calculus.var import var 
25  46  from sage.calculus.functional import derivative 
26  47  
27   # from sage.rings.real_mpfr import RR 
28   from sage.rings.rational import Rational as R 
29  48  
30  49  class FunctionAiryAiGeneral(BuiltinFunction): 
31  50  def __init__(self): 
… 
… 

33  52  The generalized derivative of the Airy Ai function 
34  53  
35  54  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  
41  62  .. math :: 
42   
 63  
43  64  f_0(z) = \operatorname{Ai}(z) 
44   
45   f_n(z) = \int_0^z f_{n1}(t) dt. 
46  65  
47    ``x``. The argument of the function. 
 66  f_n(z) = \int_0^z f_{n1}(t) dt 
48  67  
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  
52  74  EXAMPLES:: 
53  75  
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) 
56  78  airy_ai(2, x) 
57   sage: derivative(airy_ai(2,x),x) 
 79  sage: derivative(airy_ai(2, x), x) 
58  80  airy_ai(1, x) 
59   sage: airy_ai(n,x) 
 81  sage: airy_ai(n, x) 
60  82  airy_ai(n, x) 
61   sage: derivative(airy_ai(n,x),x) 
 83  sage: derivative(airy_ai(n, x), x) 
62  84  airy_ai(n + 1, x) 
63   sage: airy_ai(2,x,True) 
 85  sage: airy_ai(2, x, hold_derivative=True) 
64  86  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) 
66  88  airy_ai(3, x) 
67  89  """ 
68   
69  90  BuiltinFunction.__init__(self, "airy_ai", nargs=2, 
70   latex_name=r"\operatorname{Ai}") 
 91  latex_name=r"\operatorname{Ai}") 
71  92  
72  93  def _derivative_(self, alpha, *args, **kwds): 
73  94  """ 
74  95  EXAMPLES:: 
75  96  
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 
78  99  airy_ai(n + 1, x) 
79  100  """ 
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) 
83  103  
84  104  def _eval_(self, alpha, *args): 
85  105  """ 
86  106  EXAMPLES:: 
87  107  
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 
90  110  0.136645379421096 
91   sage: airy_ai(n,1.0) # indirect doctest 
 111  sage: airy_ai(n, 1.0) # indirect doctest 
92  112  airy_ai(n, 1.00000000000000) 
93  113  """ 
 114  x = args[0] 
94  115  
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): 
97  117  if is_inexact(x): 
98   return self._evalf_(alpha,x) 
 118  return self._evalf_(alpha, x) 
99  119  else: 
100  120  return None 
101  121  
… 
… 

103  123  """ 
104  124  EXAMPLES:: 
105  125  
106   sage: airy_ai(2,1.0) # indirect doctest 
107   0.136645379421096 
 126  sage: airy_ai(2, 1.0) # indirect doctest 
 127  0.136645379421096 
108  128  """ 
109  129  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) 
112  131  if algorithm == 'mpmath': 
113  132  import mpmath 
114  133  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) 
116  136  elif algorithm == 'maxima': 
117   raise NotImplementedError("general case not available in maxima") 
 137  raise NotImplementedError("general case not available in Maxima") 
118  138  else: 
119  139  raise ValueError("unknown algorithm") 
120  140  
 141  
121  142  class FunctionAiryAiSimple(BuiltinFunction): 
122  143  def __init__(self): 
123  144  """ 
124   The class for the Airy Ai function. 
 145  The class for the Airy Ai function 
125  146  
126  147  EXAMPLES:: 
127  148  
128  149  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 
131  152  airy_ai(x) 
132  153  """ 
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')) 
136  158  
137  159  def _derivative_(self, x, diff_param=None): 
138  160  """ 
139  161  EXAMPLES:: 
140   
141   sage: derivative(airy_ai(x),x) # indirect doctest 
 162  
 163  sage: derivative(airy_ai(x), x) # indirect doctest 
142  164  airy_ai_prime(x) 
143  165  """ 
144  166  return airy_ai_prime(x) 
… 
… 

146  168  def _eval_(self, x): 
147  169  """ 
148  170  EXAMPLES:: 
149   
150   sage: airy_ai(0) # indirect doctest 
 171  
 172  sage: airy_ai(0) # indirect doctest 
151  173  1/3*3^(1/3)/gamma(2/3) 
152   sage: airy_ai(0.0) # indirect doctest 
 174  sage: airy_ai(0.0) # indirect doctest 
153  175  0.355028053887817 
154   sage: airy_ai(I) # indirect doctest 
 176  sage: airy_ai(I) # indirect doctest 
155  177  airy_ai(I) 
156   sage: airy_ai(1.0*I) # indirect doctest 
 178  sage: airy_ai(1.0 * I) # indirect doctest 
157  179  0.331493305432141  0.317449858968444*I 
158  180  """ 
159   
160   if not isinstance(x,Expression): 
 181  if not isinstance(x, Expression): 
161  182  if is_inexact(x): 
162  183  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)) 
166  187  else: 
167  188  return None 
168  189  
169  190  def _evalf_(self, x, **kwargs): 
170  191  """ 
171  192  EXAMPLES:: 
172   
173   sage: airy_ai(0.0) # indirect doctest 
 193  
 194  sage: airy_ai(0.0) # indirect doctest 
174  195  0.355028053887817 
175   sage: airy_ai(1.0*I) # indirect doctest 
 196  sage: airy_ai(1.0 * I) # indirect doctest 
176  197  0.331493305432141  0.317449858968444*I 
177  198  
178  199  We can use several methods for numerical evaluation:: 
… 
… 

181  202  0.00659113935746 
182  203  sage: airy_ai(3).n(algorithm='mpmath') 
183  204  0.00659113935746072 
184   sage: airy_ai(3).n(algorithm='mpmath',prec=100) 
 205  sage: airy_ai(3).n(algorithm='mpmath', prec=100) 
185  206  0.0065911393574607191442574484080 
186   
 207  
187  208  TESTS:: 
188  209  
189  210  sage: airy_ai(3).n(algorithm='maxima', prec=70) 
190  211  Traceback (most recent call last): 
191  212  ... 
192   ValueError: for the maxima algorithm the precision must be 53 
193   
 213  ValueError: for the Maxima algorithm the precision must be 53 
 214  
194  215  """ 
195  216  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) 
198  218  if algorithm == 'mpmath': 
199  219  import mpmath 
200  220  from sage.libs.mpmath import utils as mpmath_utils 
201  221  return mpmath_utils.call(mpmath.airyai, x, parent=parent) 
202  222  elif algorithm == 'maxima': 
203  223  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)))) 
206  227  else: 
207  228  raise ValueError("unknown algorithm") 
208  229  
 230  
209  231  class FunctionAiryAiPrime(BuiltinFunction): 
210  232  def __init__(self): 
211  233  """ 
… 
… 

214  236  
215  237  EXAMPLES:: 
216  238  
217   sage: x,n=var('x n') 
 239  sage: x, n = var('x n') 
218  240  sage: airy_ai_prime(x) 
219  241  airy_ai_prime(x) 
220  242  sage: airy_ai_prime(0) 
221  243  1/3*3^(2/3)/gamma(1/3) 
222  244  """ 
223   
224  245  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')) 
227  249  
228  250  def _derivative_(self, x, diff_param=None): 
229  251  """ 
230  252  EXAMPLES:: 
231  253  
232   sage: derivative(airy_ai_prime(x),x) # indirect doctest 
 254  sage: derivative(airy_ai_prime(x), x) # indirect doctest 
233  255  x*airy_ai(x) 
234  256  """ 
235   return x*airy_ai_simple(x) 
 257  return x * airy_ai_simple(x) 
236  258  
237  259  def _eval_(self, x): 
238  260  """ 
239  261  EXAMPLES:: 
240  262  
241   sage: airy_ai(1,0) # indirect doctest 
 263  sage: airy_ai(1, 0) # indirect doctest 
242  264  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 
244  266  0.258819403792807 
245  267  """ 
246   if not isinstance(x,Expression): 
 268  if not isinstance(x, Expression): 
247  269  if is_inexact(x): 
248  270  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)) 
252  274  else: 
253  275  return None 
254  276  
255  277  def _evalf_(self, x, **kwargs): 
256  278  """ 
257  279  EXAMPLES:: 
258   
259   sage: airy_ai(1,0.0) # indirect doctest 
 280  
 281  sage: airy_ai(1, 0.0) # indirect doctest 
260  282  0.258819403792807 
261  283  
262  284  We can use several methods for numerical evaluation:: 
263  285  
264   sage: airy_ai(1,4).n(algorithm='maxima') 
 286  sage: airy_ai(1, 4).n(algorithm='maxima') 
265  287  0.0019586409502 
266   sage: airy_ai(1,4).n(algorithm='mpmath') 
 288  sage: airy_ai(1, 4).n(algorithm='mpmath') 
267  289  0.00195864095020418 
268   sage: airy_ai(1,4).n(algorithm='mpmath', prec=100) 
 290  sage: airy_ai(1, 4).n(algorithm='mpmath', prec=100) 
269  291  0.0019586409502041789001381409184 
270  292  
271  293  TESTS:: 
… 
… 

273  295  sage: airy_ai(1, 4).n(algorithm='maxima', prec=70) 
274  296  Traceback (most recent call last): 
275  297  ... 
276   ValueError: for the maxima algorithm the precision must be 53 
277   
278   
 298  ValueError: for the Maxima algorithm the precision must be 53 
279  299  """ 
280  300  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) 
283  302  if algorithm == 'mpmath': 
284  303  import mpmath 
285  304  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) 
287  307  elif algorithm == 'maxima': 
288  308  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)))) 
291  312  else: 
292  313  raise ValueError("unknown algorithm") 
293  314  
 315  airy_ai_general = FunctionAiryAiGeneral() 
 316  airy_ai_simple = FunctionAiryAiSimple() 
 317  airy_ai_prime = FunctionAiryAiPrime() 
294  318  
295   airy_ai_general=FunctionAiryAiGeneral() 
296   airy_ai_simple= FunctionAiryAiSimple() 
297   airy_ai_prime= FunctionAiryAiPrime() 
298  319  
299   
300   def airy_ai(alpha,x=None, hold_derivative=False, *args, **kwds): 
301   r""" 
 320  def airy_ai(alpha, x=None, hold_derivative=False, *args, **kwds): 
 321  r""" 
302  322  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 
304  324  `f''(z) +f(z)x=0`, defined by the initial conditions: 
305  325  
306  326  .. 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)}, 
308  328  
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)}. 
310  330  
311  331  Another way to define the Airy Ai function is: 
312  332  
… 
… 

315  335  \cos\left(\frac{1}{3}t^3+xt\right) dt. 
316  336  
317  337  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  
323  345  .. math :: 
324   
 346  
325  347  f_0(z) = \operatorname{Ai}(z) 
326   
327   f_n(z) = \int_0^z f_{n1}(t) dt. 
328  348  
329    ``x``. The argument of the function. 
 349  f_n(z) = \int_0^z f_{n1}(t) dt 
330  350  
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)` 
334  356  
335  357  EXAMPLES:: 
336  358  
337   sage: n,x=var('n x') 
 359  sage: n, x = var('n x') 
338  360  sage: airy_ai(x) 
339  361  airy_ai(x) 
340  362  
341  363  It can return derivatives or integrals:: 
342   
343   sage: airy_ai(1,x) 
 364  
 365  sage: airy_ai(1, x) 
344  366  airy_ai_prime(x) 
345   sage: airy_ai(2,x) 
 367  sage: airy_ai(2, x) 
346  368  x*airy_ai(x) 
347   sage: airy_ai(2,x,True) 
 369  sage: airy_ai(2, x, hold_derivative=True) 
348  370  airy_ai(2, x) 
349   sage: airy_ai(2,x) 
 371  sage: airy_ai(2, x) 
350  372  airy_ai(2, x) 
351  373  sage: airy_ai(n, x) 
352  374  airy_ai(n, x) 
353  375  
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:: 
355  378  
356  379  sage: airy_ai(0) 
357  380  1/3*3^(1/3)/gamma(2/3) 
… 
… 

362  385  sage: airy_ai(1.0*I) 
363  386  0.331493305432141  0.317449858968444*I 
364  387  
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:: 
367  391  
368  392  sage: airy_ai(2).n(prec=100) 
369  393  0.034924130423274379135322080792 
370   sage: airy_ai(2).n(algorithm='mpmath',prec=100) 
 394  sage: airy_ai(2).n(algorithm='mpmath', prec=100) 
371  395  0.034924130423274379135322080792 
372  396  sage: airy_ai(2).n(algorithm='maxima') 
373  397  0.0349241304233 
374  398  
375  399  And the derivatives can be evaluated:: 
376  400  
377   sage: airy_ai(1,0) 
 401  sage: airy_ai(1, 0) 
378  402  1/3*3^(2/3)/gamma(1/3) 
379   sage: airy_ai(1,0.0) 
 403  sage: airy_ai(1, 0.0) 
380  404  0.258819403792807 
381  405  
382  406  Plots:: 
383  407  
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  
386  411  **References** 
387   
 412  
388  413   Abramowitz, Milton; Stegun, Irene A., eds. (1965), "Chapter 10" 
389  414  
390  415   http://en.wikipedia.org/wiki/Airy_function 
391  416  """ 
 417  # We catch the case with no alpha 
 418  if x is None: 
 419  x = alpha 
 420  return airy_ai_simple(x, **kwds) 
392  421  
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: 
396  433  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: 
408  435  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) 
417  444  else: 
418   return airy_ai_general(alpha,x,**kwds) 
 445  return airy_ai_general(alpha, x, **kwds) 
419  446  
420  447  ######################################################################## 
421  448  ######################################################################## 
422  449  
 450  
423  451  class FunctionAiryBiGeneral(BuiltinFunction): 
424  452  def __init__(self): 
425  453  r""" 
426  454  The generalized derivative of the Airy Bi function 
427  455  
428  456  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  
435  464  .. math :: 
436   
 465  
437  466  f_0(z) = \operatorname{Bi}(z) 
438   
439   f_n(z) = \int_0^z f_{n1}(t) dt. 
440  467  
441    ``x``. The argument of the function. 
 468  f_n(z) = \int_0^z f_{n1}(t) dt 
442  469  
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  
446  476  EXAMPLES:: 
447  477  
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) 
450  480  airy_bi(2, x) 
451   sage: derivative(airy_bi(2,x),x) 
 481  sage: derivative(airy_bi(2, x), x) 
452  482  airy_bi(1, x) 
453   sage: airy_bi(n,x) 
 483  sage: airy_bi(n, x) 
454  484  airy_bi(n, x) 
455   sage: derivative(airy_bi(n,x),x) 
 485  sage: derivative(airy_bi(n, x), x) 
456  486  airy_bi(n + 1, x) 
457   sage: airy_bi(2,x,True) 
 487  sage: airy_bi(2, x, hold_derivative=True) 
458  488  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) 
460  490  airy_bi(3, x) 
461  491  """ 
462   
463  492  BuiltinFunction.__init__(self, "airy_bi", nargs=2, 
464   latex_name=r"\operatorname{Bi}") 
 493  latex_name=r"\operatorname{Bi}") 
465  494  
466  495  def _derivative_(self, alpha, *args, **kwds): 
467  496  """ 
468  497  EXAMPLES:: 
469  498  
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 
472  501  airy_bi(n + 1, x) 
473  502  """ 
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) 
477  505  
478  506  def _eval_(self, alpha, *args): 
479  507  """ 
480  508  EXAMPLES:: 
481  509  
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 
484  512  0.388621540699059 
485   sage: airy_bi(n,1.0) # indirect doctest 
 513  sage: airy_bi(n, 1.0) # indirect doctest 
486  514  airy_bi(n, 1.00000000000000) 
487  515  """ 
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): 
492  518  if is_inexact(x): 
493   return self._evalf_(alpha,x) 
 519  return self._evalf_(alpha, x) 
494  520  else: 
495  521  return None 
496  522  
… 
… 

498  524  """ 
499  525  EXAMPLES:: 
500  526  
501   sage: airy_bi(2,1.0) # indirect doctest 
 527  sage: airy_bi(2, 1.0) # indirect doctest 
502  528  0.388621540699059 
503  529  
504  530  """ 
505  531  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) 
508  533  if algorithm == 'mpmath': 
509  534  import mpmath 
510  535  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) 
512  538  elif algorithm == 'maxima': 
513   raise NotImplementedError("general case not available in maxima") 
 539  raise NotImplementedError("general case not available in Maxima") 
514  540  else: 
515  541  raise ValueError("unknown algorithm") 
516  542  
 543  
517  544  class FunctionAiryBiSimple(BuiltinFunction): 
518  545  def __init__(self): 
519  546  """ 
520   The class for the Airy Bi function. 
 547  The class for the Airy Bi function 
521  548  
522  549  EXAMPLES:: 
523  550  
524  551  sage: from sage.functions.airy import FunctionAiryBiSimple 
525  552  sage: airy_bi_simple= FunctionAiryBiSimple() 
526   sage: f=airy_bi_simple(x); f 
 553  sage: f = airy_bi_simple(x); f 
527  554  airy_bi(x) 
528  555  """ 
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')) 
532  560  
533  561  def _derivative_(self, x, diff_param=None): 
534  562  """ 
535  563  EXAMPLES:: 
536   
537   sage: derivative(airy_bi(x),x) # indirect doctest 
 564  
 565  sage: derivative(airy_bi(x), x) # indirect doctest 
538  566  airy_bi_prime(x) 
539  567  """ 
540  568  return airy_bi_prime(x) 
… 
… 

542  570  def _eval_(self, x): 
543  571  """ 
544  572  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 
549  577  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 
551  581  airy_bi(I) 
552   sage: airy_bi(1.0*I) # indirect doctest 
 582  sage: airy_bi(1.0 * I) # indirect doctest 
553  583  0.648858208330395 + 0.344958634768048*I 
554  584  """ 
555   
556   if not isinstance(x,Expression): 
 585  if not isinstance(x, Expression): 
557  586  if is_inexact(x): 
558  587  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)) 
562  591  else: 
563  592  return None 
564  593  
565  594  def _evalf_(self, x, **kwargs): 
566  595  """ 
567  596  EXAMPLES:: 
568   
569   sage: airy_bi(0.0) # indirect doctest 
 597  
 598  sage: airy_bi(0.0) # indirect doctest 
570  599  0.614926627446001 
571   sage: airy_bi(1.0*I) # indirect doctest 
 600  sage: airy_bi(1.0 * I) # indirect doctest 
572  601  0.648858208330395 + 0.344958634768048*I 
573  602  
574  603  We can use several methods for numerical evaluation:: 
… 
… 

585  614  sage: airy_bi(3).n(algorithm='maxima', prec=100) 
586  615  Traceback (most recent call last): 
587  616  ... 
588   ValueError: for the maxima algorithm the precision must be 53 
 617  ValueError: for the Maxima algorithm the precision must be 53 
589  618  
590  619  """ 
591  620  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) 
594  622  if algorithm == 'mpmath': 
595  623  import mpmath 
596  624  from sage.libs.mpmath import utils as mpmath_utils 
597  625  return mpmath_utils.call(mpmath.airybi, x, parent=parent) 
598  626  elif algorithm == 'maxima': 
599  627  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)))) 
602  631  else: 
603  632  raise ValueError("unknown algorithm") 
604  633  
 634  
605  635  class FunctionAiryBiPrime(BuiltinFunction): 
606  636  def __init__(self): 
607  637  """ 
… 
… 

610  640  
611  641  EXAMPLES:: 
612  642  
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 
615  645  airy_bi_prime(x) 
616   sage: airy_bi_prime(0) # indirect doctest 
 646  sage: airy_bi_prime(0) # indirect doctest 
617  647  3^(1/6)/gamma(1/3) 
618  648  """ 
619   
620  649  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')) 
623  653  
624  654  def _derivative_(self, x, diff_param=None): 
625  655  """ 
626  656  EXAMPLES:: 
627  657  
628   sage: derivative(airy_bi_prime(x),x) # indirect doctest 
 658  sage: derivative(airy_bi_prime(x), x) # indirect doctest 
629  659  x*airy_bi(x) 
630  660  """ 
631   return x*airy_bi_simple(x) 
 661  return x * airy_bi_simple(x) 
632  662  
633  663  def _eval_(self, x): 
634  664  """ 
635  665  EXAMPLES:: 
636  666  
637   sage: airy_bi(1,0) # indirect doctest 
 667  sage: airy_bi(1, 0) # indirect doctest 
638  668  3^(1/6)/gamma(1/3) 
639   sage: airy_bi(1,0.0) # indirect doctest 
 669  sage: airy_bi(1, 0.0) # indirect doctest 
640  670  0.448288357353826 
641  671  """ 
642   if not isinstance(x,Expression): 
 672  if not isinstance(x, Expression): 
643  673  if is_inexact(x): 
644  674  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) 
648  678  else: 
649  679  return None 
650  680  
651  681  def _evalf_(self, x, **kwargs): 
652  682  """ 
653  683  EXAMPLES:: 
654   
655   sage: airy_bi(1,0.0) # indirect doctest 
 684  
 685  sage: airy_bi(1, 0.0) # indirect doctest 
656  686  0.448288357353826 
657  687  
658  688  We can use several methods for numerical evaluation:: 
659  689  
660   sage: airy_bi(1,4).n(algorithm='maxima') 
 690  sage: airy_bi(1, 4).n(algorithm='maxima') 
661  691  161.926683505 
662   sage: airy_bi(1,4).n(algorithm='mpmath') 
 692  sage: airy_bi(1, 4).n(algorithm='mpmath') 
663  693  161.926683504613 
664   sage: airy_bi(1,4).n(algorithm='mpmath', prec=100) 
 694  sage: airy_bi(1, 4).n(algorithm='mpmath', prec=100) 
665  695  161.92668350461340184309492429 
666  696  
667  697  TESTS:: 
668  698  
669   sage: airy_bi(1,4).n(algorithm='maxima', prec=70) 
 699  sage: airy_bi(1, 4).n(algorithm='maxima', prec=70) 
670  700  Traceback (most recent call last): 
671  701  ... 
672   ValueError: for the maxima algorithm the precision must be 53 
673   
 702  ValueError: for the Maxima algorithm the precision must be 53 
674  703  """ 
675  704  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) 
678  706  if algorithm == 'mpmath': 
679  707  import mpmath 
680  708  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) 
682  711  elif algorithm == 'maxima': 
683  712  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)))) 
686  716  else: 
687  717  raise ValueError("unknown algorithm") 
688  718  
689   airy_bi_general=FunctionAiryBiGeneral() 
690   airy_bi_simple= FunctionAiryBiSimple() 
691   airy_bi_prime= FunctionAiryBiPrime() 
 719  airy_bi_general = FunctionAiryBiGeneral() 
 720  airy_bi_simple = FunctionAiryBiSimple() 
 721  airy_bi_prime = FunctionAiryBiPrime() 
692  722  
693   def airy_bi(alpha,x=None, hold_derivative=False, *args, **kwds): 
 723  
 724  def airy_bi(alpha, x=None, hold_derivative=False, *args, **kwds): 
694  725  r""" 
695  726  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 
697  728  `f''(z) +f(z)x=0`, defined by the initial conditions: 
698  729  
699  730  .. 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)}, 
701  732  
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)}. 
703  734  
704  735  Another way to define the Airy Bi function is: 
705  736  
… 
… 

709  740  +\sin\left(xt + \frac{1}{3}t^3\right) \right ] dt. 
710  741  
711  742  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  
717  750  .. math :: 
718   
 751  
719  752  f_0(z) = \operatorname{Bi}(z) 
720   
721   f_n(z) = \int_0^z f_{n1}(t) dt. 
722  753  
723    ``x``. The argument of the function. 
 754  f_n(z) = \int_0^z f_{n1}(t) dt 
724  755  
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)` 
728  761  
729  762  EXAMPLES:: 
730  763  
731   sage: n,x=var('n x') 
 764  sage: n, x = var('n x') 
732  765  sage: airy_bi(x) 
733  766  airy_bi(x) 
734  767  
735  768  It can return derivatives or integrals:: 
736   
737   sage: airy_bi(1,x) 
 769  
 770  sage: airy_bi(1, x) 
738  771  airy_bi_prime(x) 
739   sage: airy_bi(2,x) 
 772  sage: airy_bi(2, x) 
740  773  x*airy_bi(x) 
741   sage: airy_bi(2,x,True) 
 774  sage: airy_bi(2, x, hold_derivative=True) 
742  775  airy_bi(2, x) 
743   sage: airy_bi(2,x) 
 776  sage: airy_bi(2, x) 
744  777  airy_bi(2, x) 
745  778  sage: airy_bi(n, x) 
746  779  airy_bi(n, x) 
747  780  
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:: 
749  783  
750  784  sage: airy_bi(0) 
751   1/3*3^(5/6)/gamma(1/3) 
 785  1/3*3^(5/6)/gamma(2/3) 
752  786  sage: airy_bi(0.0) 
753  787  0.614926627446001 
754  788  sage: airy_bi(I) 
… 
… 

756  790  sage: airy_bi(1.0*I) 
757  791  0.648858208330395 + 0.344958634768048*I 
758  792  
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:: 
761  796  
762  797  sage: airy_bi(2).n(prec=100) 
763  798  3.2980949999782147102806044252 
764   sage: airy_bi(2).n(algorithm='mpmath',prec=100) 
 799  sage: airy_bi(2).n(algorithm='mpmath', prec=100) 
765  800  3.2980949999782147102806044252 
766  801  sage: airy_bi(2).n(algorithm='maxima') 
767  802  3.29809499998 
768  803  
769  804  And the derivatives can be evaluated:: 
770  805  
771   sage: airy_bi(1,0) 
 806  sage: airy_bi(1, 0) 
772  807  3^(1/6)/gamma(1/3) 
773   sage: airy_bi(1,0.0) 
 808  sage: airy_bi(1, 0.0) 
774  809  0.448288357353826 
775  810  
776  811  Plots:: 
777  812  
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  
780  816  **References** 
781   
 817  
782  818   Abramowitz, Milton; Stegun, Irene A., eds. (1965), "Chapter 10" 
783  819  
784  820   http://en.wikipedia.org/wiki/Airy_function 
785  821  """ 
 822  # We catch the case with no alpha 
 823  if x is None: 
 824  x = alpha 
 825  return airy_bi_simple(x, **kwds) 
786  826  
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: 
790  836  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: 
802  838  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) 
811  847  else: 
812   return airy_bi_general(alpha,x,**kwds) 
813   
 848  return airy_bi_general(alpha, x, **kwds) 