Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of appellf1 #14882

Merged
merged 9 commits into from Jul 9, 2018
@@ -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))

This comment has been minimized.

Copy link
@asmeurer

asmeurer Jul 7, 2018

Member

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

This comment has been minimized.

Copy link
@ashishkg0022

ashishkg0022 Jul 7, 2018

Author Contributor

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

This comment has been minimized.

Copy link
@Upabjojr

Upabjojr Jul 7, 2018

Contributor

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

This comment has been minimized.

Copy link
@asmeurer

asmeurer Jul 7, 2018

Member

It should already work automatically.

>>> 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

This comment has been minimized.

Copy link
@asmeurer

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.