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

Undefined Functions should not use the evalf name lookup scheme #6938

Closed
sympy-issue-migrator opened this Issue May 21, 2013 · 9 comments

Comments

Projects
None yet
6 participants
@sympy-issue-migrator

sympy-issue-migrator commented May 21, 2013

If I run sympy.S("ceil(2.3)").evalf() with sympy 0.7.1 then I get 3.  However, if I run the same using sympy 0.7.2 then I get an AttributeError (see below).  I discovered that switching to use ceiling() instead of ceil() works, but I have no idea why ceil() disappeared in the first place.  Someone in IRC told me that the AttributeError was not the correct behaviour for 0.7.2 either.

In [32]: S("ceil(2.3)").evalf()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-32-82d9887af7f2> in <module>()
----> 1 S("ceil(2.3)").evalf()

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/sympify.pyc in sympify(a, locals, convert_xor, strict, rational)
    176     try:
    177         a = a.replace('\n', '')
--> 178         expr = parse_expr(a, locals or {}, rational, convert_xor)
    179     except (TokenError, SyntaxError):
    180         raise SympifyError('could not parse %r' % a)

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/parsing/sympy_parser.pyc in parse_expr(s, local_dict, rationalize, convert_xor)
    160 
    161     code = _transform(s.strip(), local_dict, global_dict, rationalize, convert_xor)
--> 162     expr = eval(code, global_dict, local_dict) # take local objects in preference
    163 
    164     if not hit:

<string> in <module>()

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/symbol.pyc in __call__(self, *args)
    111     def __call__(self, *args):
    112         from function import Function
--> 113         return Function(self.name)(*args)
    114 
    115     def as_real_imag(self, deep=True, **hints):

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/function.pyc in __new__(cls, *args, **options)
    596         args = map(sympify, args)
    597         result = super(AppliedUndef, cls).__new__(cls, *args, **options)
--> 598         result.nargs = len(args)
    599         return result
    600 

AttributeError: 'Float' object has no attribute 'nargs'

Original issue for #6938: http://code.google.com/p/sympy/issues/detail?id=3839
Original author: https://code.google.com/u/113990760755850617280/

@asmeurer

This comment has been minimized.

Member

asmeurer commented May 20, 2013

The evalf has nothing to do with it. Just S("ceil(2.3)") does it. It is somehow getting confused by the name "ceil", probably due to automatic evalf lookup.

The parsing is also unrelated

In [4]: Function("ceil")(2.3)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-5705e9025752> in <module>()
----> 1 Function("ceil")(2.3)

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/core/function.pyc in __new__(cls, *args, **options)
    623         args = map(sympify, args)
    624         result = super(AppliedUndef, cls).__new__(cls, *args, **options)
--> 625         result.nargs = len(args)
    626         return result
    627

AttributeError: 'Float' object has no attribute 'nargs'

Probably the automatic evalf name lookup algorithm should be disabled on undefined Functions.  This happens with any "known" function name

In [7]: Function("sin")(2.)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-28214059820b> in <module>()
----> 1 Function("sin")(2.)

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/core/function.pyc in __new__(cls, *args, **options)
    623         args = map(sympify, args)
    624         result = super(AppliedUndef, cls).__new__(cls, *args, **options)
--> 625         result.nargs = len(args)
    626         return result
    627

AttributeError: 'Float' object has no attribute 'nargs'

**Status:** Valid  

Original comment: http://code.google.com/p/sympy/issues/detail?id=3839#c1
Original author: https://code.google.com/u/asmeurer@gmail.com/

@asmeurer

This comment has been minimized.

Member

asmeurer commented May 20, 2013

@asmeurer

This comment has been minimized.

Member

asmeurer commented May 20, 2013

**Summary:** Undefined Functions should not use the evalf name lookup scheme  <span class="oldvalue"> (was: ceil/ceiling: Difference between 0.7.2 and 0.7.1) </span>  

Original comment: http://code.google.com/p/sympy/issues/detail?id=3839#c3
Original author: https://code.google.com/u/asmeurer@gmail.com/

@smichr

This comment has been minimized.

Member

smichr commented Aug 14, 2014

>>> S("ceil(2.3)").evalf()
3.00000000000000

@smichr smichr closed this Aug 14, 2014

@asmeurer

This comment has been minimized.

Member

asmeurer commented Aug 23, 2014

Isn't this wrong?

In [1]: Function("ceil")(2.3)
Out[1]: 3.00000000000000

@asmeurer asmeurer reopened this Aug 23, 2014

@debugger22

This comment has been minimized.

Member

debugger22 commented Aug 23, 2014

You mean, it should be an int?

@asmeurer

This comment has been minimized.

Member

asmeurer commented Aug 23, 2014

No it shouldn't be evaluated at all.

@comer

This comment has been minimized.

Contributor

comer commented Aug 23, 2014

@asmeurer you mean "No it should not be evaluated at all.", right?

By the way i get the same behavior for sin in place of ceil.

@asmeurer

This comment has been minimized.

Member

asmeurer commented Aug 23, 2014

Yes, sorry. Function('sin') should be completely separate from sympy.functions.elementary.sin

cbm755 added a commit to cbm755/sympy that referenced this issue Aug 13, 2018

UndefinedFunction should not evalf
Suppose we call `Function('sin')` to create an UndefinedFunction.  It has
a suspcious name but is nevertheless still an undefined function and so
it should not evalf.  Add tests.  Fixes sympy#6938.

The fix is to return early in the `_eval_evalf` if the `func` is an
`UndefinedFunction`, instead of looking through mpmath tables for a match etc.
Thanks to @smichr for this hint.

Note I first tried to fix this by introducing `UndefinedFunction._eval_evalf`.
The reason that does not work is that `f(x)` is not itself an
`UndefinedFunction` (only `f` is).

skirpichev added a commit to skirpichev/diofant that referenced this issue Aug 18, 2018

UndefinedFunction should not evalf
Suppose we call `Function('sin')` to create an UndefinedFunction.  It has
a suspcious name but is nevertheless still an undefined function and so
it should not evalf.  Add tests.  Fixes sympy/sympy#6938.

The fix is to return early in the `_eval_evalf` if the `func` is an
`UndefinedFunction`, instead of looking through mpmath tables for a match etc.
Thanks to @smichr for this hint.

Note I first tried to fix this by introducing `UndefinedFunction._eval_evalf`.
The reason that does not work is that `f(x)` is not itself an
`UndefinedFunction` (only `f` is).

// edited by skirpichev
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment