How do you replace a function argument with a float?

54 views
Skip to first unread message

Jason Moore

unread,
Mar 10, 2016, 1:33:38 PM3/10/16
to sy...@googlegroups.com
I don't understand this behavior:

Python 3.5.1 |Continuum Analytics, Inc.| (default, Dec  7 2015, 11:16:01)
Type "copyright", "credits" or "license" for more information.

IPython 4.1.2 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from sympy import *

In [2]: phi = symbols('phi', cls=Function)

In [3]: t = symbols('t')

In [4]: phi(t).xreplace({t: 0})
Out[4]: phi(0)

In [5]: phi(t).xreplace({t: 0.0})
Out[5]: 1.61803398874989

In [6]: phi(t).xreplace({t: 5.0})
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/core/evalf.py in evalf(x, prec, options)
   1209     try:
-> 1210         rf = evalf_table[x.func]
   1211         r = rf(x, prec, options)

KeyError: phi

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-6-ec5c48b4cb2f> in <module>()
----> 1 phi(t).xreplace({t: 5.0})

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/core/basic.py in xreplace(self, rule)
   1086             args = tuple(args)
   1087             if not _aresame(args, self.args):
-> 1088                 return self.func(*args)
   1089         return self
   1090

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/core/function.py in __new__(cls, *args, **options)
    683     def __new__(cls, *args, **options):
    684         args = list(map(sympify, args))
--> 685         obj = super(AppliedUndef, cls).__new__(cls, *args, **options)
    686         return obj
    687

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/core/function.py in __new__(cls, *args, **options)
    380         pr2 = min(cls._should_evalf(a) for a in result.args)
    381         if pr2 > 0:
--> 382             return result.evalf(mlib.libmpf.prec_to_dps(pr))
    383         return result
    384

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/core/evalf.py in evalf(self, n, subs, maxn, chop, strict, quad, verbose)
   1315             options['quad'] = quad
   1316         try:
-> 1317             result = evalf(self, prec + 4, options)
   1318         except NotImplementedError:
   1319             # Fall back to the ordinary evalf

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/core/evalf.py in evalf(x, prec, options)
   1215             if 'subs' in options:
   1216                 x = x.subs(evalf_subs(prec, options['subs']))
-> 1217             re, im = x._eval_evalf(prec).as_real_imag()
   1218             if re.has(re_) or im.has(im_):
   1219                 raise NotImplementedError

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/core/function.py in _eval_evalf(self, prec)
    484
    485         with mpmath.workprec(prec):
--> 486             v = func(*args)
    487
    488         return Expr._from_mpmath(v, prec)

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/mpmath/ctx_mp_python.py in __call__(self, prec, dps, rounding)
    344         if not rounding: rounding = rounding2
    345         if dps: prec = dps_to_prec(dps)
--> 346         return self.context.make_mpf(self.func(prec, rounding))
    347
    348     @property

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/mpmath/libmp/libelefun.py in f(prec, rnd)
    114     def f(prec, rnd=round_fast):
    115         wp = prec + 20
--> 116         v = fixed(wp)
    117         if rnd in (round_up, round_ceiling):
    118             v += 1

/home/moorepants/miniconda3/lib/python3.5/site-packages/sympy/mpmath/libmp/libelefun.py in g(prec, **kwargs)
     95         memo_prec = f.memo_prec
     96         if prec <= memo_prec:
---> 97             return f.memo_val >> (memo_prec-prec)
     98         newprec = int(prec*1.05+10)
     99         f.memo_val = f(newprec, **kwargs)

TypeError: unsupported operand type(s) for >>: 'int' and 'mpf'

Can someone explain to me what is going on? I would expect "t" to be simply replaced with the number.

Sartaj Singh

unread,
Mar 10, 2016, 1:54:54 PM3/10/16
to sympy
Apparently, this also does not work,

# leosartaj at Mothership in ~/projects/sympy on git:master o [0:09:48]
$ isympy
IPython console for SymPy 1.0.1.dev (Python 2.7.11-64-bit) (ground types: python)

These commands were executed:
>>> from __future__ import division
>>> from sympy import *
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)
>>> init_printing()

Documentation can be found at http://docs.sympy.org/dev

In [1]: phi = symbols('phi', cls=Function)

In [2]: phi(5.0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-68868fcc8946> in <module>()
----> 1 phi(5.0)

/home/leosartaj/projects/sympy/sympy/core/function.pyc in __new__(cls, *args, **options)
    718     def __new__(cls, *args, **options):
    719         args = list(map(sympify, args))
--> 720         obj = super(AppliedUndef, cls).__new__(cls, *args, **options)
    721         return obj
    722 

/home/leosartaj/projects/sympy/sympy/core/cache.pyc in wrapper(*args, **kwargs)
     93                     retval = cfunc(*args, **kwargs)
     94                 except TypeError:
---> 95                     retval = func(*args, **kwargs)
     96                 return retval
     97 

/home/leosartaj/projects/sympy/sympy/core/function.pyc in __new__(cls, *args, **options)
    390         pr2 = min(cls._should_evalf(a) for a in result.args)
    391         if pr2 > 0:
--> 392             return result.evalf(mlib.libmpf.prec_to_dps(pr))
    393         return result
    394 

/home/leosartaj/projects/sympy/sympy/core/evalf.pyc in evalf(self, n, subs, maxn, chop, strict, quad, verbose)
   1384             options['quad'] = quad
   1385         try:
-> 1386             result = evalf(self, prec + 4, options)
   1387         except NotImplementedError:
   1388             # Fall back to the ordinary evalf

/home/leosartaj/projects/sympy/sympy/core/evalf.pyc in evalf(x, prec, options)
   1282             if 'subs' in options:
   1283                 x = x.subs(evalf_subs(prec, options['subs']))
-> 1284             xe = x._eval_evalf(prec)
   1285             re, im = xe.as_real_imag()
   1286             if re.has(re_) or im.has(im_):

/home/leosartaj/projects/sympy/sympy/core/function.pyc in _eval_evalf(self, prec)
    501 
    502         with mpmath.workprec(prec):
--> 503             v = func(*args)
    504 
    505         return Expr._from_mpmath(v, prec)

/home/leosartaj/anaconda/envs/my/lib/python2.7/site-packages/mpmath/ctx_mp_python.pyc in __call__(self, prec, dps, rounding)
    344         if not rounding: rounding = rounding2
    345         if dps: prec = dps_to_prec(dps)
--> 346         return self.context.make_mpf(self.func(prec, rounding))
    347 
    348     @property

/home/leosartaj/anaconda/envs/my/lib/python2.7/site-packages/mpmath/libmp/libelefun.pyc in f(prec, rnd)
    114     def f(prec, rnd=round_fast):
    115         wp = prec + 20
--> 116         v = fixed(wp)
    117         if rnd in (round_up, round_ceiling):
    118             v += 1

/home/leosartaj/anaconda/envs/my/lib/python2.7/site-packages/mpmath/libmp/libelefun.pyc in g(prec, **kwargs)
     95         memo_prec = f.memo_prec
     96         if prec <= memo_prec:
---> 97             return f.memo_val >> (memo_prec-prec)
     98         newprec = int(prec*1.05+10)
     99         f.memo_val = f(newprec, **kwargs)

TypeError: unsupported operand type(s) for >>: 'long' and 'mpf'


This does work though,

>>> phi(5)
φ(5)

However,

>>> p = symbols('p', cls=Function)    
>>>  p(5.0)
p(5.0)

>>> p(t).xreplace({t: 5.0})  
p(5.0) # works without any problems


By My understanding, is symbols with cls=Function arg not expected to make an undefined function?

Aaron Meurer

unread,
Mar 10, 2016, 2:02:10 PM3/10/16
to sy...@googlegroups.com
Since this seems to break only when the function name is "phi", this
looks like an instance of https://github.com/sympy/sympy/issues/6938.
But I'm not quite sure what other SymPy function is named "phi". I
didn't find any in a quick grep.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/b40c4bb2-e74a-4399-8a40-879e380ea65e%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Aaron Meurer

unread,
Mar 10, 2016, 2:03:40 PM3/10/16
to sy...@googlegroups.com
Oh maybe it's just looking up the mpmath function named phi. We do have

In [7]: import mpmath

In [8]: mpmath.phi
Out[8]: <Golden ratio phi: 1.61803~>

Aaron Meurer

Sartaj Singh

unread,
Mar 10, 2016, 2:04:09 PM3/10/16
to sy...@googlegroups.com
Also type(phi) gives sympy.core.function.UndefinedFunction. This is confusing.


For more options, visit https://groups.google.com/d/optout.



--
Regards
Sartaj Singh

Mathematics and Computing,
Indian Institute of Technology,
Varanasi - 221 005 INDIA

Isuru Fernando

unread,
Mar 10, 2016, 2:05:06 PM3/10/16
to sy...@googlegroups.com

Aaron Meurer

unread,
Mar 10, 2016, 2:13:08 PM3/10/16
to sy...@googlegroups.com
That is the issue here. The problem is that undefined functions do
evalf name lookups. For example

In [9]: Function("sin")(1.0)
Out[9]: 0.841470984807897

We should change it so that only direct subclasses of Function do
this, not UndefinedFunctions.

In the mean time, Jason, a workaround would be to use Function(u'φ').

Aaron Meurer
> https://groups.google.com/d/msgid/sympy/CAC%2BH8-GshNsi%2BRheh50aHcXsMeQS5KBsJLOG%3DtRUGqGZCkgotg%40mail.gmail.com.

Jason Moore

unread,
Mar 10, 2016, 2:17:13 PM3/10/16
to sy...@googlegroups.com
Thanks for explaining this. I'll try to look into pushing a fix for this.
Reply all
Reply to author
Forward
0 new messages