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

hypergeometric function drops keyword arguments when evaluated with mpmath #27785

Open
embray opened this issue May 6, 2019 · 1 comment
Open

Comments

@embray
Copy link
Contributor

embray commented May 6, 2019

As demonstrated by this ask.sagemath.org question, when trying to evaluate hypergeometric numerically, if it does not appear to be converging after the default number of iterations it raises an exception:

NoConvergence: Hypergeometric series converges too slowly. Try increasing maxterms.

For example:

sage: hypergeometric([4.14 + 15*I, -3.14 + 15*I],[1. - 1.12e7*I], -500000)
....:
---------------------------------------------------------------------------
NoConvergence                             Traceback (most recent call last)
<ipython-input-1-77676b9ed860> in <module>()
----> 1 hypergeometric([RealNumber('4.14') + Integer(15)*I, -RealNumber('3.14') + Integer(15)*I],[RealNumber('1.') - RealNumber('1.12e7')*I], -Integer(500000))

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/functions/hypergeometric.py in __call__(self, a, b, z, **kwargs)
    275                                         SR._force_pyobject(a),
    276                                         SR._force_pyobject(b),
--> 277                                         z, **kwargs)
    278
    279     def _print_latex_(self, a, b, z):

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/symbolic/function.pyx in sage.symbolic.function.BuiltinFunction.__call__ (build/cythonized/sage/symbolic/function.cpp:11840)()
    996             res = self._evalf_try_(*args)
    997             if res is None:
--> 998                 res = super(BuiltinFunction, self).__call__(
    999                         *args, coerce=coerce, hold=hold)
   1000

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/symbolic/function.pyx in sage.symbolic.function.Function.__call__ (build/cythonized/sage/symbolic/function.cpp:6979)()
    493                     (<Expression>args[1])._gobj, hold)
    494         elif self._nargs == 3:
--> 495             res = g_function_eval3(self._serial,
    496                     (<Expression>args[0])._gobj, (<Expression>args[1])._gobj,
    497                     (<Expression>args[2])._gobj, hold)

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/symbolic/function.pyx in sage.symbolic.function.BuiltinFunction._evalf_or_eval_ (build/cythonized/sage/symbolic/function.cpp:12952)()
   1082         original version of :meth:`_eval_` saved in :meth:`__init__`.
   1083         """
-> 1084         res = self._evalf_try_(*args)
   1085         if res is None:
   1086             return self._eval0_(*args)

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/functions/hypergeometric.py in _evalf_try_(self, a, b, z)
    336             if not any(isinstance(x, Expression) for x in args):
    337                 p = get_coercion_model().common_parent(*args)
--> 338                 return self._evalf_(a, b, z, parent=p)
    339
    340     def _evalf_(self, a, b, z, parent, algorithm=None):

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/functions/hypergeometric.py in _evalf_(self, a, b, z, parent, algorithm)
    353         aa = [rational_param_as_tuple(c) for c in a]
    354         bb = [rational_param_as_tuple(c) for c in b]
--> 355         return mpmath_utils.call(hyper, aa, bb, z, parent=parent)
    356
    357     def _tderivative_(self, a, b, z, *args, **kwargs):

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/libs/mpmath/utils.pyx in sage.libs.mpmath.utils.call (build/cythonized/sage/libs/mpmath/utils.c:6947)()
    435     try:
    436         mp.prec = prec
--> 437         y = func(*args, **kwargs)
    438     finally:
    439         mp.prec = orig

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/mpmath/functions/hypergeometric.py in hyper(ctx, a_s, b_s, z, **kwargs)
    224         elif q == 0: return ctx._hyp1f0(a_s[0][0], z)
    225     elif p == 2:
--> 226         if   q == 1: return ctx._hyp2f1(a_s, b_s, z, **kwargs)
    227         elif q == 2: return ctx._hyp2f2(a_s, b_s, z, **kwargs)
    228         elif q == 3: return ctx._hyp2f3(a_s, b_s, z, **kwargs)

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/mpmath/functions/hypergeometric.py in _hyp2f1(ctx, a_s, b_s, z, **kwargs)
    454                 T2 = ([-z],[-b], [c,ab],[a,c-b], [b,t+b],[ctx.mpq_1-ab],  rz)
    455                 return T1, T2
--> 456             v = ctx.hypercomb(h, [a,b], **kwargs)
    457
    458         # Use 1-z transformation

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/mpmath/functions/hypergeometric.py in hypercomb(ctx, function, params, discard_known_zeros, **kwargs)
    125                 v = ctx.fprod([ctx.hyper(a_s, b_s, z, **kwargs)] + \
    126                     [ctx.gamma(a) for a in alpha_s] + \
--> 127                     [ctx.rgamma(b) for b in beta_s] + \
    128                     [ctx.power(w,c) for (w,c) in zip(w_s,c_s)])
    129                 if verbose:

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/mpmath/functions/hypergeometric.py in hyper(ctx, a_s, b_s, z, **kwargs)
    224         elif q == 0: return ctx._hyp1f0(a_s[0][0], z)
    225     elif p == 2:
--> 226         if   q == 1: return ctx._hyp2f1(a_s, b_s, z, **kwargs)
    227         elif q == 2: return ctx._hyp2f2(a_s, b_s, z, **kwargs)
    228         elif q == 3: return ctx._hyp2f3(a_s, b_s, z, **kwargs)

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/mpmath/functions/hypergeometric.py in _hyp2f1(ctx, a_s, b_s, z, **kwargs)
    441     if absz <= 0.8 or (ctx.isint(a) and a <= 0 and a >= -1000) or \
    442                       (ctx.isint(b) and b <= 0 and b >= -1000):
--> 443         return ctx.hypsum(2, 1, (atype, btype, ctype), [a, b, c], z, **kwargs)
    444
    445     orig = ctx.prec

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/mpmath/ctx_mp.py in hypsum(ctx, p, q, flags, coeffs, z, accurate_small, **kwargs)
    713                 mag_dict = {}
    714             zv, have_complex, magnitude = summator(coeffs, v, prec, wp, \
--> 715                 epsshift, mag_dict, **kwargs)
    716             cancel = -magnitude
    717             jumps_resolved = True

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/mpmath/libmp/libhyper.py in _hypsum(coeffs, z, prec, wp, epsshift, magnitude_check, **kwargs)
    319         def _hypsum(coeffs, z, prec, wp, epsshift, magnitude_check, **kwargs):
    320             return hypsum_internal(p, q, param_types, ztype, coeffs, z,
--> 321                 prec, wp, epsshift, magnitude_check, kwargs)
    322
    323         return "(none)", _hypsum

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/libs/mpmath/ext_main.pyx in sage.libs.mpmath.ext_main.hypsum_internal (build/cythonized/sage/libs/mpmath/ext_main.c:28408)()
   2646     cdef mpc c
   2647     c = mpc.__new__(mpc)
-> 2648     have_complex, magn = MPF_hypsum(&c.re, &c.im, p, q, param_types, \
   2649         ztype, coeffs, z, prec, wp, epsshift, magnitude_check, kwargs)
   2650     if have_complex:

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/libs/mpmath/ext_impl.pyx in sage.libs.mpmath.ext_impl.MPF_hypsum (build/cythonized/sage/libs/mpmath/ext_impl.c:23878)()
   2212         if n > MAX:
   2213             from mpmath.libmp import NoConvergence
-> 2214             raise NoConvergence('Hypergeometric series converges too slowly. Try increasing maxterms.')
   2215
   2216         # +1 all parameters for next iteration

NoConvergence: Hypergeometric series converges too slowly. Try increasing maxterms.

However, when trying to call it like:

sage: hypergeometric([4.14 + 15*I, -3.14 + 15*I],[1. - 1.12e7*I], -500000, maxterms=1e6)

it just gives

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-29457394b902> in <module>()
----> 1 hypergeometric([RealNumber('4.14') + Integer(15)*I, -RealNumber('3.14') + Integer(15)*I],[RealNumber('1.') - RealNumber('1.12e7')*I], -Integer(500000), maxterms=RealNumber('1e6'))
      2

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/functions/hypergeometric.py in __call__(self, a, b, z, **kwargs)
    275                                         SR._force_pyobject(a),
    276                                         SR._force_pyobject(b),
--> 277                                         z, **kwargs)
    278
    279     def _print_latex_(self, a, b, z):

/home/embray/src/sagemath/sage-python3/local/lib/python3.7/site-packages/sage/symbolic/function.pyx in sage.symbolic.function.BuiltinFunction.__call__ (build/cythonized/sage/symbolic/function.cpp:10399)()
    895                 evalf_params_first, alt_name = alt_name)
    896
--> 897     def __call__(self, *args, bint coerce=True, bint hold=False,
    898             bint dont_call_method_on_arg=False):
    899         r"""

TypeError: __call__() got an unexpected keyword argument 'maxterms'

So, somewhere in the symbolic function interface it refuses to pass through keywords that are understood only by the underlying numerical implementation.

Component: symbolics

Issue created by migration from https://trac.sagemath.org/ticket/27785

@embray embray added this to the sage-8.8 milestone May 6, 2019
@embray
Copy link
Contributor Author

embray commented Jun 14, 2019

comment:1

As the Sage-8.8 release milestone is pending, we should delete the sage-8.8 milestone for tickets that are not actively being worked on or that still require significant work to move forward. If you feel that this ticket should be included in the next Sage release at the soonest please set its milestone to the next release milestone (sage-8.9).

@embray embray removed this from the sage-8.8 milestone Jun 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant