# Implementation of appellf1 #14882

Merged
merged 9 commits into from Jul 9, 2018
Merged

# Implementation of appellf1#14882

Commits
Show all changes
9 commits
Select commit Hold shift + click to select a range
Filter file types
Failed to load files and symbols.
+41 −0

#### Just for now

@@ -12,6 +12,8 @@
from sympy.functions import (sqrt, exp, log, sin, cos, asin, atan,
sinh, cosh, asinh, acosh, atanh, acoth, Abs)

from mpmath import appellf1 as apl

class TupleArg(Tuple):
def limit(self, x, xlim, dir='+'):
""" Compute limit x->xlim.
@@ -1043,3 +1045,42 @@ def _expr_big(cls, a, z, n):
@classmethod
def _expr_big_minus(cls, a, z, n):
return -1/sqrt(1 + 1/z)*sinh(2*a*asinh(sqrt(z)) + 2*a*pi*I*n)

class appellf1(Function):
'''
This is the Appell hypergeometric function of two variables as:
.. math ::
F_1(a,b_1,b_2,c,x,y) = \sum_{m=0}^{\infty} \sum_{n=0}^{\infty}
\frac{(a)_{m+n} (b_1)_m (b_2)_n}{(c)_{m+n}}
\frac{x^m y^n}{m! n!}.
References
==========
.. [1] https://en.wikipedia.org/wiki/Appell_series
.. [2] http://functions.wolfram.com/HypergeometricFunctions/AppellF1/
'''
@classmethod
def eval(cls, a, b1, b2, c, x, y):
if all(i.is_number for i in (a, b1, b2, c, x, y)):
return S(apl(a, b1, b2, c, x, y))

#### asmeurer Jul 7, 2018

Member

I don't think this is the proper way to get automatic numeric evaluation.

#### ashishkg0022 Jul 7, 2018

Author Contributor

can't we use mpmath's appellf1 to perform numeric evaluation ?

#### Upabjojr Jul 7, 2018

Contributor

Well, mpmath is for .evalf, not for .eval.

#### asmeurer Jul 7, 2018

Member

>>> class appellf1(Function):
...     nargs = 6
>>> appellf1(1., 2., 3., 4., 5., 6.)
-0.151473567018263


That's because Function subclasses automatically work with evalf if they use the same name as their mpmath counterpart, and _should_evalf (which is the proper way to do this) defaults to evalfing on float inputs.

def _eval_rewrite_as_factorial(self, *args):
from sympy import symbols, Sum, RisingFactorial, factorial
m, n = symbols('m n', integer = True)
a, b1, b2, c, x, y = (i for i in self.args)
return Sum(x**m*y**n*RisingFactorial(a, m + n)*RisingFactorial(b1, m)*\
RisingFactorial(b2, n)/(factorial(m)*factorial(n)*RisingFactorial(c, m + n)), (m, 0, zoo), (n, 0, zoo)).rewrite(factorial)

def fdiff(self, *args):
if len(args) == 1:
a, b1, b2, c, x, y = (i for i in self.args)
if args[0] == 5:
return (a*b1/c)*appellf1(a + 1, b1 + 1, b2, c + 1, x, y)
elif args[0] == 6:
return (a*b2/c)*appellf1(a + 1, b1, b2 + 1, c + 1, x, y)
else:
return NotImplemented

#### asmeurer Jul 7, 2018

Member

Does fdiff recognize NotImplemented? I don't recall any SymPy APIs using it.

else:
return NotImplemented
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.